This commit is contained in:
hrx 2026-06-03 17:46:01 +08:00
parent 5ef36caa71
commit 90037cae9e
6 changed files with 359 additions and 753 deletions

View File

@ -129,19 +129,19 @@ export const reqModelInfoConfig = (params = {}) => {
const isFormData = params instanceof FormData const isFormData = params instanceof FormData
return request({ return request({
url: '/cntoai/model_management_add.dspy', url: '/cntoai/model_management_add.dspy',
method: isFormData ? 'post' : 'get', method: 'post',
params: isFormData ? undefined : params, params: isFormData ? undefined : params,
data: isFormData ? params : undefined, data: isFormData ? params : undefined,
headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined
}) })
} }
// 模型信息配置编辑(编辑时需要额外传 id // 模型信息配置编辑
export const reqModelInfoConfigEdit = (params = {}) => { export const reqModelInfoConfigEdit = (params = {}) => {
const isFormData = params instanceof FormData const isFormData = params instanceof FormData
return request({ return request({
url: '/cntoai/model_management_update.dspy', url: '/cntoai/model_management_update.dspy',
method: isFormData ? 'post' : 'get', method: 'post',
params: isFormData ? undefined : params, params: isFormData ? undefined : params,
data: isFormData ? params : undefined, data: isFormData ? params : undefined,
headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined headers: isFormData ? { 'Content-Type': 'multipart/form-data' } : undefined

View File

@ -10,10 +10,10 @@
<p>核算机构<b>{{ displayValue(billingData.accounting_orgname) }}</b></p> <p>核算机构<b>{{ displayValue(billingData.accounting_orgname) }}</b></p>
<p>机构编号{{ displayValue(billingData.accounting_orgid) }}</p> <p>机构编号{{ displayValue(billingData.accounting_orgid) }}</p>
</div> </div>
<div class="view-info"> <!-- <div class="view-info">
<strong>管理员视图</strong> <strong>管理员视图</strong>
<small>生成于 2026/5/29 17:00:06</small> <small>生成于 2026/5/29 17:00:06</small>
</div> </div> -->
</div> </div>
<div class="summary-grid"> <div class="summary-grid">
@ -179,7 +179,7 @@
<td>{{ displayValue(leg.subjectname) }}</td> <td>{{ displayValue(leg.subjectname) }}</td>
<td><span class="dir-tag" :class="leg.accounting_dir === '贷' ? 'credit' : 'debit'">{{ displayValue(leg.accounting_dir) }}</span></td> <td><span class="dir-tag" :class="leg.accounting_dir === '贷' ? 'credit' : 'debit'">{{ displayValue(leg.accounting_dir) }}</span></td>
<td>{{ displayValue(leg.participanttype) }}</td> <td>{{ displayValue(leg.participanttype) }}</td>
<td>{{ displayValue(leg.accounting_orgid) }}</td> <td>{{ displayValue(leg.accounting_orgid) }}</td>
<td class="num">{{ money(leg.amount) }}</td> <td class="num">{{ money(leg.amount) }}</td>
</tr> </tr>
</tbody> </tbody>

View File

@ -18,9 +18,9 @@
<span>数据截断<b>{{ financialOverview.truncated ? '是' : '否' }}</b></span> <span>数据截断<b>{{ financialOverview.truncated ? '是' : '否' }}</b></span>
</div> </div>
</div> </div>
<div class="view-meta"> <!-- <div class="view-meta">
查看计费统计 查看计费统计
</div> </div> -->
</div> </div>
<div class="summary-grid"> <div class="summary-grid">

View File

@ -89,7 +89,7 @@ import { reqModelInfoConfigList } from '@/api/model/model'
export default { export default {
name: 'ModelInfoConfig', name: 'ModelInfoConfig',
components: { components: {
ModelInfoEditDialog, ModelInfoEditDialog,
ModelInfoDetailDialog ModelInfoDetailDialog
}, },
data() { data() {

View File

@ -84,11 +84,11 @@
<el-table v-loading="loading" :data="usageList" class="usage-table" style="width: 100%"> <el-table v-loading="loading" :data="usageList" class="usage-table" style="width: 100%">
<el-table-column prop="model" label="模型名称" min-width="180" show-overflow-tooltip></el-table-column> <el-table-column prop="model" label="模型名称" min-width="180" show-overflow-tooltip></el-table-column>
<el-table-column prop="request_count" label="调用次数" width="120"></el-table-column> <!-- <el-table-column prop="request_count" label="调用次数" width="120"></el-table-column> -->
<el-table-column prop="prompt_tokens" label="输入Token" min-width="140"></el-table-column> <el-table-column prop="prompt_tokens" label="输入Token" min-width="140"></el-table-column>
<el-table-column prop="completion_tokens" label="输出Token" min-width="140"></el-table-column> <el-table-column prop="completion_tokens" label="输出Token" min-width="140"></el-table-column>
<el-table-column prop="total_tokens" label="总Token" min-width="140"></el-table-column> <el-table-column prop="total_tokens" label="总Token" min-width="140"></el-table-column>
<el-table-column prop="amount" label="预估费用" width="130"> <el-table-column prop="amount" label="费用" width="130">
<template slot-scope="scope">¥ {{ formatAmount(scope.row.amount) }}</template> <template slot-scope="scope">¥ {{ formatAmount(scope.row.amount) }}</template>
</el-table-column> </el-table-column>
<el-table-column prop="usage_time" label="使用时间" min-width="170" show-overflow-tooltip></el-table-column> <el-table-column prop="usage_time" label="使用时间" min-width="170" show-overflow-tooltip></el-table-column>
@ -131,7 +131,7 @@ export default {
statCards: [ statCards: [
{ label: '总消耗 Token', value: '0', desc: '当前筛选范围', type: 'primary', icon: 'el-icon-coin' }, { label: '总消耗 Token', value: '0', desc: '当前筛选范围', type: 'primary', icon: 'el-icon-coin' },
{ label: '调用次数', value: '0', desc: '当前筛选范围', type: 'success', icon: 'el-icon-s-promotion' }, { label: '调用次数', value: '0', desc: '当前筛选范围', type: 'success', icon: 'el-icon-s-promotion' },
{ label: '预估费用', value: '¥ 0.00', desc: '按当前单价估算', type: 'warning', icon: 'el-icon-wallet' }, { label: ' 费用', value: '¥ 0.00', desc: '按当前单价估算', type: 'warning', icon: 'el-icon-wallet' },
{ label: '输入/输出 Token', value: '0 / 0', desc: 'Prompt / Completion', type: 'purple', icon: 'el-icon-pie-chart' } { label: '输入/输出 Token', value: '0 / 0', desc: 'Prompt / Completion', type: 'purple', icon: 'el-icon-pie-chart' }
], ],
usageList: [], usageList: [],
@ -165,11 +165,27 @@ export default {
return this.rangeLabel return this.rangeLabel
}, },
modelUsageRank() { modelUsageRank() {
const maxTokens = Math.max(...this.usageList.map(item => Number(item.total_tokens || 0)), 0) const modelMap = this.usageList.reduce((map, item) => {
return this.usageList const model = item.model || item.model_name || item.display_name || '-'
const totalTokens = Number(item.total_tokens || 0) || Number(item.prompt_tokens || 0) + Number(item.completion_tokens || 0)
if (!map[model]) {
map[model] = {
model,
total_tokens: 0,
request_count: 0,
amount: 0
}
}
map[model].total_tokens += totalTokens
map[model].request_count += Number(item.request_count || 0)
map[model].amount += Number(item.amount || 0)
return map
}, {})
const rankSource = Object.values(modelMap)
const maxTokens = Math.max(...rankSource.map(item => Number(item.total_tokens || 0)), 0)
return rankSource
.map(item => ({ .map(item => ({
model: item.model, ...item,
total_tokens: Number(item.total_tokens || 0),
percent: maxTokens ? Math.round((Number(item.total_tokens || 0) / maxTokens) * 100) : 0 percent: maxTokens ? Math.round((Number(item.total_tokens || 0) / maxTokens) * 100) : 0
})) }))
.sort((a, b) => b.total_tokens - a.total_tokens) .sort((a, b) => b.total_tokens - a.total_tokens)
@ -328,7 +344,14 @@ export default {
}, },
formatter: params => { formatter: params => {
const item = params && params[0] const item = params && params[0]
return item ? `${item.name}<br/>${this.formatNumber(item.value)} Token` : '' if (!item) return ''
const rankItem = rankList[item.dataIndex] || {}
return [
item.name,
`${this.formatNumber(item.value)} Token`,
`调用次数:${this.formatNumber(rankItem.request_count)}`,
`预估费用:¥ ${this.formatAmount(rankItem.amount)}`
].join('<br/>')
} }
}, },
xAxis: { xAxis: {