<template>
|
<div class="points-settings">
|
<div class="settings-content">
|
<!-- 左侧:积分获取规则 -->
|
<div class="left-column">
|
<el-card class="rule-section" shadow="never">
|
<template #header>
|
<div class="card-header">
|
<span class="section-title">积分获取规则</span>
|
</div>
|
</template>
|
|
<!-- 资源贡献 -->
|
<div class="rule-category">
|
<h4>资源贡献</h4>
|
<div class="rule-subcategory">
|
<h5>提报标杆</h5>
|
<div class="rule-items">
|
|
<div class="rule-item">
|
<span class="rule-desc">每提报1个标杆,并审批完成,获</span>
|
<el-input
|
v-model="rules.benchmarkSubmission"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>提报知识</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">每提报1个知识,并审批完成,获</span>
|
<el-input
|
v-model="rules.knowledgeSubmission"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>提报产品</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">每提报1个产品,并审批完成,获</span>
|
<el-input
|
v-model="rules.productSubmission"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
|
</div>
|
|
<!-- 资源交易 -->
|
<div class="rule-category">
|
<h4>资源交易</h4>
|
<div class="rule-subcategory">
|
<h5>产品接入</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">每接入1个产品,获</span>
|
<el-input
|
v-model="rules.productAccess"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>资源交易</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">每交易1个资源,获</span>
|
<el-input
|
v-model="rules.resourceTransaction"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<!-- 资源传播 -->
|
<div class="rule-category">
|
<h4>资源传播</h4>
|
<div class="rule-subcategory">
|
<h5>数字资源</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被订阅,获</span>
|
<el-input
|
v-model="rules.productSubscribed"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.productSubscribedDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被试用,获</span>
|
<el-input
|
v-model="rules.productTrialed"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.productTrialedDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被点赞,获</span>
|
<el-input
|
v-model="rules.resourceLiked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.resourceLikedDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
<!-- 后端无此规则,移除此项(如后端后续支持再开启) -->
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被试用,获</span>
|
<el-input
|
v-model="rules.productTrialed"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.productTrialedDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
</div>
|
</div>
|
|
</div>
|
|
<!-- 用户参与 -->
|
<div class="rule-category">
|
<h4>用户参与</h4>
|
<div class="rule-subcategory">
|
<h5>交流互动</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">每日首次登录,获</span>
|
<el-input
|
v-model="rules.dailyFirstLogin"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">发布提问,获</span>
|
<el-input
|
v-model="rules.postQuestion"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.postQuestionDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">发布评论,获</span>
|
<el-input
|
v-model="rules.postComment"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.postCommentDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">评论被点赞,获</span>
|
<el-input
|
v-model="rules.commentLiked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分,每日积分上限</span>
|
<el-input
|
v-model="rules.commentLikedDailyLimit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
<!-- 其他 -->
|
<div class="rule-category">
|
<h4>其他</h4>
|
<div class="rule-subcategory">
|
<h5>荣誉奖励</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">提报产品每月交易量TOP1,获</span>
|
<el-input
|
v-model="rules.monthlyTop1"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品每月交易量TOP2,获</span>
|
<el-input
|
v-model="rules.monthlyTop2"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品每月交易量TOP3,获</span>
|
<el-input
|
v-model="rules.monthlyTop3"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
|
<!-- 右侧:积分消耗规则和积分转换规则 -->
|
<div class="right-column">
|
<!-- 积分消耗规则 -->
|
<el-card class="rule-section" shadow="never">
|
<template #header>
|
<div class="card-header">
|
<span class="section-title">积分消耗规则</span>
|
</div>
|
</template>
|
|
<!-- 资源传播 -->
|
<div class="rule-category">
|
<h4>资源传播</h4>
|
<div class="rule-subcategory">
|
<h5>数字资源</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被取消收藏,扣除</span>
|
<el-input
|
v-model="rules.productUnfavorited"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被取消点赞,扣除</span>
|
<el-input
|
v-model="rules.productUnliked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>产品订阅</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被取消订阅,扣除</span>
|
<el-input
|
v-model="rules.productUnfavorited"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">提报产品被取消试用,扣除</span>
|
<el-input
|
v-model="rules.productUnliked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>交流社区</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">删除提问,扣除</span>
|
<el-input
|
v-model="rules.productUnfavorited"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">删除评论,扣除</span>
|
<el-input
|
v-model="rules.productUnliked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">评论被取消点赞,扣除</span>
|
<el-input
|
v-model="rules.productUnliked"
|
size="small"
|
style="width: 60px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
</el-card>
|
|
<!-- 积分转换规则 -->
|
<el-card class="rule-section" shadow="never">
|
<template #header>
|
<div class="card-header">
|
<span class="section-title">积分转换规则</span>
|
</div>
|
</template>
|
|
<div class="rule-category">
|
<h4>积分转换</h4>
|
<div class="rule-subcategory">
|
<h5>数字化标杆积分转换</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">数字化标杆个人</span>
|
<el-input
|
v-model="rules.benchmarkPersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化标杆单位</span>
|
<el-input
|
v-model="rules.benchmarkUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">数字化标杆单位</span>
|
<el-input
|
v-model="rules.benchmarkUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化标杆个人</span>
|
<el-input
|
v-model="rules.benchmarkPersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>数字化知识积分转换</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">数字化知识个人</span>
|
<el-input
|
v-model="rules.knowledgePersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化知识单位</span>
|
<el-input
|
v-model="rules.knowledgeUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">数字化知识单位</span>
|
<el-input
|
v-model="rules.knowledgeUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化知识个人</span>
|
<el-input
|
v-model="rules.knowledgePersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
<div class="rule-subcategory">
|
<h5>数字化产品积分转换</h5>
|
<div class="rule-items">
|
<div class="rule-item">
|
<span class="rule-desc">数字化产品个人</span>
|
<el-input
|
v-model="rules.productPersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化产品单位</span>
|
<el-input
|
v-model="rules.productUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
<div class="rule-item">
|
<span class="rule-desc">数字化产品单位</span>
|
<el-input
|
v-model="rules.productUnitToPersonal"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分兑换数字化产品个人</span>
|
<el-input
|
v-model="rules.productPersonalToUnit"
|
size="small"
|
style="width: 80px;"
|
placeholder="请输入"
|
/>
|
<span class="unit">积分</span>
|
</div>
|
</div>
|
</div>
|
</div>
|
</el-card>
|
</div>
|
</div>
|
|
<!-- 底部按钮 -->
|
<div class="bottom-actions">
|
<el-button @click="goBack" size="large">返回</el-button>
|
<el-button type="primary" @click="saveRules" size="large">保存</el-button>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, onMounted } from 'vue'
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
import { ArrowLeft } from '@element-plus/icons-vue'
|
import pointsApi from '../../../api/pointsApi'
|
|
// 积分规则配置
|
const rules = ref({
|
// 积分获取规则
|
benchmarkSubmission: 100,
|
knowledgeSubmission: 100,
|
productSubmission: 200,
|
productAccess: 1000,
|
resourceTransaction: 50,
|
resourceFavorited: 1,
|
resourceFavoritedDailyLimit: 100,
|
resourceLiked: 1,
|
resourceLikedDailyLimit: 100,
|
resourceViewThreshold: 100,
|
resourceViewed: 1,
|
resourceVideoPlayed: 5,
|
resourceDocumentViewed: 2,
|
productSubscribed: 10,
|
productSubscribedDailyLimit: 500,
|
productTrialed: 5,
|
productTrialedDailyLimit: 200,
|
dailyFirstLogin: 1,
|
postQuestion: 1,
|
postQuestionDailyLimit: 50,
|
postComment: 1,
|
postCommentDailyLimit: 100,
|
commentLiked: 1,
|
commentLikedDailyLimit: 50,
|
// 其他演示字段(后端未保存这些项时会忽略)
|
monthlyTop1: 1000,
|
monthlyTop2: 500,
|
monthlyTop3: 300,
|
|
// 积分消耗规则
|
resourceUnfavorited: 1,
|
resourceUnliked: 1,
|
productUnsubscribed: 10,
|
productUntrialed: 5,
|
deleteQuestion: 1,
|
deleteComment: 1,
|
commentUnliked: 1,
|
productUnfavorited: 2,
|
productUnliked: 1,
|
|
// 积分转换规则
|
benchmarkPersonalToUnit: 100,
|
benchmarkUnitToPersonal: 100,
|
knowledgePersonalToUnit: 100,
|
knowledgeUnitToPersonal: 100,
|
productPersonalToUnit: 100,
|
productUnitToPersonal: 100,
|
})
|
|
// 获取积分规则配置
|
const getPointsRules = async () => {
|
try {
|
const res = await pointsApi.getPointsRules()
|
if (res.code === 200 && res.data) {
|
// 将后端数据映射到前端规则对象
|
Object.assign(rules.value, res.data)
|
}
|
} catch (error) {
|
console.error('获取积分规则失败:', error)
|
}
|
}
|
|
// 保存积分规则配置
|
const saveRules = async () => {
|
try {
|
await ElMessageBox.confirm('确定要保存积分规则配置吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
|
const res = await pointsApi.savePointsRules(rules.value)
|
if (res.code === 200) {
|
ElMessage.success('保存成功')
|
} else {
|
ElMessage.error(res.msg || '保存失败')
|
}
|
} catch (error) {
|
if (error !== 'cancel') {
|
console.error('保存积分规则失败:', error)
|
ElMessage.error('保存失败')
|
}
|
}
|
}
|
|
// 重置规则
|
const resetRules = async () => {
|
try {
|
await ElMessageBox.confirm('确定要重置积分规则配置吗?', '提示', {
|
confirmButtonText: '确定',
|
cancelButtonText: '取消',
|
type: 'warning',
|
})
|
|
await getPointsRules()
|
ElMessage.success('重置成功')
|
} catch (error) {
|
if (error !== 'cancel') {
|
console.error('重置积分规则失败:', error)
|
ElMessage.error('重置失败')
|
}
|
}
|
}
|
|
// 返回上一页
|
const goBack = () => {
|
history.back()
|
}
|
|
onMounted(() => {
|
getPointsRules()
|
})
|
</script>
|
|
<style scoped lang="scss">
|
.points-settings {
|
padding: 20px;
|
background-color: #f5f5f5;
|
min-height: 100vh;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
.page-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20px;
|
padding: 16px 20px;
|
background: white;
|
border-radius: 8px;
|
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
.breadcrumb {
|
display: flex;
|
align-items: center;
|
gap: 8px;
|
|
.back-arrow {
|
cursor: pointer;
|
color: #409eff;
|
font-size: 18px;
|
|
&:hover {
|
color: #66b1ff;
|
}
|
}
|
|
.title {
|
font-size: 16px;
|
font-weight: 500;
|
color: #303133;
|
}
|
}
|
|
.actions {
|
display: flex;
|
gap: 12px;
|
}
|
}
|
|
.settings-content {
|
display: flex;
|
gap: 20px;
|
max-width: 1665px;
|
margin: 0 auto;
|
margin-bottom: 40px;
|
|
@media (max-width: 768px) {
|
flex-direction: column;
|
gap: 16px;
|
}
|
}
|
|
.bottom-actions {
|
display: flex;
|
justify-content: center;
|
gap: 20px;
|
padding: 20px 0;
|
|
.el-button {
|
min-width: 120px;
|
height: 40px;
|
font-size: 14px;
|
}
|
}
|
|
.left-column {
|
flex: 1;
|
max-width: 50%;
|
|
@media (max-width: 768px) {
|
max-width: 100%;
|
}
|
}
|
|
.right-column {
|
flex: 1;
|
max-width: 50%;
|
display: flex;
|
flex-direction: column;
|
gap: 20px;
|
|
@media (max-width: 768px) {
|
max-width: 100%;
|
gap: 16px;
|
}
|
}
|
|
.rule-section {
|
border-radius: 8px;
|
border: 1px solid #e4e7ed;
|
|
.card-header {
|
// background-color: #fafafa;
|
// background-color: rgba(221, 230, 244, 1);
|
|
// border-bottom: 1px solid #e4e7ed;
|
|
.section-title {
|
font-size: 16px;
|
font-weight: 600;
|
color: #656D9A;
|
}
|
}
|
}
|
|
.rule-category {
|
margin-bottom: 24px;
|
|
h4 {
|
font-size: 14px;
|
font-weight: 600;
|
color: #303133;
|
margin: 0 0 16px 0;
|
padding-bottom: 8px;
|
border-bottom: 1px solid #ebeef5;
|
background-color: #f8f9fa;
|
padding: 8px 12px;
|
border-radius: 4px;
|
border-left: 3px solid #409eff;
|
}
|
|
.rule-subcategory {
|
margin-left: 16px;
|
margin-bottom: 16px;
|
|
h5 {
|
font-size: 13px;
|
font-weight: 500;
|
color: #606266;
|
margin: 0 0 12px 0;
|
padding-left: 8px;
|
}
|
}
|
|
.rule-items {
|
display: flex;
|
flex-direction: column;
|
margin-left: 16px;
|
gap: 8px;
|
}
|
|
.rule-item {
|
display: flex;
|
align-items: center;
|
gap: 6px;
|
padding: 6px 8px;
|
border-radius: 4px;
|
transition: background-color 0.2s;
|
|
&:hover {
|
background-color: #f5f7fa;
|
}
|
|
.rule-desc {
|
// flex: 1;
|
font-size: 13px;
|
color: #606266;
|
line-height: 1.4;
|
}
|
|
.unit {
|
font-size: 13px;
|
color: #606266;
|
white-space: nowrap;
|
}
|
|
:deep(.el-input) {
|
.el-input__wrapper {
|
box-shadow: 0 0 0 1px #dcdfe6 inset;
|
|
&:hover {
|
box-shadow: 0 0 0 1px #c0c4cc inset;
|
}
|
|
&.is-focus {
|
box-shadow: 0 0 0 1px #409eff inset;
|
}
|
}
|
}
|
}
|
}
|
}
|
</style>
|