From c92b723d893bddd1cf9093e660806b226dc00921 Mon Sep 17 00:00:00 2001 From: seatonwan9 Date: 星期五, 15 八月 2025 19:01:56 +0800 Subject: [PATCH] 提交源码 --- src/types/points.d.ts | 3 src/views/pointsManage/settings/index.vue | 531 +++++++++++++------------------- src/views/pointsManage/ruleList/index.vue | 252 ++++++++------- src/views/pointsManage/personal/index.vue | 72 ++- src/router/modules/pointsManage.ts | 9 src/api/pointsApi.ts | 26 + src/views/pointsManage/unit/index.vue | 50 ++- 7 files changed, 456 insertions(+), 487 deletions(-) diff --git a/src/api/pointsApi.ts b/src/api/pointsApi.ts index 7b1e3db..46d7136 100644 --- a/src/api/pointsApi.ts +++ b/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 diff --git a/src/router/modules/pointsManage.ts b/src/router/modules/pointsManage.ts index b14f573..3805f0b 100644 --- a/src/router/modules/pointsManage.ts +++ b/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'), diff --git a/src/types/points.d.ts b/src/types/points.d.ts index 3722f22..7eff0d3 100644 --- a/src/types/points.d.ts +++ b/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 // 娴佹按缁撴潫鏃堕棿 } diff --git a/src/views/pointsManage/personal/index.vue b/src/views/pointsManage/personal/index.vue index 9c16a88..4ee14ac 100644 --- a/src/views/pointsManage/personal/index.vue +++ b/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> diff --git a/src/views/pointsManage/ruleList/index.vue b/src/views/pointsManage/ruleList/index.vue index 4dc8d79..6fab5c7 100644 --- a/src/views/pointsManage/ruleList/index.vue +++ b/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) + +// 褰撳墠閫変腑鐨勮鍒橧D +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) => { - // 璺宠浆鍒拌鍒欒缃晫闈紝骞朵紶鍏ヨ鍒檌d - 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 { + // 纭繚缁勪欢鑳藉姝g‘鏄剧ず + width: 100%; + } } -</style> \ No newline at end of file +</style> diff --git a/src/views/pointsManage/settings/index.vue b/src/views/pointsManage/settings/index.vue index b73ed42..c2aa98b 100644 --- a/src/views/pointsManage/settings/index.vue +++ b/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">鎻愭姤浜у搧琚彇娑堟敹钘�,鎵i櫎</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">鎻愭姤浜у搧琚彇娑堢偣璧�,鎵i櫎</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">鎻愭姤浜у搧琚彇娑堣闃咃紝鎵i櫎</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">鎻愭姤浜у搧琚彇娑堣瘯鐢紝鎵i櫎</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">璇勮琚彇娑堢偣璧烇紝鎵i櫎</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) { // 濡傛灉鏈塺uleId鍙傛暟锛屽垯鑾峰彇鐗瑰畾瑙勫垯 - 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() + // 濡傛灉鏄粠缁勪欢璋冪敤锛屽彂鍑篻oBack浜嬩欢 + if (props.ruleId) { + emit('goBack') + } else { + // 鍚﹀垯浣跨敤鍘熸湁鐨勮繑鍥為�昏緫 + history.back() + } } +// 鐩戝惉ruleId鍙樺寲 +watch(() => props.ruleId, (newRuleId) => { + if (newRuleId) { + getPointsRules() + } +}, { immediate: true }) + onMounted(() => { - getPointsRules() + // 鍙湁鍦ㄦ病鏈塸rops.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; } diff --git a/src/views/pointsManage/unit/index.vue b/src/views/pointsManage/unit/index.vue index b9b47d7..469f0a0 100644 --- a/src/views/pointsManage/unit/index.vue +++ b/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> -- Gitblit v1.8.0