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