feat: implement tiered billing expression evaluation and related functionality
- Added support for tiered billing expressions in the billing system. - Introduced new types and functions for handling billing expressions, including caching and execution. - Updated existing billing logic to accommodate tiered billing scenarios. - Enhanced request handling to support incoming billing expression requests. - Added tests for tiered billing functionality to ensure correctness.
This commit is contained in:
@@ -17,7 +17,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React, { useMemo, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import {
|
||||
Banner,
|
||||
Button,
|
||||
@@ -49,6 +49,7 @@ import {
|
||||
useModelPricingEditorState,
|
||||
} from '../hooks/useModelPricingEditorState';
|
||||
import { useIsMobile } from '../../../../hooks/common/useIsMobile';
|
||||
import TieredPricingEditor from './TieredPricingEditor';
|
||||
|
||||
const { Text } = Typography;
|
||||
const EMPTY_CANDIDATE_MODEL_NAMES = [];
|
||||
@@ -123,6 +124,8 @@ export default function ModelPricingEditor({
|
||||
handleOptionalFieldToggle,
|
||||
handleNumericFieldChange,
|
||||
handleBillingModeChange,
|
||||
handleBillingExprChange,
|
||||
handleRequestRuleExprChange,
|
||||
handleSubmit,
|
||||
addModel,
|
||||
deleteModel,
|
||||
@@ -135,6 +138,15 @@ export default function ModelPricingEditor({
|
||||
filterMode,
|
||||
});
|
||||
|
||||
const getExprModeLabel = useCallback((model) => {
|
||||
if (model?.billingMode !== 'tiered_expr') {
|
||||
return '';
|
||||
}
|
||||
return (model.billingExpr || '').includes('tier(')
|
||||
? t('阶梯计费')
|
||||
: t('表达式计费');
|
||||
}, [t]);
|
||||
|
||||
const columns = useMemo(
|
||||
() => [
|
||||
{
|
||||
@@ -175,10 +187,20 @@ export default function ModelPricingEditor({
|
||||
dataIndex: 'billingMode',
|
||||
key: 'billingMode',
|
||||
render: (_, record) => (
|
||||
<Tag color={record.billingMode === 'per-request' ? 'teal' : 'violet'}>
|
||||
<Tag
|
||||
color={
|
||||
record.billingMode === 'per-request'
|
||||
? 'teal'
|
||||
: record.billingMode === 'tiered_expr'
|
||||
? 'amber'
|
||||
: 'violet'
|
||||
}
|
||||
>
|
||||
{record.billingMode === 'per-request'
|
||||
? t('按次计费')
|
||||
: t('按量计费')}
|
||||
: record.billingMode === 'tiered_expr'
|
||||
? getExprModeLabel(record)
|
||||
: t('按量计费')}
|
||||
</Tag>
|
||||
),
|
||||
},
|
||||
@@ -208,6 +230,7 @@ export default function ModelPricingEditor({
|
||||
[
|
||||
allowDeleteModel,
|
||||
deleteModel,
|
||||
getExprModeLabel,
|
||||
selectedModelName,
|
||||
selectedModelNames,
|
||||
setSelectedModelName,
|
||||
@@ -353,10 +376,20 @@ export default function ModelPricingEditor({
|
||||
title={selectedModel ? selectedModel.name : t('模型计费编辑器')}
|
||||
headerExtraContent={
|
||||
selectedModel ? (
|
||||
<Tag color='blue'>
|
||||
<Tag
|
||||
color={
|
||||
selectedModel.billingMode === 'per-request'
|
||||
? 'teal'
|
||||
: selectedModel.billingMode === 'tiered_expr'
|
||||
? 'amber'
|
||||
: 'blue'
|
||||
}
|
||||
>
|
||||
{selectedModel.billingMode === 'per-request'
|
||||
? t('按次计费')
|
||||
: t('按量计费')}
|
||||
: selectedModel.billingMode === 'tiered_expr'
|
||||
? getExprModeLabel(selectedModel)
|
||||
: t('按量计费')}
|
||||
</Tag>
|
||||
) : null
|
||||
}
|
||||
@@ -381,10 +414,11 @@ export default function ModelPricingEditor({
|
||||
>
|
||||
<Radio value='per-token'>{t('按量计费')}</Radio>
|
||||
<Radio value='per-request'>{t('按次计费')}</Radio>
|
||||
<Radio value='tiered_expr'>{t('表达式/阶梯计费')}</Radio>
|
||||
</RadioGroup>
|
||||
<div className='mt-2 text-xs text-gray-500'>
|
||||
{t(
|
||||
'这个界面默认按价格填写,保存时会自动换算回后端需要的倍率 JSON。',
|
||||
'普通按量/按次直接填价格就行;如果价格要跟请求参数或请求头联动,请切到表达式/阶梯计费。',
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -415,6 +449,14 @@ export default function ModelPricingEditor({
|
||||
onChange={(value) => handleNumericFieldChange('fixedPrice', value)}
|
||||
extraText={t('适合 MJ / 任务类等按次收费模型。')}
|
||||
/>
|
||||
) : selectedModel.billingMode === 'tiered_expr' ? (
|
||||
<TieredPricingEditor
|
||||
model={selectedModel}
|
||||
onExprChange={handleBillingExprChange}
|
||||
requestRuleExpr={selectedModel.requestRuleExpr}
|
||||
onRequestRuleExprChange={handleRequestRuleExprChange}
|
||||
t={t}
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
<Card
|
||||
|
||||
Reference in New Issue
Block a user