From 5cea7c19a508385740de5db3e2c43d1cd2ad6662 Mon Sep 17 00:00:00 2001 From: zhoux Date: Fri, 3 Nov 2023 14:38:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=A8=A1=E5=9E=8B=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=9B=BA=E5=AE=9A=E8=A1=A8=E5=A4=B4=E8=AE=BE=E7=BD=AE=E6=89=B9?= =?UTF-8?q?=E9=87=8F=E6=8C=89=E9=92=AE=E5=AE=8C=E6=88=90=EF=BC=8C=E9=81=8D?= =?UTF-8?q?=E5=8E=86Vnode=E6=AF=94=E5=AF=B9=E5=88=B7=E6=96=B0=E8=8A=82?= =?UTF-8?q?=E7=82=B9key=E6=B7=BB=E5=8A=A0=EF=BC=8C=E5=88=86=E6=AD=A5?= =?UTF-8?q?=E8=A1=A8=E5=8D=95=E6=95=B4=E4=BD=93=E6=A0=B7=E5=BC=8F=E5=88=9D?= =?UTF-8?q?=E6=AD=A5=E5=AE=8C=E6=88=90=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 + src/locales/zh-CN/menu.ts | 11 +- .../ProjectList/components/MyCreateForm.tsx | 857 ++++++++++-------- src/pages/Project/ProjectList/index.tsx | 471 +++++----- .../AlgorithmModelList/index copy.tsx | 493 ++++++++++ .../Resource/AlgorithmModelList/index.tsx | 72 +- src/pages/Resource/ModelVersionList/index.tsx | 4 +- 7 files changed, 1271 insertions(+), 661 deletions(-) create mode 100644 src/pages/Resource/AlgorithmModelList/index copy.tsx diff --git a/README.md b/README.md index 8262ac9..a2d3cb9 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,11 @@ + # General-AI-Platform-Web 通用算法平台前端仓库 develop @@ -17,6 +25,11 @@ + + + + + ### 具体实现 1. 筛选表单区: 列表在columns配置初始数据时,需要筛选的表单项统一使用renderFormItem属性,基于renderFormItem去配置表单项field, 【searchFormItemProps】属性统一配置自定义业务 { @@ -31,4 +44,15 @@ 3. 列表action有多个按钮显示更多 暂时使用默认超过3个显示更多,如需统一处理或者权限控制下的按钮显示隐藏导致的按钮数量不一致,可根据需要独立封装TableActionComp +4. 列表多选悬浮展示在底部,顶部隐藏处理 【待处理】 + + +## ProTable 固定列表 +1. 固定表头 scroll={{ y: 500 }} +批量选择确认按钮固定,列表头内容固定 + +2. 批量选择 tableAlertOptionRender +配置多选操作选项区 + +## ProForm 表单 diff --git a/src/locales/zh-CN/menu.ts b/src/locales/zh-CN/menu.ts index 145b5cf..de93b68 100644 --- a/src/locales/zh-CN/menu.ts +++ b/src/locales/zh-CN/menu.ts @@ -1,3 +1,11 @@ +/* + * @Author: zhoux zhouxia@supervision.ltd + * @Date: 2023-11-01 13:56:33 + * @LastEditors: zhoux zhouxia@supervision.ltd + * @LastEditTime: 2023-11-03 14:24:30 + * @FilePath: \general-ai-platform-web\src\locales\zh-CN\menu.ts + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ export default { 'menu.welcome': '欢迎', 'menu.more-blocks': '更多区块', @@ -60,5 +68,6 @@ export default { 'menu.list.system.dictionary-list': '字典列表', 'menu.list.system.department-list': '部门列表', 'menu.list.staff': '人力资源', - 'menu.list.staff.employee-list': '员工列表' + 'menu.list.staff.employee-list': '员工列表', + 'menu.device.device-relation-list': '设备版本列表', }; diff --git a/src/pages/Project/ProjectList/components/MyCreateForm.tsx b/src/pages/Project/ProjectList/components/MyCreateForm.tsx index 94ae560..4bab026 100644 --- a/src/pages/Project/ProjectList/components/MyCreateForm.tsx +++ b/src/pages/Project/ProjectList/components/MyCreateForm.tsx @@ -1,411 +1,506 @@ -import {ModalForm, ProForm, ProFormList, ProFormUploadButton} from '@ant-design/pro-components'; -import {ProFormText, StepsForm, ProFormTreeSelect, ProFormUploadDragger} from '@ant-design/pro-components'; +import { postDeviceGroupGetDeviceGroupTree } from '@/services/device/DeviceGroup'; +import { postProjectCreateProject } from '@/services/project/Project'; +import { postAlgorithmModelGetAlgorithmModelFkSelect } from '@/services/resource/AlgorithmModel'; +import { beforeUploadFile } from '@/utils/common'; +import { CloseOutlined, SnippetsOutlined } from '@ant-design/icons'; import type { ProFormInstance } from '@ant-design/pro-components'; -import {postAlgorithmModelGetAlgorithmModelFkSelect} from "@/services/resource/AlgorithmModel"; -import {ProFormSwitch} from '@ant-design/pro-components'; -import {FormattedMessage, useIntl} from '@umijs/max'; -import {postProjectCreateProject, putProjectUpdateProjectGroup} from "@/services/project/Project"; -import React, {useState, useRef, useEffect} from 'react'; -import {Button, Form, message, Modal, Transfer, Tree} from 'antd'; -import {Switch} from 'antd'; +import { + ProForm, + ProFormList, + ProFormSwitch, + ProFormText, + ProFormUploadDragger, + StepsForm, +} from '@ant-design/pro-components'; +import { FormattedMessage, useIntl } from '@umijs/max'; +import { Modal, Switch, Transfer, Tree, message } from 'antd'; import type { TransferDirection } from 'antd/es/transfer'; -import {DataNode} from "antd/es/tree"; -import {postMenuGetMenuTree} from "@/services/system/Menu"; -import {postDeviceGroupGetDeviceGroupTree} from "@/services/device/DeviceGroup"; -import {CloseOutlined, SnippetsOutlined} from "@ant-design/icons"; -import {beforeUploadFile, imageInit} from "@/utils/common"; +import { DataNode } from 'antd/es/tree'; +import React, { useEffect, useRef, useState } from 'react'; // @ts-ignore import cookie from 'react-cookies'; interface RecordType { - key: string; - title: string; - description: string; - chosen: boolean; + key: string; + title: string; + description: string; + chosen: boolean; } interface ProjectConfig { - params: Array; + params: Array; } export type FormValueType = { - target?: string; - template?: string; - type?: string; - time?: string; - frequency?: string; + target?: string; + template?: string; + type?: string; + time?: string; + frequency?: string; } & Partial; export type CreateFormProps = { - createModalOpen: boolean; - handleModal: ()=>void; - values: Partial; - reload: any; + createModalOpen: boolean; + handleModal: () => void; + values: Partial; + reload: any; }; const waitTime = (time: number = 100) => { - return new Promise((resolve) => { - setTimeout(() => { - resolve(true); - }, time); - }); + return new Promise((resolve) => { + setTimeout(() => { + resolve(true); + }, time); + }); }; +/**styles 配置 */ +const formContainerWidth: number = 755 +const stepFormItemStyleProps: Record = { + width: formContainerWidth, +}; const treeData1: any[] = [ - { - title: '0-0', - key: '0-0', + { + title: '0-0', + key: '0-0', + children: [ + { + title: '0-0-0', + key: '0-0-0', children: [ - { - title: '0-0-0', - key: '0-0-0', - children: [ - { title: '0-0-0-0', key: '0-0-0-0' }, - { title: '0-0-0-1', key: '0-0-0-1' }, - { title: '0-0-0-2', key: '0-0-0-2' }, - ], - }, - { - title: '0-0-1', - key: '0-0-1', - children: [ - { title: '0-0-1-0', key: '0-0-1-0' }, - { title: '0-0-1-1', key: '0-0-1-1' }, - { title: '0-0-1-2', key: '0-0-1-2' }, - { title: '0-0-1-0', key: '0-0-1-3' }, - { title: '0-0-1-1', key: '0-0-1-4' }, - { title: '0-0-1-2', key: '0-0-1-5' }, - { title: '0-0-1-0', key: '0-0-1-6' }, - { title: '0-0-1-1', key: '0-0-1-7' }, - { title: '0-0-1-2', key: '0-0-1-8' }, - { title: '0-0-1-0', key: '0-0-1-9' }, - { title: '0-0-1-1', key: '0-0-1-10' }, - { title: '0-0-1-2', key: '0-0-1-11' }, - { title: '0-0-1-0', key: '0-0-1-12' }, - { title: '0-0-1-1', key: '0-0-1-13' }, - { title: '0-0-1-2', key: '0-0-1-14' }, - { title: '0-0-1-0', key: '0-0-1-15' }, - { title: '0-0-1-1', key: '0-0-1-16' }, - { title: '0-0-1-2', key: '0-0-1-17' }, - { title: '0-0-1-0', key: '0-0-1-18' }, - { title: '0-0-1-1', key: '0-0-1-19' }, - { title: '0-0-1-2', key: '0-0-1-20' }, - { title: '0-0-1-0', key: '0-0-1-21' }, - { title: '0-0-1-1', key: '0-0-1-22' }, - { title: '0-0-1-2', key: '0-0-1-23' }, - { title: '0-0-1-0', key: '0-0-1-24' }, - { title: '0-0-1-1', key: '0-0-1-25' }, - { title: '0-0-1-2', key: '0-0-1-26' }, - { title: '0-0-1-0', key: '0-0-1-27' }, - { title: '0-0-1-1', key: '0-0-1-28' }, - { title: '0-0-1-2', key: '0-0-1-29' }, - { title: '0-0-1-0', key: '0-0-1-30' }, - { title: '0-0-1-1', key: '0-0-1-31' }, - { title: '0-0-1-2', key: '0-0-1-32' }, - { title: '0-0-1-0', key: '0-0-1-33' }, - { title: '0-0-1-1', key: '0-0-1-34' }, - { title: '0-0-1-2', key: '0-0-1-35' }, - - ], - }, - { - title: '0-0-2', - key: '0-0-2', - }, + { title: '0-0-0-0', key: '0-0-0-0' }, + { title: '0-0-0-1', key: '0-0-0-1' }, + { title: '0-0-0-2', key: '0-0-0-2' }, ], - }, - { - title: '0-1', - key: '0-1', + }, + { + title: '0-0-1', + key: '0-0-1', children: [ - { title: '0-1-0-0', key: '0-1-0-0' }, - { title: '0-1-0-1', key: '0-1-0-1' }, - { title: '0-1-0-2', key: '0-1-0-2' }, + { title: '0-0-1-0', key: '0-0-1-0' }, + { title: '0-0-1-1', key: '0-0-1-1' }, + { title: '0-0-1-2', key: '0-0-1-2' }, + { title: '0-0-1-0', key: '0-0-1-3' }, + { title: '0-0-1-1', key: '0-0-1-4' }, + { title: '0-0-1-2', key: '0-0-1-5' }, + { title: '0-0-1-0', key: '0-0-1-6' }, + { title: '0-0-1-1', key: '0-0-1-7' }, + { title: '0-0-1-2', key: '0-0-1-8' }, + { title: '0-0-1-0', key: '0-0-1-9' }, + { title: '0-0-1-1', key: '0-0-1-10' }, + { title: '0-0-1-2', key: '0-0-1-11' }, + { title: '0-0-1-0', key: '0-0-1-12' }, + { title: '0-0-1-1', key: '0-0-1-13' }, + { title: '0-0-1-2', key: '0-0-1-14' }, + { title: '0-0-1-0', key: '0-0-1-15' }, + { title: '0-0-1-1', key: '0-0-1-16' }, + { title: '0-0-1-2', key: '0-0-1-17' }, + { title: '0-0-1-0', key: '0-0-1-18' }, + { title: '0-0-1-1', key: '0-0-1-19' }, + { title: '0-0-1-2', key: '0-0-1-20' }, + { title: '0-0-1-0', key: '0-0-1-21' }, + { title: '0-0-1-1', key: '0-0-1-22' }, + { title: '0-0-1-2', key: '0-0-1-23' }, + { title: '0-0-1-0', key: '0-0-1-24' }, + { title: '0-0-1-1', key: '0-0-1-25' }, + { title: '0-0-1-2', key: '0-0-1-26' }, + { title: '0-0-1-0', key: '0-0-1-27' }, + { title: '0-0-1-1', key: '0-0-1-28' }, + { title: '0-0-1-2', key: '0-0-1-29' }, + { title: '0-0-1-0', key: '0-0-1-30' }, + { title: '0-0-1-1', key: '0-0-1-31' }, + { title: '0-0-1-2', key: '0-0-1-32' }, + { title: '0-0-1-0', key: '0-0-1-33' }, + { title: '0-0-1-1', key: '0-0-1-34' }, + { title: '0-0-1-2', key: '0-0-1-35' }, ], - }, - { - title: '0-2', - key: '0-2', - }, + }, + { + title: '0-0-2', + key: '0-0-2', + }, + ], + }, + { + title: '0-1', + key: '0-1', + children: [ + { title: '0-1-0-0', key: '0-1-0-0' }, + { title: '0-1-0-1', key: '0-1-0-1' }, + { title: '0-1-0-2', key: '0-1-0-2' }, + ], + }, + { + title: '0-2', + key: '0-2', + }, ]; - const MyCreateForm: React.FC = (props) => { - const [treeData, setTreeData] = React.useState([]); - const [modalData, setModalData] = useState([]); - const [targetKeys, setTargetKeys] = useState([]); - const [selectKeys, setSelectKeys] = useState([]); - const [filePath, setFilePath] = useState('') - const [configData, setConfigData] = useState({params: []}); - const intl = useIntl(); - const [isAuto, setIsAuto] = useState(true); - const formRef = useRef(); - const formRef3 = useRef(); - const [current, setCurrent] = useState(0); - const getModelData = () => { - postAlgorithmModelGetAlgorithmModelFkSelect({keyword: ''}).then((res)=>{ - console.log(444, res); - let result = (res.data?.list || []).map((v: any)=>{ - return { - key: v.id, - title: v.name, - chosen: false, - } - }) - setModalData(result); - }) - // setMockData(tempMockData); - // setTargetKeys(tempTargetKeys); - }; + const [treeData, setTreeData] = React.useState([]); + const [modalData, setModalData] = useState([]); + const [targetKeys, setTargetKeys] = useState([]); + const [selectKeys, setSelectKeys] = useState([]); + const [filePath, setFilePath] = useState(''); + const [configData, setConfigData] = useState({ params: [] }); + const intl = useIntl(); + const [isAuto, setIsAuto] = useState(true); + const formRef = useRef(); + const formRef3 = useRef(); + const [current, setCurrent] = useState(0); + const getModelData = () => { + postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: '' }).then((res) => { + console.log(444, res); + let result = (res.data?.list || []).map((v: any) => { + return { + key: v.id, + title: v.name, + chosen: false, + }; + }); + setModalData(result); + }); + // setMockData(tempMockData); + // setTargetKeys(tempTargetKeys); + }; - const handleChange = (newTargetKeys: string[]) => { - setTargetKeys(newTargetKeys); - }; - useEffect(() => { - setTargetKeys([]) - if (props.createModalOpen) { - getModelData(); - postDeviceGroupGetDeviceGroupTree().then((resp: API.Response)=>{ - setTreeData(resp.data.tree) - }).catch(()=>{}) - } else { - formRef.current?.resetFields() - } - }, [props.createModalOpen]) - const handleSearch = (dir: TransferDirection, value: string) => { - postAlgorithmModelGetAlgorithmModelFkSelect({keyword: value}).then((res)=>{ - console.log(444, res); - let result = (res.data?.list || []).map((v: any)=>{ - return { - key: v.id, - title: v.name, - chosen: false, - } - }) - setModalData(result); + const handleChange = (newTargetKeys: string[]) => { + setTargetKeys(newTargetKeys); + }; + useEffect(() => { + setTargetKeys([]); + if (props.createModalOpen) { + getModelData(); + postDeviceGroupGetDeviceGroupTree() + .then((resp: API.Response) => { + setTreeData(resp.data.tree); }) - }; - return ( - - stepsProps={{}} - current={current} - onCurrentChange={setCurrent} - onFinish={async () => { - let formData = formRef.current?.getFieldsValue(); - if (formData?.name) { - formData.inferConfig = {models: targetKeys, params: configData?.params || []}; - formData.groupIds = selectKeys; - formData.projectFilePath = filePath; - postProjectCreateProject(formData).then(()=>{ - message.success(intl.formatMessage({id: 'common.success', defaultMessage: '$$$'})) - props.handleModal(); - props.reload() - }).catch(()=>{ - message.error(intl.formatMessage({id: 'common.failure', defaultMessage: '$$$'})) - return false - }) - } - return true; - }} - formProps={{ - validateMessages: { - required: '此项为必填项', - }, - }} - stepsFormRender={(dom, submitter) => { - return ( - { - setCurrent(0) - formRef.current?.resetFields() - formRef3.current?.resetFields() - props.handleModal(); - }} - open={props.createModalOpen} - footer={submitter} - destroyOnClose - > - {dom} - - ); - }} - > - - - name="base" - formRef={formRef} - title="创建项目数据" - stepProps={{ - description: '这里填入项目基本信息', - }} - onFinish={async () => { - // setFormData(formRef.current?.getFieldsValue()); - await waitTime(500); - return true; - }} - > - - } placeholder={`${intl.formatMessage({id: 'common.please_input', defaultMessage: '$$$'})}${intl.formatMessage({id: 'project.project.table.list.name', defaultMessage: '$$$'})}`} required={true} - rules={[ - { - required: true, - message: ( - - ), - }, - ]} - /> - } placeholder={`${intl.formatMessage({id: 'common.please_input', defaultMessage: '$$$'})}${intl.formatMessage({id: 'project.project.table.list.code', defaultMessage: '$$$'})}`} required={!isAuto} initialValue='' disabled={isAuto} - rules={isAuto?[]:[ - { - required: true, - message: ( - - ), - }, - ]} - addonAfter={} - unCheckedChildren={} - onChange={setIsAuto} - />}/> - } placeholder={`${intl.formatMessage({id: 'common.please_input', defaultMessage: '$$$'})}${intl.formatMessage({id: 'project.project.table.list.info', defaultMessage: '$$$'})}`} required={true} - rules={[ - { - required: true, - message: ( - - ), - }, - ]} + .catch(() => {}); + } else { + formRef.current?.resetFields(); + } + }, [props.createModalOpen]); + const handleSearch = (dir: TransferDirection, value: string) => { + postAlgorithmModelGetAlgorithmModelFkSelect({ keyword: value }).then((res) => { + console.log(444, res); + let result = (res.data?.list || []).map((v: any) => { + return { + key: v.id, + title: v.name, + chosen: false, + }; + }); + setModalData(result); + }); + }; + return ( + + stepsProps={{ + labelPlacement: 'vertical', + }} + current={current} + onCurrentChange={setCurrent} + onFinish={async () => { + let formData = formRef.current?.getFieldsValue(); + if (formData?.name) { + formData.inferConfig = { models: targetKeys, params: configData?.params || [] }; + formData.groupIds = selectKeys; + formData.projectFilePath = filePath; + postProjectCreateProject(formData) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + props.handleModal(); + props.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + return false; + }); + } + return true; + }} + formProps={{ + validateMessages: { + required: '此项为必填项', + }, + }} + stepsFormRender={(dom, submitter) => { + return ( + { + setCurrent(0); + formRef.current?.resetFields(); + formRef3.current?.resetFields(); + props.handleModal(); + }} + open={props.createModalOpen} + footer={submitter} + destroyOnClose + > + {dom} + + ); + }} + > + {/* 创建项目数据 */} + + name="base" + formRef={formRef} + title="创建项目数据" + stepProps={{ + description: '这里填入项目基本信息', + }} + onFinish={async () => { + // setFormData(formRef.current?.getFieldsValue()); + await waitTime(500); + return true; + }} + > + + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'project.project.table.list.name', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'project.project.table.list.code', + defaultMessage: '$$$', + })}`} + required={!isAuto} + initialValue="" + disabled={isAuto} + rules={ + isAuto + ? [] + : [ + { + required: true, + message: ( + - } placeholder={`${intl.formatMessage({id: 'common.please_input', defaultMessage: '$$$'})}${intl.formatMessage({id: 'project.project.table.list.remark', defaultMessage: '$$$'})}`} required={false}/> - - - } initialValue={true}/> - - - - - name="model" - title="关联算法模型" - stepProps={{ - description: '选择算法模型', - }} - onFinish={async () => { - return true; - }} - > - - item.title} - /> - - - name="project_file" - title="上传业务代码" - 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; - }} - > - - - - name="config" - title="业务参数配置" - stepProps={{ - description: '业务参数配置', - }} - onFinish={async (values: any) => { - setConfigData(values) - return true; - }} - > - - - - - - + ), + }, + ] + } + addonAfter={ + } + unCheckedChildren={} + onChange={setIsAuto} + /> + } + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'project.project.table.list.info', + defaultMessage: '$$$', + })}`} + required={true} + rules={[ + { + required: true, + message: ( + + ), + }, + ]} + /> + } + placeholder={`${intl.formatMessage({ + id: 'common.please_input', + defaultMessage: '$$$', + })}${intl.formatMessage({ + id: 'project.project.table.list.remark', + defaultMessage: '$$$', + })}`} + required={false} + /> + + + + } + initialValue={true} + /> + + + {/* 关联算法模型 */} + + name="model" + title="关联算法模型" + stepProps={{ + description: '选择算法模型', + }} + onFinish={async () => { + return true; + }} + > + - - - name="group" - title="关联网点" - stepProps={{ - description: '选择网点', - }} - onFinish={async () => { - return true; - }} - formRef={formRef3} - > - { - // form.setFieldsValue({menuIds: checkedKeys}) - setSelectKeys(checkedKeys) - // formRef3.current?.setFieldValue('groupIds', checkedKeys) - }} - treeData={treeData} - // loadData={({treeNode}) => { - // return treeData - // }} - /> - - - ) -} + locale={{ itemUnit: '项', itemsUnit: '项', searchPlaceholder: '请输入搜索内容' }} + targetKeys={targetKeys} + onChange={handleChange} + onSearch={handleSearch} + style={{ marginBottom: '20px' }} + listStyle={{width: 289, height: 300}} + operationStyle={{width: 100, alignItems: 'center'}} + render={(item) => item.title} + /> + + {/* 上传业务代码 */} + + name="project_file" + title="上传业务代码" + style={{width: stepFormItemStyleProps.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; + }} + > + + + {/* 业务参数配置 */} + + name="config" + title="业务参数配置" + stepProps={{ + description: '业务参数配置', + }} + onFinish={async (values: any) => { + setConfigData(values); + return true; + }} + > + {/* */} + {/* TODO 图标需要替换 */} + + + + + + + + + {/* 关联网点 */} + + name="group" + title="关联网点" + stepProps={{ + description: '选择网点', + }} + onFinish={async () => { + return true; + }} + style={{width: stepFormItemStyleProps.width}} + formRef={formRef3} + > +
{'选择网点'}
+ { + // form.setFieldsValue({menuIds: checkedKeys}) + setSelectKeys(checkedKeys); + // formRef3.current?.setFieldValue('groupIds', checkedKeys) + }} + treeData={treeData} + // loadData={({treeNode}) => { + // return treeData + // }} + /> + + + ); +}; export default MyCreateForm; diff --git a/src/pages/Project/ProjectList/index.tsx b/src/pages/Project/ProjectList/index.tsx index 5919c6a..69f5e12 100644 --- a/src/pages/Project/ProjectList/index.tsx +++ b/src/pages/Project/ProjectList/index.tsx @@ -1,80 +1,78 @@ -import {deleteProjectDeleteProject, postProjectGetProjectList, deleteProjectDeleteProjectByIds} from '@/services/project/Project'; +import { + deleteProjectDeleteProject, + deleteProjectDeleteProjectByIds, + postProjectGetProjectList, +} from '@/services/project/Project'; import { PlusOutlined } from '@ant-design/icons'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; -import { - FooterToolbar, - PageContainer, - ProTable, - ProFormSelect, -} from '@ant-design/pro-components'; -import { FormattedMessage, useIntl, useAccess, Access, history } from '@umijs/max'; -import {Button, message} from 'antd'; +import { FooterToolbar, PageContainer, ProTable } from '@ant-design/pro-components'; +import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; +import { Button, message } from 'antd'; import React, { useRef, useState } from 'react'; +import { ColumnDrawer } from './components/ColumnDrawer'; +import MyCreateForm from './components/MyCreateForm'; import UpdateForm from './components/UpdateForm'; -import MyCreateForm from "./components/MyCreateForm"; -import {ColumnDrawer} from "./components/ColumnDrawer"; const ProjectList: React.FC = () => { - /** - * @en-US Pop-up window of new window - * @zh-CN 新建窗口的弹窗 - * */ - const [createModalOpen, setCreateModalOpen] = useState(false); - /** - * @en-US The pop-up window of the distribution update window - * @zh-CN 分布更新窗口的弹窗 - * */ - const [updateModalOpen, setUpdateModalOpen] = useState(false); - const [showDetail, setShowDetail] = useState(false); - /** - * @en-US International configuration - * @zh-CN 国际化配置 - * */ - const access = useAccess(); - const intl = useIntl(); - const actionRef = useRef(); - const [currentRow, setCurrentRow] = useState(); - const [selectedRowsState, setSelectedRows] = useState([]); - - const handleUpdateModal = ()=>{ - if (updateModalOpen) { - setUpdateModalOpen(false) - setCurrentRow(undefined) - } else { - setUpdateModalOpen(true) - } - } - const handleCreateModal = ()=>{ - if (createModalOpen) { - setCreateModalOpen(false) - setCurrentRow(undefined) - } else { - setCreateModalOpen(true) - } - } - const handleColumnDrawer = ()=>{ - if (showDetail) { - setShowDetail(false) - setCurrentRow(undefined) - } else { - setShowDetail(true) - } - } - const handleDestroy = async (selectedRow: API.Project) => { - deleteProjectDeleteProject({id: selectedRow.id}).then(()=>{ - message.success(intl.formatMessage({id: 'common.success', defaultMessage: '$$$'})) - actionRef.current?.reload() - }).catch(()=>{ - message.error(intl.formatMessage({id: 'common.failure', defaultMessage: '$$$'})) - }) - }; + /** + * @en-US Pop-up window of new window + * @zh-CN 新建窗口的弹窗 + * */ + const [createModalOpen, setCreateModalOpen] = useState(false); + /** + * @en-US The pop-up window of the distribution update window + * @zh-CN 分布更新窗口的弹窗 + * */ + const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [showDetail, setShowDetail] = useState(false); + /** + * @en-US International configuration + * @zh-CN 国际化配置 + * */ + const access = useAccess(); + const intl = useIntl(); + const actionRef = useRef(); + const [currentRow, setCurrentRow] = useState(); + const [selectedRowsState, setSelectedRows] = useState([]); -const columns: ProColumns[] = [ + const handleUpdateModal = () => { + if (updateModalOpen) { + setUpdateModalOpen(false); + setCurrentRow(undefined); + } else { + setUpdateModalOpen(true); + } + }; + const handleCreateModal = () => { + if (createModalOpen) { + setCreateModalOpen(false); + setCurrentRow(undefined); + } else { + setCreateModalOpen(true); + } + }; + const handleColumnDrawer = () => { + if (showDetail) { + setShowDetail(false); + setCurrentRow(undefined); + } else { + setShowDetail(true); + } + }; + const handleDestroy = async (selectedRow: API.Project) => { + deleteProjectDeleteProject({ id: selectedRow.id }) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + actionRef.current?.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }; + const columns: ProColumns[] = [ { - title: (), - dataIndex: "id", + title: , + dataIndex: 'id', sorter: true, render: (dom, entity) => { return ( @@ -91,199 +89,181 @@ const columns: ProColumns[] = [ }, { - title: (), - dataIndex: "name", - hideInSearch: true, + title: , + dataIndex: 'name', + hideInSearch: true, }, - { - title: (), - dataIndex: "code", - hideInSearch: true, + title: , + dataIndex: 'code', + hideInSearch: true, }, - { - title: (), - dataIndex: "info", - hideInSearch: true, + title: , + dataIndex: 'info', + hideInSearch: true, }, - { - title: (), - dataIndex: "inferConfig", - hideInSearch: true, - hideInTable: true, - hideInDescriptions: true, + title: , + dataIndex: 'inferConfig', + hideInSearch: true, + hideInTable: true, + hideInDescriptions: true, }, - { - title: (), - dataIndex: "isEnable", - filters: true, onFilter: true, - hideInSearch: true, - valueType: 'switch', + title: , + dataIndex: 'isEnable', + filters: true, + onFilter: true, + hideInSearch: true, + valueType: 'switch', }, - { - title: (), - dataIndex: "remark", - hideInSearch: true, + title: , + dataIndex: 'remark', + hideInSearch: true, }, - { - title: (), - dataIndex: "createTime", - sorter: true, - hideInSearch: true, - valueType: 'dateTime', + title: , + dataIndex: 'createTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', }, - { - title: (), - dataIndex: "updateTime", - sorter: true, - hideInSearch: true, - valueType: 'dateTime', + title: , + dataIndex: 'updateTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', }, - - { - title: , - dataIndex: 'option', - valueType: 'option', - fixed:'right', - render: (_, record) => [ - - { - setUpdateModalOpen(true); - setCurrentRow(record); - }} - > - - - { - handleDestroy(record).then(()=>{}) - }}> - - - - ], - },]; -return ( - - - headerTitle={intl.formatMessage({ - id: 'pages.searchTable.title', - defaultMessage: '$$$', - })} - options={{ fullScreen: true, setting: true, density: true, reload: true }} - actionRef={actionRef} - rowKey="key" - search={{ - labelWidth: 120, - }} - onDataSourceChange={(data)=>{ - - }} - pagination={{ - showSizeChanger: true, - pageSize: 10, + { + title: , + dataIndex: 'option', + valueType: 'option', + fixed: 'right', + render: (_, record) => [ + + { + setUpdateModalOpen(true); + setCurrentRow(record); }} - columnsState={{ - persistenceKey: 'project_list', - persistenceType: 'localStorage' + > + + + { + handleDestroy(record).then(() => {}); }} - toolBarRender={() => [ - - - - - ]} - request={async (params = {}, sort) => { - const {current, ...rest} = params + > + + + , + ], + }, + ]; + return ( + + + headerTitle={intl.formatMessage({ + id: 'pages.searchTable.title', + defaultMessage: '$$$', + })} + options={{ fullScreen: true, setting: true, density: true, reload: true }} + actionRef={actionRef} + rowKey="key" + search={{ + labelWidth: 120, + }} + onDataSourceChange={() => {}} + pagination={{ + showSizeChanger: true, + pageSize: 10, + }} + columnsState={{ + persistenceKey: 'project_list', + persistenceType: 'localStorage', + }} + toolBarRender={() => [ + + + , + ]} + request={async (params = {}, sort) => { + const { current, ...rest } = params; const reqParams = { page: current, desc: false, - orderKey: "", + orderKey: '', ...rest, - } + }; if (sort && Object.keys(sort).length) { - reqParams.orderKey = Object.keys(sort)[0] - let sort_select = sort[reqParams.orderKey] + reqParams.orderKey = Object.keys(sort)[0]; + let sort_select = sort[reqParams.orderKey]; reqParams.desc = sort_select === 'descend'; } - let resp = await postProjectGetProjectList({...reqParams}) + let resp = await postProjectGetProjectList({ ...reqParams }); return { - data: resp.data.list.map((v: API.Project)=>{ - return {...v, key: v.id} + data: resp.data.list.map((v: API.Project) => { + return { ...v, key: v.id }; }), success: resp.success, total: resp.data.total, current: resp.data.page, - pageSize: resp.data.pageSize + pageSize: resp.data.pageSize, }; - - }} - columns={columns} - rowSelection={{ - onChange: (_, selectedRows) => { - setSelectedRows(selectedRows); - }, - }} - /> - {selectedRowsState?.length > 0 && ( - - {' '} - {selectedRowsState.length}{' '} - - - } - > - - - )} - - - - + + )} + + - - ); + + + ); }; - export default ProjectList; +export default ProjectList; diff --git a/src/pages/Resource/AlgorithmModelList/index copy.tsx b/src/pages/Resource/AlgorithmModelList/index copy.tsx new file mode 100644 index 0000000..5054751 --- /dev/null +++ b/src/pages/Resource/AlgorithmModelList/index copy.tsx @@ -0,0 +1,493 @@ +import { ColumnDrawer as ModelCategoryColumnDrawer } from '@/pages/Resource/ModelCategoryList/components/ColumnDrawer'; +import { ModelCategoryColumns } from '@/pages/Resource/ModelCategoryList/components/Columns'; +import { + deleteAlgorithmModelDeleteAlgorithmModel, + deleteAlgorithmModelDeleteAlgorithmModelByIds, + postAlgorithmModelGetAlgorithmModelList, +} from '@/services/resource/AlgorithmModel'; +import { + postModelCategoryGetModelCategoryById, + postModelCategoryGetModelCategoryFkSelect, + postModelCategoryGetModelCategoryNames, +} from '@/services/resource/ModelCategory'; +import { ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; +import type { ActionType, ProColumns } from '@ant-design/pro-components'; +import { PageContainer, ProFormSelect, ProFormText, ProTable } from '@ant-design/pro-components'; +import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; +import { Button, Modal, Popconfirm, message } from 'antd'; +import React, { useRef, useState } from 'react'; +import { ColumnDrawer } from './components/ColumnDrawer'; +import CreateForm from './components/CreateForm'; +import UpdateForm from './components/UpdateForm'; +const AlgorithmModelList: React.FC = () => { + /** + * @en-US Pop-up window of new window + * @zh-CN 新建窗口的弹窗 + * */ + const [createModalOpen, setCreateModalOpen] = useState(false); + /** + * @en-US The pop-up window of the distribution update window + * @zh-CN 分布更新窗口的弹窗 + * */ + const [updateModalOpen, setUpdateModalOpen] = useState(false); + const [showDetail, setShowDetail] = useState(false); + /** + * @en-US International configuration + * @zh-CN 国际化配置 + * */ + const access = useAccess(); + const intl = useIntl(); + const actionRef = useRef(); + // TODO 动态设置每页数量 + const [currentPageSize, setCurrentPageSize] = useState(10); + const [currentRow, setCurrentRow] = useState(); + const [selectedRowsState, setSelectedRows] = useState([]); + const [category_fk_id_open, set_category_fk_id_open] = useState(false); + const [category_fk_id, set_category_fk_id] = useState(); + const [category_fk_id_column_open, set_category_fk_id_column_open] = useState(false); + const [categoryFkIdIds, setCategoryFkIdIds] = useState([]); + const [categoryFkIdMap, setCategoryFkIdMap] = useState<{ [key: number]: string }>({}); + const handle_category_fk_id = (id: any) => { + if (category_fk_id_open) { + set_category_fk_id(undefined); + set_category_fk_id_open(false); + } else { + postModelCategoryGetModelCategoryById({ id: id }).then((resp) => { + set_category_fk_id(resp.data.modelCategory); + set_category_fk_id_open(true); + }); + } + }; + const handle_category_fk_id_column_open = () => { + if (category_fk_id_column_open) { + set_category_fk_id_column_open(false); + } else { + postModelCategoryGetModelCategoryNames({ ids: categoryFkIdIds }).then((resp) => { + let a: any = {}; + resp.data.list.forEach((v: any) => { + if (v.id) { + a[v.id] = v.name; + } + }); + setCategoryFkIdMap(a); + }); + set_category_fk_id_column_open(true); + } + }; + + const handleUpdateModal = () => { + if (updateModalOpen) { + setUpdateModalOpen(false); + setCurrentRow(undefined); + } else { + setUpdateModalOpen(true); + } + }; + const handleCreateModal = () => { + if (createModalOpen) { + setCreateModalOpen(false); + setCurrentRow(undefined); + } else { + setCreateModalOpen(true); + } + }; + const handleColumnDrawer = () => { + if (showDetail) { + setShowDetail(false); + setCurrentRow(undefined); + } else { + setShowDetail(true); + } + }; + const handleDestroy = async (selectedRow: API.AlgorithmModel) => { + deleteAlgorithmModelDeleteAlgorithmModel({ id: selectedRow.id }) + .then(() => { + message.success(intl.formatMessage({ id: 'common.success', defaultMessage: '$$$' })); + actionRef.current?.reload(); + }) + .catch(() => { + message.error(intl.formatMessage({ id: 'common.failure', defaultMessage: '$$$' })); + }); + }; + + const columns: ProColumns[] = [ + { + title: , + dataIndex: 'id', + sorter: true, + render: (dom, entity) => { + return ( + { + setCurrentRow(entity); + setShowDetail(true); + }} + > + {dom} + + ); + }, + //TODO 默认使用renderFormItem update1101 + renderFormItem: () => { + return ( + <> + + + ); + }, + }, + + { + title: ( + + ), + dataIndex: 'name', + hideInSearch: true, + }, + + { + title: ( + + ), + dataIndex: 'categoryFkId', + hideInSearch: false, + render: (text, record) => { + if (category_fk_id_column_open) { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record?.categoryFkId ? categoryFkIdMap[record.categoryFkId] : undefined} + + ); + } else { + return ( + { + handle_category_fk_id(record.categoryFkId); + }} + > + {record.categoryFkId} + + ); + } + }, + renderFormItem: () => { + return ( + // value 和 onchange 会通过 form 自动注入。 + { + const resp = await postModelCategoryGetModelCategoryFkSelect({ + keyword: keyWord?.keyWords || '', + }); + return resp.data.list.map((v: any) => { + return { + label: v.name, + value: v.id, + }; + }); + }} + /> + ); + }, + }, + { + title: ( + + ), + dataIndex: 'defaultVersionFkId', + hideInSearch: true, + }, + + { + title: ( + + ), + dataIndex: 'remark', + hideInSearch: true, + }, + + { + title: ( + + ), + dataIndex: 'createTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: ( + + ), + dataIndex: 'updateTime', + sorter: true, + hideInSearch: true, + valueType: 'dateTime', + }, + + { + title: , + dataIndex: 'option', + valueType: 'option', + fixed: 'right', + render: (_, record) => [ + + { + setUpdateModalOpen(true); + setCurrentRow(record); + }} + > + + + {/* update1101 */} + { + handleDestroy(record).then(() => {}); + }} + > + + + , + ], + }, + ]; + return ( + + + headerTitle={intl.formatMessage({ + id: 'pages.searchTable.title', + defaultMessage: '$$$', + })} + scroll={{ y: 500 }} + options={{ fullScreen: true, setting: true, density: true, reload: true }} + actionRef={actionRef} + rowKey="key" + search={{ + labelWidth: 120, + }} + onDataSourceChange={(data) => { + let CategoryFkIdIds: any = data.map((v) => { + return v.categoryFkId; + }); + setCategoryFkIdIds(CategoryFkIdIds); + }} + pagination={{ + showSizeChanger: true, + pageSize: currentPageSize, + onChange: (page, pageSize) => setCurrentPageSize(pageSize), + }} + columnsState={{ + persistenceKey: 'algorithm_model_list', + persistenceType: 'localStorage', + }} + tableAlertOptionRender={() => { + return ( + <> + {selectedRowsState?.length > 0 && ( + + )} + + ); + }} + toolBarRender={() => [ + + + + + , + ]} + request={async (params = {}, sort) => { + const { current, ...rest } = params; + const reqParams = { + page: 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 postAlgorithmModelGetAlgorithmModelList({ ...reqParams }); + return { + data: resp.data.list.map((v: API.AlgorithmModel) => { + return { ...v, key: v.id }; + }), + success: resp.success, + total: resp.data.total, + current: resp.data.page, + pageSize: resp.data.pageSize, + }; + }} + columns={columns} + rowSelection={{ + onChange: (_, selectedRows) => { + setSelectedRows(selectedRows); + }, + }} + /> + {/* TODO 不明显需要重新设计 底部已选项操作固定栏 */} + {/* {selectedRowsState?.length > 0 && ( + + {' '} + {selectedRowsState.length}{' '} + + + } + > + + + )} */} + {/* 列表关联操作项组件 */} + + + + + + + ); +}; + +export default AlgorithmModelList; diff --git a/src/pages/Resource/AlgorithmModelList/index.tsx b/src/pages/Resource/AlgorithmModelList/index.tsx index f3ab69f..cb743fc 100644 --- a/src/pages/Resource/AlgorithmModelList/index.tsx +++ b/src/pages/Resource/AlgorithmModelList/index.tsx @@ -10,7 +10,7 @@ import { postModelCategoryGetModelCategoryFkSelect, postModelCategoryGetModelCategoryNames, } from '@/services/resource/ModelCategory'; -import { PlusOutlined } from '@ant-design/icons'; +import { ExclamationCircleOutlined, PlusOutlined } from '@ant-design/icons'; import type { ActionType, ProColumns } from '@ant-design/pro-components'; import { FooterToolbar, @@ -20,7 +20,7 @@ import { ProTable, } from '@ant-design/pro-components'; import { Access, FormattedMessage, history, useAccess, useIntl } from '@umijs/max'; -import { Button, Popconfirm, message } from 'antd'; +import { Button, Modal, Popconfirm, message } from 'antd'; import React, { useRef, useState } from 'react'; import { ColumnDrawer } from './components/ColumnDrawer'; import {ModelVersionListDrawer} from "./components/ModelVersionListDrawer"; @@ -324,6 +324,7 @@ const AlgorithmModelList: React.FC = () => { id: 'pages.searchTable.title', defaultMessage: '$$$', })} + scroll={{ y: 500 }} options={{ fullScreen: true, setting: true, density: true, reload: true }} actionRef={actionRef} rowKey="key" @@ -345,6 +346,44 @@ const AlgorithmModelList: React.FC = () => { persistenceKey: 'algorithm_model_list', persistenceType: 'localStorage', }} + tableAlertOptionRender={() => { + return ( + <> + {selectedRowsState?.length > 0 && ( + + )} + + ); + }} toolBarRender={() => [ { }, }} /> - {/* TODO 不明显需要重新设计 底部已选项操作固定栏 */} - {selectedRowsState?.length > 0 && ( - - {' '} - {selectedRowsState.length}{' '} - - - } - > - - - )} {/* 列表关联操作项组件 */} { }); return ( <> - {prevActions.map((item) => { - return <>{item}; + {prevActions.map((item,index) => { + return
{item}
; })} 更多