积分消耗明细改版V1
This commit is contained in:
@@ -1328,7 +1328,7 @@ export async function adminDeductCredits(userId: string, payload: Record<string,
|
||||
return api.post(`/admin/credit-management/users/${userId}/deduct`, payload);
|
||||
}
|
||||
|
||||
// ── LLM Fixed Pre-deduct ──────────────────────────────────
|
||||
// ── LLM 场景积分配置 ───────────────────────────────────────
|
||||
export async function getLlmBillingPolicies(): Promise<import('../types').LlmBillingPolicy[]> {
|
||||
return api.get('/admin/llm-billing/policies');
|
||||
}
|
||||
|
||||
@@ -47,10 +47,11 @@ const RECORD_TYPE_MAP: Record<string, { text: string; color: string; icon: React
|
||||
|
||||
|
||||
const CHARGE_ACTION_MAP: Record<string, { text: string; color: string }> = {
|
||||
charge: { text: '真实扣费', color: 'red' },
|
||||
charge: { text: '真实消费', color: 'red' },
|
||||
refund: { text: '真实退款', color: 'blue' },
|
||||
hold: { text: '预扣占用', color: 'gold' },
|
||||
hold_release: { text: '预扣释放', color: 'green' },
|
||||
pre_deduct: { text: '历史固定预扣', color: 'default' },
|
||||
hold: { text: '历史预扣占用', color: 'gold' },
|
||||
hold_release: { text: '历史预扣释放', color: 'green' },
|
||||
};
|
||||
|
||||
const userScopeOptions = [
|
||||
@@ -105,10 +106,11 @@ const chargeKindOptions = [
|
||||
|
||||
const chargeActionOptions = [
|
||||
{ value: '', label: '全部交易动作' },
|
||||
{ value: 'charge', label: '真实扣费' },
|
||||
{ value: 'charge', label: '真实消费' },
|
||||
{ value: 'refund', label: '真实退款' },
|
||||
{ value: 'hold', label: '预扣占用' },
|
||||
{ value: 'hold_release', label: '预扣释放' },
|
||||
{ value: 'pre_deduct', label: '历史固定预扣' },
|
||||
{ value: 'hold', label: '历史预扣占用' },
|
||||
{ value: 'hold_release', label: '历史预扣释放' },
|
||||
];
|
||||
|
||||
const sourceModuleOptions = [
|
||||
@@ -306,7 +308,7 @@ const AdminCreditRecords: React.FC = () => {
|
||||
{ title: '说明', minWidth: 18, maxWidth: 42, render: (r) => r.description || '' },
|
||||
{ title: '业务归属类型', maxWidth: 18, render: (r) => r.ownerType || '' },
|
||||
{ title: '业务归属ID', maxWidth: 28, render: (r) => r.ownerId || '' },
|
||||
{ title: '积分来源分摊', minWidth: 24, maxWidth: 48, render: (r) => (r.allocations || []).map(a => `${a.sourceType || '-'}:${a.sourceId || '-'}=${a.amount}`).join(';') },
|
||||
{ title: '积分来源分摊', minWidth: 24, maxWidth: 48, render: (r) => (r.allocations || []).map(a => `${a.sourceTypeLabel || a.sourceType || '-'}:${a.sourceId || '-'}=${a.amount}`).join(';') },
|
||||
{ title: 'BizKey', maxWidth: 36, render: (r) => r.bizKey || '' },
|
||||
];
|
||||
|
||||
@@ -322,22 +324,18 @@ const AdminCreditRecords: React.FC = () => {
|
||||
],
|
||||
summaryRows: [
|
||||
['总充值', exportSummary.totalRecharge],
|
||||
['总消费(真实扣费 + 预扣占用)', exportSummary.totalConsume],
|
||||
[' · 真实扣费(独立统计:type=消费 & action=charge/NULL)', exportSummary.totalCharge],
|
||||
[' · 预扣占用(独立统计:type=消费 & action=hold)', exportSummary.totalHold],
|
||||
['总回退(真实退款 + 预扣释放)', exportSummary.totalRefund],
|
||||
[' · 真实退款(独立统计:type=回退 & action=refund/NULL)', exportSummary.totalRefundReal],
|
||||
[' · 预扣释放(独立统计:type=回退 & action=hold_release)', exportSummary.totalHoldRelease],
|
||||
['净消耗(总消费 − 总回退,≥ 0)', exportSummary.netConsume],
|
||||
['总真实消费', exportSummary.totalConsume],
|
||||
['总真实退款', exportSummary.totalRefund],
|
||||
['净消耗(总消费 − 总退款,≥ 0)', exportSummary.netConsume],
|
||||
['交易笔数', exportSummary.transactionCount],
|
||||
['生成条数', exportSummary.generationCount],
|
||||
['生成尝试次数', exportSummary.generationAttemptCount],
|
||||
['图片生成条数', exportSummary.imageGenerationCount],
|
||||
['视频生成条数', exportSummary.videoGenerationCount],
|
||||
['图片消费积分(仅真实扣费)', exportSummary.imageConsume],
|
||||
['视频消费积分(仅真实扣费)', exportSummary.videoConsume],
|
||||
['提词消费积分(仅真实扣费)', exportSummary.textConsume],
|
||||
['视频分析积分(仅真实扣费)', exportSummary.analysisConsume],
|
||||
['图片消费积分(仅真实消费)', exportSummary.imageConsume],
|
||||
['视频消费积分(仅真实消费)', exportSummary.videoConsume],
|
||||
['提词消费积分(仅真实消费)', exportSummary.textConsume],
|
||||
['视频分析积分(仅真实消费)', exportSummary.analysisConsume],
|
||||
['总 Token', exportSummary.totalTokens],
|
||||
['输入 Token', exportSummary.inputTokens],
|
||||
['输出 Token', exportSummary.outputTokens],
|
||||
@@ -389,32 +387,18 @@ const AdminCreditRecords: React.FC = () => {
|
||||
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5' }}>
|
||||
<Space><ArrowDownOutlined style={{ color: '#ef4444', fontSize: 22 }} />
|
||||
<div style={{ minWidth: 0 }}>
|
||||
<div style={{ color: '#94a3b8' }}>
|
||||
总消费
|
||||
<span style={{ marginLeft: 6, fontSize: 10, color: '#94a3b8' }}>(真实扣费 + 预扣占用)</span>
|
||||
</div>
|
||||
<div style={{ color: '#94a3b8' }}>总消费</div>
|
||||
<div style={{ fontSize: 22, fontWeight: 800, color: '#ef4444' }}>-{n(summary.totalConsume)}</div>
|
||||
<div style={{ fontSize: 11, color: '#94a3b8', marginTop: 2 }}>
|
||||
真实 <span style={{ color: '#b91c1c', fontWeight: 600 }}>{n(summary.totalCharge)}</span>
|
||||
<span style={{ margin: '0 4px', color: '#cbd5e1' }}>|</span>
|
||||
预扣 <span style={{ color: '#d97706', fontWeight: 600 }}>{n(summary.totalHold)}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: '#94a3b8', marginTop: 2 }}>仅统计真实消费流水</div>
|
||||
</div>
|
||||
</Space>
|
||||
</Card>
|
||||
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5' }}>
|
||||
<Space><RollbackOutlined style={{ color: '#3b82f6', fontSize: 22 }} />
|
||||
<div style={{ minWidth: 0 }}>
|
||||
<div style={{ color: '#94a3b8' }}>
|
||||
总回退
|
||||
<span style={{ marginLeft: 6, fontSize: 10, color: '#94a3b8' }}>(真实退款 + 预扣释放)</span>
|
||||
</div>
|
||||
<div style={{ color: '#94a3b8' }}>总退款</div>
|
||||
<div style={{ fontSize: 22, fontWeight: 800, color: '#3b82f6' }}>+{n(summary.totalRefund)}</div>
|
||||
<div style={{ fontSize: 11, color: '#94a3b8', marginTop: 2 }}>
|
||||
退款 <span style={{ color: '#1d4ed8', fontWeight: 600 }}>{n(summary.totalRefundReal)}</span>
|
||||
<span style={{ margin: '0 4px', color: '#cbd5e1' }}>|</span>
|
||||
释放 <span style={{ color: '#047857', fontWeight: 600 }}>{n(summary.totalHoldRelease)}</span>
|
||||
</div>
|
||||
<div style={{ fontSize: 11, color: '#94a3b8', marginTop: 2 }}>仅统计真实退款流水</div>
|
||||
</div>
|
||||
</Space>
|
||||
</Card>
|
||||
@@ -423,7 +407,7 @@ const AdminCreditRecords: React.FC = () => {
|
||||
<div>
|
||||
<div style={{ color: '#6366f1' }}>净消耗(实际用掉)</div>
|
||||
<div style={{ fontSize: 22, fontWeight: 800, color: '#4338ca' }}>{n(summary.netConsume)}</div>
|
||||
<div style={{ fontSize: 11, color: '#818cf8', marginTop: 2 }}>总消费 − 总回退(≥ 0)</div>
|
||||
<div style={{ fontSize: 11, color: '#818cf8', marginTop: 2 }}>总消费 − 总退款(≥ 0)</div>
|
||||
</div>
|
||||
</Space>
|
||||
</Card>
|
||||
@@ -498,8 +482,8 @@ const AdminCreditRecords: React.FC = () => {
|
||||
rowKey="id"
|
||||
dataSource={record.allocations || []}
|
||||
columns={[
|
||||
{ title: '动作', dataIndex: 'allocationAction', width: 150 },
|
||||
{ title: '积分来源', dataIndex: 'sourceType', width: 160, render: (v: string) => v || '-' },
|
||||
{ title: '动作', dataIndex: 'allocationActionLabel', width: 150, render: (v: string, r: any) => v || r.allocationAction || '-' },
|
||||
{ title: '积分来源', dataIndex: 'sourceTypeLabel', width: 160, render: (v: string, r: any) => v || r.sourceType || '-' },
|
||||
{ title: '来源ID', dataIndex: 'sourceId', width: 260, render: (v: string) => v || '-' },
|
||||
{ title: '积分数量', dataIndex: 'amount', width: 120, render: (v: number) => n(v) },
|
||||
{ title: '生效时间', dataIndex: 'validFrom', width: 190, render: (v: string) => v ? formatDate(v) : '-' },
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { LlmBillingExecution } from '../types';
|
||||
import { formatDate, formatDatePrecise } from '../utils/formatDate';
|
||||
|
||||
const STATUS_LABELS: Record<string, { label: string; color: string }> = {
|
||||
pre_deducted: { label: '已预扣', color: 'blue' },
|
||||
charged: { label: '已消费', color: 'blue' },
|
||||
processing: { label: '处理中', color: 'processing' },
|
||||
succeeded: { label: '业务成功', color: 'success' },
|
||||
final_failed: { label: '最终失败', color: 'error' },
|
||||
@@ -41,7 +41,7 @@ const AdminLlmBillingExecutions: React.FC = () => {
|
||||
}))} />
|
||||
<Descriptions bordered size="small" column={4} items={[
|
||||
{ key: 'scene', label: '功能', children: record.sceneNameSnapshot },
|
||||
{ key: 'credit', label: '固定预扣', children: record.preDeductCredits },
|
||||
{ key: 'credit', label: '消费积分', children: record.chargeCredits },
|
||||
{ key: 'calls', label: '调用', children: `${record.totalCallCount}(成功 ${record.successfulCallCount} / 失败 ${record.failedCallCount})` },
|
||||
{ key: 'tokens', label: '累计 Token', children: record.totalTokens },
|
||||
{ key: 'refundA', label: '有效积分退回', children: record.refundAvailableCredits },
|
||||
@@ -53,7 +53,7 @@ const AdminLlmBillingExecutions: React.FC = () => {
|
||||
{ title: '用户', dataIndex: 'userId' },
|
||||
{ title: '业务对象', render: (_: unknown, r: LlmBillingExecution) => `${r.ownerType}:${r.ownerId}` },
|
||||
{ title: '模型', dataIndex: 'modelNameSnapshot' },
|
||||
{ title: '预扣', dataIndex: 'preDeductCredits' },
|
||||
{ title: '消费积分', dataIndex: 'chargeCredits' },
|
||||
{ title: '调用/Token', render: (_: unknown, r: LlmBillingExecution) => `${r.totalCallCount} / ${r.totalTokens}` },
|
||||
{ title: '状态', dataIndex: 'status', render: (v: string) => { const config = STATUS_LABELS[v] || { label: v, color: 'default' }; return <Tag color={config.color}>{config.label}</Tag>; } },
|
||||
{ title: '请求时间', dataIndex: 'requestTime', render: (v: string) => formatDate(v) },
|
||||
|
||||
@@ -20,32 +20,64 @@ const AdminLlmBillingPolicies: React.FC = () => {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [form] = Form.useForm();
|
||||
const load = async () => { setLoading(true); try { setItems(await getLlmBillingPolicies()); } finally { setLoading(false); } };
|
||||
|
||||
const load = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
setItems(await getLlmBillingPolicies());
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => { load(); }, []);
|
||||
const edit = (item?: LlmBillingPolicy) => { setEditing(item || null); setOpen(true); form.resetFields(); form.setFieldsValue(item ? { scene_code: item.sceneCode, pre_deduct_credits: item.preDeductCredits, is_active: item.isActive } : { is_active: true, pre_deduct_credits: 5 }); };
|
||||
|
||||
const edit = (item?: LlmBillingPolicy) => {
|
||||
setEditing(item || null);
|
||||
setOpen(true);
|
||||
form.resetFields();
|
||||
form.setFieldsValue(item
|
||||
? { scene_code: item.sceneCode, charge_credits: item.chargeCredits, is_active: item.isActive }
|
||||
: { is_active: true, charge_credits: 5 });
|
||||
};
|
||||
|
||||
const save = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
if (editing) await updateLlmBillingPolicy(editing.id, values); else await createLlmBillingPolicy(values);
|
||||
message.success('已保存'); setOpen(false); load();
|
||||
} catch (error: any) { if (!error?.errorFields) message.error(error?.message || '保存失败'); }
|
||||
if (editing) await updateLlmBillingPolicy(editing.id, values);
|
||||
else await createLlmBillingPolicy(values);
|
||||
message.success('已保存');
|
||||
setOpen(false);
|
||||
load();
|
||||
} catch (error: any) {
|
||||
if (!error?.errorFields) message.error(error?.message || '保存失败');
|
||||
}
|
||||
};
|
||||
return <Card title={<Space><RobotOutlined />LLM固定预扣配置</Space>} extra={<Button type="primary" icon={<PlusOutlined />} onClick={() => edit()}>新增场景</Button>}>
|
||||
|
||||
return <Card
|
||||
title={<Space><RobotOutlined />LLM积分配置</Space>}
|
||||
extra={<Button type="primary" icon={<PlusOutlined />} onClick={() => edit()}>新增场景</Button>}
|
||||
>
|
||||
<Table rowKey="id" loading={loading} dataSource={items} columns={[
|
||||
{ title: '功能', dataIndex: 'sceneName' },
|
||||
{ title: '场景编码', dataIndex: 'sceneCode' },
|
||||
{ title: '固定预扣积分', dataIndex: 'preDeductCredits' },
|
||||
{ title: '消费积分', dataIndex: 'chargeCredits' },
|
||||
{ title: '版本', dataIndex: 'version' },
|
||||
{ title: '状态', dataIndex: 'isActive', render: (v: boolean) => <Tag color={v ? 'green' : 'default'}>{v ? '启用' : '停用'}</Tag> },
|
||||
{ title: '操作', render: (_: unknown, r: LlmBillingPolicy) => <Button type="link" icon={<EditOutlined />} onClick={() => edit(r)}>编辑</Button> },
|
||||
]} />
|
||||
<Modal open={open} title={editing ? '编辑LLM场景预扣' : '新增LLM场景预扣'} onOk={save} onCancel={() => setOpen(false)}>
|
||||
<Modal open={open} title={editing ? '编辑LLM积分场景' : '新增LLM积分场景'} onOk={save} onCancel={() => setOpen(false)}>
|
||||
<Form form={form} layout="vertical">
|
||||
<Form.Item name="scene_code" label="业务功能" rules={[{ required: true }]}><Select disabled={!!editing} options={SCENES} /></Form.Item>
|
||||
<Form.Item name="pre_deduct_credits" label="固定预扣积分" rules={[{ required: true }]}><InputNumber min={0.01} precision={2} style={{ width: '100%' }} /></Form.Item>
|
||||
<Form.Item name="scene_code" label="业务功能" rules={[{ required: true }]}>
|
||||
<Select disabled={!!editing} options={SCENES} />
|
||||
</Form.Item>
|
||||
<Form.Item name="charge_credits" label="消费积分" rules={[{ required: true }]}>
|
||||
<InputNumber min={0.01} precision={2} style={{ width: '100%' }} />
|
||||
</Form.Item>
|
||||
<Form.Item name="is_active" label="启用" valuePropName="checked"><Switch /></Form.Item>
|
||||
</Form>
|
||||
</Modal>
|
||||
</Card>;
|
||||
};
|
||||
|
||||
export default AdminLlmBillingPolicies;
|
||||
|
||||
@@ -63,31 +63,6 @@ const AdminSettings: React.FC = () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
|
||||
// 仅当 llm_billing_enabled 字段在当前标签页渲染时,才校验预扣积分
|
||||
const llmBillingEnabled = values.llm_billing_enabled !== undefined && values.llm_billing_enabled !== null
|
||||
? !['0', 'false', 'no', 'off', 'disabled'].includes(
|
||||
String(values.llm_billing_enabled).trim().toLowerCase(),
|
||||
)
|
||||
: false;
|
||||
if (llmBillingEnabled) {
|
||||
const holdKeys = [
|
||||
'optimize_hold_credits',
|
||||
'llm_hold_credits_default',
|
||||
'llm_hold_credits_generation_record_prompt',
|
||||
'llm_hold_credits_module_image_prompt',
|
||||
'llm_hold_credits_module_video_prompt',
|
||||
'llm_hold_credits_shot_video_analysis',
|
||||
];
|
||||
const invalidKey = holdKeys.find((key) => {
|
||||
const numericValue = Number(values[key]);
|
||||
return !Number.isFinite(numericValue) || numericValue <= 0;
|
||||
});
|
||||
if (invalidKey) {
|
||||
message.error('启用 LLM 统一计费时,所有预扣积分必须大于 0');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
setSaving(true);
|
||||
for (const config of configs) {
|
||||
const newVal = values[config.key];
|
||||
|
||||
@@ -816,9 +816,9 @@ const AdminUsers: React.FC = () => {
|
||||
pagination={false}
|
||||
dataSource={creditBalances}
|
||||
columns={[
|
||||
{ title: '来源', dataIndex: 'sourceType', width: 150, render: (v: string) => v || '-' },
|
||||
{ title: '来源', dataIndex: 'sourceTypeLabel', width: 150, render: (v: string, r: any) => v || r.sourceType || '-' },
|
||||
{ title: '来源ID', dataIndex: 'sourceId', width: 220, ellipsis: true, render: (v: string) => v || '-' },
|
||||
{ title: '积分等级', dataIndex: 'creditLevel', width: 100, render: (v: string) => v === 'promotional' ? '活动积分' : '普通积分' },
|
||||
{ title: '积分等级', dataIndex: 'creditLevelLabel', width: 100, render: (v: string, r: any) => v || r.creditLevel || '-' },
|
||||
{ title: '发放', dataIndex: 'grantAmount', width: 100, render: (v: number) => Number(v || 0).toLocaleString() },
|
||||
{ title: '剩余', dataIndex: 'unspentAmount', width: 100, render: (v: number) => Number(v || 0).toLocaleString() },
|
||||
{ title: '已消费', dataIndex: 'consumedAmount', width: 100, render: (v: number) => Number(v || 0).toLocaleString() },
|
||||
@@ -826,7 +826,7 @@ const AdminUsers: React.FC = () => {
|
||||
{ title: '已撤销', dataIndex: 'revokedAmount', width: 100, render: (v: number) => Number(v || 0).toLocaleString() },
|
||||
{ title: '生效时间', dataIndex: 'validFrom', width: 170, render: (v: string) => formatDate(v) },
|
||||
{ title: '最后可用时间', dataIndex: 'lastUsableAt', width: 180, render: (v: string) => formatDate(v) },
|
||||
{ title: '状态', dataIndex: 'status', width: 90, render: (v: string) => <Tag color={v === 'active' ? 'green' : v === 'expired' ? 'orange' : v === 'revoked' ? 'red' : 'default'}>{v}</Tag> },
|
||||
{ title: '状态', dataIndex: 'status', width: 90, render: (v: string, r: any) => <Tag color={v === 'active' ? 'green' : v === 'expired' ? 'orange' : v === 'revoked' ? 'red' : 'default'}>{r.statusLabel || v || '-'}</Tag> },
|
||||
]}
|
||||
scroll={{ x: 1410, y: 460 }}
|
||||
/>
|
||||
|
||||
@@ -868,17 +868,17 @@ export interface VideoPromptSchemaPreviewOut {
|
||||
|
||||
export interface AdminCreditRecordSummary {
|
||||
totalRecharge: number;
|
||||
/** 总消费(仅 type=consume,不含团队内部转账)= 真实扣费 + 预扣占用 */
|
||||
/** 总消费:仅真实消费,不含历史 hold/团队内部转账;兼容历史 LLM pre_deduct 真实消费 */
|
||||
totalConsume: number;
|
||||
/** 总回退(仅 type=refund)= 真实退款 + 预扣释放 */
|
||||
/** 总退款:仅真实退款,不含历史 hold_release */
|
||||
totalRefund: number;
|
||||
/** 独立统计列:真实扣费 charge(含历史 NULL),对应"筛选类型=消费 & action=charge/NULL"求和 */
|
||||
/** 兼容字段:与 totalConsume 同真实消费口径 */
|
||||
totalCharge: number;
|
||||
/** 独立统计列:预扣占用 hold */
|
||||
/** 历史兼容字段:hold 占用,不计入 totalConsume */
|
||||
totalHold: number;
|
||||
/** 独立统计列:真实退款 refund(含历史 NULL) */
|
||||
/** 兼容字段:与 totalRefund 同真实退款口径 */
|
||||
totalRefundReal: number;
|
||||
/** 独立统计列:预扣释放 hold_release(type=refund, action=hold_release) */
|
||||
/** 历史兼容字段:hold_release,不计入 totalRefund */
|
||||
totalHoldRelease: number;
|
||||
/** 净消耗 = max(totalConsume - totalRefund, 0),即真正"用掉了"的积分 */
|
||||
netConsume: number;
|
||||
@@ -887,13 +887,13 @@ export interface AdminCreditRecordSummary {
|
||||
generationAttemptCount: number;
|
||||
imageGenerationCount: number;
|
||||
videoGenerationCount: number;
|
||||
/** 子分类消费(图片)仅真实扣费 charge 口径 */
|
||||
/** 子分类消费(图片)仅真实消费 charge 口径 */
|
||||
imageConsume: number;
|
||||
/** 子分类消费(视频)仅真实扣费 charge 口径 */
|
||||
/** 子分类消费(视频)仅真实消费 charge 口径 */
|
||||
videoConsume: number;
|
||||
/** 子分类消费(提词)仅真实扣费 charge 口径 */
|
||||
/** 子分类消费(提词)仅真实消费 charge 口径 */
|
||||
textConsume: number;
|
||||
/** 子分类消费(分析)仅真实扣费 charge 口径 */
|
||||
/** 子分类消费(分析)仅真实消费 charge 口径 */
|
||||
analysisConsume: number;
|
||||
totalTokens: number;
|
||||
inputTokens: number;
|
||||
@@ -905,9 +905,12 @@ export interface AdminCreditRecordAllocation {
|
||||
creditBalanceId: string;
|
||||
sourceAllocationId?: string | null;
|
||||
allocationAction: string;
|
||||
allocationActionLabel?: string;
|
||||
amount: number;
|
||||
creditLevel?: string;
|
||||
creditLevelLabel?: string;
|
||||
sourceType?: string;
|
||||
sourceTypeLabel?: string;
|
||||
sourceId?: string;
|
||||
validFrom?: string;
|
||||
expiresAt?: string;
|
||||
@@ -1503,7 +1506,7 @@ export interface LlmBillingPolicy {
|
||||
id: string;
|
||||
sceneCode: string;
|
||||
sceneName: string;
|
||||
preDeductCredits: number;
|
||||
chargeCredits: number;
|
||||
isActive: boolean;
|
||||
version: number;
|
||||
createdBy?: string | null;
|
||||
@@ -1545,7 +1548,7 @@ export interface LlmBillingExecution {
|
||||
modelNameSnapshot?: string | null;
|
||||
providerSnapshot?: string | null;
|
||||
requestTime: string;
|
||||
preDeductCredits: number;
|
||||
chargeCredits: number;
|
||||
status: string;
|
||||
totalCallCount: number;
|
||||
successfulCallCount: number;
|
||||
|
||||
Reference in New Issue
Block a user