feat: 系统功能更新 - 添加错误统计、数据初始化、订单调度等功能
This commit is contained in:
@@ -26,6 +26,10 @@
|
||||
<el-icon><Document /></el-icon>
|
||||
<span>{{ $t('nav.tasks') }}</span>
|
||||
</div>
|
||||
<div class="nav-item" @click="goToErrorStats">
|
||||
<el-icon><Warning /></el-icon>
|
||||
<span>错误统计</span>
|
||||
</div>
|
||||
<div class="nav-item active">
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>{{ $t('nav.systemSettings') }}</span>
|
||||
@@ -107,8 +111,8 @@
|
||||
<h3>{{ level.name }}</h3>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="price">${{ level.price || 0 }}{{ $t('systemSettings.perMonth') }}</p>
|
||||
<p class="description">{{ $t('systemSettings.includesPointsPerMonth', { points: level.resourcePoints || level.pointsBonus || 0 }) }}</p>
|
||||
<p class="price">¥{{ level.price || 0 }}/年</p>
|
||||
<p class="description">包含{{ level.resourcePoints || level.pointsBonus || 0 }}积分/年</p>
|
||||
</div>
|
||||
<div class="card-footer">
|
||||
<el-button type="primary" @click="editLevel(level)">{{ $t('common.edit') }}</el-button>
|
||||
@@ -305,7 +309,7 @@
|
||||
<el-form :model="editForm" :rules="editRules" ref="editFormRef">
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ $t('systemSettings.membershipLevel') }}</label>
|
||||
<el-select v-model="editForm.level" :placeholder="$t('systemSettings.selectLevelPlaceholder')" style="width: 100%;">
|
||||
<el-select v-model="editForm.level" :placeholder="$t('systemSettings.selectLevelPlaceholder')" style="width: 100%;" disabled>
|
||||
<el-option :label="$t('systemSettings.freeMembership')" value="free"></el-option>
|
||||
<el-option :label="$t('systemSettings.standardMembership')" value="standard"></el-option>
|
||||
<el-option :label="$t('systemSettings.professionalMembership')" value="professional"></el-option>
|
||||
@@ -315,7 +319,7 @@
|
||||
<div class="form-group">
|
||||
<label class="form-label">{{ $t('systemSettings.membershipPrice') }}</label>
|
||||
<div class="price-input">
|
||||
<span class="price-prefix">$</span>
|
||||
<span class="price-prefix">¥</span>
|
||||
<input
|
||||
type="text"
|
||||
v-model="editForm.price"
|
||||
@@ -343,12 +347,12 @@
|
||||
<div class="radio-option">
|
||||
<input
|
||||
type="radio"
|
||||
id="monthly"
|
||||
id="yearly"
|
||||
v-model="editForm.validityPeriod"
|
||||
value="monthly"
|
||||
value="yearly"
|
||||
class="radio-input"
|
||||
>
|
||||
<label for="monthly" class="radio-label">{{ $t('systemSettings.monthly') }}</label>
|
||||
<label for="yearly" class="radio-label">{{ $t('systemSettings.yearly') }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -431,10 +435,11 @@ import {
|
||||
User as ArrowDown,
|
||||
Delete,
|
||||
Refresh,
|
||||
Check
|
||||
Check,
|
||||
Warning
|
||||
} from '@element-plus/icons-vue'
|
||||
import api from '@/api/request'
|
||||
import cleanupApi from '@/api/cleanup'
|
||||
import { getMembershipLevels, updateMembershipLevel } from '@/api/members'
|
||||
import LanguageSwitcher from '@/components/LanguageSwitcher.vue'
|
||||
|
||||
const router = useRouter()
|
||||
@@ -458,7 +463,7 @@ const editForm = reactive({
|
||||
level: '',
|
||||
price: '',
|
||||
resourcePoints: 0,
|
||||
validityPeriod: 'monthly'
|
||||
validityPeriod: 'yearly'
|
||||
})
|
||||
|
||||
const editRules = computed(() => ({
|
||||
@@ -522,6 +527,10 @@ const goToTasks = () => {
|
||||
router.push('/generate-task-record')
|
||||
}
|
||||
|
||||
const goToErrorStats = () => {
|
||||
router.push('/admin/error-statistics')
|
||||
}
|
||||
|
||||
const goToSettings = () => {
|
||||
router.push('/system-settings')
|
||||
}
|
||||
@@ -537,10 +546,10 @@ const handleUserCommand = (command) => {
|
||||
const editLevel = (level) => {
|
||||
// 映射后端数据到前端表单
|
||||
editForm.id = level.id
|
||||
editForm.level = level.name || level.displayName
|
||||
editForm.level = level.key
|
||||
editForm.price = level.price ? String(level.price) : '0'
|
||||
editForm.resourcePoints = level.pointsBonus || level.resourcePoints || 0
|
||||
editForm.validityPeriod = 'monthly' // 默认月付
|
||||
editForm.validityPeriod = 'yearly' // 默认年付
|
||||
editDialogVisible.value = true
|
||||
}
|
||||
|
||||
@@ -561,76 +570,54 @@ const saveEdit = async () => {
|
||||
if (!valid) return
|
||||
|
||||
try {
|
||||
// 调用后端API更新会员等级配置
|
||||
const updateData = {
|
||||
price: parseFloat(editForm.price),
|
||||
resourcePoints: parseInt(editForm.resourcePoints),
|
||||
pointsBonus: parseInt(editForm.resourcePoints),
|
||||
description: t('systemSettings.includesPointsPerMonth', { points: editForm.resourcePoints })
|
||||
const priceInt = parseInt(editForm.price)
|
||||
if (Number.isNaN(priceInt) || priceInt < 0) {
|
||||
ElMessage.error(t('systemSettings.enterValidNumber'))
|
||||
return
|
||||
}
|
||||
|
||||
await updateMembershipLevel(editForm.id, updateData)
|
||||
|
||||
// 更新本地数据
|
||||
const index = membershipLevels.value.findIndex(level => level.id === editForm.id)
|
||||
if (index !== -1) {
|
||||
membershipLevels.value[index].price = parseFloat(editForm.price)
|
||||
membershipLevels.value[index].pointsBonus = parseInt(editForm.resourcePoints)
|
||||
membershipLevels.value[index].resourcePoints = parseInt(editForm.resourcePoints)
|
||||
membershipLevels.value[index].description = t('systemSettings.includesPointsPerMonth', { points: editForm.resourcePoints })
|
||||
|
||||
// 直接更新membership_levels表
|
||||
const updateData = { price: priceInt }
|
||||
console.log('准备更新会员等级:', editForm.id, updateData)
|
||||
const response = await api.put(`/members/levels/${editForm.id}`, updateData)
|
||||
console.log('会员等级更新响应:', response.data)
|
||||
|
||||
if (response.data?.success) {
|
||||
ElMessage.success(t('systemSettings.membershipUpdateSuccess'))
|
||||
editDialogVisible.value = false
|
||||
await loadMembershipLevels()
|
||||
} else {
|
||||
ElMessage.error(t('systemSettings.membershipUpdateFailed') + ': ' + (response.data?.message || '未知错误'))
|
||||
}
|
||||
|
||||
ElMessage.success(t('systemSettings.membershipUpdateSuccess'))
|
||||
editDialogVisible.value = false
|
||||
|
||||
// 重新加载会员等级配置
|
||||
await loadMembershipLevels()
|
||||
} catch (error) {
|
||||
console.error('Update membership level failed:', error)
|
||||
ElMessage.error(t('systemSettings.membershipUpdateFailed') + ': ' + (error.response?.data?.message || error.message))
|
||||
}
|
||||
}
|
||||
|
||||
// 加载会员等级配置
|
||||
// 加载会员等级配置(从membership_levels表读取)
|
||||
const loadMembershipLevels = async () => {
|
||||
loadingLevels.value = true
|
||||
try {
|
||||
const response = await getMembershipLevels()
|
||||
console.log('会员等级配置响应:', response)
|
||||
// 从membership_levels表读取数据
|
||||
const levelsResp = await api.get('/members/levels', {
|
||||
params: { _t: Date.now() },
|
||||
headers: { 'Cache-Control': 'no-cache' }
|
||||
})
|
||||
|
||||
// 检查响应结构
|
||||
let levels = []
|
||||
if (response.data) {
|
||||
if (response.data.success && response.data.data) {
|
||||
levels = response.data.data
|
||||
} else if (Array.isArray(response.data)) {
|
||||
levels = response.data
|
||||
} else if (response.data.data && Array.isArray(response.data.data)) {
|
||||
levels = response.data.data
|
||||
}
|
||||
}
|
||||
|
||||
console.log('解析后的会员等级数据:', levels)
|
||||
|
||||
// 映射后端数据到前端显示格式
|
||||
if (levels.length > 0) {
|
||||
if (levelsResp.data?.success && levelsResp.data?.data) {
|
||||
const levels = levelsResp.data.data
|
||||
membershipLevels.value = levels.map(level => ({
|
||||
id: level.id,
|
||||
key: level.name,
|
||||
name: level.displayName || level.name,
|
||||
price: level.price || 0,
|
||||
resourcePoints: level.pointsBonus || 0,
|
||||
pointsBonus: level.pointsBonus || 0,
|
||||
description: level.description || t('systemSettings.includesPointsPerMonth', { points: level.pointsBonus || 0 })
|
||||
description: t('systemSettings.includesPointsPerMonth', { points: level.pointsBonus || 0 })
|
||||
}))
|
||||
console.log('Membership levels loaded:', membershipLevels.value)
|
||||
} else {
|
||||
// 如果没有数据,使用默认值
|
||||
console.warn('No membership data in database, using defaults')
|
||||
membershipLevels.value = [
|
||||
{ id: 1, name: t('systemSettings.freeMembership'), price: 0, resourcePoints: 200, description: t('systemSettings.includesPointsPerMonth', { points: 200 }) },
|
||||
{ id: 2, name: t('systemSettings.standardMembership'), price: 59, resourcePoints: 500, description: t('systemSettings.includesPointsPerMonth', { points: 500 }) },
|
||||
{ id: 3, name: t('systemSettings.professionalMembership'), price: 250, resourcePoints: 2000, description: t('systemSettings.includesPointsPerMonth', { points: 2000 }) }
|
||||
]
|
||||
throw new Error('获取会员等级数据失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Load membership config failed:', error)
|
||||
@@ -640,12 +627,9 @@ const loadMembershipLevels = async () => {
|
||||
const errorMessage = error.response?.data?.message || error.response?.data?.error || error.message || t('systemSettings.unknown')
|
||||
ElMessage.warning(`${t('systemSettings.loadMembershipFailed')}: ${errorMessage}, ${t('systemSettings.usingDefaultConfig')}`)
|
||||
|
||||
// 使用默认值,确保页面可以正常显示
|
||||
membershipLevels.value = [
|
||||
{ id: 1, name: t('systemSettings.freeMembership'), price: 0, resourcePoints: 200, description: t('systemSettings.includesPointsPerMonth', { points: 200 }) },
|
||||
{ id: 2, name: t('systemSettings.standardMembership'), price: 59, resourcePoints: 500, description: t('systemSettings.includesPointsPerMonth', { points: 500 }) },
|
||||
{ id: 3, name: t('systemSettings.professionalMembership'), price: 250, resourcePoints: 2000, description: t('systemSettings.includesPointsPerMonth', { points: 2000 }) }
|
||||
]
|
||||
// API调用失败,清空数据并提示用户检查数据库配置
|
||||
membershipLevels.value = []
|
||||
ElMessage.error('无法加载会员等级配置,请检查数据库中membership_levels表是否有数据')
|
||||
} finally {
|
||||
loadingLevels.value = false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user