<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" v-for="rule in rules.getPointsRuleList">
|
<h4>{{ rule.category}}</h4>
|
<div class="rule-subcategory">
|
<div class="rule-items">
|
<div class="rule-item" v-for="pointRuleDetial in rule.pointsRules">
|
<span class="rule-desc">{{ pointRuleDetial.ruleName }} : {{ pointRuleDetial.ruleDescription}} </span>
|
<el-input
|
v-model="pointRuleDetial.pointsValue"
|
size="small"
|
style="width: 50px;"
|
placeholder="请输入"
|
readonly
|
/>
|
<span class="unit">积分</span>
|
<span class="unit" v-if="pointRuleDetial.isLimit === 1">,每日积分上限</span>
|
<el-input
|
v-model="pointRuleDetial.dailyLimit"
|
size="small"
|
style="width: 50px;"
|
placeholder="请输入"
|
readonly
|
v-if="pointRuleDetial.isLimit === 1"
|
/>
|
</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" v-for="consumeRule in rules.consumePointsRuleList">
|
<h4>{{ consumeRule.category }}</h4>
|
<div class="rule-subcategory">
|
<div class="rule-items">
|
<div class="rule-item" v-for="pointRuleDetials in consumeRule.pointsRules">
|
<span class="rule-desc">{{ pointRuleDetials.ruleName }} : {{ pointRuleDetials.ruleDescription}}</span>
|
<el-input
|
v-model="pointRuleDetials.pointsValue"
|
size="small"
|
style="width: 50px;"
|
placeholder="请输入"
|
readonly
|
/>
|
<span class="unit">积分</span>
|
<span class="unit" v-if="pointRuleDetials.isLimit === 1">,每日积分上限</span>
|
<el-input
|
v-model="pointRuleDetials.dailyLimit"
|
size="small"
|
style="width: 50px;"
|
placeholder="请输入"
|
readonly
|
v-if="pointRuleDetials.isLimit === 1"
|
/>
|
</div>
|
</div>
|
</div>
|
</div>
|
|
</el-card>
|
</div>
|
</div>
|
|
<!-- 底部按钮 -->
|
<div class="bottom-actions">
|
<el-button @click="goBack" size="large">返回</el-button>
|
</div>
|
</div>
|
</template>
|
|
<script setup lang="ts">
|
import { ref, onMounted, watch } from 'vue'
|
import { useRoute } from 'vue-router'
|
import { ElMessage } from 'element-plus'
|
import pointsApi from '../../../api/pointsApi'
|
|
// 定义props
|
interface Props {
|
ruleId?: string
|
}
|
|
const props = withDefaults(defineProps<Props>(), {
|
ruleId: ''
|
})
|
|
// 定义emits
|
const emit = defineEmits<{
|
goBack: []
|
}>()
|
|
// 获取路由实例
|
const route = useRoute()
|
// 获取路由参数中的规则id,优先使用props中的ruleId
|
const ruleId = props.ruleId || (route.query.ruleId as string)
|
|
interface PointRule {
|
category: string,
|
pointsRules: PointRuleDetial[]
|
}
|
interface PointRuleDetial {
|
category: string,
|
id: number,
|
ruleDescription: string,
|
ruleName: string,
|
createdAt: string,
|
ruleType: number,
|
pointsWinner: number,
|
isLimit: number,
|
pointsValue: number,
|
dailyLimit: number
|
}
|
|
// 积分规则配置
|
interface PointsRules {
|
getPointsRuleList: PointRule[],
|
consumePointsRuleList: PointRule[]
|
}
|
|
const rules = ref<PointsRules>({
|
consumePointsRuleList: [],
|
getPointsRuleList: []
|
})
|
|
// 获取积分规则配置
|
const getPointsRules = async () => {
|
try {
|
if (ruleId) {
|
// 如果有ruleId参数,则获取特定规则
|
const formData = new URLSearchParams();
|
formData.append('ruleId', ruleId);
|
|
const res = await pointsApi.getPointsRuleById(formData)
|
if (res.code === 200 && res.data) {
|
res.data.getPointsRuleList.map(item => {
|
item.pointsRules.map(iitem => {
|
if(iitem.ruleDescription.indexOf('被') > -1){
|
iitem.descSort = 0
|
}else{
|
iitem.descSort = 1
|
}
|
return iitem
|
})
|
item.pointsRules.sort((a,b) => {
|
if(a.ruleName === b.ruleName){
|
return a.descSort - b.descSort
|
}else {
|
return a.ruleName.localeCompare(b.ruleName)
|
}
|
})
|
})
|
res.data.consumePointsRuleList.map(item => {
|
item.pointsRules.map(iitem => {
|
if(iitem.ruleDescription.indexOf('被') > -1){
|
iitem.descSort = 0
|
}else{
|
iitem.descSort = 1
|
}
|
return iitem
|
})
|
item.pointsRules.sort((a,b) => {
|
if(a.ruleName === b.ruleName){
|
return a.descSort - b.descSort
|
}else {
|
return a.ruleName.localeCompare(b.ruleName)
|
}
|
})
|
})
|
// 将后端数据映射到前端规则对象
|
Object.assign(rules.value, res.data)
|
}
|
} else {
|
// 如果没有ruleId参数,则获取所有规则
|
const res = await pointsApi.getPointsRules({})
|
if (res.code === 200 && res.data) {
|
// 将后端数据映射到前端规则对象
|
Object.assign(rules.value, res.data)
|
}
|
}
|
} catch (error) {
|
console.error('获取积分规则失败:', error)
|
}
|
}
|
|
// 返回上一页
|
const goBack = () => {
|
// 如果是从组件调用,发出goBack事件
|
if (props.ruleId) {
|
emit('goBack')
|
} else {
|
// 否则使用原有的返回逻辑
|
history.back()
|
}
|
}
|
|
// 监听ruleId变化
|
watch(() => props.ruleId, (newRuleId) => {
|
if (newRuleId) {
|
getPointsRules()
|
}
|
}, { immediate: true })
|
|
onMounted(() => {
|
// 只有在没有props.ruleId时才执行原有的逻辑
|
if (!props.ruleId) {
|
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 {
|
.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 {
|
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;
|
background-color: #f5f7fa;
|
|
&:hover {
|
box-shadow: 0 0 0 1px #c0c4cc inset;
|
}
|
|
&.is-focus {
|
box-shadow: 0 0 0 1px #409eff inset;
|
}
|
}
|
|
.el-input__inner {
|
color: #606266;
|
cursor: not-allowed;
|
}
|
}
|
}
|
}
|
}
|
</style>
|