|
|
@@ -0,0 +1,550 @@
|
|
|
+import React, { useEffect, useState } from 'react';
|
|
|
+import { Table, Button, Input, Modal, Form, Space, Typography, Radio, Notification } from '@douyinfe/semi-ui';
|
|
|
+import { IconDelete, IconPlus, IconSearch, IconSave, IconBolt } from '@douyinfe/semi-icons';
|
|
|
+import { showError, showSuccess } from '../../../helpers';
|
|
|
+import { API } from '../../../helpers';
|
|
|
+import { useTranslation } from 'react-i18next';
|
|
|
+
|
|
|
+export default function ModelRatioNotSetEditor(props) {
|
|
|
+ const { t } = useTranslation();
|
|
|
+ const [models, setModels] = useState([]);
|
|
|
+ const [visible, setVisible] = useState(false);
|
|
|
+ const [batchVisible, setBatchVisible] = useState(false);
|
|
|
+ const [currentModel, setCurrentModel] = useState(null);
|
|
|
+ const [searchText, setSearchText] = useState('');
|
|
|
+ const [currentPage, setCurrentPage] = useState(1);
|
|
|
+ const [pageSize, setPageSize] = useState(10);
|
|
|
+ const [loading, setLoading] = useState(false);
|
|
|
+ const [enabledModels, setEnabledModels] = useState([]);
|
|
|
+ const [selectedRowKeys, setSelectedRowKeys] = useState([]);
|
|
|
+ const [batchFillType, setBatchFillType] = useState('ratio');
|
|
|
+ const [batchFillValue, setBatchFillValue] = useState('');
|
|
|
+ const [batchRatioValue, setBatchRatioValue] = useState('');
|
|
|
+ const [batchCompletionRatioValue, setBatchCompletionRatioValue] = useState('');
|
|
|
+ const { Text } = Typography;
|
|
|
+ // 定义可选的每页显示条数
|
|
|
+ const pageSizeOptions = [10, 20, 50, 100];
|
|
|
+
|
|
|
+ const getAllEnabledModels = async () => {
|
|
|
+ try {
|
|
|
+ const res = await API.get('/api/channel/models_enabled');
|
|
|
+ const { success, message, data } = res.data;
|
|
|
+ if (success) {
|
|
|
+ setEnabledModels(data);
|
|
|
+ } else {
|
|
|
+ showError(message);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error(t('获取启用模型失败:'), error);
|
|
|
+ showError(t('获取启用模型失败'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ // 获取所有启用的模型
|
|
|
+ getAllEnabledModels();
|
|
|
+ }, []);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ try {
|
|
|
+ const modelPrice = JSON.parse(props.options.ModelPrice || '{}');
|
|
|
+ const modelRatio = JSON.parse(props.options.ModelRatio || '{}');
|
|
|
+ const completionRatio = JSON.parse(props.options.CompletionRatio || '{}');
|
|
|
+
|
|
|
+ // 找出所有未设置价格和倍率的模型
|
|
|
+ const unsetModels = enabledModels.filter(modelName => {
|
|
|
+ const hasPrice = modelPrice[modelName] !== undefined;
|
|
|
+ const hasRatio = modelRatio[modelName] !== undefined;
|
|
|
+ const hasCompletionRatio = completionRatio[modelName] !== undefined;
|
|
|
+
|
|
|
+ // 如果模型既没有价格也没有倍率设置,则显示
|
|
|
+ return !(hasPrice || (hasRatio && hasCompletionRatio));
|
|
|
+ });
|
|
|
+
|
|
|
+ // 创建模型数据
|
|
|
+ const modelData = unsetModels.map(name => ({
|
|
|
+ name,
|
|
|
+ price: '',
|
|
|
+ ratio: '',
|
|
|
+ completionRatio: ''
|
|
|
+ }));
|
|
|
+
|
|
|
+ setModels(modelData);
|
|
|
+ // 清空选择
|
|
|
+ setSelectedRowKeys([]);
|
|
|
+ } catch (error) {
|
|
|
+ console.error(t('JSON解析错误:'), error);
|
|
|
+ }
|
|
|
+ }, [props.options, enabledModels]);
|
|
|
+
|
|
|
+ // 首先声明分页相关的工具函数
|
|
|
+ const getPagedData = (data, currentPage, pageSize) => {
|
|
|
+ const start = (currentPage - 1) * pageSize;
|
|
|
+ const end = start + pageSize;
|
|
|
+ return data.slice(start, end);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 处理页面大小变化
|
|
|
+ const handlePageSizeChange = (size) => {
|
|
|
+ setPageSize(size);
|
|
|
+ // 重新计算当前页,避免数据丢失
|
|
|
+ const totalPages = Math.ceil(filteredModels.length / size);
|
|
|
+ if (currentPage > totalPages) {
|
|
|
+ setCurrentPage(totalPages || 1);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 在 return 语句之前,先处理过滤和分页逻辑
|
|
|
+ const filteredModels = models.filter(model =>
|
|
|
+ searchText ? model.name.toLowerCase().includes(searchText.toLowerCase()) : true
|
|
|
+ );
|
|
|
+
|
|
|
+ // 然后基于过滤后的数据计算分页数据
|
|
|
+ const pagedData = getPagedData(filteredModels, currentPage, pageSize);
|
|
|
+
|
|
|
+ const SubmitData = async () => {
|
|
|
+ setLoading(true);
|
|
|
+ const output = {
|
|
|
+ ModelPrice: JSON.parse(props.options.ModelPrice || '{}'),
|
|
|
+ ModelRatio: JSON.parse(props.options.ModelRatio || '{}'),
|
|
|
+ CompletionRatio: JSON.parse(props.options.CompletionRatio || '{}')
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 数据转换 - 只处理已修改的模型
|
|
|
+ models.forEach(model => {
|
|
|
+ // 只有当用户设置了值时才更新
|
|
|
+ if (model.price !== '') {
|
|
|
+ // 如果价格不为空,则转换为浮点数,忽略倍率参数
|
|
|
+ output.ModelPrice[model.name] = parseFloat(model.price);
|
|
|
+ } else {
|
|
|
+ if (model.ratio !== '') output.ModelRatio[model.name] = parseFloat(model.ratio);
|
|
|
+ if (model.completionRatio !== '') output.CompletionRatio[model.name] = parseFloat(model.completionRatio);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 准备API请求数组
|
|
|
+ const finalOutput = {
|
|
|
+ ModelPrice: JSON.stringify(output.ModelPrice, null, 2),
|
|
|
+ ModelRatio: JSON.stringify(output.ModelRatio, null, 2),
|
|
|
+ CompletionRatio: JSON.stringify(output.CompletionRatio, null, 2)
|
|
|
+ };
|
|
|
+
|
|
|
+ const requestQueue = Object.entries(finalOutput).map(([key, value]) => {
|
|
|
+ return API.put('/api/option/', {
|
|
|
+ key,
|
|
|
+ value
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ // 批量处理请求
|
|
|
+ const results = await Promise.all(requestQueue);
|
|
|
+
|
|
|
+ // 验证结果
|
|
|
+ if (requestQueue.length === 1) {
|
|
|
+ if (results.includes(undefined)) return;
|
|
|
+ } else if (requestQueue.length > 1) {
|
|
|
+ if (results.includes(undefined)) {
|
|
|
+ return showError(t('部分保存失败,请重试'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查每个请求的结果
|
|
|
+ for (const res of results) {
|
|
|
+ if (!res.data.success) {
|
|
|
+ return showError(res.data.message);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ showSuccess(t('保存成功'));
|
|
|
+ props.refresh();
|
|
|
+ // 重新获取未设置的模型
|
|
|
+ getAllEnabledModels();
|
|
|
+
|
|
|
+ } catch (error) {
|
|
|
+ console.error(t('保存失败:'), error);
|
|
|
+ showError(t('保存失败,请重试'));
|
|
|
+ } finally {
|
|
|
+ setLoading(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const columns = [
|
|
|
+ {
|
|
|
+ title: t('模型名称'),
|
|
|
+ dataIndex: 'name',
|
|
|
+ key: 'name',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('模型固定价格'),
|
|
|
+ dataIndex: 'price',
|
|
|
+ key: 'price',
|
|
|
+ render: (text, record) => (
|
|
|
+ <Input
|
|
|
+ value={text}
|
|
|
+ placeholder={t('按量计费')}
|
|
|
+ onChange={value => updateModel(record.name, 'price', value)}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('模型倍率'),
|
|
|
+ dataIndex: 'ratio',
|
|
|
+ key: 'ratio',
|
|
|
+ render: (text, record) => (
|
|
|
+ <Input
|
|
|
+ value={text}
|
|
|
+ placeholder={record.price !== '' ? t('模型倍率') : t('输入模型倍率')}
|
|
|
+ disabled={record.price !== ''}
|
|
|
+ onChange={value => updateModel(record.name, 'ratio', value)}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: t('补全倍率'),
|
|
|
+ dataIndex: 'completionRatio',
|
|
|
+ key: 'completionRatio',
|
|
|
+ render: (text, record) => (
|
|
|
+ <Input
|
|
|
+ value={text}
|
|
|
+ placeholder={record.price !== '' ? t('补全倍率') : t('输入补全倍率')}
|
|
|
+ disabled={record.price !== ''}
|
|
|
+ onChange={value => updateModel(record.name, 'completionRatio', value)}
|
|
|
+ />
|
|
|
+ )
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ const updateModel = (name, field, value) => {
|
|
|
+ if (value !== '' && isNaN(value)) {
|
|
|
+ showError(t('请输入数字'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setModels(prev =>
|
|
|
+ prev.map(model =>
|
|
|
+ model.name === name
|
|
|
+ ? { ...model, [field]: value }
|
|
|
+ : model
|
|
|
+ )
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const addModel = (values) => {
|
|
|
+ // 检查模型名称是否存在, 如果存在则拒绝添加
|
|
|
+ if (models.some(model => model.name === values.name)) {
|
|
|
+ showError(t('模型名称已存在'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ setModels(prev => [{
|
|
|
+ name: values.name,
|
|
|
+ price: values.price || '',
|
|
|
+ ratio: values.ratio || '',
|
|
|
+ completionRatio: values.completionRatio || ''
|
|
|
+ }, ...prev]);
|
|
|
+ setVisible(false);
|
|
|
+ showSuccess(t('添加成功'));
|
|
|
+ };
|
|
|
+
|
|
|
+ // 批量填充功能
|
|
|
+ const handleBatchFill = () => {
|
|
|
+ if (selectedRowKeys.length === 0) {
|
|
|
+ showError(t('请先选择需要批量设置的模型'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (batchFillType === 'bothRatio') {
|
|
|
+ if (batchRatioValue === '' || batchCompletionRatioValue === '') {
|
|
|
+ showError(t('请输入模型倍率和补全倍率'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isNaN(batchRatioValue) || isNaN(batchCompletionRatioValue)) {
|
|
|
+ showError(t('请输入有效的数字'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if (batchFillValue === '') {
|
|
|
+ showError(t('请输入填充值'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (isNaN(batchFillValue)) {
|
|
|
+ showError(t('请输入有效的数字'));
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据选择的类型批量更新模型
|
|
|
+ setModels(prev =>
|
|
|
+ prev.map(model => {
|
|
|
+ if (selectedRowKeys.includes(model.name)) {
|
|
|
+ if (batchFillType === 'price') {
|
|
|
+ return {
|
|
|
+ ...model,
|
|
|
+ price: batchFillValue,
|
|
|
+ ratio: '',
|
|
|
+ completionRatio: ''
|
|
|
+ };
|
|
|
+ } else if (batchFillType === 'ratio') {
|
|
|
+ return {
|
|
|
+ ...model,
|
|
|
+ price: '',
|
|
|
+ ratio: batchFillValue
|
|
|
+ };
|
|
|
+ } else if (batchFillType === 'completionRatio') {
|
|
|
+ return {
|
|
|
+ ...model,
|
|
|
+ price: '',
|
|
|
+ completionRatio: batchFillValue
|
|
|
+ };
|
|
|
+ } else if (batchFillType === 'bothRatio') {
|
|
|
+ return {
|
|
|
+ ...model,
|
|
|
+ price: '',
|
|
|
+ ratio: batchRatioValue,
|
|
|
+ completionRatio: batchCompletionRatioValue
|
|
|
+ };
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return model;
|
|
|
+ })
|
|
|
+ );
|
|
|
+
|
|
|
+ setBatchVisible(false);
|
|
|
+ Notification.success({
|
|
|
+ title: t('批量设置成功'),
|
|
|
+ content: t('已为 {{count}} 个模型设置{{type}}', {
|
|
|
+ count: selectedRowKeys.length,
|
|
|
+ type: batchFillType === 'price' ? t('固定价格') :
|
|
|
+ batchFillType === 'ratio' ? t('模型倍率') :
|
|
|
+ batchFillType === 'completionRatio' ? t('补全倍率') : t('模型倍率和补全倍率')
|
|
|
+ }),
|
|
|
+ duration: 3,
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleBatchTypeChange = (value) => {
|
|
|
+ console.log(t('Changing batch type to:'), value);
|
|
|
+ setBatchFillType(value);
|
|
|
+
|
|
|
+ // 切换类型时清空对应的值
|
|
|
+ if (value !== 'bothRatio') {
|
|
|
+ setBatchFillValue('');
|
|
|
+ } else {
|
|
|
+ setBatchRatioValue('');
|
|
|
+ setBatchCompletionRatioValue('');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const rowSelection = {
|
|
|
+ selectedRowKeys,
|
|
|
+ onChange: (selectedKeys) => {
|
|
|
+ setSelectedRowKeys(selectedKeys);
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ return (
|
|
|
+ <>
|
|
|
+ <Space vertical align="start" style={{ width: '100%' }}>
|
|
|
+ <Space>
|
|
|
+ <Button icon={<IconPlus />} onClick={() => setVisible(true)}>
|
|
|
+ {t('添加模型')}
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ icon={<IconBolt />}
|
|
|
+ type="secondary"
|
|
|
+ onClick={() => setBatchVisible(true)}
|
|
|
+ disabled={selectedRowKeys.length === 0}
|
|
|
+ >
|
|
|
+ {t('批量设置')} ({selectedRowKeys.length})
|
|
|
+ </Button>
|
|
|
+ <Button type="primary" icon={<IconSave />} onClick={SubmitData} loading={loading}>
|
|
|
+ {t('应用更改')}
|
|
|
+ </Button>
|
|
|
+ <Input
|
|
|
+ prefix={<IconSearch />}
|
|
|
+ placeholder={t('搜索模型名称')}
|
|
|
+ value={searchText}
|
|
|
+ onChange={value => {
|
|
|
+ setSearchText(value)
|
|
|
+ setCurrentPage(1);
|
|
|
+ }}
|
|
|
+ style={{ width: 200 }}
|
|
|
+ />
|
|
|
+ </Space>
|
|
|
+
|
|
|
+ <Text>{t('此页面仅显示未设置价格或倍率的模型,设置后将自动从列表中移除')}</Text>
|
|
|
+
|
|
|
+ <Table
|
|
|
+ columns={columns}
|
|
|
+ dataSource={pagedData}
|
|
|
+ rowSelection={rowSelection}
|
|
|
+ rowKey="name"
|
|
|
+ pagination={{
|
|
|
+ currentPage: currentPage,
|
|
|
+ pageSize: pageSize,
|
|
|
+ total: filteredModels.length,
|
|
|
+ onPageChange: page => setCurrentPage(page),
|
|
|
+ onPageSizeChange: handlePageSizeChange,
|
|
|
+ pageSizeOptions: pageSizeOptions,
|
|
|
+ formatPageText: (page) =>
|
|
|
+ t('第 {{start}} - {{end}} 条,共 {{total}} 条', {
|
|
|
+ start: page.currentStart,
|
|
|
+ end: page.currentEnd,
|
|
|
+ total: filteredModels.length
|
|
|
+ }),
|
|
|
+ showTotal: true,
|
|
|
+ showSizeChanger: true
|
|
|
+ }}
|
|
|
+ empty={
|
|
|
+ <div style={{ textAlign: 'center', padding: '20px' }}>
|
|
|
+ {t('没有未设置的模型')}
|
|
|
+ </div>
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </Space>
|
|
|
+
|
|
|
+ {/* 添加模型弹窗 */}
|
|
|
+ <Modal
|
|
|
+ title={t('添加模型')}
|
|
|
+ visible={visible}
|
|
|
+ onCancel={() => setVisible(false)}
|
|
|
+ onOk={() => {
|
|
|
+ currentModel && addModel(currentModel);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <Form>
|
|
|
+ <Form.Input
|
|
|
+ field="name"
|
|
|
+ label={t('模型名称')}
|
|
|
+ placeholder="strawberry"
|
|
|
+ required
|
|
|
+ onChange={value => setCurrentModel(prev => ({ ...prev, name: value }))}
|
|
|
+ />
|
|
|
+ <Form.Switch
|
|
|
+ field="priceMode"
|
|
|
+ label={<>{t('定价模式')}:{currentModel?.priceMode ? t("固定价格") : t("倍率模式")}</>}
|
|
|
+ onChange={checked => {
|
|
|
+ setCurrentModel(prev => ({
|
|
|
+ ...prev,
|
|
|
+ price: '',
|
|
|
+ ratio: '',
|
|
|
+ completionRatio: '',
|
|
|
+ priceMode: checked
|
|
|
+ }));
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ {currentModel?.priceMode ? (
|
|
|
+ <Form.Input
|
|
|
+ field="price"
|
|
|
+ label={t('固定价格(每次)')}
|
|
|
+ placeholder={t('输入每次价格')}
|
|
|
+ onChange={value => setCurrentModel(prev => ({ ...prev, price: value }))}
|
|
|
+ />
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Form.Input
|
|
|
+ field="ratio"
|
|
|
+ label={t('模型倍率')}
|
|
|
+ placeholder={t('输入模型倍率')}
|
|
|
+ onChange={value => setCurrentModel(prev => ({ ...prev, ratio: value }))}
|
|
|
+ />
|
|
|
+ <Form.Input
|
|
|
+ field="completionRatio"
|
|
|
+ label={t('补全倍率')}
|
|
|
+ placeholder={t('输入补全价格')}
|
|
|
+ onChange={value => setCurrentModel(prev => ({ ...prev, completionRatio: value }))}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+
|
|
|
+ {/* 批量设置弹窗 */}
|
|
|
+ <Modal
|
|
|
+ title={t('批量设置模型参数')}
|
|
|
+ visible={batchVisible}
|
|
|
+ onCancel={() => setBatchVisible(false)}
|
|
|
+ onOk={handleBatchFill}
|
|
|
+ width={500}
|
|
|
+ >
|
|
|
+ <Form>
|
|
|
+ <Form.Section text={t('设置类型')}>
|
|
|
+ <div style={{ marginBottom: '16px' }}>
|
|
|
+ <Space>
|
|
|
+ <Radio
|
|
|
+ checked={batchFillType === 'price'}
|
|
|
+ onChange={() => handleBatchTypeChange('price')}
|
|
|
+ >
|
|
|
+ {t('固定价格')}
|
|
|
+ </Radio>
|
|
|
+ <Radio
|
|
|
+ checked={batchFillType === 'ratio'}
|
|
|
+ onChange={() => handleBatchTypeChange('ratio')}
|
|
|
+ >
|
|
|
+ {t('模型倍率')}
|
|
|
+ </Radio>
|
|
|
+ <Radio
|
|
|
+ checked={batchFillType === 'completionRatio'}
|
|
|
+ onChange={() => handleBatchTypeChange('completionRatio')}
|
|
|
+ >
|
|
|
+ {t('补全倍率')}
|
|
|
+ </Radio>
|
|
|
+ <Radio
|
|
|
+ checked={batchFillType === 'bothRatio'}
|
|
|
+ onChange={() => handleBatchTypeChange('bothRatio')}
|
|
|
+ >
|
|
|
+ {t('模型倍率和补全倍率同时设置')}
|
|
|
+ </Radio>
|
|
|
+ </Space>
|
|
|
+ </div>
|
|
|
+ </Form.Section>
|
|
|
+
|
|
|
+ {batchFillType === 'bothRatio' ? (
|
|
|
+ <>
|
|
|
+ <Form.Input
|
|
|
+ field="batchRatioValue"
|
|
|
+ label={t('模型倍率值')}
|
|
|
+ placeholder={t('请输入模型倍率')}
|
|
|
+ value={batchRatioValue}
|
|
|
+ onChange={value => setBatchRatioValue(value)}
|
|
|
+ />
|
|
|
+ <Form.Input
|
|
|
+ field="batchCompletionRatioValue"
|
|
|
+ label={t('补全倍率值')}
|
|
|
+ placeholder={t('请输入补全倍率')}
|
|
|
+ value={batchCompletionRatioValue}
|
|
|
+ onChange={value => setBatchCompletionRatioValue(value)}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <Form.Input
|
|
|
+ field="batchFillValue"
|
|
|
+ label={
|
|
|
+ batchFillType === 'price'
|
|
|
+ ? t('固定价格值')
|
|
|
+ : batchFillType === 'ratio'
|
|
|
+ ? t('模型倍率值')
|
|
|
+ : t('补全倍率值')
|
|
|
+ }
|
|
|
+ placeholder={t('请输入数值')}
|
|
|
+ value={batchFillValue}
|
|
|
+ onChange={value => setBatchFillValue(value)}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+
|
|
|
+ <Text type="tertiary">
|
|
|
+ {t('将为选中的 ')} <Text strong>{selectedRowKeys.length}</Text> {t(' 个模型设置相同的值')}
|
|
|
+ </Text>
|
|
|
+ <div style={{ marginTop: '8px' }}>
|
|
|
+ <Text type="tertiary">
|
|
|
+ {t('当前设置类型: ')} <Text strong>{
|
|
|
+ batchFillType === 'price' ? t('固定价格') :
|
|
|
+ batchFillType === 'ratio' ? t('模型倍率') :
|
|
|
+ batchFillType === 'completionRatio' ? t('补全倍率') : t('模型倍率和补全倍率')
|
|
|
+ }</Text>
|
|
|
+ </Text>
|
|
|
+ </div>
|
|
|
+ </Form>
|
|
|
+ </Modal>
|
|
|
+ </>
|
|
|
+ );
|
|
|
+}
|