From 9bec4dcae002f36aa23231da11cb03a156b40110 Mon Sep 17 00:00:00 2001
From: schangxiang@126.com <schangxiang@126.com>
Date: 周三, 30 4月 2025 16:24:16 +0800
Subject: [PATCH] 222

---
 PipeLineLems/web/src/components/DyForm/DyForm.tsx |  317 +++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 247 insertions(+), 70 deletions(-)

diff --git a/PipeLineLems/web/src/components/DyForm/DyForm.tsx b/PipeLineLems/web/src/components/DyForm/DyForm.tsx
index 1468161..308cbd6 100644
--- a/PipeLineLems/web/src/components/DyForm/DyForm.tsx
+++ b/PipeLineLems/web/src/components/DyForm/DyForm.tsx
@@ -3,20 +3,26 @@
   defineComponent,
   PropType,
   ref,
-  Ref,
+  onMounted,
   SetupContext,
   computed,
   unref,
   markRaw,
-  DefineComponent,
+  Component,
+  watch,
+  Fragment,
+  useSlots,
 } from 'vue'
 import styles from './DyForm.module.scss'
-import ElInput from 'element-plus/es/components/input/index'
+import DyInput from '../Input/Input'
 import Option from '@/components/Select/Option'
 import Select from '@/components/Select/Select'
 import SelectInput from '@/components/SelectInput/SelectInput'
+import SearchSelect from '@/components/SearchSelect/SearchSelect'
 import type { FormInstance } from 'element-plus'
 import Icon from '../Icon/Icon'
+import { Warning } from '@element-plus/icons-vue'
+import RelationFlowDialog from '@/components/RelationFlowDialog/RelationFlowDialog'
 import {
   FormPropsType,
   FormItemPropType,
@@ -28,19 +34,44 @@
 import TextareaFlow from '../Flow/Flow'
 import get from 'lodash/get'
 import set from 'lodash/set'
+import { has } from 'lodash'
+import Tab from '@/components/Tab/Tab'
+import TabPane from '@/components/Tab/TabPane'
+import ElInputNumber from 'element-plus/es/components/input-number/index'
+import { getCurrentLang, Language } from '@/libs/Language/Language'
 
-const formItemElementMap = markRaw<Record<string, any>>({
-  input: ElInput,
+const formItemElementMap: Record<string, any> = markRaw({
+  input: DyInput,
+  inputNumber: ElInputNumber,
   select: Select,
   selectInput: SelectInput,
+  flow: RelationFlowDialog,
   variable: Variable,
   textareaFlow: TextareaFlow,
+  filterSelect: SearchSelect,
+  switch: (props: PropType<any>, { attrs }: SetupContext) => {
+    return <el-switch {...attrs} />
+  },
+  dateTime: (props: PropType<any>, { attrs }: SetupContext) => {
+    return <el-date-picker
+      type="datetime"
+      format="YYYY-MM-DD HH:mm:ss"
+      {...attrs}
+    ></el-date-picker>
+  },
+  date: (props: PropType<any>, { attrs }: SetupContext) => {
+    return <el-date-picker
+      type="date"
+      format="YYYY-MM-DD"
+      {...attrs}
+    ></el-date-picker>
+  },
 })
 
 const Type: Record<string, any> = {
   select: 'select',
 }
-export default defineComponent<FormPropsType>({
+export default defineComponent({
   //@ts-ignore
   name: '鍔ㄦ�佽〃鍗�',
   props: {
@@ -57,16 +88,31 @@
       default: () => ({}),
     },
     formItemProps: {
-      type: Array,
+      type: Array as PropType<FormItemPropType[]>,
       default: () => [],
     },
     inLine: {
       type: Boolean,
       default: false,
     },
+    customWidgetMap: {
+      type: Object,
+      default: () => ({}),
+    },
+    isCategory: {
+      type: Boolean,
+      default: false,
+    },
+    LanguageScopeKey: {
+      type: String,
+      default: '',
+    },
   },
   setup(props: PropsType, { attrs, emit, expose }: SetupContext) {
     const formRef = ref<FormInstance>()
+    const active = ref('')
+    const isZh = ref(true)
+    const slots = useSlots()
     const form: any = computed({
       get() {
         return props.formData
@@ -75,9 +121,14 @@
         emit('update:formData', v)
       },
     })
+    const formPropsRef = ref<any>({})
 
     const currentWidgetModel = computed(() => {
       return (path: string) => {
+        if (path.includes('.')) {
+          const args = path.split('.')
+          return get(form.value, args)
+        }
         return get(form.value, path)
       }
     })
@@ -94,6 +145,14 @@
         })
       })
     }
+    /**
+     * 鑾峰彇refs
+     * @returns
+     */
+    const getRefByKey = (key: string) => {
+      if (key) return formPropsRef.value[key]
+      return formPropsRef.value
+    }
 
     const resetForm = () => {
       if (!formRef.value) return false
@@ -101,10 +160,26 @@
     }
 
     const formItemProps = computed(() => {
+      if (props.isCategory) {
+        const tabMap: Record<string, FormItemPropType> = {}
+        const tabs: FormItemPropType[] = []
+        if (Array.isArray(props.formItemProps)) {
+          props.formItemProps.forEach((item: any) => {
+            tabMap[item.category] = tabMap[item.category] || []
+            tabMap[item.category].push(item)
+          })
+          Object.keys(tabMap).forEach((key: string) => {
+            tabs.push({
+              name: key,
+              content: tabMap[key],
+            })
+          })
+        }
+        return tabs
+      }
+
       return props.formItemProps || []
     })
-
-    expose({ validate, resetForm })
 
     const FormRender: any = ($props: any) => {
       const item: FormItemPropType = $props.item
@@ -112,17 +187,158 @@
       if (item.el && Type[item.el as string]) {
         return options.map((el: OptionItemType) => (
           <Option
-            label={el.label || el.description || el.name}
             value={el.value}
-          ></Option>
+            label={el.label || el.description || el.name}
+            class={styles.optionLabel}
+            key={el.value}
+          >
+            {el.label || el.description || el.name}
+            {el.tip ? (
+              <el-tooltip
+                class="box-item"
+                effect="dark"
+                content={el.tip}
+                placement="top"
+                key={el.value}
+                persistent={false}
+              >
+                <el-icon>
+                  <Warning />
+                </el-icon>
+              </el-tooltip>
+            ) : null}
+          </Option>
         ))
       }
       return null
     }
 
-    const onUpdateModelValue = (v: string | number, prop: string) => {
-      set(form.value, prop, v)
+    const onUpdateModelValue = (v: string | number, path: string) => {
+      if (path.includes('.')) {
+        const args = path.split('.')
+        return set(form.value, args, v)
+      }
+      set(form.value, path, v)
     }
+
+    const initFormData = () => {
+      formItemProps.value.forEach((item: FormItemPropType) => {
+        form.value[item.prop] = form.value[item.prop] || item.defaultValue
+      })
+      active.value = formItemProps.value[0].name
+    }
+
+    const checkZh = (lang: string) => {
+      const languageStr = lang.toLowerCase()
+      if (languageStr.includes('zh')) return true
+      if (languageStr.includes('original')) return true
+      return false
+    }
+
+    const onLanguageChange = () => {
+      Language.useChange((language: any) => {
+        isZh.value = checkZh(language.lang)
+      })
+    }
+
+    onMounted(() => {
+      isZh.value = checkZh(getCurrentLang())
+      onLanguageChange()
+    })
+
+    const RenderItemProps = ($props: any) => {
+      const WidgetMap = {
+        ...formItemElementMap,
+        ...props.customWidgetMap,
+      }
+      const formItemProps = $props.formItemProps
+
+      return (
+        <Fragment>
+          {formItemProps.map((item: FormItemPropType, index: number) => {
+            if (item.isTitle) {
+              if (typeof item.title === 'string') {
+                return <Title style="margin-bottom: 10px">{item.title}</Title>
+              }
+              return item.title
+            }
+
+            const itemProps: FormItemPropType = {}
+            Object.entries(item).forEach(([key, value]) => {
+              itemProps[key] = unref(value)
+            })
+            const el =
+              typeof itemProps.el === 'string'
+                ? WidgetMap[itemProps.el]
+                : itemProps.el || null
+            const hasSlot = itemProps.slot
+            const Component = hasSlot ? slots[itemProps.el] : el
+
+            const isHide = has(item.isHide, 'value')
+              ? item.isHide?.value
+              : item.isHide
+            return Component && !isHide ? (
+              <el-form-item
+                label={itemProps.label}
+                prop={itemProps.prop}
+                rules={itemProps.rules}
+                key={itemProps.prop + index}
+                class={styles.itemDistance}
+                labelPosition={itemProps.labelPosition}
+                labelWidth={isZh.value ? props.labelWidth : 'auto'}
+                vSlots={
+                  itemProps.icon
+                    ? {
+                      label: () => (
+                        <label
+                          key={itemProps.prop}
+                          class={styles.formitemPropsLabel}
+                        >
+                          {itemProps.label}
+                          {itemProps.icon ? (
+                            <el-tooltip
+                              class="box-item"
+                              effect="dark"
+                              content={itemProps.tip}
+                              placement="top"
+                              raw-content={itemProps.rawContent}
+                              persistent={false}
+                            >
+                              <Icon
+                                style="margin-left: 5px"
+                                icon={itemProps.icon}
+                              />
+                            </el-tooltip>
+                          ) : null}
+                        </label>
+                      ),
+                    }
+                    : null
+                }
+              >
+                <Component
+                  style={{
+                    width: itemProps.width,
+                    height: itemProps.height,
+                  }}
+                  {...itemProps}
+                  placeholder={itemProps.placeholder}
+                  ref={(ref) => (formPropsRef.value[itemProps.prop] = ref)}
+                  modelValue={currentWidgetModel.value(itemProps.prop)}
+                  onUpdate:modelValue={(val: string | number) =>
+                    onUpdateModelValue(val, itemProps.prop)
+                  }
+                >
+                  <FormRender item={itemProps} />
+                </Component>
+              </el-form-item>
+            ) : null
+          })}
+        </Fragment>
+      )
+    }
+
+    expose({ validate, resetForm, initFormData, getRefByKey })
 
     return () => {
       return (
@@ -130,67 +346,28 @@
           <el-form
             labelPosition={props.labelPosition}
             labelWidth={props.labelWidth}
+            // labelWidth={isZh.value ? props.labelWidth : 'auto'}
             model={form.value}
             ref={formRef}
             inline={props.inLine}
           >
-            {formItemProps.value.map(
-              (item: FormItemPropType, index: number) => {
-                if (item.isTitle) {
-                  if (typeof item.title === 'string') {
-                    return (
-                      <Title style="margin-bottom: 10px">{item.title}</Title>
-                    )
-                  }
-                  return item.title
-                }
-
-                const itemProps: FormItemPropType = {}
-                Object.entries(item).forEach(([key, value]) => {
-                  itemProps[key] = unref(value)
-                })
-
-                const el =
-                  typeof itemProps.el === 'string'
-                    ? formItemElementMap[itemProps.el]
-                    : itemProps.el || null
-                const Component = el
-                return Component && !item.isHide ? (
-                  <el-form-item
-                    label={itemProps.label}
-                    prop={itemProps.prop}
-                    rules={itemProps.rules}
-                    key={itemProps.prop}
-                    vSlots={
-                      itemProps.labelIcon
-                        ? {
-                            label: () => (
-                              <label class={styles.formitemPropsLabel}>
-                                {itemProps.label}
-                                <Icon icon={itemProps.labelIcon} />
-                              </label>
-                            ),
-                          }
-                        : null
-                    }
-                  >
-                    <Component
-                      style={{
-                        width: itemProps.width,
-                        height: itemProps.height,
-                      }}
-                      {...itemProps}
-                      // v-model={form.value[itemProps.prop as keyof any]}
-                      modelValue={currentWidgetModel.value(itemProps.prop)}
-                      onUpdate:modelValue={(val: string | number) =>
-                        onUpdateModelValue(val, itemProps.prop)
-                      }
-                    >
-                      <FormRender item={itemProps} />
-                    </Component>
-                  </el-form-item>
-                ) : null
-              }
+            {props.isCategory ? (
+              <Tab
+                active={active.value}
+                class={styles.tabContent}
+                size="small"
+                type="params"
+              >
+                {formItemProps.value.map((item: any) => {
+                  return (
+                    <TabPane key={item.name} label={item.name} name={item.name}>
+                      <RenderItemProps formItemProps={item.content} />
+                    </TabPane>
+                  )
+                })}
+              </Tab>
+            ) : (
+              <RenderItemProps formItemProps={formItemProps.value} />
             )}
           </el-form>
         </div>

--
Gitblit v1.9.3