| @@ -1,6 +1,6 @@ | |||||
| import SubAreaTitle from '@/components/SubAreaTitle'; | import SubAreaTitle from '@/components/SubAreaTitle'; | ||||
| import { AutoMLTaskType } from '@/enums'; | import { AutoMLTaskType } from '@/enums'; | ||||
| import { modalConfirm } from '@/utils/ui'; | |||||
| import { removeFormListItem } from '@/utils/ui'; | |||||
| import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons'; | import { MinusCircleOutlined, PlusCircleOutlined } from '@ant-design/icons'; | ||||
| import { Button, Col, Flex, Form, Input, InputNumber, Radio, Row, Select } from 'antd'; | import { Button, Col, Flex, Form, Input, InputNumber, Radio, Row, Select } from 'antd'; | ||||
| import { classificationMetrics, regressionMetrics } from './ExecuteConfig'; | import { classificationMetrics, regressionMetrics } from './ExecuteConfig'; | ||||
| @@ -72,12 +72,14 @@ function TrialConfig() { | |||||
| type="text" | type="text" | ||||
| icon={<MinusCircleOutlined />} | icon={<MinusCircleOutlined />} | ||||
| onClick={() => { | onClick={() => { | ||||
| modalConfirm({ | |||||
| title: '确定要删除该指标权重吗?', | |||||
| onOk: () => { | |||||
| remove(name); | |||||
| }, | |||||
| }); | |||||
| removeFormListItem( | |||||
| form, | |||||
| 'metrics', | |||||
| name, | |||||
| remove, | |||||
| ['name', 'value'], | |||||
| '删除后,该该指标权重将不可恢复', | |||||
| ); | |||||
| }} | }} | ||||
| ></Button> | ></Button> | ||||
| {index === fields.length - 1 && ( | {index === fields.length - 1 && ( | ||||
| @@ -8,7 +8,7 @@ import SubAreaTitle from '@/components/SubAreaTitle'; | |||||
| import { hyperParameterOptimizedModeOptions } from '@/enums'; | import { hyperParameterOptimizedModeOptions } from '@/enums'; | ||||
| import { useComputingResource } from '@/hooks/resource'; | import { useComputingResource } from '@/hooks/resource'; | ||||
| import { isEmpty } from '@/utils'; | import { isEmpty } from '@/utils'; | ||||
| import { modalConfirm } from '@/utils/ui'; | |||||
| import { modalConfirm, removeFormListItem } from '@/utils/ui'; | |||||
| import { MinusCircleOutlined, PlusCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons'; | import { MinusCircleOutlined, PlusCircleOutlined, QuestionCircleOutlined } from '@ant-design/icons'; | ||||
| import { | import { | ||||
| Button, | Button, | ||||
| @@ -396,12 +396,14 @@ function ExecuteConfig() { | |||||
| size="middle" | size="middle" | ||||
| icon={<MinusCircleOutlined />} | icon={<MinusCircleOutlined />} | ||||
| onClick={() => { | onClick={() => { | ||||
| modalConfirm({ | |||||
| title: '确定要删除该参数吗?', | |||||
| onOk: () => { | |||||
| remove(name); | |||||
| }, | |||||
| }); | |||||
| removeFormListItem( | |||||
| form, | |||||
| 'parameters', | |||||
| name, | |||||
| remove, | |||||
| ['name', 'type'], | |||||
| '删除后,该参数将不可恢复', | |||||
| ); | |||||
| }} | }} | ||||
| ></Button> | ></Button> | ||||
| {index === fields.length - 1 && ( | {index === fields.length - 1 && ( | ||||
| @@ -460,7 +462,7 @@ function ExecuteConfig() { | |||||
| ); | ); | ||||
| if (arr.length > 0 && arr.length < runParameters.length) { | if (arr.length > 0 && arr.length < runParameters.length) { | ||||
| return Promise.reject( | return Promise.reject( | ||||
| new Error(`手动运行超参数 ${name} 必须全部填写或者都不填写`), | |||||
| new Error(`手动运行超参数 "${name}" 必须全部填写或者都不填写`), | |||||
| ); | ); | ||||
| } | } | ||||
| } | } | ||||
| @@ -518,7 +520,8 @@ function ExecuteConfig() { | |||||
| icon={<MinusCircleOutlined />} | icon={<MinusCircleOutlined />} | ||||
| onClick={() => { | onClick={() => { | ||||
| modalConfirm({ | modalConfirm({ | ||||
| title: '确定要删除该运行参数吗?', | |||||
| title: '删除后,该运行参数将不可恢复', | |||||
| content: '是否确认删除?', | |||||
| onOk: () => { | onOk: () => { | ||||
| remove(name); | remove(name); | ||||
| }, | }, | ||||
| @@ -68,7 +68,7 @@ function ParameterRange({ type, value, onConfirm }: ParameterRangeProps) { | |||||
| <Flex | <Flex | ||||
| style={{ | style={{ | ||||
| marginLeft: '10px', | marginLeft: '10px', | ||||
| marginBottom: '20px', | |||||
| marginBottom: '24px', | |||||
| flex: 'none', | flex: 'none', | ||||
| width: '66px', | width: '66px', | ||||
| }} | }} | ||||
| @@ -45,11 +45,14 @@ function ModelEvolution({ | |||||
| const [enterTooltip, setEnterTooltip] = useState(false); | const [enterTooltip, setEnterTooltip] = useState(false); | ||||
| const [nodeTooltipX, setNodeToolTipX] = useState(0); | const [nodeTooltipX, setNodeToolTipX] = useState(0); | ||||
| const [nodeTooltipY, setNodeToolTipY] = useState(0); | const [nodeTooltipY, setNodeToolTipY] = useState(0); | ||||
| const [isNodeTooltipLeft, setIsNodeTooltipLeft] = useState(true); | |||||
| const [hoverNodeData, setHoverNodeData] = useState< | const [hoverNodeData, setHoverNodeData] = useState< | ||||
| ModelDepsData | ProjectDependency | TrainDataset | undefined | ModelDepsData | ProjectDependency | TrainDataset | undefined | ||||
| >(undefined); | >(undefined); | ||||
| const apiData = useRef<ModelDepsData | undefined>(undefined); // 接口返回的树形结构 | const apiData = useRef<ModelDepsData | undefined>(undefined); // 接口返回的树形结构 | ||||
| const hierarchyNodes = useRef<ModelDepsData[]>([]); // 层级迭代树形结构,得到的节点列表 | const hierarchyNodes = useRef<ModelDepsData[]>([]); // 层级迭代树形结构,得到的节点列表 | ||||
| const leaveNodeTimeout = useRef<ReturnType<typeof setTimeout> | null>(null); | |||||
| const leaveTooltipTimeout = useRef<ReturnType<typeof setTimeout> | null>(null); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| initGraph(); | initGraph(); | ||||
| @@ -134,6 +137,12 @@ function ModelEvolution({ | |||||
| // 绑定事件 | // 绑定事件 | ||||
| const bindEvents = () => { | const bindEvents = () => { | ||||
| graph.on('node:mouseenter', (e: G6GraphEvent) => { | graph.on('node:mouseenter', (e: G6GraphEvent) => { | ||||
| // 清除延时关闭tooltip的定时器 | |||||
| if (leaveNodeTimeout.current) { | |||||
| clearTimeout(leaveNodeTimeout.current); | |||||
| leaveNodeTimeout.current = null; | |||||
| } | |||||
| const nodeItem = e.item; | const nodeItem = e.item; | ||||
| graph.setItemState(nodeItem, 'hover', true); | graph.setItemState(nodeItem, 'hover', true); | ||||
| @@ -141,26 +150,37 @@ function ModelEvolution({ | |||||
| const { x, y } = model; | const { x, y } = model; | ||||
| const point = graph.getCanvasByPoint(x!, y!); | const point = graph.getCanvasByPoint(x!, y!); | ||||
| const zoom = graph.getZoom(); | const zoom = graph.getZoom(); | ||||
| // 更加缩放,调整 tooltip 位置 | |||||
| const offsetX = (nodeWidth * zoom) / 4; | |||||
| const offsetY = (nodeHeight * zoom) / 4; | |||||
| point.x += offsetX; | |||||
| // 根据缩放,调整 tooltip 位置 | |||||
| // const offsetX = (nodeWidth * zoom) / 4; | |||||
| const offsetY = (nodeHeight * zoom) / 2; | |||||
| // 25 是 `.model-evolution` 的 `padding-left` 值 | |||||
| const tooltipX = point.x + 25 - 20; | |||||
| // 20 是 `.model-evolution` 的 `padding-bottom` 值 | |||||
| const tooltipY = graphRef.current!.clientHeight - point.y + offsetY + 20 + 10; | |||||
| setNodeToolTipY(tooltipY); | |||||
| // 如果右边显示不下 | |||||
| const canvasWidth = graphRef.current!.clientWidth; | const canvasWidth = graphRef.current!.clientWidth; | ||||
| if (point.x + 300 > canvasWidth + 30) { | |||||
| point.x = canvasWidth + 30 - 300; | |||||
| // 300 是 NodeTool 的宽度,canvasWidth + 50 是 `.model-evolution` 的宽度 | |||||
| if (tooltipX + 300 > canvasWidth + 50) { | |||||
| setIsNodeTooltipLeft(false); | |||||
| setNodeToolTipX(canvasWidth + 50 - (point.x + 25) - 20); | |||||
| } else { | |||||
| setNodeToolTipX(tooltipX); | |||||
| setIsNodeTooltipLeft(true); | |||||
| } | } | ||||
| setHoverNodeData(model); | setHoverNodeData(model); | ||||
| setNodeToolTipX(point.x); | |||||
| setNodeToolTipY(graphRef.current!.clientHeight - point.y + offsetY); | |||||
| setShowNodeTooltip(true); | setShowNodeTooltip(true); | ||||
| }); | }); | ||||
| graph.on('node:mouseleave', (e: G6GraphEvent) => { | graph.on('node:mouseleave', (e: G6GraphEvent) => { | ||||
| const nodeItem = e.item; | const nodeItem = e.item; | ||||
| graph.setItemState(nodeItem, 'hover', false); | graph.setItemState(nodeItem, 'hover', false); | ||||
| setShowNodeTooltip(false); | |||||
| leaveNodeTimeout.current = setTimeout(() => { | |||||
| setShowNodeTooltip(false); | |||||
| }, 100); | |||||
| }); | }); | ||||
| graph.on('node:click', (e: G6GraphEvent) => { | graph.on('node:click', (e: G6GraphEvent) => { | ||||
| @@ -191,6 +211,12 @@ function ModelEvolution({ | |||||
| setShowNodeTooltip(false); | setShowNodeTooltip(false); | ||||
| setEnterTooltip(false); | setEnterTooltip(false); | ||||
| }); | }); | ||||
| // 开始拖拽画布时触发 | |||||
| graph.on('DRAG_START', () => { | |||||
| setShowNodeTooltip(false); | |||||
| setEnterTooltip(false); | |||||
| }); | |||||
| }; | }; | ||||
| // toggle 展开 | // toggle 展开 | ||||
| @@ -205,11 +231,18 @@ function ModelEvolution({ | |||||
| }; | }; | ||||
| const handleTooltipsMouseEnter = () => { | const handleTooltipsMouseEnter = () => { | ||||
| // 清除延时关闭tooltip的定时器 | |||||
| if (leaveTooltipTimeout.current) { | |||||
| clearTimeout(leaveTooltipTimeout.current); | |||||
| leaveTooltipTimeout.current = null; | |||||
| } | |||||
| setEnterTooltip(true); | setEnterTooltip(true); | ||||
| }; | }; | ||||
| const handleTooltipsMouseLeave = () => { | const handleTooltipsMouseLeave = () => { | ||||
| setEnterTooltip(false); | |||||
| leaveTooltipTimeout.current = setTimeout(() => { | |||||
| setEnterTooltip(false); | |||||
| }, 100); | |||||
| }; | }; | ||||
| // 获取模型依赖 | // 获取模型依赖 | ||||
| @@ -254,6 +287,7 @@ function ModelEvolution({ | |||||
| resourceId={resourceId} | resourceId={resourceId} | ||||
| x={nodeTooltipX} | x={nodeTooltipX} | ||||
| y={nodeTooltipY} | y={nodeTooltipY} | ||||
| isLeft={isNodeTooltipLeft} | |||||
| data={hoverNodeData!} | data={hoverNodeData!} | ||||
| onVersionChange={onVersionChange} | onVersionChange={onVersionChange} | ||||
| onMouseEnter={handleTooltipsMouseEnter} | onMouseEnter={handleTooltipsMouseEnter} | ||||
| @@ -33,7 +33,7 @@ export type Rect = { | |||||
| }; | }; | ||||
| export interface TrainDataset extends NodeConfig { | export interface TrainDataset extends NodeConfig { | ||||
| repo_id: number; | |||||
| repo_id: string; | |||||
| name: string; | name: string; | ||||
| version: string; | version: string; | ||||
| identifier: string; | identifier: string; | ||||
| @@ -150,11 +150,14 @@ function ModelMetrics({ resourceId, identifier, owner, version }: ModelMetricsPr | |||||
| // 表头 | // 表头 | ||||
| const columns: TableProps<TableData>['columns'] = useMemo(() => { | const columns: TableProps<TableData>['columns'] = useMemo(() => { | ||||
| const first: TableData | undefined = tableData.find( | |||||
| const firstMetrics: TableData | undefined = tableData.find( | |||||
| (item) => item.metrics_names && item.metrics_names.length > 0, | (item) => item.metrics_names && item.metrics_names.length > 0, | ||||
| ); | ); | ||||
| const metricsNames = first?.metrics_names ?? []; | |||||
| const paramsNames = first?.params_names ?? []; | |||||
| const firstParams: TableData | undefined = tableData.find( | |||||
| (item) => item.params_names && item.params_names.length > 0, | |||||
| ); | |||||
| const metricsNames = firstMetrics?.metrics_names ?? []; | |||||
| const paramsNames = firstParams?.params_names ?? []; | |||||
| return [ | return [ | ||||
| { | { | ||||
| title: '基本信息', | title: '基本信息', | ||||
| @@ -1,7 +1,5 @@ | |||||
| .node-tooltips { | .node-tooltips { | ||||
| position: absolute; | position: absolute; | ||||
| bottom: -100px; | |||||
| left: -300px; | |||||
| z-index: 10; | z-index: 10; | ||||
| width: 300px; | width: 300px; | ||||
| padding: 10px; | padding: 10px; | ||||
| @@ -10,6 +8,30 @@ | |||||
| border-radius: 4px; | border-radius: 4px; | ||||
| box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | box-shadow: 0px 3px 6px rgba(146, 146, 146, 0.09); | ||||
| &::after { | |||||
| position: absolute; | |||||
| bottom: -8px; /* 让三角形紧贴 div 底部 */ | |||||
| left: 12px; /* 控制三角形相对 div 的位置 */ | |||||
| width: 0; | |||||
| height: 0; | |||||
| border-top: 8px solid white; /* 主要颜色 */ | |||||
| border-right: 8px solid transparent; | |||||
| border-left: 8px solid transparent; | |||||
| content: ''; | |||||
| } | |||||
| &::before { | |||||
| position: absolute; | |||||
| bottom: -10px; /* 边框略大,形成描边效果 */ | |||||
| left: 10px; /* 调整边框的偏移量,使其覆盖白色三角形 */ | |||||
| width: 0; | |||||
| height: 0; | |||||
| border-top: 10px solid #eaeaea; /* 这是边框颜色 */ | |||||
| border-right: 10px solid transparent; | |||||
| border-left: 10px solid transparent; | |||||
| content: ''; | |||||
| } | |||||
| &__title { | &__title { | ||||
| margin: 10px 0; | margin: 10px 0; | ||||
| color: @text-color; | color: @text-color; | ||||
| @@ -59,3 +81,31 @@ | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| .node-tooltips.node-tooltips--right { | |||||
| &::after { | |||||
| position: absolute; | |||||
| right: 12px; /* 控制三角形相对 div 的位置 */ | |||||
| bottom: -8px; /* 让三角形紧贴 div 底部 */ | |||||
| left: auto; | |||||
| width: 0; | |||||
| height: 0; | |||||
| border-top: 8px solid white; /* 主要颜色 */ | |||||
| border-right: 8px solid transparent; | |||||
| border-left: 8px solid transparent; | |||||
| content: ''; | |||||
| } | |||||
| &::before { | |||||
| position: absolute; | |||||
| right: 10px; /* 调整边框的偏移量,使其覆盖白色三角形 */ | |||||
| bottom: -10px; /* 边框略大,形成描边效果 */ | |||||
| left: auto; | |||||
| width: 0; | |||||
| height: 0; | |||||
| border-top: 10px solid #eaeaea; /* 这是边框颜色 */ | |||||
| border-right: 10px solid transparent; | |||||
| border-left: 10px solid transparent; | |||||
| content: ''; | |||||
| } | |||||
| } | |||||
| @@ -2,6 +2,7 @@ import { ResourceInfoTabKeys } from '@/pages/Dataset/components/ResourceInfo'; | |||||
| import { getGitUrl } from '@/utils'; | import { getGitUrl } from '@/utils'; | ||||
| import { formatDate } from '@/utils/date'; | import { formatDate } from '@/utils/date'; | ||||
| import { useNavigate } from '@umijs/max'; | import { useNavigate } from '@umijs/max'; | ||||
| import classNames from 'classnames'; | |||||
| import { ModelDepsData, NodeType, ProjectDependency, TrainDataset } from '../ModelEvolution/utils'; | import { ModelDepsData, NodeType, ProjectDependency, TrainDataset } from '../ModelEvolution/utils'; | ||||
| import styles from './index.less'; | import styles from './index.less'; | ||||
| @@ -180,6 +181,7 @@ type NodeTooltipsProps = { | |||||
| data: ModelDepsData | ProjectDependency | TrainDataset; | data: ModelDepsData | ProjectDependency | TrainDataset; | ||||
| x: number; | x: number; | ||||
| y: number; | y: number; | ||||
| isLeft: boolean; | |||||
| onMouseEnter?: () => void; | onMouseEnter?: () => void; | ||||
| onMouseLeave?: () => void; | onMouseLeave?: () => void; | ||||
| onVersionChange: (version: string) => void; | onVersionChange: (version: string) => void; | ||||
| @@ -190,6 +192,7 @@ function NodeTooltips({ | |||||
| data, | data, | ||||
| x, | x, | ||||
| y, | y, | ||||
| isLeft, | |||||
| onMouseEnter, | onMouseEnter, | ||||
| onMouseLeave, | onMouseLeave, | ||||
| onVersionChange, | onVersionChange, | ||||
| @@ -208,10 +211,13 @@ function NodeTooltips({ | |||||
| ) { | ) { | ||||
| Component = <ModelInfo resourceId={resourceId} data={data} onVersionChange={onVersionChange} />; | Component = <ModelInfo resourceId={resourceId} data={data} onVersionChange={onVersionChange} />; | ||||
| } | } | ||||
| const style = isLeft | |||||
| ? { left: `${x}px`, bottom: `${y}px` } | |||||
| : { right: `${x}px`, bottom: `${y}px` }; | |||||
| return ( | return ( | ||||
| <div | <div | ||||
| className={styles['node-tooltips']} | |||||
| style={{ left: `${x}px`, bottom: `${y}px` }} | |||||
| className={classNames(styles['node-tooltips'], { [styles['node-tooltips--right']]: !isLeft })} | |||||
| style={style} | |||||
| onMouseEnter={onMouseEnter} | onMouseEnter={onMouseEnter} | ||||
| onMouseLeave={onMouseLeave} | onMouseLeave={onMouseLeave} | ||||
| > | > | ||||
| @@ -20,7 +20,7 @@ import { | |||||
| import { changePropertyName } from '@/utils'; | import { changePropertyName } from '@/utils'; | ||||
| import { to } from '@/utils/promise'; | import { to } from '@/utils/promise'; | ||||
| import SessionStorage from '@/utils/sessionStorage'; | import SessionStorage from '@/utils/sessionStorage'; | ||||
| import { modalConfirm } from '@/utils/ui'; | |||||
| import { removeFormListItem } from '@/utils/ui'; | |||||
| import { MinusCircleOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons'; | import { MinusCircleOutlined, PlusCircleOutlined, PlusOutlined } from '@ant-design/icons'; | ||||
| import { useNavigate, useParams } from '@umijs/max'; | import { useNavigate, useParams } from '@umijs/max'; | ||||
| import { App, Button, Col, Flex, Form, Input, InputNumber, Row, Select } from 'antd'; | import { App, Button, Col, Flex, Form, Input, InputNumber, Row, Select } from 'antd'; | ||||
| @@ -434,7 +434,6 @@ function CreateServiceVersion() { | |||||
| {fields.map(({ key, name, ...restField }, index) => ( | {fields.map(({ key, name, ...restField }, index) => ( | ||||
| <Flex | <Flex | ||||
| key={key} | key={key} | ||||
| align="center" | |||||
| gap="0 8px" | gap="0 8px" | ||||
| style={{ | style={{ | ||||
| position: 'relative', | position: 'relative', | ||||
| @@ -453,16 +452,16 @@ function CreateServiceVersion() { | |||||
| }, | }, | ||||
| ]} | ]} | ||||
| > | > | ||||
| <Input placeholder="请输入变量名" disabled={disabled} /> | |||||
| <Input placeholder="请输入变量名" disabled={disabled} allowClear /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <span style={{ marginBottom: '24px' }}>=</span> | |||||
| <span style={{ lineHeight: '46px' }}>=</span> | |||||
| <Form.Item | <Form.Item | ||||
| {...restField} | {...restField} | ||||
| name={[name, 'value']} | name={[name, 'value']} | ||||
| style={{ flex: 1 }} | style={{ flex: 1 }} | ||||
| rules={[{ required: true, message: '请输入变量值' }]} | rules={[{ required: true, message: '请输入变量值' }]} | ||||
| > | > | ||||
| <Input placeholder="请输入变量值" disabled={disabled} /> | |||||
| <Input placeholder="请输入变量值" disabled={disabled} allowClear /> | |||||
| </Form.Item> | </Form.Item> | ||||
| <Flex | <Flex | ||||
| style={{ | style={{ | ||||
| @@ -484,12 +483,14 @@ function CreateServiceVersion() { | |||||
| icon={<MinusCircleOutlined />} | icon={<MinusCircleOutlined />} | ||||
| disabled={disabled} | disabled={disabled} | ||||
| onClick={() => { | onClick={() => { | ||||
| modalConfirm({ | |||||
| title: '确定要删除该环境变量吗?', | |||||
| onOk: () => { | |||||
| remove(name); | |||||
| }, | |||||
| }); | |||||
| removeFormListItem( | |||||
| form, | |||||
| 'env_variables', | |||||
| name, | |||||
| remove, | |||||
| ['key', 'value'], | |||||
| '删除后,该环境变量将不可恢复', | |||||
| ); | |||||
| }} | }} | ||||
| ></Button> | ></Button> | ||||
| {index === fields.length - 1 && ( | {index === fields.length - 1 && ( | ||||
| @@ -40,7 +40,8 @@ const GlobalParamsDrawer = forwardRef( | |||||
| const removeParameter = (name: number, remove: (param: number) => void) => { | const removeParameter = (name: number, remove: (param: number) => void) => { | ||||
| modalConfirm({ | modalConfirm({ | ||||
| title: '确认删除该参数吗?', | |||||
| title: '删除后,该全局参数将不可恢复', | |||||
| content: '是否确认删除?', | |||||
| onOk: () => { | onOk: () => { | ||||
| remove(name); | remove(name); | ||||
| }, | }, | ||||
| @@ -8,7 +8,16 @@ import { removeAllPageCacheState } from '@/hooks/pageCacheState'; | |||||
| import themes from '@/styles/theme.less'; | import themes from '@/styles/theme.less'; | ||||
| import { type ClientInfo } from '@/types'; | import { type ClientInfo } from '@/types'; | ||||
| import { history } from '@umijs/max'; | import { history } from '@umijs/max'; | ||||
| import { Modal, Upload, message, type ModalFuncProps, type UploadFile } from 'antd'; | |||||
| import { | |||||
| Modal, | |||||
| Upload, | |||||
| message, | |||||
| type FormInstance, | |||||
| type ModalFuncProps, | |||||
| type UploadFile, | |||||
| } from 'antd'; | |||||
| import { NamePath } from 'antd/es/form/interface'; | |||||
| import { isEmpty } from './index'; | |||||
| import { closeAllModals } from './modal'; | import { closeAllModals } from './modal'; | ||||
| import SessionStorage from './sessionStorage'; | import SessionStorage from './sessionStorage'; | ||||
| @@ -143,16 +152,38 @@ export const limitUploadFileType = (type: string) => { | |||||
| }; | }; | ||||
| /** | /** | ||||
| * 滚动到底部 | |||||
| * | |||||
| * @param {boolean} smooth - Determines if the scroll should be smooth | |||||
| * 删除 FormList 表单项,如果表单项没有值,则直接删除,否则弹出确认框 | |||||
| * @param form From实例 | |||||
| * @param listName FormList 的 name | |||||
| * @param name FormList 的其中一项 | |||||
| * @param remove FormList 的删除方法 | |||||
| * @param fieldNames FormList 的子项名称数组 | |||||
| * @param confirmTitle 弹出确认框的标题 | |||||
| */ | */ | ||||
| export const scrollToBottom = (element: HTMLElement | null, smooth: boolean = true) => { | |||||
| if (element) { | |||||
| const optons: ScrollToOptions = { | |||||
| top: element.scrollHeight, | |||||
| behavior: smooth ? 'smooth' : 'instant', | |||||
| }; | |||||
| element.scrollTo(optons); | |||||
| export const removeFormListItem = ( | |||||
| form: FormInstance, | |||||
| listName: NamePath, | |||||
| name: number, | |||||
| remove: (name: number) => void, | |||||
| fieldNames: NamePath[], | |||||
| confirmTitle: string, | |||||
| ) => { | |||||
| const fields = fieldNames.map((item) => [listName, name, item].flat()); | |||||
| const isEmptyField = fields.every((item) => { | |||||
| const value = form.getFieldValue(item); | |||||
| return isEmpty(value); | |||||
| }); | |||||
| if (isEmptyField) { | |||||
| remove(name); | |||||
| return; | |||||
| } | } | ||||
| modalConfirm({ | |||||
| title: confirmTitle, | |||||
| content: '是否确认删除?', | |||||
| onOk: () => { | |||||
| remove(name); | |||||
| }, | |||||
| }); | |||||
| }; | }; | ||||
| @@ -44,6 +44,7 @@ public class ServiceServiceImpl implements ServiceService { | |||||
| private ServiceDao serviceDao; | private ServiceDao serviceDao; | ||||
| @Resource | @Resource | ||||
| private AssetWorkflowDao assetWorkflowDao; | private AssetWorkflowDao assetWorkflowDao; | ||||
| @Override | @Override | ||||
| public Page<com.ruoyi.platform.domain.Service> queryByPageService(com.ruoyi.platform.domain.Service service, PageRequest pageRequest) { | public Page<com.ruoyi.platform.domain.Service> queryByPageService(com.ruoyi.platform.domain.Service service, PageRequest pageRequest) { | ||||
| long total = serviceDao.countService(service); | long total = serviceDao.countService(service); | ||||
| @@ -225,9 +226,9 @@ public class ServiceServiceImpl implements ServiceService { | |||||
| String req = HttpUtils.sendPost(argoUrl + modelService + "/delete", JSON.toJSONString(paramMap)); | String req = HttpUtils.sendPost(argoUrl + modelService + "/delete", JSON.toJSONString(paramMap)); | ||||
| if (StringUtils.isNotEmpty(req)) { | if (StringUtils.isNotEmpty(req)) { | ||||
| Map<String, Object> reqMap = JacksonUtil.parseJSONStr2Map(req); | Map<String, Object> reqMap = JacksonUtil.parseJSONStr2Map(req); | ||||
| if ((Integer) reqMap.get("code") == 200) { | |||||
| return serviceDao.updateServiceVersion(serviceVersion) > 0 ? "删除成功" : "删除失败"; | |||||
| } | |||||
| // if ((Integer) reqMap.get("code") == 200) { | |||||
| return serviceDao.updateServiceVersion(serviceVersion) > 0 ? "删除成功" : "删除失败"; | |||||
| // } | |||||
| } | } | ||||
| return "删除失败"; | return "删除失败"; | ||||
| } | } | ||||