前台页面/conversation修改积分计算逻辑

1、后台页面/credit-ratios,需要选择视频,上边是模型价格,下边增加传入视频价格,也要输入对应的倍率、基础积分、每秒积分
2、前台/conversation获取积分逻辑的接口也要增加对应的传入视频的比例
3、然后前台根据用户上传视频自动获取对应的比例加上对应模型选择的积分计算总积分
4、后台提交也要验证对应的积分是否正确
5、多个视频总时长需限制15s,最低视频时长2s
This commit is contained in:
2026-07-01 19:37:51 +08:00
parent 5e70064751
commit 5302d7f531
18 changed files with 657 additions and 1662 deletions
@@ -22,6 +22,9 @@ interface CreditRatio {
ratio: number;
baseCredits: number;
perSecondCredits: number;
inputVideoRatio: number;
inputVideoBaseCredits: number;
inputVideoPerSecondCredits: number;
}
interface CreditRatioFormValues {
@@ -31,6 +34,9 @@ interface CreditRatioFormValues {
ratio: number;
baseCredits: number;
perSecondCredits?: number;
inputVideoRatio?: number;
inputVideoBaseCredits?: number;
inputVideoPerSecondCredits?: number;
}
const DEFAULT_IMAGE_SIZES = ['2K', '4K'];
@@ -117,7 +123,7 @@ const AdminCreditRatios: React.FC = () => {
const handleSave = async () => {
try {
const values = await form.validateFields();
const payload = {
const payload: any = {
model_config_id: values.modelConfigId,
gen_type: values.genType,
resolution: values.resolution,
@@ -125,6 +131,11 @@ const AdminCreditRatios: React.FC = () => {
base_credits: values.baseCredits,
per_second_credits: values.genType === 'image' ? 0 : (values.perSecondCredits || 0),
};
if (values.genType === 'video') {
payload.input_video_ratio = values.inputVideoRatio ?? 1.0;
payload.input_video_base_credits = values.inputVideoBaseCredits ?? 0;
payload.input_video_per_second_credits = values.inputVideoPerSecondCredits ?? 0;
}
if (modal.ratio) {
await saveCreditRatio({ id: modal.ratio.id, ...payload });
message.success('已更新');
@@ -174,10 +185,21 @@ const AdminCreditRatios: React.FC = () => {
ratio: ratio.ratio,
baseCredits: ratio.baseCredits,
perSecondCredits: ratio.perSecondCredits,
inputVideoRatio: ratio.inputVideoRatio,
inputVideoBaseCredits: ratio.inputVideoBaseCredits,
inputVideoPerSecondCredits: ratio.inputVideoPerSecondCredits,
});
} else {
form.resetFields();
form.setFieldsValue({ genType: 'video', ratio: 1.0, baseCredits: 60, perSecondCredits: 2 });
form.setFieldsValue({
genType: 'video',
ratio: 1.0,
baseCredits: 60,
perSecondCredits: 2,
inputVideoRatio: 1.0,
inputVideoBaseCredits: 0,
inputVideoPerSecondCredits: 0.5,
});
}
};
@@ -216,13 +238,18 @@ const AdminCreditRatios: React.FC = () => {
),
},
{
title: '示例计算', key: 'example', width: 120,
title: '示例计算', key: 'example', width: 140,
render: (_: any, r: CreditRatio) => {
let total: number;
if (r.genType === 'image') {
total = Math.round(r.baseCredits * r.ratio);
} else {
total = Math.round((r.baseCredits + r.perSecondCredits * 15) * r.ratio);
if (r.inputVideoRatio && r.inputVideoPerSecondCredits) {
total += Math.round(
(r.inputVideoBaseCredits + r.inputVideoPerSecondCredits * 10) * r.inputVideoRatio
);
}
}
return <Typography.Text strong style={{ color: '#6366f1' }}>{total} </Typography.Text>;
},
@@ -349,6 +376,31 @@ const AdminCreditRatios: React.FC = () => {
</Form.Item>
)}
</div>
{genType !== 'image' && (
<div style={{
marginTop: 8,
padding: '12px 16px',
backgroundColor: '#f5f5ff',
borderRadius: 8,
border: '1px solid #e0e0ff',
}}>
<Typography.Text strong style={{ display: 'block', marginBottom: 8, color: '#4f46e5' }}>
</Typography.Text>
<div style={{ display: 'flex', gap: 16 }}>
<Form.Item name="inputVideoRatio" label="倍率" style={{ flex: 1, marginBottom: 0 }} rules={[{ required: true, message: '请输入传入视频倍率' }]}>
<InputNumber min={0} max={10} step={0.1} style={{ width: '100%' }} size="large" />
</Form.Item>
<Form.Item name="inputVideoBaseCredits" label="基础积分" style={{ flex: 1, marginBottom: 0 }} rules={[{ required: true, message: '请输入传入视频基础积分' }]}>
<InputNumber min={0} max={500} style={{ width: '100%' }} size="large" />
</Form.Item>
<Form.Item name="inputVideoPerSecondCredits" label="每秒积分" style={{ flex: 1, marginBottom: 0 }} rules={[{ required: true, message: '请输入传入视频每秒积分' }]}>
<InputNumber min={0} max={50} style={{ width: '100%' }} size="large" />
</Form.Item>
</div>
</div>
)}
</Form>
</Modal>
</div>