feat: 系统功能更新 - 添加错误统计、数据初始化、订单调度等功能

This commit is contained in:
AIGC Developer
2025-12-20 15:24:58 +08:00
parent 0933031b59
commit 5344148a1c
70 changed files with 3649 additions and 688 deletions

View File

@@ -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
}