diff --git a/src/base.css b/src/base.css index 83a21dd..1a9bac5 100644 --- a/src/base.css +++ b/src/base.css @@ -189,7 +189,7 @@ .anticon.anticon-down.ant-dropdown-trigger.ant-transfer-list-header-dropdown { display: none; } -:where(.css-dev-only-do-not-override-1y19ift).ant-pro-steps-form-container { +.ant-pro-steps-form-container { min-width: 100%; } .ant-transfer { diff --git a/src/base.less b/src/base.less index c66a17f..8be2e43 100644 --- a/src/base.less +++ b/src/base.less @@ -220,7 +220,7 @@ .anticon.anticon-down.ant-dropdown-trigger.ant-transfer-list-header-dropdown { display: none; } -:where(.css-dev-only-do-not-override-1y19ift).ant-pro-steps-form-container { +.ant-pro-steps-form-container { min-width: 100%; } diff --git a/src/components/Tree/src/baseTree.tsx b/src/components/Tree/src/baseTree.tsx index f75c1b4..6a0a478 100644 --- a/src/components/Tree/src/baseTree.tsx +++ b/src/components/Tree/src/baseTree.tsx @@ -187,7 +187,7 @@ const BaseTree: React.FC = (props) => { useEffect(() => { setCurrTreeData(props.treeData); - // TODO 后续改从业务层获取 默认选项 + // 从业务层获取 默认选项 setCurrSeleted([props?.treeData[0]?.id]); console.log(props.treeData, 'props_treeData'); }, [props.treeData]); diff --git a/src/components/UploadFile/index.ts b/src/components/UploadFile/index.ts new file mode 100644 index 0000000..1424498 --- /dev/null +++ b/src/components/UploadFile/index.ts @@ -0,0 +1,11 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-06-04 15:13:34 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2024-06-04 15:25:13 + * @FilePath: \general-ai-platform-web\src\components\UploadFile\index.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import proFormUploadDraggerToken from './src/formUploadDraggerToken'; + +export const FormUploadDraggerToken = proFormUploadDraggerToken; diff --git a/src/components/UploadFile/src/formUploadDraggerToken.tsx b/src/components/UploadFile/src/formUploadDraggerToken.tsx new file mode 100644 index 0000000..d2e3d83 --- /dev/null +++ b/src/components/UploadFile/src/formUploadDraggerToken.tsx @@ -0,0 +1,127 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-06-04 15:14:27 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2024-06-05 15:37:03 + * @FilePath: \general-ai-platform-web\src\components\UploadFile\src\FormUploadDraggerToken.tsx + * @Description: 手动文件上传、删除 + * // TODO 需要支持多文件上传 + */ +import { apiFileDelete, apiFileUpload } from '@/services/business/file'; +import { useIntl } from '@umijs/max'; +import { RcFile, UploadChangeParam, UploadFile, message } from 'antd'; + +// import localCacha from '@/utils/localCacha'; +import { isSuccessApi } from '@/utils/forApi'; +import { ProFormUploadDragger } from '@ant-design/pro-components'; +import React, { useState } from 'react'; +import { FormUploadDraggerTokenProps } from '../typing'; + +// import { ProFormUploadDragger, type ProFormUploadDraggerProps } from '@ant-design/pro-components'; +// import type { RcFile, UploadChangeParam, UploadFile } from 'antd/es/upload'; + +const FormUploadDraggerToken: React.FC = (props) => { + const intl = useIntl(); + const { onChange } = props; + const [fileList, setFileList] = useState([ + { status: 'done', url: '/file/' + props.fileValues?.id, ...props.fileValues }, + ]); + + /** + * 文件上传事件,对上传失败的进行处理 + */ + const onChangeFile = (info: UploadChangeParam>>) => { + // 当上传成功后才开始对数据进行校验 + if (info.file.status === 'done') { + const res = info.file.response; + if (res?.code !== 200) { + info.file.status = 'error'; + // 查看 antd 源码,可自定义错误信息 官方文档并未给出相关内容 message = file.error?.statusText || file.error?.message || locale.uploadError; + info.file.error = { statusText: res?.msg }; + } + } + onChange?.(info); + }; + + /** + * 对上传前的文件进行校验,是否符合上传要求,不符合的禁止上传并给出提示 + */ + const beforeUploadFile = async (file: RcFile) => { + const formData = new FormData(); + formData.append('file', file); + const resp = await apiFileUpload(formData); + if (isSuccessApi(resp)) { + setFileList([ + { + uid: resp?.data?.result, + name: file?.name, + status: 'done', + url: '/file/' + resp?.data?.result, + }, + ]); + props.afterUploadFile({ resp, file, fileList }); + } + console.log(resp, 'apiFileUpload_resp'); + return false; // 阻止自动上传 + // if (!accept) return true; + // const suffix = file.name.substring(file.name.lastIndexOf('.')); + // const supportFile = accept.replace(/\s*/g, '').split(','); // 去除 accept 中的空格 + // if (supportFile.length > 0) { + // const validate = supportFile.includes(suffix); + // if (!validate) { + // message.error(`支持上传的文件格式:${accept}`); + // return Upload.LIST_IGNORE; + // } + // return true; + // } + }; + + /**删除图片 + */ + const onRemoveFile = async (file: UploadFile>) => { + console.log(file, 'onRemoveFile_file'); + const resp = await apiFileDelete({ file_md5: file?.uid }); + console.log(resp, 'apiFileDelete_resp'); + props.afterRemoveFile(resp, file); + if (isSuccessApi(resp)) { + message.success(`${file.name} 删除成功`); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }), + ); + } + // props.beforeRemoveFile(file); + // rc- 是通过 antd 初次上传的(自带uid),没有 rc-,证明是回显值(值是文件id或图片url地址) + // 若上传失败,删除时,直接清除页面文件,不走接口 + // if (file.uid.indexOf('rc-') !== -1 && file.response?.code !== 200) return true; + + // let fileId = ''; + // // response 存在,则证明该文件是未提交的数据(上传,然后删除) + // if (file.response?.data) fileId = file.response.data; + // else fileId = file.uid; + // const { code } = await apiFileDelete({ file_md5: fileId }); + // requestDelFile?.(code === 200); + // return code === 200; + }; + // TODO 组装初始值 + return ( + <> + false} // 阻止自动上 + {...props.proFieldProps} + fieldProps={{ + className: 'gn_proFormUploadDragger_formItem', + name: 'files', // 这里可以指定和后端对接的 filename + onRemove: onRemoveFile, + beforeUpload: beforeUploadFile, + }} + /> +
{props.nextText}
+ + ); +}; + +export default FormUploadDraggerToken; diff --git a/src/components/UploadFile/typing.ts b/src/components/UploadFile/typing.ts new file mode 100644 index 0000000..2afcd50 --- /dev/null +++ b/src/components/UploadFile/typing.ts @@ -0,0 +1,15 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-04-26 11:09:49 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2024-06-05 14:50:40 + * @FilePath: \general-ai-platform-web\src\components\UploadFile\typing.ts + * @Description: 上传的类型文件 + */ + +export interface FormUploadDraggerTokenProps extends ProFormUploadDraggerProps { + afterUploadFile?: (data: any) => void; // 上传完成后 + afterRemoveFile?: (file: UploadFile>) => void; // 删除开始 + requestDelFile?: (status: boolean) => void; + nextText?: string | React.ReactNode; +} diff --git a/src/locales/zh-CN/model.ts b/src/locales/zh-CN/model.ts index 47b7532..68f20a0 100644 --- a/src/locales/zh-CN/model.ts +++ b/src/locales/zh-CN/model.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-10 17:21:34 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-31 13:40:48 + * @LastEditTime: 2024-06-06 15:07:50 * @FilePath: \general-ai-manage\src\locales\zh-CN\model.ts * @Description: 模型管理 */ @@ -41,7 +41,9 @@ export const model_runtimeLib: { [key: string]: string } = { 'model_runtimeLib.table.list.createTime': '创建时间', 'model_runtimeLib.table.list.updateTime': '更新时间', 'model_runtimeLib.table.list.name': '运行库名称', - 'model_runtimeLib.list.table.createForm.add': '新建运行库', + 'model_runtimeLib.table.list.path': '文件地址', + 'model_runtimeLib.list.table.form.action.add': '新建运行库', + 'model_runtimeLib.list.table.form.action.edit': '编辑运行库', 'model_runtimeLib.list.table.form.name': '运行库名称', 'model_runtimeLib.list.table.form.rule.required.name': '请填写运行库名称', 'model_runtimeLib.list.table.form.IP': 'IP地址', diff --git a/src/pages/Business/BusinessModel/index.tsx b/src/pages/Business/BusinessModel/index.tsx index 2bb38f1..4c11559 100644 --- a/src/pages/Business/BusinessModel/index.tsx +++ b/src/pages/Business/BusinessModel/index.tsx @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-22 15:23:36 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-20 11:00:25 + * @LastEditTime: 2024-06-06 15:46:51 * @FilePath: \general-ai-platform-web\src\pages\Node\BusinessModel\index.tsx * @Description: 业务模型 * @交互说明 @@ -18,7 +18,9 @@ import TableActionCard from '@/components/TableActionCard'; import IsDelete from '@/components/TableActionCard/isDelete'; -import { getBusinessModelList } from '@/services/testApi/businessModel'; +import { apiModelDeploymentList } from '@/services/business/model'; +import { isSuccessApi } from '@/utils/forApi'; + import { ExclamationCircleFilled } from '@ant-design/icons'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; import { ProCard, ProTable } from '@ant-design/pro-components'; @@ -63,7 +65,7 @@ const BusinessModel: React.FC = () => { const columns: ProColumns>[] = [ { title: , - dataIndex: 'name', + dataIndex: 'model_name', hideInSearch: true, key: 'fixedName', fixed: 'left', @@ -74,7 +76,7 @@ const BusinessModel: React.FC = () => { title: ( ), - dataIndex: 'createTime', + dataIndex: 'create_time', hideInSearch: true, valueType: 'dateTime', }, @@ -185,7 +187,10 @@ const BusinessModel: React.FC = () => { pageNo: current, ...rest, }; - let resp = await getBusinessModelList({ ...reqParams }); + let resp = await apiModelDeploymentList({ ...reqParams }); + if (!isSuccessApi(resp)) { + return { data: [], success: true }; + } console.log(resp, 'getModelVersionList_resp'); return { data: resp.data?.data, diff --git a/src/pages/Business/DeviceGroup/components/deviceList.tsx b/src/pages/Business/DeviceGroup/components/deviceList.tsx index 51dccf9..c1bcde7 100644 --- a/src/pages/Business/DeviceGroup/components/deviceList.tsx +++ b/src/pages/Business/DeviceGroup/components/deviceList.tsx @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-22 15:23:36 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-30 15:25:27 + * @LastEditTime: 2024-06-04 16:33:16 * @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\deviceList.tsx * @Description: 设备节点设置 关键词 deviceGroup(dg) * @交互说明 diff --git a/src/pages/Model/ModelDetail/components/createForm.tsx b/src/pages/Model/ModelDetail/components/createForm.tsx index 3f97f43..59de60f 100644 --- a/src/pages/Model/ModelDetail/components/createForm.tsx +++ b/src/pages/Model/ModelDetail/components/createForm.tsx @@ -1,4 +1,6 @@ -import { apiFileDelete, apiFileUpload } from '@/services/business/file'; +import { FormUploadDraggerToken } from '@/components/UploadFile'; +import { apiModelVersionAdd } from '@/services/business/model'; +import { isSuccessApi } from '@/utils/forApi'; import { ProForm, ProFormInstance, @@ -54,16 +56,14 @@ const CreateForm: React.FC = (props) => { const [configFileList, setConfigFileList] = useState[]>([]); // const [form] = Form.useForm>(); - + const [currFormData, setCurrFormData] = useState>({}); const [current, setCurrent] = useState(0); const formBaseRef = useRef(); - const formProjectFileRef = useRef(); // const [filePath, setFilePath] = useState(''); - const handleFileChange = ({ file }: { file: UploadFile }) => { + const handleConfigFileChange = ({ file }: { file: UploadFile }) => { console.log(configFileList, 'handleFileChange_configFileList'); let curFile: any; - switch (file.status) { case 'uploading': case 'done': @@ -74,29 +74,44 @@ const CreateForm: React.FC = (props) => { curFile = []; break; } - setConfigFileList([...curFile]); }; - // test 测试数据 useEffect(() => { - // if (formBaseRef) { - formBaseRef.current?.setFieldsValue({ - version: '0.0.91', // 设备分类的suid - comment: - '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注', - }); - - // } + // 初始化赋值 + // setCurrFormData({ + // version: '1.0.91', // 设备分类的suid 59aa3d0c3162322e190942a9cc9add10 + // comment: + // '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注', + // }); }, [props.createModalOpen]); return ( onFinish={async (values) => { - console.log('All form values:', values, { model_id: props.modelInfo?.model_id }); + console.log('All form values:', values, {}); // 在这里处理提交数据,例如调用API - message.success('提交成功'); + let resp = await apiModelVersionAdd({ + ...values, + model_id: props.modelInfo?.model_id, + config_str: JSON.stringify(values.config_str_arr), + model_file: currFormData?.model_file, + config_file: '', + }); + if (isSuccessApi(resp)) { + message.success( + intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), + ); + props.reload(); + props.handleModal(); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }), + ); + } + return true; }} stepsProps={proFormStepsFormProps.stepsProps} current={current} @@ -165,17 +180,6 @@ const CreateForm: React.FC = (props) => { initialValue={props.modelInfo?.name} debounceTime={1000} disabled={true} - // request={async (keyWord) => { - // const resp = await postAlgorithmModelGetAlgorithmModelFkSelect({ - // keyword: keyWord?.keyWords || '', - // }); - // return resp.data.list.map((v: any) => { - // return { - // label: v.name, - // value: v.id, - // }; - // }); - // }} /> = (props) => { prefix: V, }} name="version" + initialValue={currFormData?.version} label={} placeholder={`${intl.formatMessage({ id: 'common.please_input', @@ -207,6 +212,7 @@ const CreateForm: React.FC = (props) => { } placeholder={`${intl.formatMessage({ id: 'common.please_input', @@ -224,7 +230,6 @@ const CreateForm: React.FC = (props) => { - formRef={formProjectFileRef} className="gn_form" name="project_file" title={ @@ -251,78 +256,32 @@ const CreateForm: React.FC = (props) => { return true; }} > - 上传模型文件} - title={ -
- 拖拽文件到这里,或 - 点此添加 -
- } - description="" - icon={} - name="model_file_name" - // action={fileApiActionUrl} - onRemove={async (file) => { - // 这里可以添加删除文件的接口调用逻辑 - // await deleteFileFromServer(file); - - // setFileList((prevList) => { - // const newList = prevList.filter((item) => item.uid !== file.uid); - // return newList; - // }); - const currFileId = formProjectFileRef?.current?.getFieldValue('model_file'); - const resp = await apiFileDelete({ file_md5: currFileId }); - console.log(resp, 'apiFileDelete_resp', file); - message.success('文件已删除'); - return true; // 确保文件从文件列表中移除 + 上传模型文件, + title: ( +
+ 拖拽文件到这里,或 + 点此添加 +
+ ), + description: '', + icon: , + name: 'model_file_arr', + max: 1, }} - onChange={async ({ file, fileList }) => { - // 检查文件状态 - - console.log( - file, - fileList, - 'onChange_ProjectFile', - formProjectFileRef?.current?.getFieldValue('model_file'), - ); - if (file.status === 'removed') { - // 删除文件 - // setProjectFileList(fileList.filter((item) => item.uid !== file.uid)); - // const currFileId = formProjectFileRef?.current?.getFieldValue('model_file') - // const resp = await apiFileDelete({file_md5: currFileId}) - // console.log(resp,'apiFileDelete_resp') - // message.success(`${file.name} 删除成功`); - } else { - // 处理上传 - // formProjectFileRef?.current?.setFieldValue('model_file_name', [file]); - // handleUpload(file); - } - // setProjectFileList(fileList); + afterUploadFile={({ resp }) => { + setCurrFormData((data) => { + return { ...data, model_file: resp?.data?.result }; + }); }} - max={1} - fieldProps={{ - className: 'gn_proFormUploadDragger_formItem', - name: 'file', - // beforeUpload: beforeUploadFile, - data: { path: `models/${Date.now()}` }, - - headers: { - // 'X-CSRFToken': cookie.load('csrftoken'), - // Authorization: `Bearer ${localStorage.getItem('access') || ''}`, - }, - beforeUpload: async (file) => { - const formData = new FormData(); - formData.append('file', file); - const resp = await apiFileUpload(formData); - formProjectFileRef?.current?.setFieldValue('model_file', resp?.data?.result); - console.log(resp, 'apiFileUpload_resp'); - // form.setFieldValue('logo', base64); - return false; // 阻止自动上传 - }, + afterRemoveFile={() => { + setCurrFormData((data) => { + return { ...data, model_file: '' }; + }); }} + nextText="请上传格式为zip.tar.gz的模型文件" /> -
请上传格式为zip.tar.gz的模型文件
{/* 参数配置 */} = (props) => { let formData1 = formBaseRef.current?.getFieldsValue(); if (formData1?.model_name) { await waitTime(500); - // formData1.modelConfig = { params: values?.params || [] }; - // if (filePath) { - // formData1.path = filePath; - // } - // postModelVersionCreateModelVersion(formData) - // .then(() => { - // message.success( - // intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), - // ); - // props.handleModal(); - // props.reload(); - // }) - // .catch(() => { - // message.error(intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' })); - // return false; - // }); } return true; }} @@ -379,11 +322,11 @@ const CreateForm: React.FC = (props) => { } description="" icon={} - name="config_file" + name="config_file_name" action={fileApiActionUrl} fieldProps={{ className: 'gn_proFormUploadDragger_formItem', - onChange: handleFileChange, + onChange: handleConfigFileChange, onRemove: () => { let index_ids = actionFormListRef.current?.getList()?.map((v, i) => { return i; @@ -429,7 +372,7 @@ const CreateForm: React.FC = (props) => { }} />
- 请上传格式为zip.tar.gz的模型文件 + 请上传格式为.json.yaml.yml的模型文件
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */} diff --git a/src/pages/Model/ModelDetail/components/updateForm.tsx b/src/pages/Model/ModelDetail/components/updateForm.tsx new file mode 100644 index 0000000..29d628e --- /dev/null +++ b/src/pages/Model/ModelDetail/components/updateForm.tsx @@ -0,0 +1,447 @@ +// TODO 上传文件限制为1时,还可以上传 +import { FormUploadDraggerToken } from '@/components/UploadFile'; +import { apiModelVersionEdit } from '@/services/business/model'; +import { isSuccessApi } from '@/utils/forApi'; +import { + ProForm, + ProFormInstance, + ProFormList, + ProFormText, + ProFormTextArea, + ProFormUploadDragger, + StepsForm, +} from '@ant-design/pro-components'; +import { FormListActionType } from '@ant-design/pro-form/lib'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Modal, UploadFile, message } from 'antd'; +import yaml from 'js-yaml'; +import React, { useEffect, useRef, useState } from 'react'; +import { + proFormItemStyleProps, + proFormSmallItemStyleProps, + proFormSmallModelWidth, + proFormStepsFormProps, +} from '../../../../../config/defaultForm'; +// import {beforeUploadFile} from "@/utils/common"; +// @ts-ignore +import { isValidJson } from '@/utils/is'; +import { fileApiActionUrl } from '../../../../../config/defaultApi'; + +export type UpdateFormProps = { + updateModalOpen: boolean; + values: Record; + handleModal: () => void; + modelInfo: Record; + reload: any; +}; +const waitTime = (time: number = 100) => { + return new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, time); + }); +}; +// interface ProjectConfig { +// params: Array; +// } +const UpdateForm: React.FC = (props) => { + const actionFormListRef = useRef< + FormListActionType<{ + name: string; + }> + >(); + + const intl = useIntl(); + + const [dataFormList] = useState([]); + const dataFormListRef = useRef(dataFormList); + // const [projectFileList, setProjectFileList] = useState[]>([]); + const [configFileList, setConfigFileList] = useState[]>([]); + + // const [form] = Form.useForm>(); + const [currFormData, setCurrFormData] = useState>({}); + + const [current, setCurrent] = useState(0); + const formBaseRef = useRef(); + const formProjectFileRef = useRef(); + // const [filePath, setFilePath] = useState(''); + + const handleConfigFileChange = ({ file }: { file: UploadFile }) => { + console.log(configFileList, 'handleFileChange_configFileList'); + let curFile: any; + switch (file.status) { + case 'uploading': + case 'done': + curFile = [file]; + break; + case 'removed': + default: + curFile = []; + break; + } + setConfigFileList([...curFile]); + }; + function resetForm() { + setCurrFormData({}); + } + // test 测试数据 + useEffect(() => { + // 初始化赋值 + + if (props.updateModalOpen && props.values?.version_id) { + setCurrFormData({ + ...props.values, + model_file: props.values?.model_file_md5, + }); + console.log(props.values, 'useEffect_values', currFormData); + } else { + resetForm(); + } + }, [props.updateModalOpen, props.values]); + + // useEffect(() => { + // if (formProjectFileRef) { + // formProjectFileRef.current?.setFieldValue('model_file_arr', [ + + // ]); + // } + // }, [props.updateModalOpen, props.values, formProjectFileRef]); + return ( + + onFinish={async (values) => { + console.log('All form values:', values, {}); + // 在这里处理提交数据,例如调用API + let resp = await apiModelVersionEdit({ + ...values, + model_id: props.modelInfo?.model_id, + config_str: JSON.stringify(values.config_str_arr), + model_file: currFormData?.model_file, + version_id: currFormData?.version_id, + config_file: '', + }); + if (isSuccessApi(resp)) { + message.success( + intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), + ); + props.reload(); + props.handleModal(); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }), + ); + } + props.handleModal(); + return true; + message.success('提交成功'); + }} + stepsProps={proFormStepsFormProps.stepsProps} + current={current} + onCurrentChange={setCurrent} + formProps={{ + validateMessages: { + required: '此项为必填项', + }, + }} + stepsFormRender={(dom, submitter) => { + return ( + + } + width={proFormSmallModelWidth} + onCancel={() => { + setCurrent(0); + formBaseRef.current?.resetFields(); + // setProjectFileList([]); + props.handleModal(); + }} + open={props.updateModalOpen} + footer={submitter} + destroyOnClose + > + {dom} + + ); + }} + > + {/* 版本信息 */} + + className="gn_form" + name="base" + formRef={formBaseRef} + title={ + + } + stepProps={{ + description: ( + + ), + }} + onFinish={async () => { + // setFormData(formBaseRef.current?.getFieldsValue()); + await waitTime(500); + return true; + }} + > + + {/* 默认填充模型 无需选择 */} + + } + required={true} + initialValue={props.modelInfo?.name} + debounceTime={1000} + disabled={true} + /> + V, + }} + name="version" + initialValue={currFormData?.version} + label={} + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_detail.version.form.name', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_detail.version.form.remark', + defaultMessage: '$$$', + })}`} + required={false} + disabled={false} + /> + + + {/* 版本上传 */} + + className="gn_form" + name="project_file" + formRef={formProjectFileRef} + title={ + + } + style={{ width: proFormItemStyleProps.width }} + stepProps={{ + description: ( + + ), + }} + onFinish={async (values: any) => { + console.log(values, 'values'); + // if ('projectFilePath' in values && values['projectFilePath'].length > 0) { + // let projectFilePath = values['projectFilePath'][0]?.response?.data?.path || ''; + // setFilePath(projectFilePath); + // } + return true; + }} + > + 上传模型文件, + title: ( +
+ 拖拽文件到这里,或 + 点此添加 +
+ ), + description: '', + icon: , + name: 'model_file_arr', + max: 1, + initialValue: currFormData?.model_file_md5 + ? [ + { + uid: currFormData?.model_file_md5, + name: currFormData?.model_file_name || currFormData?.model_file_md5, + status: 'done', + url: '/file/' + currFormData?.model_file_md5, + }, + ] + : [], + }} + afterUploadFile={({ resp, file }) => { + console.log(resp, file, 'afterRemoveFile'); + setCurrFormData((data) => { + return { ...data, model_file: resp?.data?.result }; + }); + }} + afterRemoveFile={() => { + setCurrFormData((data) => { + return { ...data, model_file: '' }; + }); + }} + nextText="请上传格式为zip.tar.gz的模型文件" + /> + + {/* 参数配置 */} + + className="gn_form" + name="config" + title={ + + } + stepProps={{ + description: ( + + ), + }} + onFinish={async (values: any) => { + // setConfigFileList([]); + console.log(values, 'config_values'); + let formData1 = formBaseRef.current?.getFieldsValue(); + if (formData1?.model_name) { + await waitTime(500); + } + return true; + }} + > + 模型配置文件上传} + title={ +
+ 拖拽文件到这里,或 + 点此添加 +
+ } + description="" + icon={} + name="config_file_name" + action={fileApiActionUrl} + fieldProps={{ + className: 'gn_proFormUploadDragger_formItem', + onChange: handleConfigFileChange, + onRemove: () => { + let index_ids = actionFormListRef.current?.getList()?.map((v, i) => { + return i; + }); + actionFormListRef.current?.remove(index_ids || []); + }, + beforeUpload: (file) => { + if ( + !file.name.endsWith('.yaml') && + !file.name.endsWith('.yml') && + !file.name.endsWith('.json') + ) { + message.error('请上传yaml或json文件').then(() => {}); + return false; + } else { + let parsedData = {}; + file + .text() + .then((text) => { + if (file.name.endsWith('.yaml') || file.name.endsWith('.yml')) { + parsedData = yaml.load(text) as Record; + } + if (file.name.endsWith('.json')) { + parsedData = JSON.parse(text) as Record; + } + if (Object.keys(parsedData).length > 0) { + dataFormListRef.current = Object.entries(parsedData).map(([key, value]) => ({ + name: key, + default: value, + })); + + dataFormListRef.current.forEach((v: any, i: number) => { + actionFormListRef.current?.add(v, i); + }); + } + return true; + }) + .catch(() => { + return false; + }); + } + }, + }} + /> +
+ 请上传格式为.json.yaml.yml的模型文件 +
+ + {/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */} + + 模型参数 +
+ 暂未上传模型配置文件,可根据业务需求手动添加参数字段~ +
+ + } + initialValue={ + isValidJson(props.values?.config_str) ? JSON.parse(props.values?.config_str) : [] + } + actionRef={actionFormListRef} + itemContainerRender={(doms) => { + return {doms}; + }} + alwaysShowItemLabel + > + {() => { + return ( + <> + + + + ); + }} +
+ + + ); +}; +export default UpdateForm; diff --git a/src/pages/Model/ModelDetail/index.tsx b/src/pages/Model/ModelDetail/index.tsx index 95459cf..8cc4739 100644 --- a/src/pages/Model/ModelDetail/index.tsx +++ b/src/pages/Model/ModelDetail/index.tsx @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-08 10:36:06 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-31 14:38:28 + * @LastEditTime: 2024-06-05 10:34:16 * @FilePath: \general-ai-manage\src\pages\Model\ModelDetail\index.tsx * @Description: 模型详情(基础信息展示、模型版本列表) * @交互说明 @@ -14,34 +14,37 @@ import InnerPageBack from '@/components/Back/innerPageBack'; import { CommButton } from '@/components/Button'; import TableActionCard from '@/components/TableActionCard'; import IsDelete from '@/components/TableActionCard/isDelete'; -import { apiModelInfo, apiModelVersionList } from '@/services/business/model'; +import { + apiModelInfo, + apiModelVersionDelete, + apiModelVersionInfo, + apiModelVersionList, + apiModelVersionSetdefault, +} from '@/services/business/model'; import { isSuccessApi } from '@/utils/forApi'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; import { ProCard, ProDescriptions, ProTable } from '@ant-design/pro-components'; -import { FormattedMessage, useParams } from '@umijs/max'; -import { Button } from 'antd'; +import { FormattedMessage, useIntl, useParams } from '@umijs/max'; +import { Button, message } from 'antd'; import { useRef, useState } from 'react'; import { proTablePaginationOptions } from '../../../../config/defaultTable'; import CreateForm from './components/createForm'; +import UpdateForm from './components/updateForm'; const ModelDetail: React.FC = () => { const routeParams = useParams(); // 路由参数读取 // const access = useAccess(); - // const intl = useIntl(); + const intl = useIntl(); const actionRef = useRef(); const [createModalOpen, setCreateModalOpen] = useState(false); // const [categoryFkIdIds, setCategoryFkIdIds] = useState([]); // 动态设置每页数量 const [currentPageSize, setCurrentPageSize] = useState(10); - // const [currentRow, setCurrentRow] = useState>({}); + const [currentRow, setCurrentRow] = useState>({}); const [modelInfo, setModelInfo] = useState>({}); - /** - * @en-US The pop-up window of the distribution update window - * @zh-CN 分布更新窗口的弹窗 - * */ - // const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [updateModalOpen, setUpdateModalOpen] = useState(false); // const [showDetail, setShowDetail] = useState(false); /**新增 编辑 删除 */ @@ -49,6 +52,19 @@ const ModelDetail: React.FC = () => { const handleCreateModal = () => { setCreateModalOpen(!createModalOpen); }; + // 编辑 + const handleUpdateModal = () => { + setUpdateModalOpen(!updateModalOpen); + }; + + // 模型版本信息 + async function loadDetail(record) { + const resp = await apiModelVersionInfo({ version_id: record?.version_id }); + if (isSuccessApi(resp) && resp?.data) { + setCurrentRow({ ...resp?.data, version_id: record?.version_id }); + setUpdateModalOpen(true); + } + } function reloadList() { actionRef.current?.reload(); @@ -64,11 +80,12 @@ const ModelDetail: React.FC = () => { title: , dataIndex: 'name', }, + // TODO 缺失默认版本信息字段 { title: ( ), - dataIndex: 'default_version', + dataIndex: 'version', }, { title: , @@ -83,7 +100,7 @@ const ModelDetail: React.FC = () => { const columns: ProColumns>[] = [ { title: , - dataIndex: 'name', + dataIndex: 'version', hideInSearch: true, key: 'fixedName', fixed: 'left', @@ -91,9 +108,9 @@ const ModelDetail: React.FC = () => { render: (dom, record) => (
- {dom} + V{dom} - {record.isEnable && ( + {record.is_default === 1 && ( { defaultMessage="更新时间" /> ), - dataIndex: 'updateTime', + dataIndex: 'update_time', hideInSearch: true, valueType: 'dateTime', }, @@ -157,7 +174,6 @@ const ModelDetail: React.FC = () => { { key="setDefault" type="link" size="small" - onClick={() => { - // setCurrentRow(record); - // history.push('/home/model-detail'); - // doToDetail(record); - // setShowDetail(true); + onClick={async () => { + const resp = await apiModelVersionSetdefault({ + model_id: Number(routeParams.id), + version_id: record?.version_id, + }); + if (isSuccessApi(resp)) { + message.success( + intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), + ); + reloadList(); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ + id: 'common.action.failure', + defaultMessage: '$$$', + }), + ); + } }} > @@ -181,22 +211,17 @@ const ModelDetail: React.FC = () => { ), }, { - key: 'updateDetail', + key: 'update', renderDom: ( ), }, @@ -205,7 +230,16 @@ const ModelDetail: React.FC = () => { renderDom: ( { - handleDestroy(record).then(() => {}); + console.log('删除成功'); + apiModelVersionDelete({ version_id: record.version_id }).then(() => { + message.success( + intl.formatMessage({ + id: 'common.action.success', + defaultMessage: '$$$', + }), + ); + reloadList(); + }); }} > ), @@ -331,6 +365,13 @@ const ModelDetail: React.FC = () => { modelInfo={modelInfo} reload={reloadList} /> +
); }; diff --git a/src/pages/Model/ModelRuntimeLib/components/createForm.tsx b/src/pages/Model/ModelRuntimeLib/components/createForm.tsx index 86a37c8..c59067b 100644 --- a/src/pages/Model/ModelRuntimeLib/components/createForm.tsx +++ b/src/pages/Model/ModelRuntimeLib/components/createForm.tsx @@ -1,5 +1,5 @@ import { CommButton } from '@/components/Button'; -import { apiModelHubSync } from '@/services/business/model'; +import { apiModelHubAdd, apiModelHubSync } from '@/services/business/model'; import { ModalForm, ProForm, @@ -11,6 +11,7 @@ import { FormattedMessage, useIntl } from '@umijs/max'; import { Form, message } from 'antd'; import React, { useState } from 'react'; +import { isSuccessApi } from '@/utils/forApi'; import { proFormSmallItemStyleProps, proFormSmallModelWidth, @@ -31,7 +32,7 @@ const CreateForm: React.FC = (props) => { className="gn_form gn_modal_form" width={proFormSmallModelWidth} title={intl.formatMessage({ - id: 'model_runtimeLib.list.table.createForm.add', + id: 'model_runtimeLib.list.table.form.action.add', defaultMessage: '新建', })} open={props.createModalOpen} @@ -44,16 +45,19 @@ const CreateForm: React.FC = (props) => { submitTimeout={2000} onFinish={async (values) => { console.log(values, 'add_finish_values'); - // TODO 对接新增接口 - // postModelCategoryCreateModelCategory(values) - // .then(() => { - // message.success(intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' })); - // props.reload(); - // }) - // .catch(() => { - // message.error(intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' })); - // }); - props.handleModal(); + let resp = await apiModelHubAdd(values); + if (isSuccessApi(resp)) { + message.success( + intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), + ); + props.reload(); + props.handleModal(); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }), + ); + } return true; }} > @@ -87,8 +91,8 @@ const CreateForm: React.FC = (props) => { } @@ -115,7 +119,7 @@ const CreateForm: React.FC = (props) => { } @@ -151,9 +155,8 @@ const CreateForm: React.FC = (props) => { color: '#154ddd', }} onClick={() => { - const { ip, port } = form.getFieldsValue(); - if (ip && port) { - // 访问接口拿数据 + const { host, port } = form.getFieldsValue(); + if (host && port) { setOpenFiles(true); } else { message.error('请填写IP和端口'); @@ -167,7 +170,7 @@ const CreateForm: React.FC = (props) => { {openFiles ? ( = (props) => { showSearch debounceTime={500} request={async () => { - const { data } = await apiModelHubSync(); + const { host, port } = form.getFieldsValue(); + const { data } = await apiModelHubSync({ + host, + port, + }); return data?.data?.map((v: Record) => { - return { ...v, label: v.name, value: v.id }; + return { ...v, label: v, value: v }; }); }} rules={[ @@ -202,7 +209,7 @@ const CreateForm: React.FC = (props) => { } diff --git a/src/pages/Model/ModelRuntimeLib/components/updateForm.tsx b/src/pages/Model/ModelRuntimeLib/components/updateForm.tsx index e69de29..c16ae17 100644 --- a/src/pages/Model/ModelRuntimeLib/components/updateForm.tsx +++ b/src/pages/Model/ModelRuntimeLib/components/updateForm.tsx @@ -0,0 +1,241 @@ +import { CommButton } from '@/components/Button'; +import { apiModelHubEdit, apiModelHubSync } from '@/services/business/model'; +import { + ModalForm, + ProForm, + ProFormSelect, + ProFormText, + ProFormTextArea, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Form, message } from 'antd'; +import React, { useEffect, useState } from 'react'; + +import { isSuccessApi } from '@/utils/forApi'; +import { + proFormSmallItemStyleProps, + proFormSmallModelWidth, +} from '../../../../../config/defaultForm'; + +export type UpdateFormProps = { + updateModalOpen: boolean; + values: Record; + handleModal: () => void; + reload: any; +}; +const UpdateForm: React.FC = (props) => { + const intl = useIntl(); + const [openFiles, setOpenFiles] = useState(false); + const [form] = Form.useForm(); + function resetForm() { + form.resetFields(); + } + useEffect(() => { + if (props.updateModalOpen && props.values?.id) { + form.setFieldsValue({ ...props.values }); + console.log(props.values, 'useEffect_values'); + } else { + resetForm(); + } + }, [props.updateModalOpen, props.values]); + return ( + + className="gn_form gn_modal_form" + width={proFormSmallModelWidth} + title={intl.formatMessage({ + id: 'model_runtimeLib.list.table.form.action.edit', + defaultMessage: '编辑', + })} + open={props.updateModalOpen} + form={form} + autoFocusFirstInput + modalProps={{ + destroyOnClose: true, + onCancel: () => props.handleModal(), + }} + submitTimeout={2000} + onFinish={async (values) => { + console.log(values, 'add_finish_values'); + let resp = await apiModelHubEdit({ ...values, id: props.values.id }); + if (isSuccessApi(resp)) { + message.success( + intl.formatMessage({ id: 'common.action.success', defaultMessage: '$$$' }), + ); + props.reload(); + props.handleModal(); + } else { + message.error( + resp?.meta?.message || + intl.formatMessage({ id: 'common.action.failure', defaultMessage: '$$$' }), + ); + } + return true; + }} + > + + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_runtimeLib.list.table.form.name', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_runtimeLib.list.table.form.IP', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_runtimeLib.list.table.form.port', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + + { + const { host, port } = form.getFieldsValue(); + if (host && port) { + setOpenFiles(true); + } else { + message.error('请填写IP和端口'); + } + + console.log(form.getFieldsValue(), 'searchIP'); + }} + buttonLabel={} + > + + {openFiles ? ( + { + const { host, port } = form.getFieldsValue(); + const { data } = await apiModelHubSync({ + host, + port, + }); + return data?.data?.map((v: Record) => { + return { ...v, label: v, value: v }; + }); + }} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + ) : ( + <> + )} + + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'model_runtimeLib.list.table.form.rule.required.remark', + defaultMessage: '$$$', + })}`} + required={false} + disabled={false} + /> + + + ); +}; +export default UpdateForm; diff --git a/src/pages/Model/ModelRuntimeLib/index.tsx b/src/pages/Model/ModelRuntimeLib/index.tsx index b32e2ba..585ccec 100644 --- a/src/pages/Model/ModelRuntimeLib/index.tsx +++ b/src/pages/Model/ModelRuntimeLib/index.tsx @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-08 10:36:06 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-31 14:20:31 + * @LastEditTime: 2024-06-06 15:13:25 * @FilePath: \general-ai-manage\src\pages\Model\ModelRuntimeLib\index.tsx * @Description: 模型运行库 * @交互说明 @@ -11,7 +11,7 @@ * */ -import { apiModelHubList } from '@/services/business/model'; +import { apiModelHubDelete, apiModelHubInfo, apiModelHubList } from '@/services/business/model'; import { isSuccessApi } from '@/utils/forApi'; import { CommButton } from '@/components/Button'; @@ -20,17 +20,19 @@ import IsDelete from '@/components/TableActionCard/isDelete'; import { SearchOutlined } from '@ant-design/icons'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; import { ProCard, ProForm, ProFormText, ProTable } from '@ant-design/pro-components'; -import { Access, FormattedMessage, history, useAccess } from '@umijs/max'; -import { Button } from 'antd'; +import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; +import { Button, message } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; import { proTableCommonOptions, proTablePaginationOptions } from '../../../../config/defaultTable'; import CreateForm from './components/createForm'; +import UpdateForm from './components/updateForm'; + import { ReactComponent as ResetIcon } from '/public/home/reset_icon.svg'; import { ReactComponent as SearchIcon } from '/public/home/search_icon.svg'; const ModelRuntimeLib: React.FC = () => { const access = useAccess(); - // const intl = useIntl(); + const intl = useIntl(); const actionRef = useRef(); const [querysData, setQuerysData] = useState>({}); // 列表查询参数 @@ -41,24 +43,25 @@ const ModelRuntimeLib: React.FC = () => { const [currentRow, setCurrentRow] = useState>({}); const [form] = ProForm.useForm(); // form 对象 - /** - * @en-US The pop-up window of the distribution update window - * @zh-CN 分布更新窗口的弹窗 - * */ - // const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [updateModalOpen, setUpdateModalOpen] = useState(false); // const [showDetail, setShowDetail] = useState(false); /**新增 编辑 删除 */ // 新增 const handleCreateModal = () => { - if (createModalOpen) { - setCreateModalOpen(false); - setCurrentRow(undefined); - } else { - setCreateModalOpen(true); - } + setCreateModalOpen(!createModalOpen); }; - + // 编辑 + const handleUpdateModal = () => { + setUpdateModalOpen(!updateModalOpen); + }; + // 设备节点信息 + async function loadDetail(record) { + const resp = await apiModelHubInfo({ id: record?.id }); + if (isSuccessApi(resp) && resp?.data) { + setCurrentRow({ ...resp?.data, id: record?.id }); + } + } function reloadList() { actionRef.current?.reload(); } @@ -68,7 +71,6 @@ const ModelRuntimeLib: React.FC = () => { reloadList(); } }, [actionRef, querysData]); - // TODO 完善列表展示字段 const columns: ProColumns>[] = [ { title: , @@ -77,11 +79,17 @@ const ModelRuntimeLib: React.FC = () => { key: 'fixedName', fixed: 'left', }, + { + title: , + dataIndex: 'path', + hideInSearch: true, + }, + { title: ( ), - dataIndex: 'createTime', + dataIndex: 'create_time', hideInSearch: true, valueType: 'dateTime', }, @@ -90,7 +98,7 @@ const ModelRuntimeLib: React.FC = () => { title: ( ), - dataIndex: 'updateTime', + dataIndex: 'update_time', hideInSearch: true, valueType: 'dateTime', }, @@ -113,8 +121,8 @@ const ModelRuntimeLib: React.FC = () => { type="link" size="small" onClick={() => { - // setUpdateModalOpen(true); - setCurrentRow(record); + loadDetail(record); + setUpdateModalOpen(true); }} > @@ -126,7 +134,16 @@ const ModelRuntimeLib: React.FC = () => { renderDom: ( { - handleDestroy(record).then(() => {}); + console.log('删除成功'); + apiModelHubDelete({ id: record.id }).then(() => { + message.success( + intl.formatMessage({ + id: 'common.action.success', + defaultMessage: '$$$', + }), + ); + reloadList(); + }); }} > ), @@ -216,7 +233,10 @@ const ModelRuntimeLib: React.FC = () => { setCreateModalOpen(true); }} > - + } @@ -250,23 +270,18 @@ const ModelRuntimeLib: React.FC = () => { persistenceKey: 'algorithm_model_list', persistenceType: 'localStorage', }} - request={async (params = {}, sort) => { + request={async (params = {}) => { const { current, ...rest } = params; const reqParams = { pageNo: current, - desc: false, - orderKey: '', + ...rest, }; - if (sort && Object.keys(sort).length) { - reqParams.orderKey = Object.keys(sort)[0]; - let sort_select = sort[reqParams.orderKey]; - reqParams.desc = sort_select === 'descend'; - } let resp = await apiModelHubList({ ...reqParams, ...querysData }); - if (isSuccessApi(resp)) { + if (!isSuccessApi(resp)) { return { data: [], success: true }; } + console.log(resp, 'apiEntityNodesDeviceList_resp'); return { data: resp.data?.data, success: resp.success, @@ -280,10 +295,15 @@ const ModelRuntimeLib: React.FC = () => { + ); }; diff --git a/src/services/business/entity.ts b/src/services/business/entity.ts index 891a042..34ea47b 100644 --- a/src/services/business/entity.ts +++ b/src/services/business/entity.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-05-23 13:50:50 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-30 15:01:21 + * @LastEditTime: 2024-06-06 15:39:10 * @FilePath: \general-ai-platform-web\src\services\Business\entity.ts * @Description: api 实体 */ diff --git a/src/services/business/model.ts b/src/services/business/model.ts index bd4eb76..1f8e6a2 100644 --- a/src/services/business/model.ts +++ b/src/services/business/model.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-05-24 17:57:19 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-31 14:19:28 + * @LastEditTime: 2024-06-06 15:44:20 * @FilePath: \general-ai-platform-web\src\services\business\model.ts * @Description: api 模型 */ @@ -15,7 +15,7 @@ import { request } from '@umijs/max'; // 添加企业部署的业务模型 export async function apiModelDeploymentAdd(body: any, options?: { [key: string]: any }) { return request( - `/api/v1/model/deployment/add`, + `/api/v1/enterprise/model/deployment/add`, { method: 'POST', headers: { @@ -30,7 +30,7 @@ export async function apiModelDeploymentAdd(body: any, options?: { [key: string] // 编辑企业部署的业务模型 export async function apiModelDeploymentEdit(body: any, options?: { [key: string]: any }) { return request( - `/api/v1/model/deployment/edit`, + `/api/v1/enterprise/model/deployment/edit`, { method: 'POST', headers: { @@ -45,7 +45,7 @@ export async function apiModelDeploymentEdit(body: any, options?: { [key: string // 企业部署的业务模型列表 export async function apiModelDeploymentList(body: any, options?: { [key: string]: any }) { return request( - `/api/v1/model/deployment/list`, + `/api/v1/enterprise/model/deployment/list`, { method: 'POST', headers: { @@ -60,7 +60,7 @@ export async function apiModelDeploymentList(body: any, options?: { [key: string // // 删除企业部署的业务模型 // export async function apiModelDeploymentDelete(body: any, options?: { [key: string]: any }) { // return request( -// `/api/v1/model/deployment/delete`, +// `/api/v1/enterprise/model/deployment/delete`, // { // method: 'POST', // headers: { @@ -76,7 +76,7 @@ export async function apiModelDeploymentList(body: any, options?: { [key: string // 企业部署的业务模型信息 export async function apiModelDeploymentInfo(body: any, options?: { [key: string]: any }) { return request( - `/api/v1/model/deployment/info`, + `/api/v1/enterprise/model/deployment/info`, { method: 'POST', headers: { diff --git a/src/utils/forApi.ts b/src/utils/forApi.ts index 1e32668..530eda0 100644 --- a/src/utils/forApi.ts +++ b/src/utils/forApi.ts @@ -2,7 +2,7 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2024-04-24 10:11:48 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2024-05-27 14:00:45 + * @LastEditTime: 2024-06-05 10:47:32 * @FilePath: \general-ai-platform-web\src\utils\forApi.ts * @Description: 这是接口层和业务层的转换工具方法集 */ @@ -18,6 +18,7 @@ export function isSuccessApi(result: API.API_COMMON_DATA): boolean { if (meta.code < 300 && meta.code >= 200) { return true; } + return false; } return false; } diff --git a/src/utils/is.ts b/src/utils/is.ts new file mode 100644 index 0000000..53ec73d --- /dev/null +++ b/src/utils/is.ts @@ -0,0 +1,22 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2024-06-05 13:32:31 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2024-06-06 13:13:25 + * @FilePath: \general-ai-platform-web\src\utils\is.ts + * @Description: 校验方法库 + */ + +/** + * @是否是JSONString + * @param jsonString 目标字符串 + * @returns boolean + */ +export function isValidJson(jsonString) { + try { + JSON.parse(jsonString); + return true; + } catch (e) { + return false; + } +}