Add admin-frontend and user-frontend standalone projects, certification/invoice/discovery features, fix auth header and theme consistency
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-for="q in quotas" :key="q.version" class="quota-card">
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<div class="quota-header">
|
||||
<span class="quota-version">{{ q.version === 'ecommerce' ? '电商版' : '通用版' }}</span>
|
||||
<el-tag size="small" v-if="q.description">{{ q.description }}</el-tag>
|
||||
</div>
|
||||
</template>
|
||||
<div class="quota-stat">
|
||||
<span class="quota-label">{{ q.current_month || '当前月' }}</span>
|
||||
<el-progress :percentage="quotaPercent(q)" :stroke-width="20" />
|
||||
<span class="quota-value">{{ q.used_chars }} / {{ q.monthly_limit }}</span>
|
||||
</div>
|
||||
<div class="quota-actions">
|
||||
<el-form :inline="true" size="small">
|
||||
<el-form-item label="月限额">
|
||||
<el-input-number :model-value="q._edit_limit !== undefined ? q._edit_limit : q.monthly_limit" :min="1000" :step="10000" style="width:140px" @update:model-value="q._edit_limit=$event" />
|
||||
</el-form-item>
|
||||
<el-form-item label="启用">
|
||||
<el-switch :model-value="q._edit_enabled !== undefined ? q._edit_enabled : q.enabled" @update:model-value="q._edit_enabled=$event" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="save(q)">保存</el-button>
|
||||
<el-button @click="resetQuota(q.version)">重置用量</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
<el-empty v-if="!quotas.length" description="暂无配额数据" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { listQuotas, updateQuota, resetQuota as resetApi } from '@/api'
|
||||
|
||||
const quotas = ref([])
|
||||
|
||||
function quotaPercent(q) {
|
||||
const limit = q.monthly_limit || 1
|
||||
return Math.min(100, Math.round((q.used_chars / limit) * 100))
|
||||
}
|
||||
|
||||
async function load() {
|
||||
try {
|
||||
const r = await listQuotas()
|
||||
quotas.value = (r.items || r || []).map(q => ({ ...q, _edit_limit: undefined, _edit_enabled: undefined }))
|
||||
} catch (e) { console.error(e) }
|
||||
}
|
||||
|
||||
async function save(q) {
|
||||
try {
|
||||
const data = {}
|
||||
if (q._edit_limit !== undefined && q._edit_limit !== null) data.monthly_limit = q._edit_limit
|
||||
if (q._edit_enabled !== undefined && q._edit_enabled !== null) data.enabled = q._edit_enabled
|
||||
if (!Object.keys(data).length) { ElMessage.info('无改动'); return }
|
||||
await updateQuota(q.version, data)
|
||||
if (data.monthly_limit !== undefined) q.monthly_limit = data.monthly_limit
|
||||
if (data.enabled !== undefined) q.enabled = data.enabled
|
||||
q._edit_limit = undefined; q._edit_enabled = undefined
|
||||
ElMessage.success('已保存')
|
||||
} catch (e) { ElMessage.error(e?.detail || '保存失败') }
|
||||
}
|
||||
|
||||
async function resetQuota(version) {
|
||||
try { await resetApi(version); ElMessage.success('已重置'); load() }
|
||||
catch (e) { ElMessage.error(e?.detail || '重置失败') }
|
||||
}
|
||||
|
||||
onMounted(load)
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.quota-card { margin-bottom: 16px; }
|
||||
.quota-header { display: flex; align-items: center; gap: 12px; }
|
||||
.quota-version { font-size: 15px; font-weight: 600; }
|
||||
.quota-stat { display: flex; align-items: center; gap: 16px; margin-bottom: 16px; }
|
||||
.quota-label { width: 80px; font-size: 13px; color: #666; flex-shrink: 0; }
|
||||
.el-progress { flex: 1; }
|
||||
.quota-value { width: 180px; font-size: 13px; color: #333; text-align: right; flex-shrink: 0; }
|
||||
.quota-actions { }
|
||||
</style>
|
||||
Reference in New Issue
Block a user