Selaa lähdekoodia

feat(model): 添加模型类型字段编辑功能

- 后端 Update 函数添加 type 字段支持更新
- 前端 EditModelModal 添加模型类型下拉选择器
- 新增 MODEL_TYPE_OPTIONS 共享常量(与后端 ModelType 一致)
- 添加中英文 i18n 翻译
- 修复首页"全部供应商"计数显示错误的 bug

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
feat/alipay-payment
fengsilin 1 kuukausi sitten
vanhempi
commit
3a32ab11dd
6 muutettua tiedostoa jossa 64 lisäystä ja 7 poistoa
  1. +1
    -1
      model/model_meta.go
  2. +21
    -0
      web/src/components/table/models/modals/EditModelModal.jsx
  3. +13
    -0
      web/src/constants/common.constant.js
  4. +9
    -0
      web/src/i18n/locales/en.json
  5. +10
    -1
      web/src/i18n/locales/zh-CN.json
  6. +10
    -5
      web/src/pages/Home/HomePricingFilters.jsx

+ 1
- 1
model/model_meta.go Näytä tiedosto

@@ -89,7 +89,7 @@ func (mi *Model) Update() error {
mi.UpdatedTime = common.GetTimestamp() mi.UpdatedTime = common.GetTimestamp()
// 使用 Select 强制更新所有字段,包括零值 // 使用 Select 强制更新所有字段,包括零值
return DB.Model(&Model{}).Where("id = ?", mi.Id). return DB.Model(&Model{}).Where("id = ?", mi.Id).
Select("model_name", "description", "icon", "tags", "vendor_id", "endpoints", "status", "sync_official", "name_rule", "updated_time").
Select("model_name", "description", "icon", "tags", "type", "vendor_id", "endpoints", "status", "sync_official", "name_rule", "updated_time").
Updates(mi).Error Updates(mi).Error
} }




+ 21
- 0
web/src/components/table/models/modals/EditModelModal.jsx Näytä tiedosto

@@ -38,6 +38,7 @@ import { IconAlertTriangle, IconLink } from '@douyinfe/semi-icons';
import { API, showError, showSuccess } from '../../../../helpers'; import { API, showError, showSuccess } from '../../../../helpers';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import { useIsMobile } from '../../../../hooks/common/useIsMobile'; import { useIsMobile } from '../../../../hooks/common/useIsMobile';
import { MODEL_TYPE_OPTIONS } from '../../../../constants/common.constant';


const { Text, Title } = Typography; const { Text, Title } = Typography;


@@ -117,6 +118,7 @@ const EditModelModal = (props) => {
description: '', description: '',
icon: '', icon: '',
tags: [], tags: [],
type: 1, // 默认对话模型
vendor_id: undefined, vendor_id: undefined,
vendor: '', vendor: '',
vendor_icon: '', vendor_icon: '',
@@ -330,6 +332,25 @@ const EditModelModal = (props) => {
/> />
</Col> </Col>


<Col span={24}>
<Form.Select
field='type'
label={t('模型类型')}
placeholder={t('请选择模型类型')}
optionList={MODEL_TYPE_OPTIONS.map((o) => ({
label: t(o.label),
value: o.value,
}))}
rules={[
{ required: true, message: t('请选择模型类型') },
]}
extraText={t(
'选择模型的类型,用于分类和筛选',
)}
style={{ width: '100%' }}
/>
</Col>

<Col span={24}> <Col span={24}>
<Form.Input <Form.Input
field='icon' field='icon'


+ 13
- 0
web/src/constants/common.constant.js Näytä tiedosto

@@ -44,3 +44,16 @@ export const TASK_ACTION_TEXT_GENERATE = 'textGenerate';
export const TASK_ACTION_FIRST_TAIL_GENERATE = 'firstTailGenerate'; export const TASK_ACTION_FIRST_TAIL_GENERATE = 'firstTailGenerate';
export const TASK_ACTION_REFERENCE_GENERATE = 'referenceGenerate'; export const TASK_ACTION_REFERENCE_GENERATE = 'referenceGenerate';
export const TASK_ACTION_REMIX_GENERATE = 'remixGenerate'; export const TASK_ACTION_REMIX_GENERATE = 'remixGenerate';

// 模型类型常量,与 model/model_meta.go ModelType 保持一致
export const MODEL_TYPE_OPTIONS = [
{ value: 0, label: 'modelType.unset' },
{ value: 1, label: 'modelType.chat' },
{ value: 2, label: 'modelType.image' },
{ value: 3, label: 'modelType.audio' },
{ value: 4, label: 'modelType.video' },
{ value: 5, label: 'modelType.embedding' },
{ value: 6, label: 'modelType.rerank' },
{ value: 7, label: 'modelType.vision' },
{ value: 8, label: 'modelType.other' },
];

+ 9
- 0
web/src/i18n/locales/en.json Näytä tiedosto

@@ -2868,6 +2868,15 @@
"绑定渠道": "Bind Channel", "绑定渠道": "Bind Channel",
"可选,绑定后该令牌只能使用指定渠道": "Optional. Once bound, the token can only use the specified channel.", "可选,绑定后该令牌只能使用指定渠道": "Optional. Once bound, the token can only use the specified channel.",
"请选择标签": "Please select tags", "请选择标签": "Please select tags",
"modelType.unset": "Unset",
"modelType.chat": "Chat",
"modelType.image": "Image",
"modelType.audio": "Audio",
"modelType.video": "Video",
"modelType.embedding": "Embedding",
"modelType.rerank": "Rerank",
"modelType.vision": "Vision",
"modelType.other": "Other",
"设计版本": "b80c3466cb6feafeb3990c7820e10e50" "设计版本": "b80c3466cb6feafeb3990c7820e10e50"
} }
} }

+ 10
- 1
web/src/i18n/locales/zh-CN.json Näytä tiedosto

@@ -2845,6 +2845,15 @@
"暂无渠道定价数据,请先创建渠道并设置模型": "暂无渠道定价数据,请先创建渠道并设置模型", "暂无渠道定价数据,请先创建渠道并设置模型": "暂无渠道定价数据,请先创建渠道并设置模型",
"绑定渠道": "绑定渠道", "绑定渠道": "绑定渠道",
"可选,绑定后该令牌只能使用指定渠道": "可选,绑定后该令牌只能使用指定渠道", "可选,绑定后该令牌只能使用指定渠道": "可选,绑定后该令牌只能使用指定渠道",
"请选择标签": "请选择标签"
"请选择标签": "请选择标签",
"modelType.unset": "未设置",
"modelType.chat": "对话",
"modelType.image": "图像",
"modelType.audio": "音频",
"modelType.video": "视频",
"modelType.embedding": "嵌入",
"modelType.rerank": "重排序",
"modelType.vision": "视觉",
"modelType.other": "其他"
} }
} }

+ 10
- 5
web/src/pages/Home/HomePricingFilters.jsx Näytä tiedosto

@@ -71,16 +71,21 @@ const HomePricingFilters = ({ t }) => {
} }
}); });
const vendors = Array.from(vendorSet).sort(); const vendors = Array.from(vendorSet).sort();
const getCount = (v) => {
const getVendorCount = () => {
// 计算供应商数量(包含未知供应商)
const count = vendorSet.size + (hasUnknown ? 1 : 0);
return count;
};
const getModelCount = (v) => {
if (v === 'all') return vendorModels.length; if (v === 'all') return vendorModels.length;
if (v === 'unknown') return vendorModels.filter((m) => !m.vendor_name).length; if (v === 'unknown') return vendorModels.filter((m) => !m.vendor_name).length;
return vendorModels.filter((m) => m.vendor_name === v).length; return vendorModels.filter((m) => m.vendor_name === v).length;
}; };
const items = [ const items = [
{ value: 'all', label: t('全部供应商'), tagCount: getCount('all'), disabled: (models || []).length === 0 },
{ value: 'all', label: t('全部供应商'), tagCount: getVendorCount(), disabled: (models || []).length === 0 },
]; ];
vendors.forEach((v) => { vendors.forEach((v) => {
const count = getCount(v);
const count = getModelCount(v);
items.push({ items.push({
value: v, value: v,
label: v, label: v,
@@ -93,8 +98,8 @@ const HomePricingFilters = ({ t }) => {
items.push({ items.push({
value: 'unknown', value: 'unknown',
label: t('未知供应商'), label: t('未知供应商'),
tagCount: getCount('unknown'),
disabled: getCount('unknown') === 0,
tagCount: getModelCount('unknown'),
disabled: getModelCount('unknown') === 0,
}); });
} }
return items; return items;


Ladataan…
Peruuta
Tallenna