Files
iot-device-management-frontend/apps/web-antd/src/components/form-create/helpers.ts

238 lines
6.2 KiB
TypeScript
Raw Normal View History

import type { Ref } from 'vue';
2025-04-23 22:37:33 +08:00
import type { Menu } from '#/components/form-create/typing';
2025-10-17 16:15:54 +08:00
import { isRef, nextTick, onMounted } from 'vue';
import formCreate from '@form-create/ant-design-vue';
2025-04-23 22:37:33 +08:00
import { apiSelectRule } from '#/components/form-create/rules/data';
import {
useDictSelectRule,
useEditorRule,
useSelectRule,
useUploadFileRule,
2025-04-23 22:37:33 +08:00
useUploadImageRule,
useUploadImagesRule,
} from './rules';
2025-10-17 16:15:54 +08:00
// 编码表单 Conf
export function encodeConf(designerRef: any) {
return JSON.stringify(designerRef.value.getOption());
}
// 编码表单 Fields
export function encodeFields(designerRef: any) {
const rule = JSON.parse(designerRef.value.getJson());
const fields: string[] = [];
rule.forEach((item: unknown) => {
fields.push(JSON.stringify(item));
});
return fields;
}
// 解码表单 Fields
export function decodeFields(fields: string[]) {
const rule: object[] = [];
fields.forEach((item) => {
rule.push(formCreate.parseJson(item));
});
return rule;
}
// 设置表单的 Conf 和 Fields适用 FcDesigner 场景
export function setConfAndFields(
designerRef: any,
conf: string,
fields: string | string[],
) {
designerRef.value.setOption(formCreate.parseJson(conf));
// 处理 fields 参数类型,确保传入 decodeFields 的是 string[] 类型
const fieldsArray = Array.isArray(fields) ? fields : [fields];
designerRef.value.setRule(decodeFields(fieldsArray));
}
// 设置表单的 Conf 和 Fields适用 form-create 场景
export function setConfAndFields2(
detailPreview: any,
conf: string,
fields: string[],
value?: any,
) {
if (isRef(detailPreview)) {
detailPreview = detailPreview.value;
}
detailPreview.option = formCreate.parseJson(conf);
detailPreview.rule = decodeFields(fields);
if (value) {
detailPreview.value = value;
}
}
2025-04-23 22:37:33 +08:00
export function makeRequiredRule() {
return {
type: 'Required',
field: 'formCreate$required',
title: '是否必填',
};
}
2025-10-17 16:15:54 +08:00
export function localeProps(
2025-04-23 22:37:33 +08:00
t: (msg: string) => any,
prefix: string,
rules: any[],
2025-10-17 16:15:54 +08:00
) {
2025-04-23 22:37:33 +08:00
return rules.map((rule: { field: string; title: any }) => {
if (rule.field === 'formCreate$required') {
rule.title = t('props.required') || rule.title;
} else if (rule.field && rule.field !== '_optionType') {
rule.title = t(`components.${prefix}.${rule.field}`) || rule.title;
}
return rule;
});
2025-10-17 16:15:54 +08:00
}
2025-04-23 22:37:33 +08:00
/**
* field, title
*
* @param rule https://www.form-create.com/v3/guide/rule
* @param fields
* @param parentTitle
*/
2025-10-17 16:15:54 +08:00
export function parseFormFields(
2025-04-23 22:37:33 +08:00
rule: Record<string, any>,
fields: Array<Record<string, any>> = [],
parentTitle: string = '',
2025-10-17 16:15:54 +08:00
) {
2025-04-23 22:37:33 +08:00
const { type, field, $required, title: tempTitle, children } = rule;
if (field && tempTitle) {
let title = tempTitle;
if (parentTitle) {
title = `${parentTitle}.${tempTitle}`;
}
let required = false;
if ($required) {
required = true;
}
fields.push({
field,
title,
type,
required,
});
// TODO 子表单 需要处理子表单字段
// if (type === 'group' && rule.props?.rule && Array.isArray(rule.props.rule)) {
// // 解析子表单的字段
// rule.props.rule.forEach((item) => {
// parseFields(item, fieldsPermission, title)
// })
// }
}
if (children && Array.isArray(children)) {
children.forEach((rule) => {
parseFormFields(rule, fields);
});
}
2025-10-17 16:15:54 +08:00
}
/**
* hook
*
* -
* -
* -
* -
* -
* -
* -
*/
2025-10-17 16:15:54 +08:00
export async function useFormCreateDesigner(designer: Ref) {
const editorRule = useEditorRule();
const uploadFileRule = useUploadFileRule();
2025-04-23 22:37:33 +08:00
const uploadImageRule = useUploadImageRule();
const uploadImagesRule = useUploadImagesRule();
/**
*
*/
2025-10-17 16:15:54 +08:00
function buildFormComponents() {
// 移除自带的上传组件规则,使用 uploadFileRule、uploadImgRule、uploadImgsRule 替代
designer.value?.removeMenuItem('upload');
// 移除自带的富文本组件规则,使用 editorRule 替代
designer.value?.removeMenuItem('fc-editor');
const components = [
editorRule,
uploadFileRule,
2025-04-23 22:37:33 +08:00
uploadImageRule,
uploadImagesRule,
];
components.forEach((component) => {
// 插入组件规则
designer.value?.addComponent(component);
// 插入拖拽按钮到 `main` 分类下
designer.value?.appendMenuItem('main', {
icon: component.icon,
name: component.name,
label: component.label,
});
});
2025-10-17 16:15:54 +08:00
}
const userSelectRule = useSelectRule({
name: 'UserSelect',
label: '用户选择器',
icon: 'icon-eye',
});
const deptSelectRule = useSelectRule({
name: 'DeptSelect',
label: '部门选择器',
icon: 'icon-tree',
});
const dictSelectRule = useDictSelectRule();
const apiSelectRule0 = useSelectRule({
name: 'ApiSelect',
label: '接口选择器',
icon: 'icon-json',
props: [...apiSelectRule],
event: ['click', 'change', 'visibleChange', 'clear', 'blur', 'focus'],
});
/**
*
*/
2025-10-17 16:15:54 +08:00
function buildSystemMenu() {
// 移除自带的下拉选择器组件,使用 currencySelectRule 替代
// designer.value?.removeMenuItem('select')
// designer.value?.removeMenuItem('radio')
// designer.value?.removeMenuItem('checkbox')
const components = [
userSelectRule,
deptSelectRule,
dictSelectRule,
apiSelectRule0,
];
const menu: Menu = {
name: 'system',
title: '系统字段',
list: components.map((component) => {
// 插入组件规则
designer.value?.addComponent(component);
// 插入拖拽按钮到 `system` 分类下
return {
icon: component.icon,
name: component.name,
label: component.label,
};
}),
};
designer.value?.addMenu(menu);
2025-10-17 16:15:54 +08:00
}
onMounted(async () => {
await nextTick();
buildFormComponents();
buildSystemMenu();
});
2025-10-17 16:15:54 +08:00
}