From 6aabfd0832b729655fa87eb7d5473d4fdc33898f Mon Sep 17 00:00:00 2001 From: donghao Date: Fri, 1 Aug 2025 17:41:45 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BD=BF=E7=94=A8t-ui-plus=E5=AE=8C?= =?UTF-8?q?=E6=88=90=E5=9B=BE=E5=83=8F=E6=BA=90=E5=92=8C=E5=A4=9A=E5=9B=BE?= =?UTF-8?q?=E9=87=87=E9=9B=86=E6=A8=A1=E5=9D=97=E5=86=85=E5=AE=B9=E5=BC=80?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/renderer/src/components/Button/index.ts | 4 +- .../components/Button/src/addItemButton.tsx | 105 +++ src/renderer/src/components/Form/dsSwitch.tsx | 35 +- src/renderer/src/components/Form/formList.tsx | 141 ++++ src/renderer/src/components/Form/index.ts | 8 +- .../src/components/Form/inputNumber.tsx | 14 +- src/renderer/src/styles/ds-dialog.scss | 12 +- src/renderer/src/styles/ds-from.scss | 62 +- src/renderer/src/styles/global.scss | 2 + src/renderer/src/styles/t-element-plus.scss | 2 +- .../FlowImagesCapture/imageNodeModel copy.vue | 270 -------- .../FlowImagesCapture/imageNodeModel.scss | 0 .../FlowImagesCapture/imageNodeModel.vue | 89 ++- .../multiImageNodeModel copy.vue | 328 --------- .../multiImageNodeModel.scss | 40 -- .../FlowImagesCapture/multiImageNodeModel.vue | 632 +++++++++++------- .../views/Design/Workflow/logicFlowView.vue | 10 +- 17 files changed, 760 insertions(+), 994 deletions(-) create mode 100644 src/renderer/src/components/Button/src/addItemButton.tsx create mode 100644 src/renderer/src/components/Form/formList.tsx delete mode 100644 src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel copy.vue delete mode 100644 src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.scss delete mode 100644 src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel copy.vue delete mode 100644 src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.scss diff --git a/src/renderer/src/components/Button/index.ts b/src/renderer/src/components/Button/index.ts index ad8d554..1d45107 100644 --- a/src/renderer/src/components/Button/index.ts +++ b/src/renderer/src/components/Button/index.ts @@ -2,9 +2,11 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-08 09:43:27 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-08 09:47:01 + * @LastEditTime: 2025-07-30 17:28:42 * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Button\index.ts * @Description: */ import button from './src/button.tsx' +import addItemButton from './src/addItemButton.tsx' export const DSButton = button +export const DSAddItemButton = addItemButton \ No newline at end of file diff --git a/src/renderer/src/components/Button/src/addItemButton.tsx b/src/renderer/src/components/Button/src/addItemButton.tsx new file mode 100644 index 0000000..b121043 --- /dev/null +++ b/src/renderer/src/components/Button/src/addItemButton.tsx @@ -0,0 +1,105 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-29 10:48:37 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-07-31 14:07:39 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\Button.tsx + * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + */ +import { defineComponent, h, computed, normalizeClass } from 'vue' +import addIcon from '@/assets/images/common/table_addBtn.png' +export interface DsAddItemButtonProps { + /** + * Button 前面的文案 + */ + // prefixRender?: (...ags: any[]) => any // 前缀内容 render渲染 + /** + * Button 后面的文案 + */ + suffixRender?: (...ags: any[]) => any // 后缀内容 render渲染 + /** + * Button 后面的文案 + */ + suffixText?: string + /** + * container容器样式 + */ + iconClassName?: string + + /** + * 整体容器样式 + */ + componentClassName?: string +} + +export default defineComponent({ + name: 'DSSwitch', + props: { + suffixRender: { + type: Function as DsAddItemButtonProps['suffixRender'], + default: null + }, + suffixText: { + type: String, + default: '' + }, + iconClassName: { + type: String, + default: '' + }, + componentClassName: { + type: String, + default: '' + } + }, + setup(props, { emit, attrs }) { + const { iconClassName, componentClassName, ...restProps } = props + // 处理自定义类名和 Vue 的 class 属性 + const componentClasses = computed(() => { + const classes = [ + 'ds-formItem-add-btn cursor-pointer px-[10px] flex items-center', + componentClassName + ] + // 处理 Vue 的 class 属性(支持字符串/数组/对象) + if (attrs.class) { + classes.push(normalizeClass(attrs.class)) + } + return classes.filter((c) => c).join(' ') + }) + // 处理自定义类名和 Vue 的 class 属性 + const iconClasses = computed(() => { + const classes = ['w-[16px] h-[16px] mr-2', iconClassName] + // 处理 Vue 的 class 属性(支持字符串/数组/对象) + if (attrs.class) { + classes.push(normalizeClass(attrs.class)) + } + return classes.filter((c) => c).join(' ') + }) + + // 渲染自定义前缀内容 + // const renderPrefix = () => { + // if (props.prefixRender) { + // return props?.prefixRender?.() + // } + // return null + // } + // 渲染自定义后缀内容 + const renderSuffix = () => { + if (props.suffixRender) { + return props?.suffixRender?.() + } + if (props.suffixText) { + return props.suffixText + } + return '添加数据' + } + + return () => ( +
+ {/* {renderPrefix()} */} + + {renderSuffix()} +
+ ) + } +}) diff --git a/src/renderer/src/components/Form/dsSwitch.tsx b/src/renderer/src/components/Form/dsSwitch.tsx index fb4d8e0..a68441d 100644 --- a/src/renderer/src/components/Form/dsSwitch.tsx +++ b/src/renderer/src/components/Form/dsSwitch.tsx @@ -2,43 +2,24 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-29 10:48:37 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-30 14:32:45 + * @LastEditTime: 2025-07-31 10:09:54 * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\switch.tsx - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + * @Description: Switch 组件 */ import { defineComponent, h, withDefaults, computed, normalizeClass } from 'vue' import { ElSwitch } from 'element-plus' import type { SwitchProps } from 'element-plus' -import { spawn } from 'child_process' interface DsSwitchProps extends SwitchProps { - /** - * switch 前面的文案 - */ label?: string - - /** - * switch 前面的文案 - */ prefixRender?: (...ags: any[]) => any // 前缀内容 render渲染 - /** - * switch 后面的文案 - */ suffixRender?: (...ags: any[]) => any // 后缀内容 render渲染 - - /** - * container容器样式 - */ - containerClassName?: string - - /** - * 整体容器样式 - */ - componentClassName?: string + containerClassName?: string // container容器样式 + componentClassName?: string // 整体容器样式 } export default defineComponent({ - name: 'DsSwitch', + name: 'DSSwitch', props: { modelValue: { type: [Boolean, String, Number], @@ -93,11 +74,7 @@ export default defineComponent({ if (props.prefixRender) { return props?.prefixRender?.() } - return ( - - {props?.label} - - ) + return {props?.label} } // 渲染自定义后缀内容 const renderSuffix = () => { diff --git a/src/renderer/src/components/Form/formList.tsx b/src/renderer/src/components/Form/formList.tsx new file mode 100644 index 0000000..54a3a92 --- /dev/null +++ b/src/renderer/src/components/Form/formList.tsx @@ -0,0 +1,141 @@ +/* + * @Author: donghao donghao@supervision.ltd + * @Date: 2025-07-31 10:03:44 + * @LastEditors: donghao donghao@supervision.ltd + * @LastEditTime: 2025-08-01 17:04:27 + * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\formList.tsx + * @Description: 定义 formList 组件 + */ +// +import { defineComponent, getCurrentInstance, ComputedRef, computed, toRaw } from 'vue' +import type { FormTypes } from '@wocwin/t-ui-plus' +import { TForm } from '@wocwin/t-ui-plus' +import { ElMessage } from 'element-plus' +import { generateId } from '@/utils/plugins/random' +import { DSAddItemButton } from '@/components/Button' +import { Delete } from '@element-plus/icons-vue' + +// 定义组件属性类型(保留所有 ElInputNumber 属性) +type DSFormListProps = { + formConfig: FormTypes + prefixRender?: (...ags: any[]) => any // 前置内容 render渲染 + suffixRender?: (...ags: any[]) => any // 后置内容 render渲染 + min?: number + max?: number +} + +export default defineComponent({ + name: 'DSFormList', + props: { + formConfig: { + type: Object as FormTypes, + default: {} + }, + modelValue: { + type: Array, + default: () => [] + }, + min: { + type: Number, + default: 0 + }, + max: { + type: Number, + default: Infinity + } + }, + emits: ['update:modelValue'], + setup(props: DSFormListProps, { emit, slots, attrs }) { + const tFormAttrs = (index) => { + const { formConfig, ...propsRest } = props + const refId = formConfig.ref + index + const finalOpts = { + ...formConfig, + ref: refId, + modelValue: refId, + formData: props.modelValue[index] + } + return { ...finalOpts, formOpts: finalOpts } + } + + const addItem = () => { + const list = props.modelValue + if (list.length >= props.max) { + ElMessage.warning(`最多只能添加 ${props.max} 项`) + return + } + list.push({ formItemsUuid: generateId() }) + emit( + 'update:modelValue', + list.map(({ formItemsUuid, ...rest }) => rest) + ) + } + + const removeItem = (formItem, index) => { + const list = props.modelValue + if (list.length <= props.min) { + ElMessage.warning(`至少需要保留 ${props.min} 项`) + return + } + console.log('removeItem', formItem, index) + list.splice(index, 1) + emit('update:modelValue', list) + } + + const moveItem = (index, direction) => { + const list = props.modelValue + if ( + (direction === 'up' && index === 0) || + (direction === 'down' && index === list.length - 1) + ) { + return + } + + const newIndex = direction === 'up' ? index - 1 : index + 1 + const item = list.splice(index, 1)[0] + list.splice(newIndex, 0, item) + emit('update:modelValue', list) + } + // const canAdd = list.length < props.max + // const canRemove = list.length > props.min + // 渲染自定义前缀内容 + const renderPrefix = (formItem, index) => { + // props?.suffixRender && + if (props.prefixRender) { + return props?.prefixRender?.() + } + return ( +
+ + {props.formConfig?.title} + {Number(index) + 1} + +
removeItem(formItem, index)} + class="flex items-center justify-center ds-dialog-formList-delete" + > + +
+
+ ) + } + return () => ( +
+ + addItem()}> +
+ ) + } +}) diff --git a/src/renderer/src/components/Form/index.ts b/src/renderer/src/components/Form/index.ts index a07a003..adcb71e 100644 --- a/src/renderer/src/components/Form/index.ts +++ b/src/renderer/src/components/Form/index.ts @@ -2,11 +2,13 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-28 10:07:16 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-30 11:29:49 + * @LastEditTime: 2025-07-31 13:47:27 * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\index.ts - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + * @Description: 统一导出表单组件 */ import inputNumber from './inputNumber' import dsSwitch from './dsSwitch' +import formList from './formList' export const DSInputNumber = inputNumber -export const DsSwitch = dsSwitch \ No newline at end of file +export const DSSwitch = dsSwitch +export const DSFormList = formList diff --git a/src/renderer/src/components/Form/inputNumber.tsx b/src/renderer/src/components/Form/inputNumber.tsx index ce58812..bdc4aeb 100644 --- a/src/renderer/src/components/Form/inputNumber.tsx +++ b/src/renderer/src/components/Form/inputNumber.tsx @@ -2,9 +2,9 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-28 16:45:11 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-30 14:30:36 + * @LastEditTime: 2025-07-31 13:12:10 * @FilePath: \Robot-Al-Platform-Web\src\renderer\src\components\Form\inputNumber.tsx - * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE + * @Description: inputNumber */ import { defineComponent, getCurrentInstance, ComputedRef, computed } from 'vue' import { ElInputNumber, inputNumberProps, InputNumberProps } from 'element-plus' @@ -16,6 +16,7 @@ type DSInputNumberProps = InputNumberProps & { // 可在此处添加自定义属性 prefixRender?: (...ags: any[]) => any // 前置内容 render渲染 suffixRender?: (...ags: any[]) => any // 后置内容 render渲染 + isHasSuffix?: boolean // 是否有后置内容 } export default defineComponent({ @@ -27,6 +28,10 @@ export default defineComponent({ controlsPosition: { type: String, default: 'right' + }, + isHasSuffix: { + type: Boolean, + default: true } }, emits: [ @@ -38,7 +43,7 @@ export default defineComponent({ 'input' ] as unknown as InputNumberEmits, - setup(props: CustomInputNumberProps, { emit, slots, attrs }) { + setup(props: DSInputNumberProps, { emit, slots, attrs }) { const instance = getCurrentInstance()! // 处理自定义逻辑 @@ -74,6 +79,9 @@ export default defineComponent({ // 渲染自定义后缀内容 const renderSuffix = () => { // props?.suffixRender && + if(!props.isHasSuffix){ + return null + } if (props.suffixRender) { return props?.suffixRender?.() } diff --git a/src/renderer/src/styles/ds-dialog.scss b/src/renderer/src/styles/ds-dialog.scss index c8860f3..b61e4fd 100644 --- a/src/renderer/src/styles/ds-dialog.scss +++ b/src/renderer/src/styles/ds-dialog.scss @@ -35,15 +35,5 @@ .el-dialog__header { height: var(--ds-dialog-header-height); } - // 弹窗图标 - .ds-dialog-icon-box { - width: 48px; - height: 32px; - background-color: var(--ds-dialog-icon-background-color); - font-size: 14px !important; - cursor: pointer; - svg { - width: 28px; - } - } + } diff --git a/src/renderer/src/styles/ds-from.scss b/src/renderer/src/styles/ds-from.scss index 0a74b14..a10c0c8 100644 --- a/src/renderer/src/styles/ds-from.scss +++ b/src/renderer/src/styles/ds-from.scss @@ -1,5 +1,10 @@ // 表单弹框 .ds-dialog-form-container { + padding: 24px 12px 24px 24px; + + .ds-dialog-form-footer { + margin-right: 12px; + } .el-select__wrapper { background: var(--ds-form-item-background-color) !important; .el-select__selected-item { @@ -16,36 +21,73 @@ } } + /* 适配表单间距 */ + .t-form { + gap: 16px 0; + } .el-form-item--large { - margin-bottom: 16px; - // margin-right: 12px !important; + margin-bottom: 0 !important; + .el-form-item__content { + width: calc(100% - 2px); + } + } + // proFormList + .ds-form-list-comp-form{ + width: calc(100% + 12px); } .el-form-item--large .el-form-item__content { line-height: 32px; - height: 32px; + // height: 32px; } .el-select--large .el-select__wrapper { - min-height: 32px; + min-height: var(--ds-form-item-height); padding: 4px 16px; } // el-switch .el-switch--large .el-switch__core { border-radius: 16px; height: 20px; - line-height: 20; + line-height: 20px; min-width: 40px; width: 40px; } + .ds-switch-box{ + height: var(--ds-form-item-height); + } + // 重置输入框样式 + .el-input__wrapper { + background: var(--ds-form-item-background-color); + } } -.el-input__wrapper { - background: var(--ds-form-item-background-color) !important; +// 常规字体 +.ds-form-normal-text { + color: var(--ds-color-info); } // 描述字体 .ds-form-des-text { color: var(--ds-des-text-1); } -// 描述字体 -.ds-form-normal-text { - color: var(--ds-color-info); + +// 弹窗图标 +.ds-dialog-icon-box { + width: 48px; + height: 32px; + background-color: var(--ds-dialog-icon-background-color); + font-size: 14px !important; + cursor: pointer; + svg { + width: 28px; + } +} +// formList删除按钮 +.ds-dialog-formList-delete { + width: 48px; + height: 32px; + font-size: 14px !important; + cursor: pointer; + color: var(--ds-light-1); + svg { + width: 18px; + } } diff --git a/src/renderer/src/styles/global.scss b/src/renderer/src/styles/global.scss index 4e91b28..07ae810 100644 --- a/src/renderer/src/styles/global.scss +++ b/src/renderer/src/styles/global.scss @@ -29,11 +29,13 @@ --ds-bg-color-light-5: #565656; // 背景色 // #4E5969 --ds-light-0: #00b429; // 浅色1 + --ds-light-1: #F53F3E; // 浅色2 --ds-des-text-1: #86909c; // 描述色8 --ds-border-width: 1px; // 边框宽度 --ds-border-color: #4e5969; // 边框色 --ds-border-style: solid; // 边框样式 --ds-box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.1); // 阴影 + --ds-form-item-height: 32px; // 边框色 // --ds-light-2: #eaeaea; // 浅色2 // --ds-light-3: #dcdcdc; // 浅色3 diff --git a/src/renderer/src/styles/t-element-plus.scss b/src/renderer/src/styles/t-element-plus.scss index 5a9bd7b..28ddc43 100644 --- a/src/renderer/src/styles/t-element-plus.scss +++ b/src/renderer/src/styles/t-element-plus.scss @@ -97,7 +97,7 @@ margin-left: 0px; } .t-form .t-margin-top-5 { - margin-top: 5px; + margin-top: 0px; // 重置此样式 } .t-form .el-input-number .el-input .el-input__inner { text-align: left; diff --git a/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel copy.vue b/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel copy.vue deleted file mode 100644 index d543128..0000000 --- a/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel copy.vue +++ /dev/null @@ -1,270 +0,0 @@ - - - diff --git a/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.scss b/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.scss deleted file mode 100644 index e69de29..0000000 diff --git a/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.vue b/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.vue index 4a46b16..997c423 100644 --- a/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.vue +++ b/src/renderer/src/views/Design/FlowImagesCapture/imageNodeModel.vue @@ -2,39 +2,17 @@ * @Author: donghao donghao@supervision.ltd * @Date: 2025-07-03 11:12:04 * @LastEditors: donghao donghao@supervision.ltd - * @LastEditTime: 2025-07-30 15:52:28 + * @LastEditTime: 2025-08-01 09:19:24 * @FilePath: \electron-project\Robot-Al\Robot-Al-Platform-Web\src\renderer\src\views\Design\FlowImagesCapture\imageNodeModel.vue * @Description: 图像源节点 --> - - - - + diff --git a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel copy.vue b/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel copy.vue deleted file mode 100644 index c1ca8df..0000000 --- a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel copy.vue +++ /dev/null @@ -1,328 +0,0 @@ - - - - - diff --git a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.scss b/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.scss deleted file mode 100644 index 95aafd7..0000000 --- a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.scss +++ /dev/null @@ -1,40 +0,0 @@ -/* 弹框整体样式 */ -.controllerManagement-container { - position: relative; - width: 100%; - height: 766px; - box-sizing: border-box; - display: flex; - - .controllerManagement-content { - flex: 1; - height: 100%; - overflow: auto; - box-sizing: border-box; - padding: 16px 24px 24px; - - .form-device-btn { - width: 80px; - padding: 0 12px; - } - } - - .custom-table { - .customList-table { - width: 100%; - height: 190px; - background: #363940; - } - } - - .table-add-btn { - /* 按钮样式 */ - box-sizing: border-box; - width: 128px; - height: 40px; - display: flex; - align-items: center; - justify-content: center; - cursor: pointer; - } -} diff --git a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.vue b/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.vue index c1ca8df..95b0366 100644 --- a/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.vue +++ b/src/renderer/src/views/Design/FlowImagesCapture/multiImageNodeModel.vue @@ -1,20 +1,26 @@ - - - - diff --git a/src/renderer/src/views/Design/Workflow/logicFlowView.vue b/src/renderer/src/views/Design/Workflow/logicFlowView.vue index 5dbfef5..42ac2aa 100644 --- a/src/renderer/src/views/Design/Workflow/logicFlowView.vue +++ b/src/renderer/src/views/Design/Workflow/logicFlowView.vue @@ -129,15 +129,15 @@ const initEvents = () => { // // currNodeData.value = data // console.log('node:click-currNodeData', currNodeData.value) // // changeAttrPanelStatus(true) + // currNodeData.value = data + // console.log('node:dbclick-currNodeData', currNodeData.value) + // changeAttrPanelStatus(true) + }) + lf.value.on('node:dbclick', ({ data }) => { currNodeData.value = data console.log('node:dbclick-currNodeData', currNodeData.value) changeAttrPanelStatus(true) }) - // lf.value.on('node:dbclick', ({ data }) => { - // currNodeData.value = data - // console.log('node:dbclick-currNodeData', currNodeData.value) - // changeAttrPanelStatus(true) - // }) // lf.value.on('edge:dbclick', ({ data }) => { // currNodeData.value = data // })