- Add bound_channel_id field to EditTokenModal for channel binding - Load channels list for dropdown selection - Add i18n translations for channel pricing features (zh-CN, en) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>feat/alipay-payment
| @@ -62,6 +62,7 @@ const EditTokenModal = (props) => { | |||||
| const formApiRef = useRef(null); | const formApiRef = useRef(null); | ||||
| const [models, setModels] = useState([]); | const [models, setModels] = useState([]); | ||||
| const [groups, setGroups] = useState([]); | const [groups, setGroups] = useState([]); | ||||
| const [channels, setChannels] = useState([]); | |||||
| const isEdit = props.editingToken.id !== undefined; | const isEdit = props.editingToken.id !== undefined; | ||||
| const getInitValues = () => ({ | const getInitValues = () => ({ | ||||
| @@ -75,6 +76,7 @@ const EditTokenModal = (props) => { | |||||
| group: '', | group: '', | ||||
| cross_group_retry: false, | cross_group_retry: false, | ||||
| tokenCount: 1, | tokenCount: 1, | ||||
| bound_channel_id: null, | |||||
| }); | }); | ||||
| const handleCancel = () => { | const handleCancel = () => { | ||||
| @@ -149,6 +151,20 @@ const EditTokenModal = (props) => { | |||||
| } | } | ||||
| }; | }; | ||||
| const loadChannels = async () => { | |||||
| let res = await API.get(`/api/channel/`); | |||||
| const { success, message, data } = res.data; | |||||
| if (success) { | |||||
| let localChannelOptions = (data || []).map((channel) => ({ | |||||
| label: `${channel.name} (ID: ${channel.id})`, | |||||
| value: channel.id, | |||||
| })); | |||||
| setChannels(localChannelOptions); | |||||
| } else { | |||||
| showError(t(message)); | |||||
| } | |||||
| }; | |||||
| const loadToken = async () => { | const loadToken = async () => { | ||||
| setLoading(true); | setLoading(true); | ||||
| let res = await API.get(`/api/token/${props.editingToken.id}`); | let res = await API.get(`/api/token/${props.editingToken.id}`); | ||||
| @@ -179,6 +195,7 @@ const EditTokenModal = (props) => { | |||||
| } | } | ||||
| loadModels(); | loadModels(); | ||||
| loadGroups(); | loadGroups(); | ||||
| loadChannels(); | |||||
| }, [props.editingToken.id]); | }, [props.editingToken.id]); | ||||
| useEffect(() => { | useEffect(() => { | ||||
| @@ -559,6 +576,17 @@ const EditTokenModal = (props) => { | |||||
| style={{ width: '100%' }} | style={{ width: '100%' }} | ||||
| /> | /> | ||||
| </Col> | </Col> | ||||
| <Col span={24}> | |||||
| <Form.Select | |||||
| field='bound_channel_id' | |||||
| label={t('绑定渠道')} | |||||
| placeholder={t('可选,绑定后该令牌只能使用指定渠道')} | |||||
| optionList={channels} | |||||
| filter | |||||
| showClear | |||||
| style={{ width: '100%' }} | |||||
| /> | |||||
| </Col> | |||||
| <Col span={24}> | <Col span={24}> | ||||
| <Form.TextArea | <Form.TextArea | ||||
| field='allow_ips' | field='allow_ips' | ||||
| @@ -2835,6 +2835,38 @@ | |||||
| "缓存写": "Cache Write", | "缓存写": "Cache Write", | ||||
| "写": "Write", | "写": "Write", | ||||
| "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Per Anthropic conventions, /v1/messages input tokens count only non-cached input and exclude cache read/write tokens.", | "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "Per Anthropic conventions, /v1/messages input tokens count only non-cached input and exclude cache read/write tokens.", | ||||
| "全局定价": "Global Pricing", | |||||
| "渠道定价": "Channel Pricing", | |||||
| "标签管理": "Tag Management", | |||||
| "添加标签": "Add Tag", | |||||
| "编辑标签": "Edit Tag", | |||||
| "标签名称": "Tag Name", | |||||
| "颜色": "Color", | |||||
| "描述": "Description", | |||||
| "排序": "Sort Order", | |||||
| "确定删除此标签?": "Are you sure to delete this tag?", | |||||
| "请输入标签名称": "Please enter tag name", | |||||
| "计费类型": "Billing Type", | |||||
| "按量计费": "By Tokens", | |||||
| "按次计费": "By Call", | |||||
| "输入倍率": "Input Ratio", | |||||
| "输出倍率": "Output Ratio", | |||||
| "固定价格": "Fixed Price", | |||||
| "标签": "Tags", | |||||
| "已配置": "Configured", | |||||
| "渠道数量": "Channel Count", | |||||
| "收起": "Collapse", | |||||
| "展开": "Expand", | |||||
| "渠道": "Channel", | |||||
| "按量": "Tokens", | |||||
| "按次": "Call", | |||||
| "编辑渠道定价": "Edit Channel Pricing", | |||||
| "渠道定价详情": "Channel Pricing Details", | |||||
| "确定删除此渠道定价?": "Are you sure to delete this channel pricing?", | |||||
| "暂无渠道定价数据,请先创建渠道并设置模型": "No channel pricing data. Please create channels and configure models first.", | |||||
| "绑定渠道": "Bind Channel", | |||||
| "可选,绑定后该令牌只能使用指定渠道": "Optional. Once bound, the token can only use the specified channel.", | |||||
| "请选择标签": "Please select tags", | |||||
| "设计版本": "b80c3466cb6feafeb3990c7820e10e50" | "设计版本": "b80c3466cb6feafeb3990c7820e10e50" | ||||
| } | } | ||||
| } | } | ||||
| @@ -2812,6 +2812,38 @@ | |||||
| "缓存读": "缓存读", | "缓存读": "缓存读", | ||||
| "缓存写": "缓存写", | "缓存写": "缓存写", | ||||
| "写": "写", | "写": "写", | ||||
| "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。" | |||||
| "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。": "根据 Anthropic 协定,/v1/messages 的输入 tokens 仅统计非缓存输入,不包含缓存读取与缓存写入 tokens。", | |||||
| "全局定价": "全局定价", | |||||
| "渠道定价": "渠道定价", | |||||
| "标签管理": "标签管理", | |||||
| "添加标签": "添加标签", | |||||
| "编辑标签": "编辑标签", | |||||
| "标签名称": "标签名称", | |||||
| "颜色": "颜色", | |||||
| "描述": "描述", | |||||
| "排序": "排序", | |||||
| "确定删除此标签?": "确定删除此标签?", | |||||
| "请输入标签名称": "请输入标签名称", | |||||
| "计费类型": "计费类型", | |||||
| "按量计费": "按量计费", | |||||
| "按次计费": "按次计费", | |||||
| "输入倍率": "输入倍率", | |||||
| "输出倍率": "输出倍率", | |||||
| "固定价格": "固定价格", | |||||
| "标签": "标签", | |||||
| "已配置": "已配置", | |||||
| "渠道数量": "渠道数量", | |||||
| "收起": "收起", | |||||
| "展开": "展开", | |||||
| "渠道": "渠道", | |||||
| "按量": "按量", | |||||
| "按次": "按次", | |||||
| "编辑渠道定价": "编辑渠道定价", | |||||
| "渠道定价详情": "渠道定价详情", | |||||
| "确定删除此渠道定价?": "确定删除此渠道定价?", | |||||
| "暂无渠道定价数据,请先创建渠道并设置模型": "暂无渠道定价数据,请先创建渠道并设置模型", | |||||
| "绑定渠道": "绑定渠道", | |||||
| "可选,绑定后该令牌只能使用指定渠道": "可选,绑定后该令牌只能使用指定渠道", | |||||
| "请选择标签": "请选择标签" | |||||
| } | } | ||||
| } | } | ||||