diff --git a/src/pages/Project/ProjectList/components/MyCreateForm.tsx b/src/pages/Project/ProjectList/components/MyCreateForm.tsx index 9b55734..32a2ee8 100644 --- a/src/pages/Project/ProjectList/components/MyCreateForm.tsx +++ b/src/pages/Project/ProjectList/components/MyCreateForm.tsx @@ -100,13 +100,17 @@ const MyCreateForm: React.FC<CreateFormProps> = (props) => { setFileList([...curFile]); }; + // todo disabled: !v?.defaultVersionFkId,设置 暂时设置为false 创建成功后报error const getModelData = () => { postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: '' }).then((res) => { + console.log(66666, res.data) let result = (res.data?.list || []).map((v: any) => { + console.log(v) return { key: v.id, title: v.name, chosen: false, + disabled: false, }; }); setModalData(result); @@ -341,7 +345,7 @@ const MyCreateForm: React.FC<CreateFormProps> = (props) => { name="model" title="关联算法模型" stepProps={{ - description: '选择算法模型', + description: '请先为模型设置默认版本', }} onFinish={async () => { return true; diff --git a/src/pages/Resource/AlgorithmModelList/components/Columns.tsx b/src/pages/Resource/AlgorithmModelList/components/Columns.tsx index 98515a5..5d2a3d9 100644 --- a/src/pages/Resource/AlgorithmModelList/components/Columns.tsx +++ b/src/pages/Resource/AlgorithmModelList/components/Columns.tsx @@ -13,7 +13,7 @@ export const AlgorithmModelColumns = [{ title: (<FormattedMessage id="resource.algorithm_model.table.list.categoryFkId" defaultMessage="$$$"/>), - dataIndex: "category_fk_id", + dataIndex: "categoryFkId", },{ title: (<FormattedMessage id="resource.algorithm_model.table.list.remark" @@ -23,10 +23,13 @@ export const AlgorithmModelColumns = [{ title: (<FormattedMessage id="resource.algorithm_model.table.list.createTime" defaultMessage="$$$"/>), - dataIndex: "create_time", + dataIndex: "createTime", + valueType: 'dateTime', },{ title: (<FormattedMessage id="resource.algorithm_model.table.list.updateTime" defaultMessage="$$$"/>), - dataIndex: "update_time", + dataIndex: "updateTime", + valueType: 'dateTime', },] + diff --git a/src/pages/Resource/AlgorithmModelList/detail.tsx b/src/pages/Resource/AlgorithmModelList/detail.tsx index c4d5801..0f5b349 100644 --- a/src/pages/Resource/AlgorithmModelList/detail.tsx +++ b/src/pages/Resource/AlgorithmModelList/detail.tsx @@ -1,4 +1,7 @@ -import { postAlgorithmModelGetAlgorithmModelById } from '@/services/resource/AlgorithmModel'; +import { + postAlgorithmModelGetAlgorithmModelById, + putAlgorithmModelUpdateAlgorithmModel +} from '@/services/resource/AlgorithmModel'; import { deleteModelVersionDeleteModelVersion, postModelVersionGetModelVersionList } from '@/services/resource/ModelVersion'; import { ArrowLeftOutlined, PlusOutlined } from '@ant-design/icons'; import { @@ -17,7 +20,9 @@ import MyCreateForm from '../ModelVersionList/components/MyCreateForm'; import TableActionCard from '@/components/TableActionCard'; import IsDelete from '@/components/TableActionCard/isDelete'; import UpdateForm from '../ModelVersionList/components/UpdateForm'; - +import {proTableCommonOptions} from "../../../../config/defaultTable"; +import {AlgorithmModelColumns} from "./components/Columns" +import IsConfirmAction from "@/components/TableActionCard/isConfirmAction"; /**styles */ const detailStylesProps = { @@ -66,35 +71,20 @@ const AlgorithmModelDetail: React.FC = () => { dataIndex: 'id', sorter: true, }, - - { - title: ( - <FormattedMessage id="resource.model_version.table.list.modelFkId" defaultMessage="$$$" /> - ), - dataIndex: 'modelFkId', - hideInSearch: false, - }, - + + { title: <FormattedMessage id="resource.model_version.table.list.version" defaultMessage="$$$" />, dataIndex: 'version', hideInSearch: true, }, - + { title: <FormattedMessage id="resource.model_version.table.list.path" defaultMessage="$$$" />, dataIndex: 'path', hideInSearch: true, }, - - { - title: ( - <FormattedMessage id="resource.model_version.table.list.startCode" defaultMessage="$$$" /> - ), - dataIndex: 'startCode', - hideInSearch: true, - }, - + { title: ( <FormattedMessage id="resource.model_version.table.list.isEnable" defaultMessage="$$$" /> @@ -105,7 +95,7 @@ const AlgorithmModelDetail: React.FC = () => { hideInSearch: true, valueType: 'switch', }, - + { title: <FormattedMessage id="resource.model_version.table.list.remark" defaultMessage="$$$" />, dataIndex: 'remark', @@ -123,7 +113,7 @@ const AlgorithmModelDetail: React.FC = () => { 5: { text: '已关闭', status: 'Error' }, }, }, - + { title: ( <FormattedMessage id="resource.model_version.table.list.createTime" defaultMessage="$$$" /> @@ -133,7 +123,7 @@ const AlgorithmModelDetail: React.FC = () => { hideInSearch: true, valueType: 'dateTime', }, - + { title: ( <FormattedMessage id="resource.model_version.table.list.updateTime" defaultMessage="$$$" /> @@ -152,6 +142,32 @@ const AlgorithmModelDetail: React.FC = () => { <TableActionCard key="TableActionCardRef" renderActions={[ + { + key: 'default', + renderDom: ( + <IsConfirmAction + title="设为默认" + buttonText="设为默认" + confirmAction={() => { + // setPublishModalOpen(true); + putAlgorithmModelUpdateAlgorithmModel({ + id: record.modelFkId, + defaultVersionFkId: record.id, + }) + .then(() => { + message.success( + intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' }), + ); + }) + .catch(() => { + message.error( + intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' }), + ); + }); + }} + ></IsConfirmAction> + ), + }, { key: 'update', renderDom: ( @@ -243,7 +259,7 @@ const AlgorithmModelDetail: React.FC = () => { column={4} title="模型详细信息" tooltip="包含了模型详细信息" - columns={columns} + columns={AlgorithmModelColumns} request={async () => { console.log(routeParams, 'id'); const resp = await postAlgorithmModelGetAlgorithmModelById({ @@ -284,9 +300,12 @@ const AlgorithmModelDetail: React.FC = () => { actionRef={actionRef} tableStyle={{ paddingTop: 15, paddingBottom: 15 }} columns={columns} + scroll={{ + x: proTableCommonOptions.scrollX, + }} cardBordered toolBarRender={() => [ - + ]} request={async (params = {}, sort) => { const { current, ...rest } = params; diff --git a/src/pages/Resource/ModelImageList/components/CreateForm.tsx b/src/pages/Resource/ModelImageList/components/CreateForm.tsx index af40af0..bc64969 100644 --- a/src/pages/Resource/ModelImageList/components/CreateForm.tsx +++ b/src/pages/Resource/ModelImageList/components/CreateForm.tsx @@ -4,6 +4,7 @@ import { ModalForm, ProForm, ProFormDependency, + ProFormTextArea, ProFormSelect, ProFormText, } from '@ant-design/pro-components'; @@ -53,12 +54,12 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { return false; } - if (!isValidIPv4(form.getFieldValue('IP'))) { + if (!isValidIPv4(form.getFieldValue('ip'))) { message.warning('无效的服务器地址'); return; } - if (!isValidPort(form.getFieldValue('IPPort'))) { + if (!isValidPort(form.getFieldValue('ipPort'))) { message.warning('无效的端口'); return; } @@ -66,7 +67,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { setIsFlag(true); } - const handleResponse = (data) => { + const handleResponse = (data: any) => { console.log(data, 'handleResponse'); // 对返回的数据进行处理 }; @@ -74,15 +75,16 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { async function postCurrentIP() { // http://192.168.10.96:5003/v2/_catalog const resp = await axios.get( - `http://${form.getFieldValue('IP')}:${form.getFieldValue('IPPort')}/v2/_catalog`, + `http://${form.getFieldValue('ip')}:${form.getFieldValue('ipPort')}/v2/_catalog`, ); console.log(resp, 'resp'); return resp?.data; } - async function doChangeUseIPPort() { + async function doChangeUseipPort() { + form.setFieldValue('imageVersion', null) const resp = await axios.get( - `http://${form.getFieldValue('IP')}:${form.getFieldValue('IPPort')}/v2/${form.getFieldValue('useIPPort')}/tags/list`, + `http://${form.getFieldValue('ip')}:${form.getFieldValue('ipPort')}/v2/${form.getFieldValue('imageName')}/tags/list`, ); let finalData = resp?.data?.tags?.map((v: any) => { return { @@ -108,7 +110,7 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { } return ( - <ModalForm<API.ModelImage> + <ModalForm<API.ModelImage & {imageName?: string, imageVersion?: string, ip?: string, ipPort?: string }> width={proFormModelWidth} title={intl.formatMessage({ id: 'resource.model_image.table.list.add', @@ -123,6 +125,9 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { }} submitTimeout={2000} onFinish={async (values) => { + console.log(4444, values) + // let imageId = `${values.ip}:${values.ipPort}/${values.imageName}:${values.imageVersion}` + // console.log(5555, imageId) postModelImageCreateModelImage(values) .then(() => { message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); @@ -162,40 +167,10 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { }, ]} /> - <ProFormSelect - width={proFormItemStyleProps.column2Width} - name="modelVersionFkId" - label={ - <FormattedMessage - id="resource.model_image.table.list.modelVersionFkId" - defaultMessage="$$$" - /> - } - placeholder={`${intl.formatMessage({ - id: 'common.please_select', - defaultMessage: '$$$', - })}${intl.formatMessage({ - id: 'resource.model_image.table.list.modelVersionFkId', - defaultMessage: '$$$', - })}`} - required={true} - showSearch - debounceTime={1000} - request={async (keyWord) => { - const resp = await postModelVersionGetModelVersionFkSelect({ - keyword: keyWord?.keyWords || '', - }); - return resp.data.list.map((v: any) => { - return { - label: v.name, - value: v.id, - }; - }); - }} - /> <ProFormText width={proFormItemStyleProps.column2Width} name="path" + tooltip={'请在下方填入镜像服务器地址'} label={ <FormattedMessage id="resource.model_image.table.list.path" defaultMessage="$$$" /> } @@ -206,40 +181,22 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { id: 'resource.model_image.table.list.path', defaultMessage: '$$$', })}`} - required={false} - /> - <ProFormText - width={proFormItemStyleProps.column2Width} - name="startCode" - label={ - <FormattedMessage id="resource.model_image.table.list.startCode" defaultMessage="$$$" /> - } - placeholder={`${intl.formatMessage({ - id: 'common.please_input', - defaultMessage: '$$$', - })}${intl.formatMessage({ - id: 'resource.model_image.table.list.startCode', - defaultMessage: '$$$', - })}`} - required={false} - /> - <ProFormText - width={proFormItemStyleProps.column2Width} - name="remark" - label={ - <FormattedMessage id="resource.model_image.table.list.remark" defaultMessage="$$$" /> - } - placeholder={`${intl.formatMessage({ - id: 'common.please_input', - defaultMessage: '$$$', - })}${intl.formatMessage({ - id: 'resource.model_image.table.list.remark', - defaultMessage: '$$$', - })}`} - required={false} + required={true} + disabled={true} + rules={[ + { + required: true, + message: ( + <FormattedMessage + id="resource.model_image.table.rule.required.path" + defaultMessage="path is required" + /> + ), + }, + ]} /> - {/* + {/* // TODO update联动查询 */} @@ -252,22 +209,24 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { <Space> <ProFormText width={180} - name="IP" + name="ip" label={'IP地址'} + initialValue={"192.168.10.60"} placeholder={'请输入IP地址'} required={false} - onChange={() => { - setIsFlag(false); - }} + fieldProps={{onChange: () => { + setIsFlag(false)} + }} /> <ProFormText width={110} - name="IPPort" + name="ipPort" label={'端口号'} placeholder={'请输入端口号'} + initialValue={"5000"} required={false} - onChange={() => { - setIsFlag(false); + fieldProps={{onChange: () => { + setIsFlag(false)} }} /> <Button style={{ marginTop: 15 }} type="primary" onClick={() => doFindIPNext()}> @@ -276,14 +235,14 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { </Space> {isFlag ? ( <> - <ProFormDependency name={['IP']}> - {({ IP }) => { - if (IP) { + <ProFormDependency name={['ip']}> + {({ ip }) => { + if (ip) { return ( <ProFormSelect width={175} - name="useIPPort" - label="选择1" + name="imageName" + label="镜像名称" debounceTime={1000} request={async () => { const resp = await postCurrentIP(); @@ -294,21 +253,25 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { }; }); }} - onChange={() => doChangeUseIPPort()} + onChange={() => doChangeUseipPort()} /> ); } return <></>; }} </ProFormDependency> - <ProFormDependency name={['useIPPort']}> - {({ useIPPort }) => { - if (useIPPort) { + <ProFormDependency name={['imageName', 'ip', 'ipPort', 'imageName']}> + {({ imageName, ip, ipPort }) => { + if (imageName) { return ( <ProFormSelect width={175} - name="useMode2" - label="选择2" + onChange={(value) =>{ + console.log(`${ip}:${ipPort}/${imageName}:${value}`) + form.setFieldValue('path', `${ip}:${ipPort}/${imageName}:${value}`) + }} + name="imageVersion" + label="镜像版本" debounceTime={1000} options={mode2Options} /> @@ -319,9 +282,40 @@ const CreateForm: React.FC<CreateFormProps> = (props) => { </ProFormDependency> </> ) : ( - '' + <></> )} </ProForm.Group> + <ProFormTextArea + width={proFormItemStyleProps.column2Width} + name="startCode" + label={ + <FormattedMessage id="resource.model_image.table.list.startCode" defaultMessage="$$$" /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'resource.model_image.table.list.startCode', + defaultMessage: '$$$', + })}`} + required={false} + /> + <ProFormText + width={proFormItemStyleProps.column2Width} + name="remark" + label={ + <FormattedMessage id="resource.model_image.table.list.remark" defaultMessage="$$$" /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'resource.model_image.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + /> + </ProForm.Group> </ModalForm> ); diff --git a/src/pages/Resource/ModelVersionList/components/MyCreateForm.tsx b/src/pages/Resource/ModelVersionList/components/MyCreateForm.tsx index 0af975b..91ce84a 100644 --- a/src/pages/Resource/ModelVersionList/components/MyCreateForm.tsx +++ b/src/pages/Resource/ModelVersionList/components/MyCreateForm.tsx @@ -24,10 +24,14 @@ import { Form, Modal, UploadFile, message } from 'antd'; import yaml from 'js-yaml'; import React, { useEffect, useRef, useState } from 'react'; import { + proFormItemStyleProps, proFormMaxItemStyleProps, proFormMaxModelWidth, proFormStepsFormProps, } from '../../../../../config/defaultForm'; +import {beforeUploadFile} from "@/utils/common"; +// @ts-ignore +import cookie from 'react-cookies'; export type FormValueType = { target?: string; @@ -89,6 +93,7 @@ const MyCreateForm: React.FC<MyCreateFormProps> = (props) => { const [current, setCurrent] = useState(0); const formRef = useRef<ProFormInstance>(); const [configData, setConfigData] = useState<ProjectConfig>({ params: [] }); + const [filePath, setFilePath] = useState(''); @@ -203,61 +208,51 @@ const MyCreateForm: React.FC<MyCreateFormProps> = (props) => { required={false} /> - <ProFormText - width={proFormMaxItemStyleProps.column2Width} - name="startCode" - label={ - <FormattedMessage - id="resource.model_version.table.list.startCode" - defaultMessage="$$$" - /> - } - placeholder={`${intl.formatMessage({ - id: 'common.please_input', - defaultMessage: '$$$', - })}${intl.formatMessage({ - id: 'resource.model_version.table.list.startCode', - defaultMessage: '$$$', - })}`} - required={false} - /> - <ProFormSwitch - width={proFormMaxItemStyleProps.column2Width} - name="isEnable" - label={ - <FormattedMessage - id="resource.model_version.table.list.isEnable" - defaultMessage="$$$" - /> - } - initialValue={true} - /> - <ProFormText - width={proFormMaxItemStyleProps.column2Width} - name="path" - label={ - <FormattedMessage id="resource.model_version.table.list.path" defaultMessage="$$$" /> - } - placeholder={`${intl.formatMessage({ - id: 'common.please_input', - defaultMessage: '$$$', - })}${intl.formatMessage({ - id: 'resource.model_version.table.list.path', - defaultMessage: '$$$', - })}`} - required={true} - rules={[ - { - required: true, - message: ( - <FormattedMessage - id="resource.model_version.table.rule.required.path" - defaultMessage="path is required" - /> - ), - }, - ]} - /> + {/*<ProFormText*/} + {/* width={proFormMaxItemStyleProps.column2Width}*/} + {/* name="startCode"*/} + {/* label={*/} + {/* <FormattedMessage*/} + {/* id="resource.model_version.table.list.startCode"*/} + {/* defaultMessage="$$$"*/} + {/* />*/} + {/* }*/} + {/* placeholder={`${intl.formatMessage({*/} + {/* id: 'common.please_input',*/} + {/* defaultMessage: '$$$',*/} + {/* })}${intl.formatMessage({*/} + {/* id: 'resource.model_version.table.list.startCode',*/} + {/* defaultMessage: '$$$',*/} + {/* })}`}*/} + {/* required={false}*/} + {/*/>*/} + + {/*<ProFormText*/} + {/* width={proFormMaxItemStyleProps.column2Width}*/} + {/* name="path"*/} + {/* label={*/} + {/* <FormattedMessage id="resource.model_version.table.list.path" defaultMessage="$$$" />*/} + {/* }*/} + {/* placeholder={`${intl.formatMessage({*/} + {/* id: 'common.please_input',*/} + {/* defaultMessage: '$$$',*/} + {/* })}${intl.formatMessage({*/} + {/* id: 'resource.model_version.table.list.path',*/} + {/* defaultMessage: '$$$',*/} + {/* })}`}*/} + {/* required={true}*/} + {/* rules={[*/} + {/* {*/} + {/* required: true,*/} + {/* message: (*/} + {/* <FormattedMessage*/} + {/* id="resource.model_version.table.rule.required.path"*/} + {/* defaultMessage="path is required"*/} + {/* />*/} + {/* ),*/} + {/* },*/} + {/* ]}*/} + {/*/>*/} <ProFormText width={proFormMaxItemStyleProps.column2Width} name="remark" @@ -276,8 +271,53 @@ const MyCreateForm: React.FC<MyCreateFormProps> = (props) => { })}`} required={false} /> + <ProFormSwitch + width={proFormMaxItemStyleProps.column2Width} + name="isEnable" + label={ + <FormattedMessage + id="resource.model_version.table.list.isEnable" + defaultMessage="$$$" + /> + } + initialValue={true} + /> </ProForm.Group> </StepsForm.StepForm> + + <StepsForm.StepForm<{ + project_file: string; + }> + name="project_file" + title="上传模型文件" + style={{ width: proFormItemStyleProps.width }} + stepProps={{ + description: '上传模型文件格式为(.zip,.tar.gz)', + }} + onFinish={async (values: any) => { + if ('projectFilePath' in values && values['projectFilePath'].length > 0) { + let projectFilePath = values['projectFilePath'][0]?.response?.data?.path || ''; + setFilePath(projectFilePath); + } + return true; + }} + > + <ProFormUploadDragger + label={<span className='h3 gn'>上传文件</span>} + name="projectFilePath" + action="/api/v1/file/uploadFile" + max={1} + fieldProps={{ + name: 'file', + // beforeUpload: beforeUploadFile, + data: { path: `models/${Date.now()}` }, + headers: { + 'X-CSRFToken': cookie.load('csrftoken'), + Authorization: `Bearer ${localStorage.getItem('access') || ''}`, + }, + }} + /> + </StepsForm.StepForm> <StepsForm.StepForm<{ config: string; }> @@ -292,6 +332,9 @@ const MyCreateForm: React.FC<MyCreateFormProps> = (props) => { if (formData?.modelFkId) { await waitTime(500); formData.modelConfig = { params: values?.params || [] }; + if (filePath) { + formData.path = filePath + } postModelVersionCreateModelVersion(formData) .then(() => { message.success( diff --git a/src/pages/Setting/AlgorithmSetting.tsx b/src/pages/Setting/AlgorithmSetting.tsx index e723bf6..dbd41f3 100644 --- a/src/pages/Setting/AlgorithmSetting.tsx +++ b/src/pages/Setting/AlgorithmSetting.tsx @@ -80,7 +80,7 @@ const AlgorithmSetting: React.FC = () => { { title: ( - <FormattedMessage id="device.device_group.table.list.createTime" defaultMessage="$$$" /> + <FormattedMessage id="device.device_group.table.list.createTime" defaultMessage="$$$" /> ), dataIndex: 'createTime', sorter: true, @@ -90,7 +90,7 @@ const AlgorithmSetting: React.FC = () => { { title: ( - <FormattedMessage id="device.device_group.table.list.updateTime" defaultMessage="$$$" /> + <FormattedMessage id="device.device_group.table.list.updateTime" defaultMessage="$$$" /> ), dataIndex: 'updateTime', sorter: true, @@ -126,38 +126,38 @@ const AlgorithmSetting: React.FC = () => { console.log(resp.data.list); let model_data = ([...v?.models] || []).map((item: any) => ({ content: ( - <ProCard - style={{ backgroundColor: 'rgba(21, 91, 212, 0.03)' }} - bodyStyle={{ margin: 0, padding: 0 }} - > - <div - style={{ - display: 'flex', - alignItems: 'center', - padding: 15, - justifyContent: 'space-between', - }} + <ProCard + style={{ backgroundColor: 'rgba(21, 91, 212, 0.03)' }} + bodyStyle={{ margin: 0, padding: 0 }} > - <div> - <img src="/images/icons/logo.svg" alt="" style={{ width: '64px' }} /> - </div> - <Button - type="link" - size="small" - key={item.configId} - style={{ padding: 0, fontWeight: 700 }} - onClick={() => { - setProjectData(item); - console.log(item, 'setProjectData_item', projectData); - setProjectConfigId(item.configId); - handleUpdateModal(); - }} + <div + style={{ + display: 'flex', + alignItems: 'center', + padding: 15, + justifyContent: 'space-between', + }} > - 配置参数 - </Button> - </div> - <ProjectCard info={item}></ProjectCard> - </ProCard> + <div> + <img src="/images/icons/logo.svg" alt="" style={{ width: '64px' }} /> + </div> + <Button + type="link" + size="small" + key={item.configId} + style={{ padding: 0, fontWeight: 700 }} + onClick={() => { + setProjectData(item); + console.log(item, 'setProjectData_item', projectData); + setProjectConfigId(item.configId); + handleUpdateModal(); + }} + > + 配置参数 + </Button> + </div> + <ProjectCard info={item}></ProjectCard> + </ProCard> ), })); setModelData(model_data); @@ -184,34 +184,34 @@ const AlgorithmSetting: React.FC = () => { subTitle: <Tag color="#5BD8A6">经典算法</Tag>, avatar: 'https://gw.alipayobjects.com/zos/antfincdn/UCSiy1j6jx/xingzhuang.svg', content: ( - <ProCard bodyStyle={{ margin: 0, padding: 0 }}> - <div - style={{ - display: 'flex', - alignItems: 'center', - padding: 15, - justifyContent: 'space-between', - }} - > - <div> - <div>{JSON.stringify(item.configId)}</div> - <img src="/images/model.png" alt="" style={{ width: '64px' }} /> - </div> - <Button - type="link" - size="small" - key={item.configId} - style={{ padding: 0 }} - onClick={() => { - setProjectConfigId(item.configId); - handleUpdateModal(); - }} + <ProCard bodyStyle={{ margin: 0, padding: 0 }}> + <div + style={{ + display: 'flex', + alignItems: 'center', + padding: 15, + justifyContent: 'space-between', + }} > - 配置 - </Button> - </div> - <ProjectCard info={item}></ProjectCard> - </ProCard> + <div> + <div>{JSON.stringify(item.configId)}</div> + <img src="/images/model.png" alt="" style={{ width: '64px' }} /> + </div> + <Button + type="link" + size="small" + key={item.configId} + style={{ padding: 0 }} + onClick={() => { + setProjectConfigId(item.configId); + handleUpdateModal(); + }} + > + 配置 + </Button> + </div> + <ProjectCard info={item}></ProjectCard> + </ProCard> ), }; }); @@ -227,180 +227,175 @@ const AlgorithmSetting: React.FC = () => { } useEffect(() => { postDeviceGroupGetDeviceGroupTree() - .then((resp) => { - setNodeTreeData(resp.data.tree); - setHasInit(true); - }) - .catch(() => { - message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); - }); + .then((resp) => { + setNodeTreeData(resp.data.tree); + setHasInit(true); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); }, []); return ( - <PageContainer className="algorithmSetting_project_box gn"> - <TreeAndTableList - leftCard={ - { - title: '网点选择', - } as ProCardTypeProps - } - leftDom={ - hasInit && ( - <Tree - checkable={false} - defaultExpandAll={true} - selectedKeys={selectNodes} - treeData={nodeTreeData} - onSelect={(selectKeys, info) => { - // TODO_1 此处接口需要重新联调 - console.log(info.node, 'onSelect_info'); - setSelectNodes(selectKeys); - fetchProjectInfoByGroupId(info?.node); - fetchProjectByGroupId(info?.node); - actionRef.current?.reload(); - }} - checkStrictly={false} - /> - ) - } - rightDom={ - <> - <ProCard - title="网点详细信息" - headStyle={{ borderBottom: '1px solid #E0E0E0', padding: '0px 16px 16px' }} - style={{ background: 'transparent', paddingTop: 16 }} - bodyStyle={{ padding: '16px 16px 0px' }} - colSpan="80%" - > - <ProDescriptions - column={3} - dataSource={currentRow} - columns={columns} - ></ProDescriptions> - </ProCard> - {tabs?.length ? ( + <PageContainer className="algorithmSetting_project_box gn"> + <TreeAndTableList + leftCard={ + { + title: '网点选择', + } as ProCardTypeProps + } + leftDom={ + hasInit && ( + <Tree + checkable={false} + defaultExpandAll={true} + selectedKeys={selectNodes} + treeData={nodeTreeData} + onSelect={(selectKeys, info) => { + // TODO_1 此处接口需要重新联调 + console.log(info.node, 'onSelect_info'); + setSelectNodes(selectKeys); + fetchProjectInfoByGroupId(info?.node); + fetchProjectByGroupId(info?.node); + actionRef.current?.reload(); + }} + checkStrictly={false} + /> + ) + } + rightDom={ <> - <Tabs - activeKey={tab} - items={tabs} - onChange={(key) => { - setActiveMode('1'); // 重置到项目详情 - changeProjectTab(key); - }} - ></Tabs> - <ProCard bodyStyle={{ padding: 0, margin: 0 }} style={{ padding: 0, margin: 0 }}> - <ul - className="algorithmSetting_mode_box" - style={{ display: 'flex', padding: '0 16px', margin: 0 }} - > - {tabModeList.map((item) => { - // TODO 统一使用button默认效果 'primary' : 'default' - return ( - <li - key={item.value} - className={item.value === activeMode ? 'active' : ''} - onClick={() => changeMode(item)} - style={{ - padding: '16px 12px 0 0', + <ProCard + title="网点详细信息" + headStyle={{ borderBottom: '1px solid #E0E0E0', padding: '0px 16px 16px' }} + style={{ background: 'transparent', paddingTop: 16 }} + bodyStyle={{ padding: '16px 16px 0px' }} + colSpan="80%" + > + <ProDescriptions + column={3} + dataSource={currentRow} + columns={columns} + ></ProDescriptions> + </ProCard> + {tabs?.length ? ( + <> + <Tabs + activeKey={tab} + items={tabs} + onChange={(key) => { + setActiveMode('1'); // 重置到项目详情 + changeProjectTab(key); }} + ></Tabs> + <ProCard bodyStyle={{ padding: 0, margin: 0 }} style={{ padding: 0, margin: 0 }}> + <ul + className="algorithmSetting_mode_box" + style={{ display: 'flex', padding: '0 16px', margin: 0 }} > - <Button type="default">{item.label}</Button> - </li> - ); - })} - </ul> + {tabModeList.map((item) => { + return ( + <li + key={item.value} + className={item.value === activeMode ? 'active' : ''} + onClick={() => changeMode(item)} + style={{ + padding: '16px 12px 0 0', + }} + > + <Button type="default">{item.label}</Button> + </li> + ); + })} + </ul> - {/* 项目 */} - {activeMode === '1' ? ( - <> - <div - style={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'space-between', - padding: '16px 16px 3px', - }} - > - <span style={{ fontSize: 16, fontWeight: 700 }}>模型列表</span> - {/* // TODO 需要对接接口 */} - {false ? ( - <Button type="primary" danger> - <PauseOutlined style={{ fontSize: 14, lineHeight: 1.5 }} /> - 结束运行 - </Button> + {/* 项目 */} + {activeMode === '1' ? ( + <> + <div + style={{ + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + padding: '16px 16px 3px', + }} + > + <span style={{ fontSize: 16, fontWeight: 700 }}>模型列表</span> + {/* // TODO 需要对接接口 */} + {( + <Button type="primary"> + <CaretRightOutlined style={{fontSize: 14, lineHeight: 1.5}}/> + 开始运行 + </Button> + )} + </div> + <ProList<any> + actionRef={actionRef} + style={{ + padding: '0px 16px 16px', + }} + className="gn" + ghost={true} + itemCardProps={{ + ghost: true, + bodyStyle: { padding: 0, margin: 0 }, + }} + pagination={{ + defaultPageSize: 6, + showSizeChanger: false, + }} + showActions="hover" + grid={{ gutter: 8, xs: 1, md: 2, xl: 3, xxl: 4 }} + metas={{ + type: {}, + content: {}, + actions: { + cardActionProps: 'extra', + }, + }} + dataSource={modelData} + /> + </> ) : ( - <Button type="primary"> - <CaretRightOutlined style={{ fontSize: 14, lineHeight: 1.5 }} /> - 开始运行 - </Button> + <div style={{ padding: 16 }}> + <AlarmSetForm + currentRow={{ + type: '2', + ways: [ + { + label: '短信', + value: [], + isChecked: [], + }, + { + label: '邮件', + value: [], + isChecked: [], + }, + ], + }} + ></AlarmSetForm> + </div> )} - </div> - <ProList<any> - style={{ - padding: '0px 16px 16px', - }} - className="gn" - ghost={true} - itemCardProps={{ - ghost: true, - bodyStyle: { padding: 0, margin: 0 }, - }} - pagination={{ - defaultPageSize: 6, - showSizeChanger: false, - }} - showActions="hover" - grid={{ gutter: 8, xs: 1, md: 2, xl: 3, xxl: 4 }} - metas={{ - type: {}, - content: {}, - actions: { - cardActionProps: 'extra', - }, - }} - dataSource={modelData} - /> + </ProCard> </> - ) : ( - <div style={{ padding: 16 }}> - <AlarmSetForm - currentRow={{ - type: '2', - ways: [ - { - label: '短信', - value: [], - isChecked: [], - }, - { - label: '邮件', - value: [], - isChecked: [], - }, - ], - }} - ></AlarmSetForm> - </div> - )} - </ProCard> - </> - ) : ( - <> - <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> + ) : ( + <> + <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} /> + </> + )} </> - )} - </> - } - ></TreeAndTableList> - <UpdateForm - projectData={projectData as Record<string, any>} - updateModalOpen={updateModalOpen} - handleModal={handleUpdateModal} - groupId={currentRow?.id || 0} - reload={actionRef.current?.reload} - projectModelConfigId={projectConfigId} - /> - </PageContainer> + } + ></TreeAndTableList> + <UpdateForm + projectData={projectData as Record<string, any>} + updateModalOpen={updateModalOpen} + handleModal={handleUpdateModal} + groupId={currentRow?.id || 0} + reload={actionRef.current?.reload} + projectModelConfigId={projectConfigId} + /> + </PageContainer> ); }; diff --git a/src/pages/Setting/components/UpdateForm.tsx b/src/pages/Setting/components/UpdateForm.tsx index f6b7d35..c1f51e0 100644 --- a/src/pages/Setting/components/UpdateForm.tsx +++ b/src/pages/Setting/components/UpdateForm.tsx @@ -18,6 +18,7 @@ import { useIntl } from '@umijs/max'; import { Modal, message } from 'antd'; import React, { useEffect, useState } from 'react'; import { proFormMaxItemStyleProps, proFormMaxModelWidth } from '../../../../config/defaultForm'; +import {postModelImageGetModelImageFkSelect} from "@/services/resource/ModelImage"; /**styles */ const modelParamsFormItemProps = { @@ -226,12 +227,12 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { return ( // eslint-disable-next-line react/jsx-key <div + key={index} style={{ width: modelParamsFormItemProps.width, }} > <ProFormSwitch - key={index} name={item.name} label={item.name} initialValue={item.value} @@ -250,8 +251,6 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { tooltip={item.remark} /> ); - } else { - return <></>; } })} </div> @@ -261,6 +260,50 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { </ProForm.Group> </> </StepsForm.StepForm> + <StepsForm.StepForm<{ + config: string; + }> + name="image" + title="镜像配置" + stepProps={{ + description: '镜像选择', + }} + onFinish={async (values: any) => { + configResult.imageFkId = values.imageFkId; + return true; + }} + > + <> + <ProForm.Group> + {renderProjectItems()} + {isInit && projectModelConfig.modelFkId && projectModelConfig.modelFkId !== 0 && ( + <ProFormSelect + width={proFormMaxItemStyleProps.width} + name="imageFkId" + label={ + <> + <span className="gn h4">基础镜像 </span> + <span className="gn des_1"> (选择基础镜像)</span> + </> + } + onChange={handleSelectChange} + initialValue={projectModelConfig.imageFkId} + // dependencies 的内容会注入 request 中 + request={async () => { + let resp = await postModelImageGetModelImageFkSelect({ + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + )} + </ProForm.Group> + </> + </StepsForm.StepForm> <StepsForm.StepForm<{ config: string; }> @@ -404,7 +447,7 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { </> </StepsForm.StepForm> - {/* 关联算法模型 */} + {/* 设备关联配置 */} <StepsForm.StepForm<{ config: string; @@ -415,7 +458,9 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { description: '设备关联配置', }} onFinish={async () => { + console.log(targetKeys, 'targetKeys') configResult.devices = targetKeys.join(','); + console.log(configResult.devices, 'targetKeys') configResult.id = props.projectModelConfigId; putProjectModelConfigUpdateProjectModelConfig(configResult) .then(() => { @@ -424,7 +469,8 @@ const UpdateForm: React.FC<UpdateFormProps> = (props) => { props.reload(); return true; }) - .catch(() => { + .catch((err) => { + console.log(err) message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); return false; }); diff --git a/src/pages/System/OperationRecordList/index.tsx b/src/pages/System/OperationRecordList/index.tsx index 37e3c26..e1048c5 100644 --- a/src/pages/System/OperationRecordList/index.tsx +++ b/src/pages/System/OperationRecordList/index.tsx @@ -298,7 +298,7 @@ const OperationRecordList: React.FC = () => { },]; return ( <PageContainer> - <ProTable<API.OperationRecord, API.ApiListResponse> + <ProTable<API.OperationRecord> headerTitle={intl.formatMessage({ id: 'pages.searchTable.title', defaultMessage: '$$$', diff --git a/src/pages/Welcome/components/FootInfoCard.tsx b/src/pages/Welcome/components/FootInfoCard.tsx index 9701cb9..1155188 100644 --- a/src/pages/Welcome/components/FootInfoCard.tsx +++ b/src/pages/Welcome/components/FootInfoCard.tsx @@ -18,10 +18,10 @@ const { useState } = React; // static data 静态数据 const data = [ - { rank: 1, keyword: '网点一', users: 1000, range: 37, status: 1 }, - { rank: 2, keyword: '网点二', users: 800, range: 62, status: 1 }, - { rank: 3, keyword: '网点三', users: 1500, range: 20, status: 0 }, - { rank: 4, keyword: '网点四', users: 1200, range: 36, status: 0 }, + { rank: 1, keyword: '产线A01', users: 100, range: 37, status: 1 }, + { rank: 2, keyword: '产线A02', users: 80, range: 62, status: 1 }, + { rank: 3, keyword: '产线A03', users: 150, range: 20, status: 0 }, + { rank: 4, keyword: '产线A04', users: 120, range: 36, status: 0 }, // 添加更多数据项 ]; @@ -88,9 +88,9 @@ const trendItemHeadStyle = { padding: 0 }; /**state 初始化数据 */ const offendingTrendData: Record<string, any>[] = [ - { label: '玩手机', value1: 11093, value2: '17.1', status: 0 }, - { label: '打瞌睡', value1: 26, value2: '27.1', status: 1 }, - { label: '离岗', value1: 145, value2: '37.1', status: 1 }, + { label: '表面缺陷', value1: 204, value2: '17.1', status: 0 }, + { label: '抽烟检测', value1: 26, value2: '27.1', status: 1 }, + { label: '划痕检测', value1: 145, value2: '37.1', status: 1 }, ]; /**methods 事件交互 */ @@ -158,7 +158,7 @@ const DonutChart: React.FC = () => { legend: { orient: 'vertical', left: 10, - data: ['玩手机', '打瞌睡', '离岗'], + data: ['表面缺陷', '划痕检测', '抽烟检测'], }, series: [ { @@ -182,9 +182,9 @@ const DonutChart: React.FC = () => { show: false, }, data: [ - { value: 235, name: '玩手机'}, - { value: 510, name: '打瞌睡' }, - { value: 134, name: '离岗' }, + { value: 235, name: '表面缺陷'}, + { value: 510, name: '划痕检测' }, + { value: 134, name: '抽烟检测' }, ], }, ], @@ -232,7 +232,7 @@ const FootInfoCard: React.FC = () => { <ProCard key="resize-observer" wrap gutter={24} bodyStyle={{ marginTop: 40, padding: 0 }}> <ProCard gutter={24} - title="线上热门搜索" + title="车间异常汇总" headStyle={footItemHeadStyleProps} colSpan={footItemColSpanProps} bodyStyle={{ margin: 0, padding: 0 }} diff --git a/src/pages/Welcome/components/NavInfoCardList.tsx b/src/pages/Welcome/components/NavInfoCardList.tsx index 5389737..d810463 100644 --- a/src/pages/Welcome/components/NavInfoCardList.tsx +++ b/src/pages/Welcome/components/NavInfoCardList.tsx @@ -49,7 +49,7 @@ const NavInfoCardList: React.FC = () => { } colSpan={topColSpanProps} style={topItemStyle} - + > <StatisticCard bodyStyle={{ padding: 0, backgroundColor: '#FFFAF5' }} @@ -91,7 +91,7 @@ const NavInfoCardList: React.FC = () => { } colSpan={topColSpanProps} style={topItemStyle1} - + > <StatisticCard bodyStyle={{ padding: 0, backgroundColor: '#F5F8FF' }} @@ -130,7 +130,7 @@ const NavInfoCardList: React.FC = () => { gutter={24} wrap ghost - title="覆盖网点" + title="覆盖车间" headStyle={topItemHeadStyle} extra={ <> @@ -141,12 +141,12 @@ const NavInfoCardList: React.FC = () => { } colSpan={topColSpanProps} style={topItemStyle2} - + > <StatisticCard bodyStyle={{ padding: 0, backgroundColor: '#F5F3FD' }} statistic={{ - value: 3048, + value: 40, style:chartsStyle, description: ( <> @@ -189,7 +189,7 @@ const NavInfoCardList: React.FC = () => { } colSpan={topColSpanProps} style={topItemStyle3} - + > <StatisticCard bodyStyle={{ padding: 0, backgroundColor: '#F5FBFF' }} diff --git a/src/services/project/typings.d.ts b/src/services/project/typings.d.ts index acf0ff7..67bfdb7 100644 --- a/src/services/project/typings.d.ts +++ b/src/services/project/typings.d.ts @@ -43,6 +43,7 @@ declare namespace API { }; type ProjectModelConfig = { + imageFkId?: number; createTime?: string; /** 设备是一个 以,隔开的存储device id的字符例如 1,2 */ devices?: string;