feat: 模型部署详情更新初始化联调完成

develop2
donghao 10 months ago
parent b4e53f8544
commit 9f5cd5caf1

@ -2,7 +2,7 @@
* @Author: zhoux zhouxia@supervision.ltd
* @Date: 2023-11-14 15:49:36
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-24 14:07:20
* @LastEditTime: 2024-06-25 14:26:32
* @FilePath: \general-ai-platform-web\src\components\TableActionCard\index.tsx
* @Description: ,`customMade`, koroFileHeader : https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
@ -59,7 +59,6 @@ const TableActionCard: React.FC<TableActionItemProps> = (props) => {
setMoreActions(startMoreActions);
}
}, [props.renderActions]);
return (
<div className="flex items-center">
{prevActions.map((item, index) => {
@ -74,8 +73,10 @@ const TableActionCard: React.FC<TableActionItemProps> = (props) => {
);
})}
{isHasMore ? (
// TODO 此处有警告需要解决 findDOMNode is deprecated and will be removed in the next major release. Instead, add a ref directly to the element you want to reference
<Dropdown
menu={{ items: moreActions }}
trigger={['click']}
onMouseDown={(e) => e.stopPropagation()}
getPopupContainer={(triggerNode) => triggerNode.parentNode}
>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-10 17:21:34
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-06 15:07:50
* @LastEditTime: 2024-06-25 14:42:13
* @FilePath: \general-ai-manage\src\locales\zh-CN\model.ts
* @Description:
*/
@ -64,7 +64,9 @@ export const model_version: { [key: string]: string } = {
'model_detail.version.table.list.remark': '备注',
'model_detail.version.table.list.createTime': '创建时间',
'model_detail.version.table.list.updateTime': '更新时间',
'model_detail.version.table.list.add': '新建模型版本',
'model_detail.version.table.list.action.add': '新建模型版本',
'model_detail.version.table.list.action.edit': '编辑模型版本',
'model_detail.version.table.list.update': '更新模型版本',
'model_detail.version.stepForm.base': '版本信息',
'model_detail.version.stepForm.base.description': '填写版本基础信息',
@ -87,7 +89,9 @@ export const model_version: { [key: string]: string } = {
// 业务模型
export const business_model: { [key: string]: string } = {
'business_model.table.title': '业务模型列表',
'business_model.table.list.add.name': '创建模型',
'business_model.table.list.action.add': '创建模型',
'business_model.table.list.action.edit': '编辑模型',
'business_model.table.list.name': '业务模型名称',
'business_model.table.list.createTime': '创建时间',
'business_model.stepForm.base': '基本信息',

@ -97,11 +97,11 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
// test 测试数据
useEffect(() => {
// 初始化赋值
setCurrFormData({
name: '晶圆检测工艺00',
comment:
'测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
});
// setCurrFormData({
// name: '晶圆检测工艺00',
// comment:
// '测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注测试一下备注',
// });
}, [props.createModalOpen]);
return (
<div>
@ -154,7 +154,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
<Modal
className="gn_model_steps_form"
title={
<FormattedMessage id="business_model.table.list.add.name" defaultMessage="新增" />
<FormattedMessage id="business_model.table.list.action.add" defaultMessage="新增" />
}
width={proFormMaxModelWidth}
onCancel={() => {
@ -252,10 +252,13 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
),
}}
onFinish={async () => {
if (modelLinkKeys.length === 0) {
message.warning('请至少选择一项内容');
return false;
}
return true;
}}
>
{/* //TODO 062501 此项校验必填 与UI确定调整尺寸布局 */}
<Transfer
dataSource={modalData}
titles={['基础模型库', '已选模型']}

@ -0,0 +1,464 @@
import { FormUploadDraggerToken } from '@/components/UploadFile';
import { apiEntityNodes } from '@/services/business/entity';
import { apiModelDeploymentEdit } from '@/services/business/model';
import { isSuccessApi } from '@/utils/forApi';
import {
ProForm,
ProFormInstance,
ProFormText,
ProFormTextArea,
StepsForm,
} from '@ant-design/pro-components';
import { FormattedMessage, useIntl } from '@umijs/max';
import { Modal, Transfer, Tree, message } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import {
proFormMaxItemStyleProps,
proFormMaxModelWidth,
proFormStepsFormProps,
} from '../../../../../config/defaultForm';
// import {beforeUploadFile} from "@/utils/common";
// @ts-ignore
import { apiModelListSimple } from '@/services/business/model';
import { mathExtractIds } from '@/utils/forMath';
import { isArrayAndNotEmpty } from '@/utils/is';
export type UpdateFormProps = {
updateModalOpen: boolean;
handleModal: () => void;
commInfo: Record<string, any>;
values: Record<string, any>;
reload: any;
};
const waitTime = (time: number = 100) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve(true);
}, time);
});
};
const UpdateForm: React.FC<UpdateFormProps> = (props) => {
const intl = useIntl();
// state
const [currFormData, setCurrFormData] = useState<Record<string, any>>({});
// 关联模型state
const [modalData, setModalData] = useState<RecordType[]>([]);
const [modelLinkKeys, setModelLinkKeys] = useState<string[]>([]);
// 关联节点state
const [deviceTreeList, setDeviceTreeList] = useState<Record<string, any>[]>([]);
const [deviceLinkKeys, setDeviceLinkKeys] = useState([]);
// const [form] = Form.useForm<API.ModelVersion>();
const [current, setCurrent] = useState(0);
const formRef = useRef<ProFormInstance>();
// 获取所有模型选项
const loadModelData = async () => {
const resp = await apiModelListSimple();
if (isSuccessApi(resp) && resp?.data) {
console.log('apiModelListSimple_resp', resp.data);
let result = (resp.data?.result || []).map((v: any) => {
console.log(v);
return {
key: v.id,
title: v.name,
chosen: false,
disabled: false,
};
});
setModalData(result);
}
};
// 设备节点树
async function loadDeviceTree() {
const resp = await apiEntityNodes({ entity_id: props.commInfo.id });
if (isSuccessApi(resp)) {
setDeviceTreeList(resp?.data.data);
}
}
const handleChange = (newTargetKeys: string[]) => {
console.log(newTargetKeys, 'newTargetKeys');
setModelLinkKeys(newTargetKeys);
};
function resetForm() {
setCurrFormData({});
formRef.current?.resetFields();
}
// 处理其它表单内容
function setOthersData() {
const { basemodel_list, link_node_list } = props.values;
console.log('mathExtractIds', mathExtractIds(basemodel_list));
const currModelLinkKeys = mathExtractIds(basemodel_list);
if (isArrayAndNotEmpty(currModelLinkKeys)) {
handleChange(currModelLinkKeys);
}
const currLinkNodeList = mathExtractIds(link_node_list, 'node_id');
console.log(currLinkNodeList, 'currLinkNodeList');
if (isArrayAndNotEmpty(currLinkNodeList)) {
setDeviceLinkKeys(currLinkNodeList);
}
}
useEffect(() => {
setModelLinkKeys([]);
// 初始化赋值
if (props.updateModalOpen && props.values?.id) {
loadModelData();
loadDeviceTree();
setCurrFormData({
...props.values,
business_logic: props.values?.business_logic_md5,
business_conf_file: props.values?.business_conf_md5,
});
setOthersData();
console.log(props.values, 'useEffect_values', currFormData);
} else {
resetForm();
}
}, [props.updateModalOpen, props.values]);
return (
<div>
<StepsForm<{
name: string;
}>
onFinish={async (values) => {
console.log('All form values:', values, {
...currFormData,
entity_id: props.commInfo.id,
basemodel_ids: modelLinkKeys,
link_node_ids: deviceLinkKeys,
});
// 在这里处理提交数据例如调用API
let resp = await apiModelDeploymentEdit({
...values,
id: props.values?.id,
entity_id: props.commInfo.id,
basemodel_ids: isArrayAndNotEmpty(modelLinkKeys) ? modelLinkKeys.join(',') : '',
business_logic: currFormData?.business_logic,
business_conf_file: currFormData?.business_conf_file,
link_node_ids: isArrayAndNotEmpty(deviceLinkKeys) ? deviceLinkKeys.join(',') : '',
});
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}
onCurrentChange={setCurrent}
formProps={{
validateMessages: {
required: `${intl.formatMessage({
id: 'common.form.required',
defaultMessage: '此项为必填项',
})}`,
},
}}
stepsFormRender={(dom, submitter) => {
return (
<Modal
className="gn_model_steps_form"
title={
<FormattedMessage
id="business_model.table.list.action.edit"
defaultMessage="编辑"
/>
}
width={proFormMaxModelWidth}
onCancel={() => {
setCurrent(0);
formRef.current?.resetFields();
props.handleModal();
}}
open={props.updateModalOpen}
footer={submitter}
destroyOnClose
>
{dom}
</Modal>
);
}}
>
{/* 基本信息 数据创建 */}
<StepsForm.StepForm<{
name: string;
}>
className="gn_form"
name="base"
formRef={formRef}
title={<FormattedMessage id="business_model.stepForm.base" defaultMessage="基本信息" />}
stepProps={{
description: (
<FormattedMessage
id="business_model.stepForm.base.description"
defaultMessage="填写基础信息"
/>
),
}}
onFinish={async () => {
// setFormData(formRef.current?.getFieldsValue());
await waitTime(500);
return true;
}}
>
<ProForm.Group>
<ProFormText
width={proFormMaxItemStyleProps.width}
name="name"
label={<FormattedMessage id="business_model.form.modelFkId" defaultMessage="名称" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'business_model.form.modelFkId',
defaultMessage: '$$$',
})}`}
required={true}
initialValue={currFormData?.name}
rules={[
{
required: true,
message: (
<FormattedMessage
id="model_index.create.form.rule.required.name"
defaultMessage="name is required"
/>
),
},
]}
/>
<ProFormTextArea
width={proFormMaxItemStyleProps.width}
name="comment"
label={<FormattedMessage id="business_model.form.remark" defaultMessage="简介" />}
placeholder={`${intl.formatMessage({
id: 'common.please_input',
defaultMessage: '$$$',
})}${intl.formatMessage({
id: 'business_model.form.remark',
defaultMessage: '$$$',
})}`}
initialValue={currFormData?.comment}
required={false}
/>
</ProForm.Group>
</StepsForm.StepForm>
{/* 关联算法模型 */}
<StepsForm.StepForm<{
model: string;
}>
name="baseModel"
title={
<FormattedMessage id="business_model.stepForm.baseModel" defaultMessage="关联模型" />
}
stepProps={{
description: (
<FormattedMessage
id="business_model.stepForm.baseModel.description"
defaultMessage="关联基础模型"
/>
),
}}
onFinish={async () => {
if (modelLinkKeys.length === 0) {
message.warning('请至少选择一项内容');
return false;
}
return true;
}}
>
<Transfer
dataSource={modalData}
titles={['基础模型库', '已选模型']}
locale={{ itemUnit: '项', itemsUnit: '项', searchPlaceholder: '请输入搜索内容' }}
targetKeys={modelLinkKeys}
onChange={handleChange}
// onSearch={handleSearch}
style={{ marginBottom: '20px' }}
listStyle={{ width: 410, height: 300 }}
operationStyle={{ width: 50, alignItems: 'center' }}
render={(item) => item.title}
/>
</StepsForm.StepForm>
{/* 业务代码 */}
<StepsForm.StepForm<{
project_file: string;
}>
className="gn_form"
name="project_file"
title={
<FormattedMessage id="business_model.stepForm.project_file" defaultMessage="业务代码" />
}
style={{ width: proFormMaxItemStyleProps.width }}
stepProps={{
description: (
<FormattedMessage
id="business_model.stepForm.project_file.description"
defaultMessage="上传业务代码"
/>
),
}}
>
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>zip.tar.gz</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'business_logic_arr',
max: 1,
initialValue: currFormData?.business_logic_md5
? [
{
uid: currFormData?.business_logic_md5,
name: currFormData?.business_logic_name || currFormData?.business_logic_md5,
status: 'done',
url: '/file/' + currFormData?.business_logic_md5,
},
]
: [],
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, business_logic: resp?.data?.result };
});
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, business_logic: '' };
});
}}
openPreviewFile={true}
/>
</StepsForm.StepForm>
{/* 参数配置 */}
<StepsForm.StepForm<{
config: string;
}>
className="gn_form"
name="config"
title={<FormattedMessage id="business_model.stepForm.config" defaultMessage="参数配置" />}
stepProps={{
description: (
<FormattedMessage
id="business_model.stepForm.config.description"
defaultMessage="配置业务参数"
/>
),
}}
onFinish={async (values: any) => {
console.log(values, 'config_values');
return true;
}}
>
<FormUploadDraggerToken
proFieldProps={{
label: (
<div className="flex">
<span className="font-bold"></span>
<div style={{ color: '#666666' }}>.json.yaml.yml</div>
</div>
),
title: (
<div className="gn_uploadfile_title py-[16px] text1 text-center">
<span></span>
<a></a>
</div>
),
description: '',
icon: <i className="iconfont icon-shangchuanwenjian text_primary text-[32px]"></i>,
name: 'business_conf_file_arr',
max: 1,
initialValue: currFormData?.business_conf_md5
? [
{
uid: currFormData?.business_conf_md5,
name: currFormData?.business_conf_name || currFormData?.business_conf_md5,
status: 'done',
url: '/file/' + currFormData?.business_conf_md5,
},
]
: [],
}}
afterUploadFile={({ resp }) => {
setCurrFormData((data) => {
return { ...data, business_conf_file: resp?.data?.result };
});
}}
afterRemoveFile={() => {
setCurrFormData((data) => {
return { ...data, business_conf_file: '' };
});
}}
openPreviewFile={true}
/>
</StepsForm.StepForm>
{/* 关联节点 */}
<StepsForm.StepForm<{
group: string;
}>
name="group"
title={<FormattedMessage id="business_model.stepForm.group" defaultMessage="关联节点" />}
stepProps={{
description: (
<FormattedMessage
id="business_model.stepForm.group.description"
defaultMessage="关联相关设备节点"
/>
),
}}
onFinish={async () => {
return true;
}}
style={{ width: proFormMaxItemStyleProps.width }}
>
<div style={{ paddingBottom: 10, fontWeight: 700 }}>{'节点信息'}</div>
<Tree
fieldNames={{
title: 'name',
key: 'id',
children: 'children',
}}
checkable
defaultExpandAll={true}
checkedKeys={deviceLinkKeys}
autoExpandParent={true}
onCheck={(checkedKeys: any) => {
// form.setFieldsValue({menuIds: checkedKeys})
console.log(checkedKeys, 'checkedKeys');
setDeviceLinkKeys(checkedKeys);
// formRef3.current?.setFieldValue('groupIds', checkedKeys)
}}
treeData={deviceTreeList}
/>
</StepsForm.StepForm>
</StepsForm>
</div>
);
};
export default UpdateForm;

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-22 15:23:36
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-25 10:00:13
* @LastEditTime: 2024-06-25 15:10:47
* @FilePath: \general-ai-platform-web\src\pages\Node\BusinessModel\index.tsx
* @Description:
* @
@ -28,6 +28,8 @@ 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';
import DetailCard from './components/detailCard';
const BusinessModel: React.FC = () => {
const intl = useIntl();
@ -37,7 +39,7 @@ const BusinessModel: React.FC = () => {
const [commInfo] = useState<Record<string, any>>({ ...getStoreBusinessInfo() }); // 通用信息
const [createModalOpen, setCreateModalOpen] = useState<boolean>(false);
// const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
const [updateModalOpen, setUpdateModalOpen] = useState<boolean>(false);
const [detailModalOpen, setDetailModalOpen] = useState<boolean>(false); // 编辑窗口是否打开
const [currentRow, setCurrentRow] = useState<Record<string, any>>({});
@ -51,19 +53,22 @@ const BusinessModel: React.FC = () => {
setCreateModalOpen(!createModalOpen);
};
// 编辑
// const handleUpdateModal = () => {
// setUpdateModalOpen(!updateModalOpen);
// };
const handleUpdateModal = () => {
setUpdateModalOpen(!updateModalOpen);
};
// 详情
const handleDetailModal = () => {
setDetailModalOpen(!detailModalOpen);
};
// 设备节点信息
async function loadDetail(record) {
async function loadDetail(record, isOpenDetail = false) {
const resp = await apiModelDeploymentInfo({ id: record?.model_id });
if (isSuccessApi(resp) && resp?.data) {
setCurrentRow({ ...resp?.data, id: record?.model_id });
if (isOpenDetail) {
setUpdateModalOpen(true);
}
}
}
@ -117,7 +122,21 @@ const BusinessModel: React.FC = () => {
</Button>
),
},
// TODO 062502 编辑接口在新建交互完善后对接
{
key: 'update',
renderDom: (
<Button
key="update"
type="link"
size="small"
onClick={() => {
loadDetail(record, true);
}}
>
<FormattedMessage id="pages.searchTable.update" defaultMessage="查看" />
</Button>
),
},
{
key: 'destroy',
renderDom: (
@ -167,7 +186,7 @@ const BusinessModel: React.FC = () => {
setCreateModalOpen(true);
}}
>
<FormattedMessage id="business_model.table.list.add.name" defaultMessage="新增" />
<FormattedMessage id="business_model.table.list.action.add" defaultMessage="新增" />
</Button>
}
>
@ -189,7 +208,7 @@ const BusinessModel: React.FC = () => {
search={false}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
rowKey="model_id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
@ -235,6 +254,13 @@ const BusinessModel: React.FC = () => {
commInfo={commInfo}
reload={reloadList}
/>
<UpdateForm
updateModalOpen={updateModalOpen}
handleModal={handleUpdateModal}
commInfo={commInfo}
values={currentRow}
reload={reloadList}
/>
<DetailCard
info={currentRow}
detailModalOpen={detailModalOpen}

@ -120,7 +120,7 @@ const UpdateServerForm: React.FC<UpdateServerFormProps> = (props) => {
defaultMessage: '$$$',
})}`}
/>
{/* // TODO 密码默认渲染*** */}
{/* 密码默认渲染*** */}
<ProFormText.Password
width={proFormSmallItemStyleProps.column2Width}
label={<FormattedMessage id="server_state.table.form.pwd" defaultMessage="密码" />}

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-23 17:00:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-28 16:45:52
* @LastEditTime: 2024-06-25 14:08:27
* @FilePath: \general-ai-platform-web\src\pages\Business\DeviceGroup\components\baseInfo.tsx
* @Description:
*
@ -25,14 +25,6 @@ const BaseInfo: React.FC<BaseInfoProps> = ({ info }) => {
{
title: <FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />,
dataIndex: 'parent_name',
// TODO 需要接口返回上级节点的名称
// render: (_, record) => {
// if(record?.lon && record?.lat){
// return record?.lon + ',' + record?.lat;
// }
// return '-'
// },
},
{
title: <FormattedMessage id="device_group.tree_node.address" defaultMessage="地址" />,

@ -4,8 +4,7 @@ import { ModalForm, ProForm, ProFormText, ProFormTextArea } from '@ant-design/pr
import { FormattedMessage, useIntl } from '@umijs/max';
import { Form, message } from 'antd';
import React from // , {useEffect}
'react';
import React from 'react'; // , {useEffect}
import {
proFormSmallItemStyleProps,
proFormSmallModelWidth,
@ -109,7 +108,6 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
label={
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
}
// TODO 此处在联调时确定下上级节点数据获取来源
placeholder={
!props.parentInfo?.name
? `${intl.formatMessage({

@ -72,7 +72,6 @@ const UpdateDeviceForm: React.FC<UpdateDeviceFormProps> = (props) => {
submitTimeout={2000}
onFinish={async (values) => {
console.log(values, 'add_finish_values');
// TODO 对接新增接口
let resp = await apiEntityNodesDeviceEdit({
...values,
device_id: props.values.device_id,

@ -112,7 +112,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
label={
<FormattedMessage id="device_group.tree_node.fatherName" defaultMessage="上级节点" />
}
// TODO 此处在联调时确定下上级节点数据获取来源
placeholder={
!props.values?.parent_name
? `${intl.formatMessage({

@ -98,7 +98,10 @@ const CreateForm: React.FC<CreateFormProps> = (props) => {
<Modal
className="gn_model_steps_form"
title={
<FormattedMessage id="model_detail.version.table.list.add" defaultMessage="新增" />
<FormattedMessage
id="model_detail.version.table.list.action.add"
defaultMessage="新增"
/>
}
width={proFormSmallModelWidth}
onCancel={() => {

@ -54,10 +54,8 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
function resetForm() {
setCurrFormData({});
}
// test 测试数据
useEffect(() => {
// 初始化赋值
if (props.updateModalOpen && props.values?.version_id) {
setCurrFormData({
...props.values,
@ -69,13 +67,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
}
}, [props.updateModalOpen, props.values]);
// useEffect(() => {
// if (formProjectFileRef) {
// formProjectFileRef.current?.setFieldValue('model_file_arr', [
// ]);
// }
// }, [props.updateModalOpen, props.values, formProjectFileRef]);
return (
<StepsForm<{
name: string;
@ -120,7 +111,10 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
<Modal
className="gn_model_steps_form"
title={
<FormattedMessage id="model_detail.version.table.list.add" defaultMessage="新增" />
<FormattedMessage
id="model_detail.version.table.list.action.edit"
defaultMessage="编辑"
/>
}
width={proFormSmallModelWidth}
onCancel={() => {
@ -426,7 +420,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => {
.json.yaml.yml
</div> */}
{/* // TODO label字重与上面统一, 操作按钮需要与输入框对齐 */}
{/* <ProFormList
name="config_str_arr"
label={

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-08 10:36:06
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-05 10:34:16
* @LastEditTime: 2024-06-25 14:32:10
* @FilePath: \general-ai-manage\src\pages\Model\ModelDetail\index.tsx
* @Description:
* @
@ -80,12 +80,17 @@ const ModelDetail: React.FC = () => {
title: <FormattedMessage id="model_index.table.list.name" defaultMessage="$$$" />,
dataIndex: 'name',
},
// TODO 缺失默认版本信息字段
{
title: (
<FormattedMessage id="model_index.table.list.defaultVersionFkId" defaultMessage="$$$" />
),
dataIndex: 'version',
dataIndex: 'default_version',
render: (dom, record) => (
<div>
{record?.default_version ? <span>V</span> : <></>}
<span>{dom || '-'}</span>
</div>
),
},
{
title: <FormattedMessage id="model_index.table.list.updateTime" defaultMessage="$$$" />,

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 14:02:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-14 14:08:11
* @LastEditTime: 2024-06-25 14:31:24
* @FilePath: \general-ai-manage\src\pages\ModelIndex\ModelIndex.tsx
* @Description:
* @
@ -122,6 +122,12 @@ const ModelIndex: React.FC = () => {
),
dataIndex: 'default_version',
hideInSearch: true,
render: (dom, record) => (
<div>
{record?.default_version ? <span>V</span> : <></>}
<span>{dom}</span>
</div>
),
},
{
@ -295,62 +301,63 @@ const ModelIndex: React.FC = () => {
</Access>
}
>
{/* // TODO 需要控制表格溢出滚动高度 */}
<ProTable
className="gn_pro_table"
cardProps={{
bodyStyle: {
padding: '0',
},
}}
search={false}
scroll={{ x: proTableCommonOptions.commscrollX }}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
onChange: (pageNo, pageSize) => setCurrentPageSize(pageSize),
}}
columnsState={{
persistenceKey: 'algorithm_model_list',
persistenceType: 'localStorage',
}}
request={async (params = {}, sort) => {
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 apiModelList({ ...reqParams, ...querysData });
if (!isSuccessApi(resp)) {
return { data: [], success: true };
}
return {
data: resp.data.data,
success: resp.success,
total: resp.data.count,
current: current,
<div className="gn_scroll_list_wrap" style={{ maxHeight: 'calc(100vh - 292px)' }}>
<ProTable
className="gn_pro_table"
cardProps={{
bodyStyle: {
padding: '0',
},
}}
search={false}
scroll={{ x: proTableCommonOptions.commscrollX }}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
};
}}
columns={columns}
/>
onChange: (pageNo, pageSize) => setCurrentPageSize(pageSize),
}}
columnsState={{
persistenceKey: 'algorithm_model_list',
persistenceType: 'localStorage',
}}
request={async (params = {}, sort) => {
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 apiModelList({ ...reqParams, ...querysData });
if (!isSuccessApi(resp)) {
return { data: [], success: true };
}
return {
data: resp.data.data,
success: resp.success,
total: resp.data.count,
current: current,
pageSize: currentPageSize,
};
}}
columns={columns}
/>
</div>
</ProCard>
<CreateForm
createModalOpen={createModalOpen}

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-08 10:36:06
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-06 15:13:25
* @LastEditTime: 2024-06-25 14:16:22
* @FilePath: \general-ai-manage\src\pages\Model\ModelRuntimeLib\index.tsx
* @Description:
* @
@ -241,57 +241,58 @@ const ModelRuntimeLib: React.FC = () => {
</Access>
}
>
{/* // TODO 需要控制表格溢出滚动高度 */}
<ProTable
className="gn_pro_table"
cardProps={{
bodyStyle: {
padding: '0',
},
}}
search={false}
scroll={{ x: proTableCommonOptions.commscrollX }}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
onChange: (pageNo, pageSize) => setCurrentPageSize(pageSize),
}}
columnsState={{
persistenceKey: 'algorithm_model_list',
persistenceType: 'localStorage',
}}
request={async (params = {}) => {
const { current, ...rest } = params;
const reqParams = {
pageNo: current,
...rest,
};
let resp = await apiModelHubList({ ...reqParams, ...querysData });
if (!isSuccessApi(resp)) {
return { data: [], success: true };
}
console.log(resp, 'apiEntityNodesDeviceList_resp');
return {
data: resp.data?.data,
success: resp.success,
total: resp.data.count,
current: current,
<div className="gn_scroll_list_wrap" style={{ maxHeight: 'calc(100vh - 292px)' }}>
<ProTable
className="gn_pro_table"
cardProps={{
bodyStyle: {
padding: '0',
},
}}
search={false}
scroll={{ x: proTableCommonOptions.commscrollX }}
options={{ fullScreen: false, setting: false, density: false, reload: false }}
actionRef={actionRef}
rowKey="id"
onDataSourceChange={(data) => {
console.log(data, 'onDataSourceChange_data');
// let CategoryFkIdIds: any = data.map((v) => {
// return v.categoryFkId;
// });
// setCategoryFkIdIds(CategoryFkIdIds);
}}
pagination={{
...proTablePaginationOptions,
pageSize: currentPageSize,
};
}}
columns={columns}
/>
onChange: (pageNo, pageSize) => setCurrentPageSize(pageSize),
}}
columnsState={{
persistenceKey: 'algorithm_model_list',
persistenceType: 'localStorage',
}}
request={async (params = {}) => {
const { current, ...rest } = params;
const reqParams = {
pageNo: current,
...rest,
};
let resp = await apiModelHubList({ ...reqParams, ...querysData });
if (!isSuccessApi(resp)) {
return { data: [], success: true };
}
console.log(resp, 'apiEntityNodesDeviceList_resp');
return {
data: resp.data?.data,
success: resp.success,
total: resp.data.count,
current: current,
pageSize: currentPageSize,
};
}}
columns={columns}
/>
</div>
</ProCard>
<CreateForm
createModalOpen={createModalOpen}

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-23 17:46:47
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-27 13:39:11
* @LastEditTime: 2024-06-25 13:42:26
* @FilePath: \general-ai-platform-web\src\pages\Project\BusinessInfo\components\accountPsw.tsx
* @Description:
*/
@ -13,7 +13,6 @@ import React, { useEffect } from 'react';
type AccountPswProps = {
info: Record<string, any>;
};
// TODO 企业账号未获取到
const AccountPsw: React.FC<AccountPswProps> = (props) => {
const [form] = ProForm.useForm(); // form 对象
const intl = useIntl();
@ -44,7 +43,7 @@ const AccountPsw: React.FC<AccountPswProps> = (props) => {
<ProForm.Group>
<ProFormText
width="34.45vw"
name="name"
name="phone"
label={
<FormattedMessage id="business_info.list.table.form.name" defaultMessage="企业账号" />
}

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-23 17:00:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-05-27 13:33:14
* @LastEditTime: 2024-06-25 14:03:51
* @FilePath: \general-ai-platform-web\src\pages\Project\BusinessInfo\components\baseInfo.tsx
* @Description:
*
@ -14,7 +14,6 @@ import { FormattedMessage } from '@umijs/max';
type BaseInfoProps = {
info: Record<string, any>;
};
// TODO 行业信息、服务有效期未从接口获取到
const BaseInfo: React.FC<BaseInfoProps> = ({ info }) => {
// 模型基本信息
const ModelDetailColumns = [
@ -39,7 +38,7 @@ const BaseInfo: React.FC<BaseInfoProps> = ({ info }) => {
defaultMessage="服务有效期"
/>
),
dataIndex: 'validity_period',
dataIndex: 'expire_at',
},
{
title: <FormattedMessage id="business.list.table.form.address" defaultMessage="公司地址" />,

@ -15,7 +15,6 @@ import { getBusinessAlgorithmList } from '@/services/testApi/businessProject';
import { isSuccessApi } from '@/utils/forApi';
import { ProCard, ProList } from '@ant-design/pro-components';
import { Button } from 'antd';
import businessLogoIcon from '/public/home/business_logo.svg';
import React, { useEffect, useState } from 'react';
import { proTablePaginationOptions } from '../../../../config/defaultTable';
@ -125,8 +124,7 @@ const BusinessInfo: React.FC = () => {
>
<div className="baseInfo_box">
<div className="flex pb-[12px] items-center">
{/* // TODO 替换使用公司的logo字段 */}
<img src={businessLogoIcon} />
<img src={detailInfo?.logo} />
<div className="pl-[12px]">
<span className="head3 ">{detailInfo?.name}</span>
<div className="text_color_2 pt-[12px]">
@ -141,7 +139,7 @@ const BusinessInfo: React.FC = () => {
<div className="gn_head_card mb-[20px]">
<ProCard className="gn_card_wrap" title={<span className="head3"></span>}>
<AccountPsw info={pwdInfo}></AccountPsw>
<AccountPsw info={{ ...pwdInfo, phone: detailInfo?.phone }}></AccountPsw>
</ProCard>
</div>

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-04-07 14:02:00
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-24 14:36:52
* @LastEditTime: 2024-06-25 14:26:08
* @FilePath: \general-ai-manage\src\pages\BusinessProject\BusinessProject.tsx
* @Description:
* @
@ -11,7 +11,7 @@
* 3.
* # 使city
* # logobase64
* // TODO 本页有警告需要解决
*
*/
import { CommButton, TextButton } from '@/components/Button';
import { isSuccessApi } from '@/utils/forApi';
@ -130,7 +130,7 @@ const BusinessProject: React.FC = () => {
info={item}
renderActions={[
{
key: 'update',
key: 'updateDetail',
renderDom: (
<div
className="action_item_box"

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-05-24 17:57:19
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-11 13:59:11
* @LastEditTime: 2024-06-25 13:58:15
* @FilePath: \general-ai-platform-web\src\services\business\model.ts
* @Description: api
*/
@ -74,7 +74,7 @@ export async function apiModelDeploymentList(body: any, options?: { [key: string
},
);
}
// // 删除企业部署的业务模型
// 删除企业部署的业务模型
export async function apiModelDeploymentDelete(body: any, options?: { [key: string]: any }) {
return request<API.Response & { data?: API.ENTITY_INDEX_DATA; msg?: string }>(
`/api/v1/enterprise/model/deployment/delete`,

@ -2,7 +2,7 @@
* @Author: donghao donghao@supervision.ltd
* @Date: 2024-06-18 13:36:03
* @LastEditors: donghao donghao@supervision.ltd
* @LastEditTime: 2024-06-20 16:22:01
* @LastEditTime: 2024-06-25 14:54:04
* @FilePath: \general-ai-platform-web\src\utils\math.ts
* @Description:
*/
@ -50,7 +50,11 @@ export function mathConvertJoinArrayToString(inputArr: string[]): string {
* @param objectsArray - The array of objects, each containing an 'id' property.
* @returns An array of 'id' values, or an empty array if input is invalid.
*/
export function mathExtractIds(objectsArray: any): (number | string)[] {
export function mathExtractIds(objectsArray: any, formatKey?: string): (number | string)[] {
if (!formatKey) {
// eslint-disable-next-line no-param-reassign
formatKey = 'id';
}
// Check if the input is an array
if (!Array.isArray(objectsArray)) {
console.error('Input is not an array');
@ -59,12 +63,12 @@ export function mathExtractIds(objectsArray: any): (number | string)[] {
// Check if every item in the array is an object and has an 'id' property
for (const obj of objectsArray) {
if (typeof obj !== 'object' || obj === null || !('id' in obj)) {
if (typeof obj !== 'object' || obj === null || !(formatKey in obj)) {
console.error("Invalid object in array or missing 'id' property");
return [];
}
}
// Map the array to extract 'id' properties
return objectsArray.map((obj) => obj.id);
return objectsArray.map((obj) => obj[formatKey]);
}

Loading…
Cancel
Save