Merge branch 'main' of https://git.opencomputing.cn/yumoqing/kboss
This commit is contained in:
commit
95ab19979b
@ -112,4 +112,13 @@ export const reqModelExperienceDeleteHistory = (params = {}) => {
|
|||||||
method: 'get',
|
method: 'get',
|
||||||
params
|
params
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// token用量查询
|
||||||
|
export const reqTokenUsage = (params = {}) => {
|
||||||
|
return request({
|
||||||
|
url: '/cntoai/model_usage_user_report.dspy',
|
||||||
|
method: 'post',
|
||||||
|
params
|
||||||
|
})
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@
|
|||||||
<div class="two-btn">
|
<div class="two-btn">
|
||||||
<span class="forgot-password" @click="forgotPasswordVisible = true">忘记密码?</span>
|
<span class="forgot-password" @click="forgotPasswordVisible = true">忘记密码?</span>
|
||||||
<span :loading="loading" type="primary" class="go-register"
|
<span :loading="loading" type="primary" class="go-register"
|
||||||
style="width: 127px; margin-bottom: 30px; margin-left: 0px" @click.native.prevent="handleRegister"
|
@click.native.prevent="handleRegister"
|
||||||
@click="handleRegister">
|
@click="handleRegister">
|
||||||
没有账号?<span class="go-register-btn">去注册</span>
|
没有账号?<span class="go-register-btn">去注册</span>
|
||||||
</span>
|
</span>
|
||||||
@ -1018,8 +1018,7 @@ $dark_gray: #889aa4;
|
|||||||
|
|
||||||
/* 统一表单项目样式 + 边距 */
|
/* 统一表单项目样式 + 边距 */
|
||||||
::v-deep .el-form-item {
|
::v-deep .el-form-item {
|
||||||
margin-bottom: 15px !important;
|
margin-bottom: 30px !important;
|
||||||
/* 给错误提示预留空间 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 统一输入框外框 */
|
/* 统一输入框外框 */
|
||||||
@ -1103,7 +1102,7 @@ $dark_gray: #889aa4;
|
|||||||
height: 42px;
|
height: 42px;
|
||||||
line-height: 42px;
|
line-height: 42px;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
margin-top: 0 !important;
|
margin-top: 4px !important;
|
||||||
margin-bottom: 12px !important;
|
margin-bottom: 12px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1117,10 +1116,14 @@ $dark_gray: #889aa4;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.forgot-password {
|
.forgot-password {
|
||||||
margin-bottom: 12px;
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 22px;
|
||||||
|
margin-bottom: 0;
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
@ -1128,8 +1131,12 @@ $dark_gray: #889aa4;
|
|||||||
}
|
}
|
||||||
|
|
||||||
.go-register {
|
.go-register {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
height: 22px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #333;
|
color: #333;
|
||||||
|
line-height: 22px;
|
||||||
|
|
||||||
.go-register-btn {
|
.go-register-btn {
|
||||||
color: #409eff;
|
color: #409eff;
|
||||||
|
|||||||
@ -181,14 +181,6 @@ print(response.json())`
|
|||||||
return match ? match[0] : ''
|
return match ? match[0] : ''
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
if (this.$route.query.from === 'tokenMarket') {
|
|
||||||
if (this.$route.query.single === '1') {
|
|
||||||
this.$router.push({ path: '/tokenMarket', query: { category: 'TOKEN市集', single: '1' } })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$router.push({ path: '/product', query: { category: 'TOKEN市集' } })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$router.back()
|
this.$router.back()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +216,8 @@ print(response.json())`
|
|||||||
}
|
}
|
||||||
|
|
||||||
.doc-container {
|
.doc-container {
|
||||||
width: 920px;
|
width: 1180px;
|
||||||
|
max-width: calc(100vw - 48px);
|
||||||
margin: 28px auto 0;
|
margin: 28px auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -192,12 +192,8 @@ export default {
|
|||||||
this.clearStreamFlushTimer()
|
this.clearStreamFlushTimer()
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// 返回上一页;从 TOKEN 市集进入时固定回到 TOKEN 市集分类。
|
// 返回浏览器历史记录中的上一页。
|
||||||
goBack() {
|
goBack() {
|
||||||
if (this.$route.query.from === 'tokenMarket') {
|
|
||||||
this.$router.push({ path: '/product', query: { category: 'TOKEN市集' } })
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$router.back()
|
this.$router.back()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@ -41,7 +41,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="version-actions">
|
<div class="version-actions">
|
||||||
<el-button size="small" @click="goApiDocument">API文档</el-button>
|
<el-button size="small" @click="goApiDocument">API文档</el-button>
|
||||||
<el-button size="small" type="primary" @click="goExperience">体验</el-button>
|
<el-button
|
||||||
|
size="small"
|
||||||
|
:type="canExperience ? 'primary' : 'info'"
|
||||||
|
:disabled="!canExperience"
|
||||||
|
@click="goExperience"
|
||||||
|
>
|
||||||
|
体验
|
||||||
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@ -124,7 +131,8 @@ export default {
|
|||||||
inputPrice: '0.0021',
|
inputPrice: '0.0021',
|
||||||
outputPrice: '0.0084',
|
outputPrice: '0.0084',
|
||||||
cacheHitInputPrice: '',
|
cacheHitInputPrice: '',
|
||||||
priceUnit: '元/千Tokens'
|
priceUnit: '元/千Tokens',
|
||||||
|
experience: 1
|
||||||
},
|
},
|
||||||
capabilityList: [
|
capabilityList: [
|
||||||
{ label: '接口类型', value: '/v2/chat/completions' },
|
{ label: '接口类型', value: '/v2/chat/completions' },
|
||||||
@ -147,6 +155,11 @@ export default {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
canExperience() {
|
||||||
|
return Number(this.modelInfo.experience) === 1
|
||||||
|
}
|
||||||
|
},
|
||||||
created() {
|
created() {
|
||||||
this.loadModelDetail()
|
this.loadModelDetail()
|
||||||
},
|
},
|
||||||
@ -180,7 +193,8 @@ export default {
|
|||||||
inputPrice: this.formatPrice(model.input_token_price),
|
inputPrice: this.formatPrice(model.input_token_price),
|
||||||
outputPrice: this.formatPrice(model.output_token_price),
|
outputPrice: this.formatPrice(model.output_token_price),
|
||||||
cacheHitInputPrice: this.formatPrice(model.cache_hit_input_price),
|
cacheHitInputPrice: this.formatPrice(model.cache_hit_input_price),
|
||||||
priceUnit: this.getPriceUnit(model.billing_unit)
|
priceUnit: this.getPriceUnit(model.billing_unit),
|
||||||
|
experience: this.normalizeExperience(model.experience)
|
||||||
}
|
}
|
||||||
this.capabilityList = this.parseInfoList(model.capabilities, [
|
this.capabilityList = this.parseInfoList(model.capabilities, [
|
||||||
{ label: '接口类型', value: '-' },
|
{ label: '接口类型', value: '-' },
|
||||||
@ -271,6 +285,9 @@ export default {
|
|||||||
hasValue(value) {
|
hasValue(value) {
|
||||||
return value !== undefined && value !== null && value !== '' && value !== '-'
|
return value !== undefined && value !== null && value !== '' && value !== '-'
|
||||||
},
|
},
|
||||||
|
normalizeExperience(value) {
|
||||||
|
return Number(value) === 1 ? 1 : 0
|
||||||
|
},
|
||||||
goTokenMarket() {
|
goTokenMarket() {
|
||||||
if (this.$route.query.single === '1') {
|
if (this.$route.query.single === '1') {
|
||||||
this.$router.push({ path: '/tokenMarket', query: { category: 'TOKEN市集', single: '1' } })
|
this.$router.push({ path: '/tokenMarket', query: { category: 'TOKEN市集', single: '1' } })
|
||||||
@ -279,10 +296,6 @@ export default {
|
|||||||
this.$router.push({ path: '/product', query: { category: 'TOKEN市集' } })
|
this.$router.push({ path: '/product', query: { category: 'TOKEN市集' } })
|
||||||
},
|
},
|
||||||
goBack() {
|
goBack() {
|
||||||
if (this.$route.query.from === 'tokenMarket') {
|
|
||||||
this.goTokenMarket()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
this.$router.back()
|
this.$router.back()
|
||||||
},
|
},
|
||||||
buildModelQuery() {
|
buildModelQuery() {
|
||||||
@ -298,6 +311,7 @@ export default {
|
|||||||
this.$router.push({ name: 'modelApiDocument', query: this.buildModelQuery() })
|
this.$router.push({ name: 'modelApiDocument', query: this.buildModelQuery() })
|
||||||
},
|
},
|
||||||
goExperience() {
|
goExperience() {
|
||||||
|
if (!this.canExperience) return
|
||||||
this.$router.push({ name: 'modelExperience', query: this.buildModelQuery() })
|
this.$router.push({ name: 'modelExperience', query: this.buildModelQuery() })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -354,7 +368,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.detail-container {
|
.detail-container {
|
||||||
width: 920px;
|
width: 1180px;
|
||||||
|
max-width: calc(100vw - 48px);
|
||||||
margin: 28px auto 0;
|
margin: 28px auto 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -139,7 +139,12 @@
|
|||||||
<i class="el-icon-document"></i>
|
<i class="el-icon-document"></i>
|
||||||
API文档
|
API文档
|
||||||
</button>
|
</button>
|
||||||
<button v-if="index === 0" class="experience" @click.stop="goModelExperience(product)">
|
<button
|
||||||
|
class="experience"
|
||||||
|
:class="{ disabled: !isModelExperienceEnabled(product) }"
|
||||||
|
:disabled="!isModelExperienceEnabled(product)"
|
||||||
|
@click.stop="goModelExperience(product)"
|
||||||
|
>
|
||||||
<i class="el-icon-video-play"></i>
|
<i class="el-icon-video-play"></i>
|
||||||
体验
|
体验
|
||||||
</button>
|
</button>
|
||||||
@ -354,6 +359,11 @@ export default {
|
|||||||
return provider ? provider.slice(0, 1) : 'M';
|
return provider ? provider.slice(0, 1) : 'M';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// experience 为 1 才允许模型体验,0 时按钮置灰禁用。
|
||||||
|
isModelExperienceEnabled(model) {
|
||||||
|
return Number(model && model.experience) === 1;
|
||||||
|
},
|
||||||
|
|
||||||
// TOKEN 市集卡片点击:进入模型详情页。
|
// TOKEN 市集卡片点击:进入模型详情页。
|
||||||
goModelDetail(model) {
|
goModelDetail(model) {
|
||||||
this.cacheTokenMarketModel(model);
|
this.cacheTokenMarketModel(model);
|
||||||
@ -387,6 +397,7 @@ export default {
|
|||||||
|
|
||||||
// TOKEN 市集体验按钮:进入模型体验页。
|
// TOKEN 市集体验按钮:进入模型体验页。
|
||||||
goModelExperience(model) {
|
goModelExperience(model) {
|
||||||
|
if (!this.isModelExperienceEnabled(model)) return;
|
||||||
if (!this.loginState) {
|
if (!this.loginState) {
|
||||||
this.$message.warning('请先登录再进行体验哦')
|
this.$message.warning('请先登录再进行体验哦')
|
||||||
return;
|
return;
|
||||||
@ -1418,6 +1429,20 @@ export default {
|
|||||||
border-color: #a5b4fc;
|
border-color: #a5b4fc;
|
||||||
background: #eef2ff;
|
background: #eef2ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.disabled,
|
||||||
|
&:disabled {
|
||||||
|
color: #98a2b3;
|
||||||
|
cursor: not-allowed;
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-color: #e5e7eb;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #98a2b3;
|
||||||
|
background: #f3f4f6;
|
||||||
|
border-color: #e5e7eb;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
<span class="title-icon">
|
<span class="title-icon">
|
||||||
<i class="el-icon-data-line"></i>
|
<i class="el-icon-data-line"></i>
|
||||||
</span>
|
</span>
|
||||||
<h2>Token用量</h2>
|
<h2>Token用量</h2>
|
||||||
</div>
|
</div>
|
||||||
<p>查看模型调用 Token 消耗、调用次数和费用趋势。</p>
|
<p>查看模型调用 Token 消耗、调用次数和费用趋势。</p>
|
||||||
</div>
|
</div>
|
||||||
@ -53,6 +53,8 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import { reqTokenUsage } from '@/api/model/model'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'TokenUsage',
|
name: 'TokenUsage',
|
||||||
data() {
|
data() {
|
||||||
@ -65,36 +67,24 @@ export default {
|
|||||||
{ label: '活跃模型', value: '8', desc: '最近 7 天有调用', type: 'purple' }
|
{ label: '活跃模型', value: '8', desc: '最近 7 天有调用', type: 'purple' }
|
||||||
],
|
],
|
||||||
usageList: [
|
usageList: [
|
||||||
{
|
|
||||||
modelName: 'DeepSeek-V4',
|
|
||||||
calls: 1260,
|
|
||||||
inputTokens: '420,000',
|
|
||||||
outputTokens: '318,000',
|
|
||||||
totalTokens: '738,000',
|
|
||||||
cost: '¥ 73.80',
|
|
||||||
updatedAt: '2026-05-25 10:00:00'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
modelName: '通义千问-Plus',
|
|
||||||
calls: 856,
|
|
||||||
inputTokens: '210,400',
|
|
||||||
outputTokens: '156,000',
|
|
||||||
totalTokens: '366,400',
|
|
||||||
cost: '¥ 38.20',
|
|
||||||
updatedAt: '2026-05-25 09:42:16'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
modelName: '腾讯混元-Pro',
|
|
||||||
calls: 342,
|
|
||||||
inputTokens: '102,000',
|
|
||||||
outputTokens: '80,000',
|
|
||||||
totalTokens: '182,000',
|
|
||||||
cost: '¥ 16.64',
|
|
||||||
updatedAt: '2026-05-25 09:18:31'
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
created() {
|
||||||
|
this.getTokenList()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getCurrentUserId() {
|
||||||
|
return sessionStorage.getItem('userId') || localStorage.getItem('userId') || ''
|
||||||
|
},
|
||||||
|
async getTokenList() {
|
||||||
|
const userid = this.getCurrentUserId()
|
||||||
|
const res = await reqTokenUsage({ userid:userid })
|
||||||
|
console.log('token用量',res);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user