src/api/pointsApi.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/router/modules/pointsManage.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/types/points.d.ts | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/pointsManage/personal/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/pointsManage/ruleList/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/pointsManage/settings/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/views/pointsManage/unit/index.vue | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/api/pointsApi.ts
@@ -5,7 +5,7 @@ const pointsApi = { // 积分规则设置相关接口 // 获取积分规则配置 getPointsRules(data?: object): ApiPromise { getPointsRules(data: object): ApiPromise { return createAxios({ url: `${url}main/page`, data: data, @@ -13,14 +13,14 @@ }, // 根据ID获取积分规则 getPointsRuleById(data?: object): ApiPromise { getPointsRuleById(data: URLSearchParams): ApiPromise { return createAxios({ url: `${url}rule/list`, method: 'post', data: data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, data:data, 'Content-Type': 'application/x-www-form-urlencoded' } }) as ApiPromise }, @@ -34,9 +34,9 @@ // 个人积分相关接口 // 获取个人积分统计 getPersonalPointsStats(): ApiPromise { getPersonalPointsStats(userId: number): ApiPromise { return createAxios({ url: `${url}personal/stats`, url: `${url}/total/user/` + userId, method: 'get', }) as ApiPromise }, @@ -44,7 +44,7 @@ // 获取个人积分流水 getPersonalPointsFlow(data: object): ApiPromise { return createAxios({ url: `${url}personal/flow`, url: `${url}flow/personal/page`, data: data, }) as ApiPromise }, @@ -81,6 +81,14 @@ data, }) as ApiPromise }, // 获取积分流水数据类目列表 getPointsFlowCategories(): ApiPromise { return createAxios({ url: `${url}flow/categories`, method: 'get', }) as ApiPromise }, } export default pointsApi src/router/modules/pointsManage.ts
@@ -12,6 +12,15 @@ }, }, { path: 'ruleDetail', name: 'pointsRuleDetail', component: () => import('@/views/pointsManage/ruleDetail/index.vue'), meta: { title: '积分规则详情', keepAlive: false, }, }, { path: 'settings', name: 'pointsSettings', component: () => import('@/views/pointsManage/settings/index.vue'), src/types/points.d.ts
@@ -44,6 +44,7 @@ // 查询参数接口 export interface PointsQueryParams { userId?: string // 用户ID dateRange?: string // 日期范围 dataCategory?: string // 数据类目 dataType?: string // 数据类型 @@ -54,4 +55,6 @@ day?: string // 日期 pageNum?: number // 页码 pageSize?: number // 每页大小 flowStartTime?: string // 流水开始时间 flowEndTime?: string // 流水结束时间 } src/views/pointsManage/personal/index.vue
@@ -58,24 +58,25 @@ <span class="filter-label">数据类目:</span> <el-select v-model="queryParams.dataCategory" placeholder="全部" clearable> <el-option label="全部" value="" /> <el-option label="资源贡献" value="resource_contribution" /> <el-option label="资源交易" value="resource_transaction" /> <el-option label="资源传播" value="resource_dissemination" /> <el-option label="用户参与" value="user_participation" /> <el-option label="积分转换" value="points_conversion" /> <el-option label="其他" value="other" /> <el-option v-for="category in categoryList" :key="category" :label="getCategoryLabel(category)" :value="category" /> </el-select> </div> <div class="filter-item"> <span class="filter-label">时间:</span> <el-date-picker v-model="dateRange" type="daterange" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD" value-format="YYYY-MM-DD" format="YYYY-MM-DD HH:mm:ss" date-format="YYYY-MM-DD" time-format="HH:mm:ss" @change="handleDateChange" /> </div> @@ -83,9 +84,8 @@ <span class="filter-label">数据类型:</span> <el-select v-model="queryParams.dataType" placeholder="全部" clearable> <el-option label="全部" value="" /> <el-option label="获取" value="earned" /> <el-option label="消耗" value="consumed" /> <el-option label="转换" value="converted" /> <el-option label="获取" value="0" /> <el-option label="消耗" value="1" /> </el-select> </div> </div> @@ -110,9 +110,9 @@ <span>{{ getCategoryLabel(row.dataCategory) }}</span> </template> </el-table-column> <el-table-column prop="name" label="名称" min-width="300" show-overflow-tooltip /> <el-table-column prop="flowTime" label="时间" width="180" align="center" /> <el-table-column prop="points" label="积分" width="100" align="center"> <el-table-column prop="name" label="名称" show-overflow-tooltip /> <el-table-column prop="flowTime" label="时间" align="center" /> <el-table-column prop="points" label="积分" align="center"> <template #default="{ row }"> <span :class="row.points > 0 ? 'points-earned' : 'points-consumed'"> {{ row.points > 0 ? '+' : '' }}{{ row.points }} @@ -144,7 +144,7 @@ <script setup lang="ts"> import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage } from 'element-plus' import { dayjs, ElMessage } from 'element-plus' import { ArrowLeft, Refresh, @@ -160,18 +160,17 @@ // 积分统计 const stats = ref<PointsStats>({ balance: 20000, totalEarned: 10000, totalConsumed: 200, balance: 0, totalEarned: 0, totalConsumed: 0, totalConverted: 0, }) // 查询参数 const queryParams = reactive<PointsQueryParams>({ userId: '1', dataCategory: '', dataType: '', startTime: '', endTime: '', pageNum: 1, pageSize: 10, }) @@ -184,6 +183,9 @@ // 总数 const total = ref(0) // 数据类目列表 const categoryList = ref<string[]>([]) // 格式化数字 const formatNumber = (num: number) => { @@ -206,12 +208,25 @@ // 获取积分统计 const getPointsStats = async () => { try { const res = await pointsApi.getPersonalPointsStats() const userId = 1; const res = await pointsApi.getPersonalPointsStats(userId) if (res.code === 200 && res.data) { stats.value = res.data } } catch (error) { console.error('获取积分统计失败:', error) } } // 获取数据类目列表 const getCategoryList = async () => { try { const res = await pointsApi.getPointsFlowCategories() if (res.code === 200 && res.data) { categoryList.value = res.data } } catch (error) { console.error('获取数据类目失败:', error) } } @@ -238,8 +253,8 @@ const resetQuery = () => { queryParams.dataCategory = '' queryParams.dataType = '' queryParams.startTime = '' queryParams.endTime = '' queryParams.flowStartTime = '' queryParams.flowEndTime = '' dateRange.value = null queryParams.pageNum = 1 queryData() @@ -248,11 +263,11 @@ // 处理日期变化 const handleDateChange = (dates: [string, string] | null) => { if (dates) { queryParams.startTime = dates[0] queryParams.endTime = dates[1] queryParams.flowStartTime = dayjs(dates[0]).format('YYYY-MM-DD HH:mm:ss'); queryParams.flowEndTime = dayjs(dates[1]).format('YYYY-MM-DD HH:mm:ss'); } else { queryParams.startTime = '' queryParams.endTime = '' queryParams.flowStartTime = '' queryParams.flowEndTime = '' } } @@ -288,6 +303,7 @@ onMounted(() => { getPointsStats() getPointsFlow() getCategoryList() }) </script> src/views/pointsManage/ruleList/index.vue
@@ -1,81 +1,100 @@ <template> <div class="points-rule-list"> <!-- 页面标题 --> <div class="page-title">积分规则管理</div> <!-- 列表页面 --> <div v-if="currentView === 'list'"> <!-- 页面标题 --> <div class="page-title">积分规则管理</div> <!-- 规则列表卡片 --> <el-card shadow="never" class="rule-list-card"> <!-- 筛选条件 --> <div class="filter-section"> <div class="filter-row"> <div class="filter-item"> <span class="filter-label">生效时间:</span> <el-date-picker v-model="queryParams.dateRange" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss" value-format="YYYY-MM-DD HH:mm:ss" <!-- 规则列表卡片 --> <el-card shadow="never" class="rule-list-card"> <!-- 筛选条件 --> <div class="filter-section"> <div class="filter-row"> <div class="filter-item"> <span class="filter-label">生效时间:</span> <el-date-picker v-model="queryParams.dateRange" type="datetimerange" range-separator="至" start-placeholder="开始日期" end-placeholder="结束日期" format="YYYY-MM-DD HH:mm:ss" date-format="YYYY-MM-DD" time-format="HH:mm:ss" style="margin-left: 8px;" @change="handleDateChange" /> </div> </div> <div class="filter-actions"> <el-button type="primary" @click="queryData"> <el-icon><Search /></el-icon> 查询 </el-button> <el-button @click="resetQuery"> <el-icon><Refresh /></el-icon> 重置 </el-button> </div> </div> style="margin-left: 8px;" @change="handleDateChange" /> </div> <!-- 规则表格 --> <div class="table-section"> <el-table :data="ruleList" stripe style="width: 100%"> <el-table-column prop="id" label="序号" width="80" align="center" /> <el-table-column prop="pointsName" label="名称" align="ceter"> <template #default="{ row }"> {{ row.pointsName}}{{ row.updatedAt}}V{{ row.version }} </template> </el-table-column> <el-table-column prop="effectiveStart" label="开始生效时间" align="center" /> <el-table-column prop="modifierName" label="修改人" align="center" /> <el-table-column label="操作" align="center" fixed="right"> <template #default="{ row }"> <el-button type="primary" size="small" @click="editRule(row)">查看</el-button> <el-button type="primary" size="small" @click="editRule(row)">编辑</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <div class="pagination-section"> <div class="pagination-info"> 共{{ total }}条 </div> <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :total="total" layout="sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> <div class="filter-actions"> <el-button type="primary" @click="queryData"> <el-icon><Search /></el-icon> 查询 </el-button> <el-button @click="resetQuery"> <el-icon><Refresh /></el-icon> 重置 </el-button> </div> </div> </div> </el-card> <!-- 规则表格 --> <div class="table-section"> <el-table :data="ruleList" stripe style="width: 100%"> <el-table-column type="index" label="序号" width="80" align="center" /> <el-table-column prop="pointsName" label="名称" align="ceter"> <template #default="{ row }"> {{ row.pointsName}}{{ dayjs(row.updatedAt).format('YYYYMMDD')}}V{{ row.version }} </template> </el-table-column> <el-table-column prop="effectiveStart" label="开始生效时间" align="center" /> <el-table-column prop="modifierName" label="修改人" align="center" /> <el-table-column label="操作" align="center" fixed="right"> <template #default="{ row }"> <el-button type="primary" size="small" @click="viewRule(row)">查看</el-button> <el-button type="primary" size="small" @click="editRule(row)">编辑</el-button> </template> </el-table-column> </el-table> <!-- 分页 --> <div class="pagination-section"> <div class="pagination-info"> 共{{ total }}条 </div> <el-pagination v-model:current-page="queryParams.pageNum" v-model:page-size="queryParams.pageSize" :page-sizes="[10, 20, 50, 100]" :total="total" layout="sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange" /> </div> </div> </el-card> </div> <!-- 编辑页面 --> <div v-if="currentView === 'edit'" class="edit-container"> <SettingsComponent :ruleId="currentRuleId" @goBack="goBackToList" @saveSuccess="handleSaveSuccess" /> </div> <!-- 查看详情页面 --> <div v-if="currentView === 'view'" class="view-container"> <RuleDetailComponent :ruleId="currentRuleId" @goBack="goBackToList" /> </div> </div> </template> @@ -85,14 +104,14 @@ import { Search, Refresh } from '@element-plus/icons-vue' import pointsApi from '@/api/pointsApi' import type { PointsRule, PointsQueryParams } from '@/types/points' // 导入路由钩子 import { useRouter } from 'vue-router' import SettingsComponent from '../settings/index.vue' import RuleDetailComponent from '../ruleDetail/index.vue' // 当前视图状态:'list' | 'edit' | 'view' const currentView = ref<'list' | 'edit' | 'view'>('list') // 查询参数 const queryParams = reactive<PointsQueryParams>({ // ruleType: '', // category: '', // status: '', dateRange: '', pageNum: 1, pageSize: 10, @@ -103,6 +122,9 @@ // 总数 const total = ref(0) // 当前选中的规则ID const currentRuleId = ref<string>('') // 页面加载时获取数据 onMounted(() => { @@ -144,65 +166,41 @@ queryData() } // 获取规则类型标签 const getRuleTypeLabel = (type: string) => { const typeMap: Record<string, string> = { acquisition: '获取', consumption: '消耗', conversion: '转换', } return typeMap[type] || type } // 获取分类标签 const getCategoryLabel = (category: string) => { const categoryMap: Record<string, string> = { resource_contribution: '资源贡献', resource_transaction: '资源交易', resource_dissemination: '资源传播', user_participation: '用户参与', other: '其他', } return categoryMap[category] || category } // 处理状态变化 const handleStatusChange = async (row: PointsRule) => { try { await pointsApi.savePointsRules({ id: row.id, status: row.status }) ElMessage.success('状态更新成功') } catch (error) { ElMessage.error('状态更新失败') // 恢复原来的状态 row.status = row.status === 1 ? 0 : 1 console.error('更新规则状态失败:', error) } } // 处理日期变化 const handleDateChange = (dates: [string, string] | null) => { if (dates) { queryParams.effectiveStartTime = dates[0] queryParams.effectiveEndTime = dates[1] queryParams.effectiveStartTime = dayjs(dates[0]).format('YYYY-MM-DD HH:mm:ss'); queryParams.effectiveEndTime = dayjs(dates[1]).format('YYYY-MM-DD HH:mm:ss'); } else { queryParams.effectiveStartTime = '' queryParams.effectiveEndTime = '' } } // 创建路由实例 const router = useRouter() // 编辑规则 const editRule = (row: PointsRule) => { // 跳转到规则设置界面,并传入规则id router.push({ path: '/points/settings', query: { ruleId: row.id } }) currentRuleId.value = row.id?.toString() || '' currentView.value = 'edit' } // 查看规则 const viewRule = (row: PointsRule) => { currentRuleId.value = row.id?.toString() || '' currentView.value = 'view' } // 返回列表页面 const goBackToList = () => { currentView.value = 'list' currentRuleId.value = '' } // 处理保存成功 const handleSaveSuccess = () => { ElMessage.success('保存成功') goBackToList() // 重新加载列表数据 queryData() } </script> @@ -265,5 +263,11 @@ } } } .edit-container, .view-container { // 确保组件能够正确显示 width: 100%; } } </style> </style> src/views/pointsManage/settings/index.vue
@@ -9,26 +9,26 @@ <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"> <!-- <h5>提报标杆</h5> --> <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="rules.benchmarkSubmission" <el-input v-model="pointRuleDetial.pointsValue" size="small" style="width: 80px;" placeholder="请输入" /> <span class="unit">积分</span> <span class="unit" v-if="pointRuleDetial.isLimit === 1">,每日积分上限</span> <el-input v-model="rules.productSubscribedDailyLimit" <el-input v-model="pointRuleDetial.dailyLimit" size="small" style="width: 80px;" placeholder="请输入" @@ -42,8 +42,8 @@ <div class="rule-items"> <div class="rule-item"> <span class="rule-desc">每提报1个知识,并审批完成,获</span> <el-input v-model="rules.knowledgeSubmission" <el-input v-model="rules.knowledgeSubmission" size="small" style="width: 80px;" placeholder="请输入" @@ -57,8 +57,8 @@ <div class="rule-items"> <div class="rule-item"> <span class="rule-desc">每提报1个产品,并审批完成,获</span> <el-input v-model="rules.productSubmission" <el-input v-model="rules.productSubmission" size="small" style="width: 80px;" placeholder="请输入" @@ -67,7 +67,7 @@ </div> </div> </div> --> </div> <!-- 资源交易 --> @@ -78,8 +78,8 @@ <div class="rule-items"> <div class="rule-item"> <span class="rule-desc">每接入1个产品,获</span> <el-input v-model="rules.productAccess" <el-input v-model="rules.productAccess" size="small" style="width: 60px;" placeholder="请输入" @@ -93,8 +93,8 @@ <div class="rule-items"> <div class="rule-item"> <span class="rule-desc">每交易1个资源,获</span> <el-input v-model="rules.resourceTransaction" <el-input v-model="rules.resourceTransaction" size="small" style="width: 60px;" placeholder="请输入" @@ -117,228 +117,166 @@ <span class="section-title">积分消耗规则</span> </div> </template> <!-- 资源传播 --> <div class="rule-category"> <h4>资源传播</h4> <div class="rule-category" v-for="consumeRule in rules.consumePointsRuleList"> <h4>{{ consumeRule.category }}</h4> <div class="rule-subcategory"> <h5>数字资源</h5> <!-- <h5>数字资源</h5>--> <div class="rule-items"> <div class="rule-item"> <span class="rule-desc">提报产品被取消收藏,扣除</span> <el-input v-model="rules.productUnfavorited" <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: 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> <span class="unit" v-if="pointRuleDetials.isLimit === 1">,每日积分上限</span> <el-input v-model="pointRuleDetials.dailyLimit" size="small" style="width: 80px;" placeholder="请输入" v-if="pointRuleDetials.isLimit === 1" /> </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> <!-- <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> @@ -351,17 +289,27 @@ </template> <script setup lang="ts"> import { ref, onMounted } from 'vue' import { ref, onMounted, watch } from 'vue' import { useRoute } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import { ArrowLeft } from '@element-plus/icons-vue' import pointsApi from '../../../api/pointsApi' import qs from 'qs' // 获取路由实例 const route = useRoute() // 获取路由参数中的规则id const ruleId = route.query.ruleId as string // 定义props interface Props { ruleId?: string } const props = withDefaults(defineProps<Props>(), { ruleId: '' }) // 定义emits const emit = defineEmits<{ goBack: [] saveSuccess: [] }>() interface PointRule { category: string, @@ -375,81 +323,29 @@ createdAt: string, ruleType: number, pointsWinner: number, isLimit: number isLimit: number, pointsValue: number, dailyLimit: number } // 积分规则配置 interface PointsRules { getPointsRuleList: PointRule[], consumePointsRuleList: PointRule[], benchmarkSubmission: number, productSubscribedDailyLimit: number, productAccess: number, resourceTransaction: number, productSubscribed: number, productTrialed: number, productTrialedDailyLimit: number, resourceLiked: number, resourceLikedDailyLimit: number, dailyFirstLogin: number, postQuestion: number, postQuestionDailyLimit: number, postComment: number, postCommentDailyLimit: number, commentLiked: number, commentLikedDailyLimit: number, monthlyTop1: number, monthlyTop2: number, monthlyTop3: number, productUnfavorited: number, productUnliked: number, benchmarkPersonalToUnit: number, benchmarkUnitToPersonal: number, knowledgePersonalToUnit: number, knowledgeUnitToPersonal: number, productPersonalToUnit: number, productUnitToPersonal: number consumePointsRuleList: PointRule[] } const rules = ref<PointsRules>({ consumePointsRuleList: [], getPointsRuleList: [], benchmarkSubmission: 0, productSubscribedDailyLimit: 0, productAccess: 0, resourceTransaction: 0, productSubscribed: 0, productTrialed: 0, productTrialedDailyLimit: 0, resourceLiked: 0, resourceLikedDailyLimit: 0, dailyFirstLogin: 0, postQuestion: 0, postQuestionDailyLimit: 0, postComment: 0, postCommentDailyLimit: 0, commentLiked: 0, commentLikedDailyLimit: 0, monthlyTop1: 0, monthlyTop2: 0, monthlyTop3: 0, productUnfavorited: 0, productUnliked: 0, benchmarkPersonalToUnit: 0, benchmarkUnitToPersonal: 0, knowledgePersonalToUnit: 0, knowledgeUnitToPersonal: 0, productPersonalToUnit: 0, productUnitToPersonal: 0 getPointsRuleList: [] }) // 获取积分规则配置 const getPointsRules = async () => { try { if (ruleId) { if (props.ruleId) { // 如果有ruleId参数,则获取特定规则 const formData = new URLSearchParams(); formData.append('ruleId', ruleId); const formData = new URLSearchParams(); formData.append('ruleId', props.ruleId); const res = await pointsApi.getPointsRuleById(formData) if (res.code === 200 && res.data) { @@ -457,13 +353,8 @@ Object.assign(rules.value, res.data) console.log(rules.value) } } else { // 如果没有ruleId参数,则获取所有规则 const res = await pointsApi.getPointsRules() if (res.code === 200 && res.data) { // 将后端数据映射到前端规则对象 Object.assign(rules.value, res.data) } }else{ ElMessage.error('对应规则设置不存在') } } catch (error) { console.error('获取积分规则失败:', error) @@ -478,10 +369,16 @@ cancelButtonText: '取消', type: 'warning', }) const res = await pointsApi.savePointsRules(rules.value) let pointRuleDetials: PointRuleDetial[] = [] rules.value.getPointsRuleList.forEach(k => { pointRuleDetials.push(...k.pointsRules) }) rules.value.consumePointsRuleList.forEach(k => pointRuleDetials.push(...k.pointsRules)) const res = await pointsApi.savePointsRules(pointRuleDetials) if (res.code === 200) { ElMessage.success('保存成功') // 发出保存成功事件 emit('saveSuccess') } else { ElMessage.error(res.msg || '保存失败') } @@ -501,7 +398,7 @@ cancelButtonText: '取消', type: 'warning', }) await getPointsRules() ElMessage.success('重置成功') } catch (error) { @@ -514,11 +411,27 @@ // 返回上一页 const goBack = () => { history.back() // 如果是从组件调用,发出goBack事件 if (props.ruleId) { emit('goBack') } else { // 否则使用原有的返回逻辑 history.back() } } // 监听ruleId变化 watch(() => props.ruleId, (newRuleId) => { if (newRuleId) { getPointsRules() } }, { immediate: true }) onMounted(() => { getPointsRules() // 只有在没有props.ruleId时才执行原有的逻辑 if (!props.ruleId) { getPointsRules() } }) </script> @@ -548,7 +461,7 @@ cursor: pointer; color: #409eff; font-size: 18px; &:hover { color: #66b1ff; } @@ -573,7 +486,7 @@ max-width: 1665px; margin: 0 auto; margin-bottom: 40px; @media (max-width: 768px) { flex-direction: column; gap: 16px; @@ -585,7 +498,7 @@ justify-content: center; gap: 20px; padding: 20px 0; .el-button { min-width: 120px; height: 40px; @@ -596,7 +509,7 @@ .left-column { flex: 1; max-width: 50%; @media (max-width: 768px) { max-width: 100%; } @@ -608,7 +521,7 @@ display: flex; flex-direction: column; gap: 20px; @media (max-width: 768px) { max-width: 100%; gap: 16px; @@ -618,13 +531,13 @@ .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; @@ -697,11 +610,11 @@ :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; } src/views/pointsManage/unit/index.vue
@@ -104,12 +104,12 @@ <span class="filter-label">数据类目:</span> <el-select v-model="queryParams.dataCategory" placeholder="全部" clearable> <el-option label="全部" value="" /> <el-option label="资源贡献" value="resource_contribution" /> <el-option label="资源交易" value="resource_transaction" /> <el-option label="资源传播" value="resource_dissemination" /> <el-option label="用户参与" value="user_participation" /> <el-option label="积分转换" value="points_conversion" /> <el-option label="其他" value="other" /> <el-option v-for="category in categoryList" :key="category" :label="getCategoryLabel(category)" :value="category" /> </el-select> </div> <div class="filter-item"> @@ -234,7 +234,7 @@ <script setup lang="ts"> import { ref, reactive, onMounted, computed } from 'vue' import { ElMessage } from 'element-plus' import { dayjs, ElMessage } from 'element-plus' import { Money, Plus, @@ -257,8 +257,8 @@ const queryParams = reactive<PointsQueryParams>({ dataCategory: '', dataType: '', startTime: '', endTime: '', flowStartTime: '', flowEndTime: '', year: new Date().getFullYear().toString(), month: '', day: '', @@ -280,6 +280,9 @@ // 总数 const total = ref(0) // 数据类目列表 const categoryList = ref<string[]>([]) // 获取积分详情 const earnedDetails = ref<UnitPointsDetail[]>([ @@ -327,6 +330,18 @@ } } // 获取数据类目列表 const getCategoryList = async () => { try { const res = await pointsApi.getPointsFlowCategories() if (res.code === 200 && res.data) { categoryList.value = res.data } } catch (error) { console.error('获取数据类目失败:', error) } } // 获取单位积分流水 const getUnitPointsFlow = async () => { try { @@ -351,8 +366,8 @@ const resetQuery = () => { queryParams.dataCategory = '' queryParams.dataType = '' queryParams.startTime = '' queryParams.endTime = '' queryParams.flowStartTime = '' queryParams.flowEndTime = '' queryParams.year = new Date().getFullYear().toString() queryParams.month = '' queryParams.day = '' @@ -366,8 +381,8 @@ // 处理时间类型变化 const handleTimeTypeChange = (type: string | number | boolean | undefined) => { // 清空其他时间字段 queryParams.startTime = '' queryParams.endTime = '' queryParams.flowStartTime = '' queryParams.flowEndTime = '' queryParams.month = '' queryParams.day = '' monthValue.value = '' @@ -389,11 +404,11 @@ // 处理日期变化 const handleDateChange = (dates: [string, string] | null) => { if (dates) { queryParams.startTime = dates[0] queryParams.endTime = dates[1] queryParams.flowStartTime = dates[0] queryParams.flowEndTime = dates[1] } else { queryParams.startTime = '' queryParams.endTime = '' queryParams.flowStartTime = '' queryParams.flowEndTime = '' } } @@ -413,6 +428,7 @@ onMounted(() => { getUnitPointsStats() getUnitPointsFlow() getCategoryList() }) </script>