You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2677 lines
86 KiB
2677 lines
86 KiB
<!--
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 08:47:28
|
|
@ 备注: 表单控件(app)专用
|
|
-->
|
|
<script lang="ts" setup>
|
|
import { getRequest } from "@/api/DesignForm";
|
|
import { chineseToPinyin, customerFormGroupList } from "@/api/DesignForm/requestapi";
|
|
import { formatNumber } from "@/api/DesignForm/utils";
|
|
import appValidate from "./validateApp";
|
|
import appNumberValidate from "./rule/numberRules";
|
|
import { useDesignFormStore } from "@/store/DesignForm/designForm";
|
|
|
|
import { VideoMsg, PublicAtrr } from "@/api/DesignForm/types";
|
|
import { genFileId } from "element-plus";
|
|
import type { UploadInstance, UploadProps, UploadRawFile } from "element-plus";
|
|
|
|
//数学计算公式编辑器
|
|
import MathFormula from "@/components/DesignForm/math/mathFormula.vue";
|
|
//样式布局
|
|
import LayoutPage from "@/components/DesignForm/layoutPage/index.vue";
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 09:07:53
|
|
@ 功能: 接收父级参数
|
|
*/
|
|
const props = withDefaults(
|
|
defineProps<{
|
|
formData: any;
|
|
formList: any;
|
|
formConfig: any;
|
|
formOtherData: any;
|
|
customerformid: number | string;
|
|
formInfo: any;
|
|
isEdit: boolean;
|
|
formField: any[];
|
|
}>(),
|
|
{
|
|
formConfig: () => {
|
|
return {};
|
|
},
|
|
formOtherData: () => {
|
|
// 其他不需要保存在formData里的数据
|
|
return {};
|
|
},
|
|
isEdit: () => {
|
|
return false;
|
|
},
|
|
formField: () => {
|
|
return [];
|
|
},
|
|
}
|
|
);
|
|
//注册自定义事件
|
|
const emits = defineEmits<{
|
|
(e: "openDialog", data: any): void;
|
|
(e: "update:formOtherData", data: any): void;
|
|
(e: "videoMsgChange", data: VideoMsg): void;
|
|
//(e: 'update:formData', data: any): void
|
|
//(e: 'update:formConfig', data: any): void
|
|
}>();
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 09:08:19
|
|
@ 功能: 接收值转化ref对象
|
|
*/
|
|
const { formConfig, formData } = toRefs(props);
|
|
const store = useDesignFormStore() as any;
|
|
const designType = inject("formDesignType");
|
|
const dataSourceOption = ref([]);
|
|
|
|
const controlData = computed(() => {
|
|
// console.log("注册自定义事件----------------->",store.controlAttr)
|
|
return store.controlAttr;
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 09:14:03
|
|
@ 功能: 表单及组件单元控制属性
|
|
*/
|
|
const state = reactive({
|
|
dataSourceList: [], //数据源列表
|
|
customRulesList: [...appValidate], // 自定义校验规则
|
|
tooltip: {
|
|
css: "当前表单应用页的样式,类似于.vue文件中的style scoped中的样式",
|
|
dict:
|
|
'数据字典,用于匹配多选组、下拉选择等,提供动态获取Options接口字典数据,一般不设置,从接口dict获取。json格式:"sex":{"0":"男","1":"女"}',
|
|
rules:
|
|
"可参考UI组件表单校验,<a href='https://element-plus.gitee.io/zh-CN/component/form.html#%E8%A1%A8%E5%8D%95%E6%A0%A1%E9%AA%8C' target='_blank' style='color:red'>详情点击</a>",
|
|
props: "可添加当前组件所有prop属性及事件方法",
|
|
},
|
|
tabsName: "second",
|
|
numberRulesList: [...appNumberValidate],
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 10:15:14
|
|
@ 功能: 分组数据
|
|
*/
|
|
const page = ref<number>(1);
|
|
const pageSize = ref<number>(200000);
|
|
const loadingmore = ref(false);
|
|
const loadingnomore = ref(false);
|
|
const formGroup = ref<any[]>([]);
|
|
const gainFormGroupList = () => {
|
|
loadingmore.value = true;
|
|
let sendInfo = {
|
|
page: page.value,
|
|
pagesize: pageSize.value,
|
|
state: 1,
|
|
};
|
|
customerFormGroupList(sendInfo)
|
|
.then((data) => {
|
|
formGroup.value = data.data;
|
|
})
|
|
.finally(() => {
|
|
loadingmore.value = false;
|
|
});
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 09:44:23
|
|
@ 功能: 表单控制项
|
|
*/
|
|
const formControlProject = computed(() => {
|
|
const isSearch = state.isSearch;
|
|
return [
|
|
{
|
|
label: "表单名称",
|
|
placeholder: "用于保存的表单名称",
|
|
value: props.formOtherData.formName,
|
|
key: "formName",
|
|
hide: isSearch,
|
|
},
|
|
{
|
|
label: "数据源",
|
|
placeholder: "请选择数据源",
|
|
value: formatNumber(props.formOtherData.source),
|
|
type: "select",
|
|
options: dataSourceOption.value,
|
|
key: "source",
|
|
hide: isSearch || !dataSourceOption.value?.length,
|
|
clearable: true,
|
|
},
|
|
{
|
|
label: "表单标识",
|
|
value: formData.value.name,
|
|
placeholder: "表单唯一标识,可为空",
|
|
key: "name",
|
|
hide: isSearch,
|
|
},
|
|
];
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:20:18
|
|
@ 功能: 根据选定数据源获取表单字段
|
|
*/
|
|
const getFormFieldBySource = (id?: string) => {
|
|
if (state.isSearch) {
|
|
// 搜索设计这里不需要数据源
|
|
return;
|
|
}
|
|
const source = id;
|
|
if (source) {
|
|
getRequest("sourceById", { id: source })
|
|
.then((res) => {
|
|
// console.log(res)
|
|
const tableData = res.data.result?.tableData;
|
|
if (tableData && tableData.length) {
|
|
state.dataSourceList = tableData.filter((item: any) => item.enterable);
|
|
}
|
|
})
|
|
.catch((res) => {
|
|
// console.log(res)
|
|
});
|
|
}
|
|
};
|
|
defineExpose({ getFormFieldBySource });
|
|
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:19:01
|
|
@ 功能: 表单属性修改
|
|
*/
|
|
const formAttrChange = (obj: any, val?: any) => {
|
|
// console.log("表单属性修改--->",obj,val,{ [obj.key]: obj.value })
|
|
if (obj.key === "source") {
|
|
getFormFieldBySource(obj.value); // 改变了数据源了,重新请求数据
|
|
// 清空设计区已选择的组件,再一次选择时字段标识才会变
|
|
store.setActiveKey("");
|
|
store.setControlAttr({});
|
|
}
|
|
if (["formName", "source"].includes(obj.key)) {
|
|
emits(
|
|
"update:formOtherData",
|
|
Object.assign(props.formOtherData, { [obj.key]: obj.value })
|
|
);
|
|
formData.value[obj.key] = obj.value;
|
|
return;
|
|
}
|
|
if (obj.path === "config") {
|
|
formConfig.value[obj.key] = obj.value || val;
|
|
} else {
|
|
formData.value[obj.key] = obj.value;
|
|
}
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 10:17:29
|
|
@ 功能: 组件加载完毕执行
|
|
*/
|
|
onMounted(() => {
|
|
gainFormGroupList();
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:22:26
|
|
@ 功能: 判断输入框是否可写
|
|
*/
|
|
const isNotWrite = (val: any) => {
|
|
if (val.key === "name" && props.customerformid != "") {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
const isNotWriteWord = (val: any) => {
|
|
// console.log("判断输入框是否可写--->",val,props.customerformid)
|
|
let ary = ["creater", "creater_time", "edit_time", "owner", "org"];
|
|
if (ary.includes(val)) {
|
|
return true;
|
|
} else {
|
|
if (
|
|
val.eventName === "filedNameKey" &&
|
|
props.customerformid != "" &&
|
|
props.formField.includes(val.value)
|
|
) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-18 11:42:52
|
|
@ 功能: 上传图标相关
|
|
*/
|
|
const imgUploadApiUrl = import.meta.env.VITE_APP_BASE_API + "/api/upordown"; //上传地址
|
|
const handleAvatarSuccess: UploadProps["onSuccess"] = (response, uploadFile) => {
|
|
// imageUrl.value = URL.createObjectURL(uploadFile.raw!)
|
|
formConfig.value.imageUrl = response.data.url;
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:28:40
|
|
@ 功能: 上传前验证
|
|
*/
|
|
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
|
|
// console.log("beforeAvatarUpload",rawFile.type)
|
|
if (
|
|
rawFile.type !== "image/jpeg" &&
|
|
rawFile.type !== "image/jpg" &&
|
|
rawFile.type !== "image/png" &&
|
|
rawFile.type !== "image/gif" &&
|
|
rawFile.type !== "image/icon"
|
|
) {
|
|
ElMessage.error("请上传以下格式的图片(jpg、jpeg、png、gif、icon)!" + rawFile.type);
|
|
return false;
|
|
} else if (rawFile.size / 1024 / 1024 > 2) {
|
|
ElMessage.error("图片大小不要大于 2MB!");
|
|
return false;
|
|
}
|
|
return true;
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:34:15
|
|
@ 功能: 表单接口事件
|
|
*/
|
|
const eventClick = (type: string, tooltip?: string) => {
|
|
emits("openDialog", { type: type, title: tooltip, direction: "ltr" });
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:52:57
|
|
@ 功能: 编辑表单样式
|
|
*/
|
|
const editFormStyle = (tooltip: string) => {
|
|
emits("openDialog", {
|
|
codeType: "css",
|
|
direction: "ltr",
|
|
type: "css",
|
|
title: tooltip,
|
|
});
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 11:53:45
|
|
@ 功能: 设置数据字典
|
|
*/
|
|
const editFormDict = (tooltip: string) => {
|
|
emits("openDialog", {
|
|
type: "dict",
|
|
direction: "ltr",
|
|
codeType: "json",
|
|
title: tooltip,
|
|
});
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 13:19:37
|
|
@ 功能: 组件属性
|
|
*/
|
|
const attrList = computed(() => {
|
|
if (Object.keys(controlData.value).length) {
|
|
const {
|
|
control = {},
|
|
type,
|
|
name,
|
|
config = {},
|
|
item = {},
|
|
attr = {},
|
|
selectvalue = "default",
|
|
mathFormula = {},
|
|
}: {
|
|
control: any;
|
|
type: any;
|
|
name: any;
|
|
item: any;
|
|
attr: any;
|
|
config: any;
|
|
selectvalue: any;
|
|
mathFormula: any;
|
|
} = controlData.value;
|
|
let columnIndex = false; // 是否显示序号列
|
|
if (type === "table") {
|
|
// 表格时处理
|
|
const list = controlData.value && controlData.value.list;
|
|
if (list && list.length > 0) {
|
|
columnIndex = list[0].type === "index";
|
|
}
|
|
}
|
|
const temp = reactive<PublicAtrr[]>([
|
|
{
|
|
label: "标签名称",
|
|
value: item.label,
|
|
path: "item.label",
|
|
vHide: [
|
|
"table",
|
|
"grid",
|
|
"tabs",
|
|
"title",
|
|
"gridChild",
|
|
"div",
|
|
"inputSlot",
|
|
"flex",
|
|
"button",
|
|
"txt",
|
|
],
|
|
eventName: "labelNameVal",
|
|
},
|
|
{
|
|
label: "自定义Class",
|
|
value: config.className,
|
|
placeholder: "样式类名",
|
|
path: "config.className",
|
|
},
|
|
{
|
|
label: "字段标识",
|
|
value: name,
|
|
type: Object.keys(state.dataSourceList).length > 0 ? "select" : "text",
|
|
placeholder: "字段唯一标识,对应数据库",
|
|
dict: state.dataSourceList,
|
|
path: "name",
|
|
vHide: [
|
|
"grid",
|
|
"tabs",
|
|
"card",
|
|
"title",
|
|
"gridChild",
|
|
"tableColumn",
|
|
"divider",
|
|
"txt",
|
|
"div",
|
|
"button",
|
|
],
|
|
eventName: "filedNameKey",
|
|
},
|
|
{
|
|
label: "占位内容",
|
|
value: control.placeholder,
|
|
placeholder: "placeholder",
|
|
path: "control.placeholder",
|
|
vShow: [
|
|
"password",
|
|
"input",
|
|
"textarea",
|
|
"select",
|
|
"date",
|
|
"number",
|
|
"datePicker",
|
|
"tinymce",
|
|
"timePicker",
|
|
"treeSelect",
|
|
],
|
|
},
|
|
{
|
|
label: "帮助信息",
|
|
value: config.help,
|
|
path: "config.help",
|
|
vHide: [
|
|
"table",
|
|
"grid",
|
|
"tabs",
|
|
"gridChild",
|
|
"divider",
|
|
"div",
|
|
"inputSlot",
|
|
"flex",
|
|
"button",
|
|
"txt",
|
|
],
|
|
},
|
|
{
|
|
label: "按钮类型",
|
|
value: control.type,
|
|
path: "control.type",
|
|
type: "select",
|
|
dict: {
|
|
primary: "primary",
|
|
success: "success",
|
|
info: "info",
|
|
warning: "warning",
|
|
danger: "danger",
|
|
},
|
|
vShow: ["button"],
|
|
clearable: true,
|
|
},
|
|
{
|
|
label: "按钮名称",
|
|
value: control.label,
|
|
path: "control.label",
|
|
vShow: ["button"],
|
|
},
|
|
{
|
|
label: "按钮事件",
|
|
value: control.key,
|
|
path: "control.key",
|
|
type: "select",
|
|
dict: {
|
|
submit: "提交表单",
|
|
reset: "重置表单",
|
|
cancel: "取消返回",
|
|
none: "无动作(自定义)",
|
|
},
|
|
vShow: ["button"],
|
|
},
|
|
{
|
|
label: "对齐方式",
|
|
value: config.textAlign,
|
|
path: "config.textAlign",
|
|
type: "select",
|
|
dict: {
|
|
left: "left",
|
|
right: "right",
|
|
center: "center",
|
|
},
|
|
vShow: ["button", "div"],
|
|
},
|
|
|
|
{
|
|
label: "隐藏label",
|
|
value: item.showLabel,
|
|
path: "item.showLabel",
|
|
type: "switch",
|
|
vHide: [
|
|
"table",
|
|
"grid",
|
|
"tabs",
|
|
"title",
|
|
"gridChild",
|
|
"divider",
|
|
"card",
|
|
"div",
|
|
"inputSlot",
|
|
"flex",
|
|
"button",
|
|
"txt",
|
|
],
|
|
},
|
|
|
|
{
|
|
label: "表单栅格",
|
|
value: config.span,
|
|
placeholder: "表单区域栅格宽,0为自动宽",
|
|
path: "config.span",
|
|
vHide: ["gridChild"],
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "文本值",
|
|
value: control.modelValue,
|
|
placeholder: "支持html",
|
|
path: "control.modelValue",
|
|
vShow: ["txt"],
|
|
inputStyle: "textarea",
|
|
},
|
|
{
|
|
label: "设为密码",
|
|
value: type,
|
|
type: "select",
|
|
dict: { input: "文本", password: "密码" },
|
|
path: "type",
|
|
vShow: ["input", "password"],
|
|
vIf: state.isSearch, // 搜索模式下隐藏 为true
|
|
},
|
|
{
|
|
label: "文本域高度",
|
|
value: control.rows,
|
|
placeholder: "输入框行数",
|
|
path: "control.rows",
|
|
vShow: ["textarea"],
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "前缀",
|
|
value: config.prepend,
|
|
placeholder: "文本前缀",
|
|
path: "config.prepend",
|
|
vShow: ["input", "password"],
|
|
},
|
|
{
|
|
label: "后缀",
|
|
value: config.append,
|
|
placeholder: "文本后缀",
|
|
path: "config.append",
|
|
vShow: ["input", "password"],
|
|
},
|
|
{
|
|
label: "状态打开时的值",
|
|
value: control.activeValue,
|
|
placeholder: "状态打开时的值",
|
|
path: "control.activeValue",
|
|
vShow: ["switch"],
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "状态关闭时的值",
|
|
value: control.inactiveValue,
|
|
placeholder: "状态关闭时的值",
|
|
path: "control.inactiveValue",
|
|
vShow: ["switch"],
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "增加按钮文案",
|
|
value: config.addBtnText,
|
|
path: "config.addBtnText",
|
|
type: "text",
|
|
Show: ["flex", "table"],
|
|
},
|
|
{
|
|
label: "删除按钮文案",
|
|
value: config.delBtnText,
|
|
path: "config.delBtnText",
|
|
type: "text",
|
|
vShow: ["flex", "table"],
|
|
},
|
|
{
|
|
label: "是否多选",
|
|
value: control.multiple,
|
|
path: "control.multiple",
|
|
type: "switch",
|
|
vShow: ["select", "treeSelect"],
|
|
eventName: "selectMultiple",
|
|
},
|
|
{
|
|
label: "可清空",
|
|
value: control.clearable,
|
|
path: "control.clearable",
|
|
type: "switch",
|
|
vShow: ["select"],
|
|
},
|
|
{
|
|
label: "是否禁用",
|
|
value: control.disabled,
|
|
path: "control.disabled",
|
|
type: "switch",
|
|
vShow: [
|
|
"input",
|
|
"password",
|
|
"textarea",
|
|
"radio",
|
|
"checkbox",
|
|
"select",
|
|
"date",
|
|
"switch",
|
|
"number",
|
|
"cascader",
|
|
"upload",
|
|
"rate",
|
|
"tinymce",
|
|
"treeSelect",
|
|
],
|
|
vIf: state.isSearch,
|
|
},
|
|
{
|
|
label: "是否禁用编辑",
|
|
value: config.editDisabled,
|
|
path: "config.editDisabled",
|
|
type: "switch",
|
|
vShow: [
|
|
"input",
|
|
"password",
|
|
"textarea",
|
|
"radio",
|
|
"checkbox",
|
|
"select",
|
|
"date",
|
|
"switch",
|
|
"number",
|
|
"cascader",
|
|
"upload",
|
|
"treeSelect",
|
|
"table",
|
|
"flex",
|
|
],
|
|
vIf: state.isSearch,
|
|
},
|
|
{
|
|
label: "添加页隐藏",
|
|
value: config.disabledAdd,
|
|
path: "config.disabledAdd",
|
|
type: "switch",
|
|
vIf: state.isSearch,
|
|
vHide: ["inputSlot"],
|
|
},
|
|
{
|
|
label: "编辑页隐藏",
|
|
value: config.disabledEdit,
|
|
path: "config.disabledEdit",
|
|
type: "switch",
|
|
vIf: state.isSearch,
|
|
vHide: ["inputSlot"],
|
|
},
|
|
{
|
|
label: "详情页隐藏",
|
|
value: config.disabledDetail,
|
|
path: "config.disabledDetail",
|
|
type: "switch",
|
|
vIf: state.isSearch,
|
|
vHide: ["inputSlot"],
|
|
},
|
|
{
|
|
label: "设为Input输入框的前/后缀",
|
|
value: type === "inputSlot",
|
|
path: "",
|
|
type: "switch",
|
|
vShow: ["select", "inputSlot"],
|
|
eventName: "setInputSlot",
|
|
},
|
|
{
|
|
label: "标题",
|
|
value: control.modelValue,
|
|
path: "control.modelValue",
|
|
vShow: ["title"],
|
|
},
|
|
{
|
|
label: "占据的列数span",
|
|
value: attr.span,
|
|
path: "attr.span",
|
|
vShow: ["gridChild"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "左侧的间隔格数offset",
|
|
value: attr.offset,
|
|
path: "attr.offset",
|
|
vShow: ["gridChild"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "向右移动格数push",
|
|
value: attr.push,
|
|
path: "attr.push",
|
|
vShow: ["gridChild"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "向左移动格数pull",
|
|
value: attr.pull,
|
|
path: "attr.pull",
|
|
vShow: ["gridChild"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "序号列",
|
|
value: columnIndex,
|
|
type: "switch",
|
|
vShow: ["table"],
|
|
eventName: "tableColumn1",
|
|
},
|
|
{
|
|
label: "组件名",
|
|
value: config.componentName,
|
|
placeholder: "全局注册的组件名称",
|
|
path: "config.componentName",
|
|
vShow: ["component"],
|
|
},
|
|
{
|
|
label: "隐藏条件",
|
|
value: config.associatedForms,
|
|
path: "config.associatedForms",
|
|
type: "associatedForms_hide",
|
|
vIf: state.isSearch,
|
|
vShow: ["associatedForms"],
|
|
},
|
|
{
|
|
label: "关联表单",
|
|
value: config.associatedForms,
|
|
path: "config.associatedForms",
|
|
type: "associatedForms_form",
|
|
vIf: state.isSearch,
|
|
vShow: ["associatedForms"],
|
|
},
|
|
{
|
|
label: "数据范围",
|
|
value: config.associatedForms,
|
|
path: "config.associatedForms",
|
|
type: "associatedForms_dataRange",
|
|
vIf: state.isSearch,
|
|
vShow: ["associatedForms"],
|
|
},
|
|
{
|
|
label: "数据填充规则",
|
|
value: config.associatedForms,
|
|
path: "config.associatedForms",
|
|
type: "associatedForms_FillRoles",
|
|
vIf: state.isSearch,
|
|
vShow: ["associatedForms"],
|
|
},
|
|
{
|
|
label: "轮播图设置",
|
|
value: config.carousel,
|
|
path: "config.carousel",
|
|
type: "carousel",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeCarsusel"],
|
|
},
|
|
|
|
{
|
|
label: "穿梭框名",
|
|
value: config.transfer,
|
|
path: "config.transfer",
|
|
type: "transfer_name",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeTransfer"],
|
|
},
|
|
{
|
|
label: "选项数据源",
|
|
value: config.transfer,
|
|
path: "config.transfer",
|
|
type: "transfer_options_datasource",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeTransfer"],
|
|
},
|
|
{
|
|
label: "上传视频",
|
|
value: config.uploadvideo,
|
|
path: "config.uploadvideo",
|
|
type: "uploadvideo_url",
|
|
vIf: state.isSearch,
|
|
vShow: ["videoUpAndPlay"],
|
|
},
|
|
{
|
|
label: "上传图片",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_url",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "尺寸",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_showMode",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "契合度",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_fit",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "圆角",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_radius",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "边框和阴影",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_boderAndShadow",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "图片链接",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_link",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "浮动",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_float",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "内外四边距",
|
|
value: config.lowcodeImage,
|
|
path: "config.lowcodeImage",
|
|
type: "lowcodeImage_marginAndPadding",
|
|
vIf: state.isSearch,
|
|
vShow: ["lowcodeImage"],
|
|
},
|
|
{
|
|
label: "视频宽度(像素)",
|
|
value: config.uploadvideo,
|
|
path: "config.uploadvideo",
|
|
type: "uploadvideo_width",
|
|
vIf: state.isSearch,
|
|
vShow: ["videoUpAndPlay"],
|
|
},
|
|
{
|
|
label: "视频高度(像素)",
|
|
value: config.uploadvideo,
|
|
path: "config.uploadvideo",
|
|
type: "uploadvideo_height",
|
|
vIf: state.isSearch,
|
|
vShow: ["videoUpAndPlay"],
|
|
},
|
|
{
|
|
label: "视频自动播放",
|
|
value: config.uploadvideo,
|
|
path: "config.uploadvideo",
|
|
type: "uploadvideo_autoPlay",
|
|
vIf: state.isSearch,
|
|
vShow: ["videoUpAndPlay"],
|
|
},
|
|
{
|
|
label: "视频循环播放",
|
|
value: config.uploadvideo,
|
|
path: "config.uploadvideo",
|
|
type: "uploadvideo_loopPlay",
|
|
vIf: state.isSearch,
|
|
vShow: ["videoUpAndPlay"],
|
|
},
|
|
|
|
{
|
|
label: "上传地址",
|
|
value: control.action,
|
|
placeholder: "图片/文件上传地址,可不填有默认值",
|
|
path: "control.action",
|
|
vShow: ["upload"],
|
|
},
|
|
{
|
|
label: "文件字段名",
|
|
value: control.name,
|
|
placeholder: "上传的文件字段名,默认file",
|
|
path: "control.name",
|
|
vShow: ["upload"],
|
|
},
|
|
{
|
|
label: "列表类型",
|
|
value: control.listType,
|
|
type: "select",
|
|
dict: {
|
|
text: "text",
|
|
picture: "picture",
|
|
"picture-card": "picture-card",
|
|
},
|
|
path: "control.listType",
|
|
vShow: ["upload"],
|
|
},
|
|
{
|
|
label: "提示文字",
|
|
value: config.tip,
|
|
placeholder: "提示说明文字",
|
|
path: "config.tip",
|
|
vShow: ["upload"],
|
|
},
|
|
{
|
|
label: "按钮文本",
|
|
value: config.btnText,
|
|
placeholder: "上传按钮文本",
|
|
path: "config.btnText",
|
|
vShow: ["upload"],
|
|
},
|
|
{
|
|
label: "分割线方向",
|
|
type: "select",
|
|
dict: { horizontal: "horizontal", vertical: "vertical" },
|
|
placeholder: "分割线方向,默认horizontal",
|
|
value: control.direction,
|
|
path: "control.direction",
|
|
vShow: ["divider"],
|
|
},
|
|
{
|
|
label: "分隔符样式",
|
|
placeholder: "分隔符样式,默认solid",
|
|
value: control.borderStyle,
|
|
path: "control.borderStyle",
|
|
vShow: ["divider"],
|
|
},
|
|
{
|
|
label: "文字方位",
|
|
type: "select",
|
|
dict: { left: "left", right: "right", center: "center" },
|
|
value: control.contentPosition,
|
|
path: "control.contentPosition",
|
|
vShow: ["divider"],
|
|
},
|
|
{
|
|
label: "最小值",
|
|
value: control.min,
|
|
path: "control.min",
|
|
vShow: ["slider"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "最大值",
|
|
value: control.max,
|
|
path: "control.max",
|
|
vShow: ["rate", "slider"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "步长",
|
|
value: control.step,
|
|
path: "control.step",
|
|
vShow: ["slider"],
|
|
eventName: "formatNumber",
|
|
isNum: true,
|
|
},
|
|
{
|
|
label: "显示类型",
|
|
value: control.type,
|
|
path: "control.type",
|
|
vShow: ["datePicker"],
|
|
type: "select",
|
|
placeholder: "显示类型",
|
|
dict: {
|
|
year: "年",
|
|
month: "月",
|
|
date: "日期",
|
|
datetime: "日期+时间",
|
|
week: "周",
|
|
datetimerange: "开始日期时间至结束日期时间",
|
|
daterange: "开始日期至结束日期",
|
|
monthrange: "开始月至结束月",
|
|
},
|
|
},
|
|
{
|
|
label: "时间格式",
|
|
value: control.format,
|
|
path: "control.format",
|
|
vShow: ["datePicker", "timePicker"],
|
|
placeholder: "显示在输入框中的格式",
|
|
},
|
|
{
|
|
label: "color-format",
|
|
value: control.colorFormat,
|
|
path: "control.colorFormat",
|
|
type: "select",
|
|
placeholder: "写入 v-model 的颜色的格式",
|
|
dict: { hsl: "hsl", hsv: "hsv", hex: "hex", rgb: "rgb" },
|
|
vShow: ["colorPicker"],
|
|
},
|
|
{
|
|
label: "文本高度",
|
|
value: control.height,
|
|
path: "control.height",
|
|
placeholder: "文本高度(预览查看效果)",
|
|
vShow: ["tinymce"],
|
|
},
|
|
{
|
|
label: "文本宽度",
|
|
value: control.width,
|
|
path: "control.width",
|
|
placeholder: "文本宽度(预览查看效果)",
|
|
vShow: ["tinymce"],
|
|
},
|
|
{
|
|
label: "图片上传地址",
|
|
value: control.imgUrl,
|
|
path: "control.imgUrl",
|
|
placeholder: "图片上传地址",
|
|
vShow: ["tinymce"],
|
|
},
|
|
{
|
|
label: "附件上传地址",
|
|
value: control.blobUrl,
|
|
path: "control.blobUrl",
|
|
placeholder: "附件上传地址",
|
|
vShow: ["tinymce"],
|
|
},
|
|
{
|
|
label: "显示模式",
|
|
value: config.style,
|
|
path: "config.style",
|
|
placeholder: "显示风格(预览查看效果)",
|
|
type: "select",
|
|
dict: { default: "default", simple: "simple" },
|
|
vShow: ["tinymce"],
|
|
},
|
|
{
|
|
label: "默认值",
|
|
value: control.mathsValue,
|
|
selectvalue: selectvalue,
|
|
path: "control.mathsValue",
|
|
placeholder: "显示风格(预览查看效果)",
|
|
type: "digitpage",
|
|
dict: { default: "自定义", simple: "编辑公式" },
|
|
vShow: ["digitpage"],
|
|
control: control,
|
|
},
|
|
]);
|
|
// 过滤显示对应的值
|
|
return temp.filter((item: any) => {
|
|
let hasFilter = true;
|
|
if (item.vShow) {
|
|
hasFilter = item.vShow.includes(type);
|
|
}
|
|
if (item.vHide) {
|
|
hasFilter = !item.vHide.includes(type);
|
|
}
|
|
if (item.vIf) {
|
|
// 不显示vif=true的
|
|
hasFilter = false;
|
|
}
|
|
return hasFilter;
|
|
});
|
|
} else {
|
|
return [];
|
|
}
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 13:33:51
|
|
@ 功能: 组件属性变化
|
|
*/
|
|
const fileSignAry = reactive<any>([]);
|
|
const controlChange = (obj: any, val: any) => {
|
|
switch (obj.eventName) {
|
|
case "selectMultiple":
|
|
if (val) {
|
|
// 多选,将值改为数组
|
|
controlData.value.control.modelValue = [];
|
|
} else {
|
|
// 单选
|
|
controlData.value.control.modelValue = "";
|
|
}
|
|
break;
|
|
case "tableColumn1":
|
|
tableColumnAdd(val);
|
|
break;
|
|
case "formatNumber":
|
|
val = parseInt(val); // 将值转数值
|
|
break;
|
|
case "filedNameKey":
|
|
// 选择字段标识时,同时修改显示标题
|
|
// 根据value找key
|
|
if (obj.type === "select") {
|
|
state.dataSourceList.forEach((item: any) => {
|
|
if (item.name === val) {
|
|
if (controlData.value.item) {
|
|
controlData.value.item.label = item.label;
|
|
}
|
|
controlData.value.name = item.label;
|
|
}
|
|
});
|
|
}
|
|
break;
|
|
case "setInputSlot":
|
|
if (val) {
|
|
// 将类型改为inputSlot
|
|
controlData.value.type = "inputSlot";
|
|
ElMessage.success(
|
|
`请在对应的Input输入框属性前后缀设置key:${controlData.value.name}`
|
|
);
|
|
} else {
|
|
controlData.value.type = "select";
|
|
}
|
|
// 这里会报错Cannot set properties of null (setting 'checked')
|
|
// 因value:type===inputSlot,这里使用了v-model,影响不大暂不处理
|
|
break;
|
|
case "labelNameVal":
|
|
if (val != "") {
|
|
// console.log("props.customerformid",props.customerformid)
|
|
// console.log("props.formField",props.formField)
|
|
// console.log("props.formField.includes(obj.value)",props.formField.includes(controlData.value.name))
|
|
// console.log("obj.value",controlData.value.name)
|
|
let ary = ["founder", "founderTime", "editTime", "owner", "deptOrg"];
|
|
if (!ary.includes(controlData.value.type)) {
|
|
if (!props.formField.includes(controlData.value.name)) {
|
|
chineseToPinyin({
|
|
title: val,
|
|
types: 8,
|
|
connector: "",
|
|
formJson: JSON.stringify(props.formInfo),
|
|
}).then((data: any) => {
|
|
if (data.code == 0) {
|
|
if (data.data != "") {
|
|
if (!fileSignAry.includes(data.data)) {
|
|
controlData.value.name = data.data;
|
|
fileSignAry.push(data.data);
|
|
} else {
|
|
let isEnd = true;
|
|
do {
|
|
let titleVal = data.data + Rand(10000000, 99999999);
|
|
if (!fileSignAry.includes(titleVal)) {
|
|
controlData.value.name = titleVal;
|
|
fileSignAry.push(titleVal);
|
|
isEnd = false;
|
|
}
|
|
} while (isEnd);
|
|
}
|
|
} else {
|
|
if (!fileSignAry.includes(val)) {
|
|
controlData.value.name = val;
|
|
fileSignAry.push(val);
|
|
} else {
|
|
let titleVal = val + Rand(10000000, 99999999);
|
|
if (!fileSignAry.includes(titleVal)) {
|
|
controlData.value.name = titleVal;
|
|
fileSignAry.push(titleVal);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
// console.log("字段编辑--fileSignAry--》",fileSignAry)
|
|
break;
|
|
}
|
|
if (obj.path) {
|
|
const newVal = obj.isNum ? formatNumber(val) : val; // 类型为数字时转整数
|
|
obj.path && getPropByPath(controlData.value, obj.path, newVal);
|
|
}
|
|
};
|
|
// 更多属性弹窗
|
|
const openAttrDialog = (type?: string, tooltip?: string) => {
|
|
let editData = controlData.value.control;
|
|
if (controlData.value.type === "button") {
|
|
// 按钮组件编辑属性
|
|
editData = controlData.value.config;
|
|
type = "button";
|
|
}
|
|
switch (type) {
|
|
case "treeSelect":
|
|
editData = controlData.value.control.data;
|
|
break;
|
|
case "cascader":
|
|
editData = controlData.value.options;
|
|
break;
|
|
case "optionsParams": // 选项请求附加参数
|
|
editData = controlData.value.config.beforeRequest;
|
|
// params.codeType = 'json'
|
|
break;
|
|
case "optionsResult":
|
|
editData = controlData.value.config.afterResponse;
|
|
break;
|
|
}
|
|
const emitsParams = {
|
|
content: editData,
|
|
title: tooltip,
|
|
type: type,
|
|
direction: "ltr",
|
|
callback: (result: any) => {
|
|
switch (type) {
|
|
case "treeSelect":
|
|
controlData.value.control.data = result;
|
|
break;
|
|
case "cascader":
|
|
controlData.value.options = result;
|
|
break;
|
|
case "optionsParams":
|
|
controlData.value.config.beforeRequest = result;
|
|
break;
|
|
case "optionsResult":
|
|
controlData.value.config.afterResponse = result;
|
|
break;
|
|
case "button":
|
|
controlData.value.config = result;
|
|
break;
|
|
default:
|
|
controlData.value.control = {};
|
|
Object.assign(controlData.value.control, result);
|
|
}
|
|
},
|
|
};
|
|
emits("openDialog", emitsParams);
|
|
};
|
|
// 必填校验
|
|
const requiredChange = (val: any) => {
|
|
if (!controlData.value.item?.rules) {
|
|
controlData.value.item.rules = [];
|
|
}
|
|
if (val) {
|
|
controlData.value.item.rules.push({
|
|
required: true,
|
|
message: "必填项",
|
|
trigger: "change",
|
|
});
|
|
} else {
|
|
controlData.value.item.rules.splice(0, 1);
|
|
}
|
|
};
|
|
// 多选固定选项增加
|
|
const addSelectOption = (type: any) => {
|
|
if (controlData.value.type === "cascader") {
|
|
// 级联时打开弹窗口
|
|
openAttrDialog("cascader");
|
|
} else if (controlData.value.type === "treeSelect") {
|
|
openAttrDialog("treeSelect", "编辑组件下拉选项数据");
|
|
} else {
|
|
if (type === "tabs") {
|
|
controlData.value.columns.push({
|
|
label: "标签名称",
|
|
list: [],
|
|
});
|
|
} else {
|
|
controlData.value.options.push({
|
|
label: "",
|
|
value: "",
|
|
});
|
|
}
|
|
}
|
|
};
|
|
// 属性设置相关结束
|
|
// 多选固定选项删除
|
|
const delSelectOption = (index: number, type?: string) => {
|
|
if (type === "tabs") {
|
|
controlData.value.columns.splice(index, 1);
|
|
} else {
|
|
controlData.value.options.splice(index, 1);
|
|
}
|
|
};
|
|
// 添加校验规则
|
|
const addRules = (tooltip: string) => {
|
|
if (!controlData.value.item?.rules) {
|
|
controlData.value.item.rules = [];
|
|
}
|
|
const params = {
|
|
content: controlData.value.item?.rules,
|
|
title: tooltip,
|
|
direction: "ltr",
|
|
callback: (result: any) => {
|
|
Object.assign(controlData.value.item.rules, result);
|
|
},
|
|
};
|
|
emits("openDialog", params);
|
|
};
|
|
// 校验规则必填勾选设置,存在校验规则时勾选
|
|
const checkboxRequired = computed(() => {
|
|
const val = controlData.value && controlData.value.item?.rules;
|
|
if (val && val.length > 0) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
});
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 13:39:12
|
|
@ 功能: 子表时添加序号和操作列
|
|
*/
|
|
const tableColumnAdd = (val: string) => {
|
|
const item = {
|
|
name: "index",
|
|
type: "index",
|
|
item: {
|
|
label: "序号",
|
|
},
|
|
control: {},
|
|
config: {},
|
|
};
|
|
if (val) {
|
|
controlData.value.list.unshift(item);
|
|
} else {
|
|
controlData.value.list.splice(0, 1);
|
|
}
|
|
};
|
|
// 快速添加一条校验规则
|
|
const addRulesFast = () => {
|
|
if (!controlData.value.customRules) {
|
|
controlData.value.customRules = [];
|
|
}
|
|
controlData.value.customRules.push({
|
|
type: "required",
|
|
message: "必填项",
|
|
trigger: "blur",
|
|
});
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 13:40:14
|
|
@ 功能: 修改指定路径下的值
|
|
*/
|
|
const getPropByPath = (obj: any, path: string, val: any) => {
|
|
let tempObj = obj;
|
|
const keyArr = path.split(".");
|
|
let i = 0;
|
|
for (i; i < keyArr.length - 1; i++) {
|
|
const key = keyArr[i];
|
|
if (key in tempObj) {
|
|
tempObj = tempObj[key];
|
|
} else {
|
|
throw new Error(`${key} is undefined`);
|
|
}
|
|
}
|
|
const key = keyArr[i];
|
|
const value = tempObj[keyArr[i]];
|
|
|
|
if (val !== undefined) {
|
|
tempObj[key] = val;
|
|
}
|
|
return {
|
|
obj: tempObj,
|
|
key: key,
|
|
value: value,
|
|
};
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 15:02:37
|
|
@ 功能: 默认值处理
|
|
*/
|
|
const unitInfo = ref<any>();
|
|
const formListmap = ref<any>();
|
|
const subUnit = ref<any>();
|
|
const mathBoxShow = ref(false);
|
|
const digitPageSub = (val: any, envt: any) => {
|
|
subUnit.value = val;
|
|
controlData.value.selectvalue = envt;
|
|
formListmap.value = props.formList;
|
|
if (envt == "simple") {
|
|
unitInfo.value = attrList.value;
|
|
mathBoxShow.value = true;
|
|
}
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 15:05:47
|
|
@ 功能: 打开数学公司编辑器
|
|
*/
|
|
const openMathDialog = (val: any) => {
|
|
subUnit.value = val;
|
|
formListmap.value = props.formList;
|
|
unitInfo.value = attrList.value;
|
|
mathBoxShow.value = true;
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-10 15:30:55
|
|
@ 功能: 根据不同类型判断是否显示当前属性
|
|
*/
|
|
const showHide = (type: string[], show?: boolean) => {
|
|
// show=true 条件成立显示,false符合条件隐藏
|
|
if ((type && type.length === 0) || Object.keys(controlData.value).length === 0) {
|
|
return false;
|
|
}
|
|
const index = type.indexOf(controlData.value.type);
|
|
return show ? index !== -1 : index === -1;
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-03-01 08:16:459097
|
|
@ 功能: 判断是否是组件
|
|
*/
|
|
const cssIsShouw = (val: any) => {
|
|
// console.log("判断是否是组件",val)
|
|
if (val && val.length && val.length > 0) {
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
/**
|
|
* 获取非负整数随机数
|
|
* @param Min 最小整数
|
|
* @param Max 最大整数
|
|
* @returns 随机数
|
|
*/
|
|
const Rand = (Min: number, Max: number) => {
|
|
switch (Min) {
|
|
case 0:
|
|
return Math.round(Math.random() * Max);
|
|
case 1:
|
|
return Math.ceil(Math.random() * Max);
|
|
default:
|
|
return Math.round(Math.random() * (Max - Min) + Min);
|
|
}
|
|
};
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-13 15:46:24
|
|
@ 功能:
|
|
*/
|
|
watch(
|
|
() => store.activeKey,
|
|
(val: string) => {
|
|
// console.log("监听数据编号--->", val)
|
|
if (controlData.value.type === "lowcodeCarsusel") {
|
|
const carsuselConfigData: CarsuselConfig[] =
|
|
controlData.value.control.carsuselConfigArr;
|
|
carsuselConfigData.forEach((element) => {
|
|
//console.log(element)
|
|
if (element.imgId == "") {
|
|
//console.log("初始化imgid")
|
|
let onlyNumber = uuidv4().replaceAll("-", "").toString(); //获取唯一编码
|
|
element.imgId = onlyNumber;
|
|
}
|
|
});
|
|
} else if (controlData.value.type === "associatedForms") {
|
|
controlData.value.control.fillRoles[0].id = uuidv4().replaceAll("-", "").toString();
|
|
}
|
|
if (val) {
|
|
// 有值时自动跳到第一项
|
|
state.tabsName = "first";
|
|
cssIsShouw(attrList);
|
|
}
|
|
}
|
|
);
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-05-15 11:07:37
|
|
@ 功能: 获取组件样式Demo
|
|
*/
|
|
const controlDataStyls = computed(() => {
|
|
return store.controlAttr.styles;
|
|
});
|
|
// 返回选项配置提示
|
|
const getOptionPlaceholder = (type: number) => {
|
|
switch (type) {
|
|
case 1:
|
|
return "数据源接口URL,可带参数";
|
|
case 2:
|
|
return "字典key,默认为字段标识";
|
|
}
|
|
return "";
|
|
};
|
|
// 删除一条校验规则
|
|
const delAddRules = (index: number) => {
|
|
controlData.value.customRules && controlData.value.customRules.splice(index, 1);
|
|
};
|
|
//添加一条编码规则
|
|
const addNumRules = () => {
|
|
if (!controlData.value.config.customRules) {
|
|
controlData.value.config.customRules = [];
|
|
}
|
|
controlData.value.config.customRules.push({
|
|
type: "time",
|
|
rule: "YYYYMMDD",
|
|
});
|
|
};
|
|
//删除一条编码规则
|
|
const delNumRules = (index: number) => {
|
|
controlData.value.config.customRules &&
|
|
controlData.value.config.customRules.splice(index, 1);
|
|
};
|
|
// 快速添加校验规则改变时,填写默认的校验提示信息
|
|
const rulesSelectChange = (item: any, val: string) => {
|
|
const filter = validate.filter((item) => item.type === val);
|
|
if (filter && filter.length) {
|
|
item.message = filter[0].message;
|
|
}
|
|
};
|
|
const rulesSelectNumChange = (item: any, val: string) => {
|
|
// console.log("快速添加校验规则改变时",item,val)
|
|
const filter = state.numberRulesList.filter((item) => item.type === val);
|
|
if (filter && filter.length) {
|
|
item.message = filter[0].msg;
|
|
if (val == "time") {
|
|
item.rule = "YYYYMMDD";
|
|
} else {
|
|
item.rule = "";
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
@ 作者: 秦东
|
|
@ 时间: 2024-06-22 13:57:55
|
|
@ 功能: 判断该输入框是否不可编辑
|
|
*/
|
|
const disabledIstrue = (val: string) => {
|
|
let ary = ["creater", "creater_time", "edit_time", "owner", "org"];
|
|
if (ary.includes(val)) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
};
|
|
</script>
|
|
<template>
|
|
<div class="sidebar-tools_e">
|
|
<el-tabs v-model="state.tabsName">
|
|
<el-tab-pane label="字段配置" name="first">
|
|
<el-scrollbar class="formAttributeBox">
|
|
<el-form size="small" class="form">
|
|
<el-divider content-position="left">通用属性</el-divider>
|
|
<template v-for="(item, index) in attrList" :key="index">
|
|
<el-form-item :label="item.label" class="form_cont">
|
|
<el-select
|
|
v-if="item.type === 'select'"
|
|
:placeholder="item.placeholder"
|
|
v-model="item.value"
|
|
:filterable="item.path === 'name'"
|
|
:allow-create="item.path === 'name'"
|
|
:clearable="item.clearable"
|
|
@change="controlChange(item, $event)"
|
|
>
|
|
<el-option
|
|
v-for="(opt, key) in item.dict"
|
|
:key="key"
|
|
:value="item.path === 'name' ? opt.name : key"
|
|
:label="item.path === 'name' ? `${opt.label}(${opt.name})` : opt"
|
|
/>
|
|
</el-select>
|
|
<el-switch
|
|
v-else-if="item.type === 'switch'"
|
|
v-model="item.value"
|
|
@change="controlChange(item, $event)"
|
|
/>
|
|
<template v-else-if="item.type === 'digitpage'">
|
|
<el-row>
|
|
<el-col :span="12">
|
|
<el-select
|
|
v-model="item.selectvalue"
|
|
:placeholder="item.placeholder"
|
|
:filterable="item.path === 'name'"
|
|
:allow-create="item.path === 'name'"
|
|
:clearable="item.clearable"
|
|
@change="digitPageSub(item, $event)"
|
|
>
|
|
<el-option
|
|
v-for="(opt, key) in item.dict"
|
|
:key="key"
|
|
:value="item.path === 'name' ? opt.name : key"
|
|
:label="
|
|
item.path === 'name' ? `${opt.label}(${opt.name})` : opt
|
|
"
|
|
/>
|
|
</el-select>
|
|
</el-col>
|
|
<el-col :span="12">
|
|
<el-input-number
|
|
v-if="item.selectvalue == 'default'"
|
|
v-model="item.value"
|
|
class="mx-4"
|
|
/>
|
|
</el-col>
|
|
</el-row>
|
|
<div
|
|
v-if="item.selectvalue == 'simple'"
|
|
style="width: 100%; cursor: pointer; margin-top: 10px"
|
|
@click="openMathDialog(item)"
|
|
v-html="item.control.mathFormula.formulaHtml"
|
|
></div>
|
|
<MathFormula
|
|
v-model:show="mathBoxShow"
|
|
:sub-unit="subUnit"
|
|
:unit-info="attrList"
|
|
:form-listmap="formListmap"
|
|
@updata-digit="updataDigit"
|
|
/>
|
|
</template>
|
|
<el-row v-else-if="item.type === 'uploadvideo_url'">
|
|
<el-upload
|
|
:action="uploadUrl"
|
|
:before-remove="beforeRemove"
|
|
:on-success="videoUploadOk"
|
|
:show-file-list="true"
|
|
:on-error="videoUploadErr"
|
|
:limit="1"
|
|
:on-exceed="handleExceed"
|
|
accept=".mp4,.MOV,.WMV,.FLV,.AVI,.AVCHD,.WebM,.MKV,.rmvb"
|
|
>
|
|
<el-button
|
|
v-if="!controlData.control.videoMsg[videoIndex].videoReady"
|
|
type="primary"
|
|
>点此上传</el-button
|
|
>
|
|
<el-button
|
|
v-if="controlData.control.videoMsg[videoIndex].videoReady"
|
|
type="primary"
|
|
>已上传,点击修改</el-button
|
|
>
|
|
</el-upload>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'uploadvideo_autoPlay'">
|
|
<el-switch
|
|
v-model="controlData.control.videoMsg[videoIndex].videoAutoPlay"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'uploadvideo_loopPlay'">
|
|
<el-switch v-model="controlData.control.videoMsg[videoIndex].loop" />
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'uploadvideo_width'">
|
|
<el-input-number
|
|
v-model="controlData.control.videoMsg[videoIndex].videoWidth"
|
|
:step="50"
|
|
:max="4096"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'uploadvideo_height'">
|
|
<el-input-number
|
|
v-model="controlData.control.videoMsg[videoIndex].videoHeight"
|
|
:step="50"
|
|
:max="2160"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'carousel'">
|
|
<el-button
|
|
type="primary"
|
|
append-to-body="true"
|
|
modal="true"
|
|
@click="dialogTableVisible = true"
|
|
>轮播图设置</el-button
|
|
>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'transfer_name'">
|
|
<el-input
|
|
v-model="controlData.config.transferName"
|
|
placeholder="请输入穿梭框名"
|
|
style="width: 221px"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'transfer_options_datasource'">
|
|
<el-select
|
|
v-model="controlData.config.transferDataSource"
|
|
placeholder="选项数据源"
|
|
style="width: 150px; height: 20px"
|
|
>
|
|
<el-option
|
|
v-for="dataSourceOption1 in transferDataSourceOptions"
|
|
:key="dataSourceOption1.value"
|
|
:label="dataSourceOption1.label"
|
|
:value="dataSourceOption1.value"
|
|
/>
|
|
</el-select>
|
|
<div
|
|
v-if="controlData.config.transferDataSource === '固定选项'"
|
|
style="
|
|
width: auto;
|
|
margin-top: 33px;
|
|
margin-left: -220px;
|
|
padding-bottom: 6px;
|
|
"
|
|
>
|
|
<el-button
|
|
type="primary"
|
|
append-to-body="true"
|
|
modal="true"
|
|
@click="transferDialogTableVisible = true"
|
|
>编辑固定选项</el-button
|
|
>
|
|
</div>
|
|
<div
|
|
v-if="controlData.config.transferDataSource === '数据源'"
|
|
style="width: auto; margin-top: 20px"
|
|
>
|
|
<el-input
|
|
v-model="controlData.config.apiUrl"
|
|
style="width: 278px; margin-left: -68px; margin-top: -5px"
|
|
placeholder="数据源接口url"
|
|
>
|
|
<template #prepend>
|
|
<el-select
|
|
v-model="controlData.config.method"
|
|
style="width: 100px"
|
|
>
|
|
<el-option label="get" value="get" />
|
|
<el-option label="post" value="post" />
|
|
</el-select>
|
|
</template>
|
|
</el-input>
|
|
</div>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_radius'">
|
|
<el-switch
|
|
v-model="controlData.control.radius"
|
|
style="margin-right: 15px"
|
|
/>
|
|
<el-popover
|
|
placement="top-start"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="数值越大圆角程度越高"
|
|
>
|
|
<template #reference>
|
|
<el-input-number
|
|
v-if="controlData.control.radius"
|
|
v-model="controlData.control.radiusNum"
|
|
:step="1"
|
|
/>
|
|
</template>
|
|
</el-popover>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_url'">
|
|
<el-upload
|
|
:action="uploadUrl"
|
|
:before-remove="beforeRemove"
|
|
:on-success="lowcodeImageUploadSuccess"
|
|
:on-error="videoUploadErr"
|
|
:limit="1"
|
|
accept=".jpg,.jpeg,.png,.tif,.tga,.bmp,.dds,.svg,.eps,.pdf,.hdr,.raw,.exr,.psd,.afphoto,.afdesign"
|
|
>
|
|
<el-button v-if="!controlData.control.uploadFlag" type="primary"
|
|
>点此上传</el-button
|
|
>
|
|
<el-button v-if="controlData.control.uploadFlag" type="primary"
|
|
>已上传,点击修改</el-button
|
|
>
|
|
</el-upload>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_showMode'">
|
|
<el-select
|
|
v-model="controlData.control.showMode"
|
|
placeholder="选项数据源"
|
|
style="width: 150px; height: 20px"
|
|
>
|
|
<el-option
|
|
v-for="showModeSelected in showModeSelectOptions"
|
|
:key="showModeSelected.value"
|
|
:label="showModeSelected.label"
|
|
:value="showModeSelected.value"
|
|
/>
|
|
</el-select>
|
|
<div
|
|
v-if="controlData.control.showMode === '自定义像素值'"
|
|
style="
|
|
width: auto;
|
|
margin-top: 33px;
|
|
margin-left: -187px;
|
|
padding-bottom: 6px;
|
|
"
|
|
>
|
|
<span style="margin-right: 10px">宽度(像素) </span
|
|
><el-input-number
|
|
v-model="controlData.control.pxWidth"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px">高度(像素) </span
|
|
><el-input-number v-model="controlData.control.pxHeight" />
|
|
</div>
|
|
<div
|
|
v-if="controlData.control.showMode === '自定义占父容器比例'"
|
|
style="
|
|
width: auto;
|
|
margin-top: 33px;
|
|
margin-left: -187px;
|
|
padding-bottom: 6px;
|
|
"
|
|
>
|
|
<span style="margin-right: 10px">百分比宽 </span
|
|
><el-input-number
|
|
v-model="controlData.control.widthPercent"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px">百分比高 </span
|
|
><el-input-number v-model="controlData.control.heightPercent" />
|
|
</div>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_fit'">
|
|
<el-radio-group v-model="controlData.control.fit">
|
|
<el-popover
|
|
placement="top-start"
|
|
title="填充"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="默认值。调整替换后的内容大小,以填充元素的内容框。如有必要,将拉伸或挤压物体以适应该对象。"
|
|
>
|
|
<template #reference>
|
|
<el-radio :label="1" :value="1">填充</el-radio
|
|
><!-- fill -->
|
|
</template>
|
|
</el-popover>
|
|
|
|
<el-popover
|
|
placement="top-start"
|
|
title="适应"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="缩放替换后的内容以保持其纵横比,同时将其放入元素的内容框。"
|
|
>
|
|
<template #reference>
|
|
<el-radio :label="2" :value="2">适应</el-radio
|
|
><!-- contain -->
|
|
</template>
|
|
</el-popover>
|
|
|
|
<el-popover
|
|
placement="top-start"
|
|
title="裁切"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="调整替换内容的大小,以在填充元素的整个内容框时保持其长宽比。该对象将被裁剪以适应。"
|
|
>
|
|
<template #reference>
|
|
<el-radio :label="3" :value="3">裁切</el-radio
|
|
><!-- cover -->
|
|
</template>
|
|
</el-popover>
|
|
|
|
<el-popover
|
|
placement="top-start"
|
|
title="无"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="不对替换的内容调整大小。"
|
|
>
|
|
<template #reference>
|
|
<el-radio :label="4" :value="4">无</el-radio
|
|
><!-- none -->
|
|
</template>
|
|
</el-popover>
|
|
|
|
<el-popover
|
|
placement="top-start"
|
|
title="缩减"
|
|
:width="200"
|
|
trigger="hover"
|
|
content="调整内容大小就像没有指定内容或包含内容一样(将导致较小的具体对象尺寸)"
|
|
>
|
|
<template #reference>
|
|
<el-radio :label="5" :value="5">缩减</el-radio
|
|
><!-- scale-down -->
|
|
</template>
|
|
</el-popover>
|
|
</el-radio-group>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_boderAndShadow'">
|
|
<el-switch
|
|
v-model="controlData.control.boderAndShadow"
|
|
style="margin-right: 15px"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_link'">
|
|
<el-input
|
|
v-model="controlData.control.link"
|
|
placeholder="请录入图片链接地址"
|
|
style="width: 221px"
|
|
/>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_marginAndPadding'">
|
|
<div
|
|
style="
|
|
width: auto;
|
|
margin-top: 33px;
|
|
margin-left: -47px;
|
|
padding-bottom: 6px;
|
|
"
|
|
>
|
|
<span style="margin-right: 10px"> 外边距(上)</span
|
|
><el-input-number
|
|
v-model="controlData.control.mt"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 外边距(下)</span
|
|
><el-input-number
|
|
v-model="controlData.control.mb"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 外边距(左)</span
|
|
><el-input-number
|
|
v-model="controlData.control.ml"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 外边距(右)</span
|
|
><el-input-number
|
|
v-model="controlData.control.mr"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 内边距(上)</span
|
|
><el-input-number
|
|
v-model="controlData.control.pt"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 内边距(下)</span
|
|
><el-input-number
|
|
v-model="controlData.control.pb"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 内边距(左)</span
|
|
><el-input-number
|
|
v-model="controlData.control.pl"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
<span style="margin-right: 10px"> 内边距(右)</span
|
|
><el-input-number
|
|
v-model="controlData.control.pr"
|
|
style="margin-bottom: 10px"
|
|
/><br />
|
|
</div>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'lowcodeImage_float'">
|
|
<el-switch
|
|
v-model="controlData.control.floatFlag"
|
|
style="margin-right: 15px"
|
|
/>
|
|
<el-select
|
|
v-if="controlData.control.floatFlag"
|
|
v-model="controlData.control.floatValue"
|
|
style="width: 150px; height: 20px"
|
|
>
|
|
<el-option
|
|
v-for="showModeSelected1 in floatSelectOptions"
|
|
:key="showModeSelected1.value"
|
|
:label="showModeSelected1.label"
|
|
:value="showModeSelected1.value"
|
|
/>
|
|
</el-select>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'associatedForms_hide'">
|
|
<el-button
|
|
v-if="controlData.control.hideConditionHtml === ''"
|
|
style="padding-top: 5px"
|
|
type="primary"
|
|
link
|
|
append-to-body="true"
|
|
modal="true"
|
|
@click="associatedFormsHideDialoghandle"
|
|
>设置隐藏条件</el-button
|
|
>
|
|
<div
|
|
style="width: 100%; cursor: pointer"
|
|
@click="associatedFormsHideDialoghandle"
|
|
v-html="controlData.control.hideConditionHtml"
|
|
></div>
|
|
</el-row>
|
|
<el-row v-else-if="item.type === 'associatedForms_form'">
|
|
<div style="margin-top: 25px; margin-left: -60px">
|
|
<el-tree-select
|
|
v-model="controlData.control.formid"
|
|
style="width: 260px"
|
|
:data="customerFormTree[0].children"
|
|
check-strictly
|
|
:render-after-expand="false"
|
|
filterable
|
|
@change="formidChanged"
|
|
/>
|
|
</div>
|
|
<!-- <div v-html="controlData.control.formid"></div> -->
|
|
</el-row>
|
|
|
|
<el-row v-else-if="item.type === 'associatedForms_dataRange'">
|
|
<el-button
|
|
v-if="controlData.control.dataRangeConditionHtml === ''"
|
|
style="padding-top: 5px"
|
|
type="primary"
|
|
link
|
|
append-to-body="true"
|
|
modal="true"
|
|
@click="associatedFormsDataRangeDialoghandle"
|
|
>设置数据范围</el-button
|
|
>
|
|
<div
|
|
style="width: 100%; cursor: pointer"
|
|
@click="associatedFormsDataRangeDialoghandle"
|
|
v-html="controlData.control.dataRangeConditionHtml"
|
|
></div>
|
|
</el-row>
|
|
|
|
<el-row v-else-if="item.type === 'associatedForms_FillRoles'">
|
|
<el-button
|
|
style="padding-top: 5px"
|
|
type="primary"
|
|
link
|
|
append-to-body="true"
|
|
modal="true"
|
|
@click="associatedFormsDataFillRolesDialoghandle"
|
|
>设置数据填充规则</el-button
|
|
>
|
|
</el-row>
|
|
<el-input
|
|
v-else
|
|
:type="item.inputStyle"
|
|
v-model="item.value"
|
|
:placeholder="item.placeholder"
|
|
:disabled="isNotWriteWord(item)"
|
|
@input="controlChange(item, $event)"
|
|
/>
|
|
</el-form-item>
|
|
</template>
|
|
<template v-if="controlData.config">
|
|
<!-- <el-form-item label="联动条件" class="form_cont">
|
|
<el-switch v-model="controlData.config.linkKey" />
|
|
</el-form-item> -->
|
|
<template v-if="controlData.config.linkKey">
|
|
<el-form-item class="form_cont">
|
|
<el-input
|
|
v-model="controlData.config.linkValue"
|
|
type="textarea"
|
|
placeholder="表达式如: $.input>1 $表示为当前表单数据,input为字段标识"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item
|
|
class="form_cont"
|
|
v-if="
|
|
showHide(
|
|
[
|
|
'input',
|
|
'textarea',
|
|
'radio',
|
|
'checkbox',
|
|
'select',
|
|
'date',
|
|
'switch',
|
|
'number',
|
|
'cascader',
|
|
'slider',
|
|
'datePicker',
|
|
'timePicker',
|
|
'colorPicker',
|
|
'inputNumber',
|
|
'rate',
|
|
'treeSelect',
|
|
],
|
|
true
|
|
)
|
|
"
|
|
label="联动结果"
|
|
>
|
|
<el-radio-group
|
|
v-model="controlData.config.linkResult"
|
|
class="option-radio"
|
|
>
|
|
<el-radio label="hidden">隐藏(默认)</el-radio>
|
|
<el-radio label="disabled">禁用</el-radio>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</template>
|
|
</template>
|
|
<template v-if="showHide(['tabs'], true)">
|
|
<!-- <div class="h3"><h3>标签配置项</h3></div> -->
|
|
<el-divider content-position="left">标签配置项</el-divider>
|
|
<el-form-item
|
|
class="form_cont"
|
|
v-for="(item, index) in controlData.columns"
|
|
:key="index"
|
|
>
|
|
<el-col :span="12">
|
|
<el-input v-model="item.label" placeholder="标签配置项" />
|
|
</el-col>
|
|
<el-col :span="2" :offset="1">
|
|
<i
|
|
class="icon-del"
|
|
@click="delSelectOption(index as number, 'tabs')"
|
|
></i>
|
|
</el-col>
|
|
</el-form-item>
|
|
<el-form-item class="form_cont">
|
|
<el-button @click="addSelectOption('tabs')">增加标签</el-button>
|
|
</el-form-item>
|
|
</template>
|
|
<!--编号规则设置--->
|
|
<div v-if="showHide(['serialNumber'], true)">
|
|
<el-divider content-position="left">编码规则配置</el-divider>
|
|
<el-form-item label="编码方式" class="form_cont">
|
|
<el-switch
|
|
v-model="controlData.config.automatic"
|
|
inline-prompt
|
|
active-text="自动编码"
|
|
inactive-text="手动编码"
|
|
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #e6a23c"
|
|
/>
|
|
</el-form-item>
|
|
<div v-if="controlData.config.automatic">
|
|
<el-form-item
|
|
v-for="(item, index) in controlData.config.customRules"
|
|
:key="index"
|
|
class="form_cont"
|
|
>
|
|
<el-input
|
|
v-model="item.rule"
|
|
:placeholder="item.message ? item.message : '请输入自定义字符'"
|
|
>
|
|
<template #prepend>
|
|
<el-select
|
|
v-model="item.type"
|
|
style="width: 100px"
|
|
@change="rulesSelectNumChange(item, $event)"
|
|
>
|
|
<el-option
|
|
v-for="list in state.numberRulesList"
|
|
:key="list.type"
|
|
:label="list.label"
|
|
:value="list.type"
|
|
/>
|
|
</el-select>
|
|
</template>
|
|
<template #append>
|
|
<i class="icon-del" @click="delNumRules(index as number)"></i>
|
|
</template>
|
|
</el-input>
|
|
</el-form-item>
|
|
<el-form-item class="form_cont">
|
|
<el-button @click="addNumRules">添加规则</el-button>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
<div
|
|
v-if="
|
|
showHide(
|
|
['radio', 'select', 'checkbox', 'cascader', 'inputSlot', 'treeSelect'],
|
|
true
|
|
)
|
|
"
|
|
>
|
|
<el-divider content-position="left">选项配置</el-divider>
|
|
<el-form-item
|
|
v-if="showHide(['select'], true)"
|
|
label="添加全部项"
|
|
class="form_cont"
|
|
>
|
|
<el-input
|
|
v-model="controlData.config.addAll"
|
|
placeholder="请输入全部项文案"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="选项数据源" class="form_cont">
|
|
<el-select
|
|
v-model="controlData.config.optionsType"
|
|
@change="controlData.config.optionsFun = ''"
|
|
>
|
|
<el-option :value="0" label="固定选项" />
|
|
<el-option :value="1" label="数据源" />
|
|
<el-option :value="2" label="接口字典" />
|
|
</el-select>
|
|
</el-form-item>
|
|
<template v-if="controlData.config.optionsType === 0">
|
|
<div v-if="controlData.type !== 'cascader'">
|
|
<el-form-item
|
|
v-for="(item, index) in controlData.options"
|
|
:key="index"
|
|
class="form_cont"
|
|
>
|
|
<el-col :span="10">
|
|
<el-input v-model="item.label" placeholder="选项标签" />
|
|
</el-col>
|
|
<el-col :span="10" :offset="1">
|
|
<el-input v-model="item.value" placeholder="选项值" />
|
|
</el-col>
|
|
<el-col :span="2" :offset="1">
|
|
<i class="icon-del" @click="delSelectOption(index as number)"></i>
|
|
</el-col>
|
|
</el-form-item>
|
|
</div>
|
|
<el-form-item class="form_cont">
|
|
<el-button @click="addSelectOption">{{
|
|
controlData.type === "cascader" ? "编辑" : "新增"
|
|
}}</el-button>
|
|
</el-form-item>
|
|
</template>
|
|
<template v-else>
|
|
<el-form-item class="form_cont">
|
|
<el-input
|
|
v-model="controlData.config.optionsFun"
|
|
:placeholder="getOptionPlaceholder(controlData.config.optionsType)"
|
|
>
|
|
<template v-if="controlData.config.optionsType === 1" #prepend>
|
|
<el-select v-model="controlData.config.method" style="width: 80px">
|
|
<el-option label="get" value="get" />
|
|
<el-option label="post" value="post" />
|
|
</el-select>
|
|
</template>
|
|
</el-input>
|
|
</el-form-item>
|
|
<template v-if="controlData.config.optionsType === 1">
|
|
<el-form-item label="指定label属性值" class="form_cont">
|
|
<el-input
|
|
v-model="controlData.config.label"
|
|
placeholder="返回数据中没有label时可设置"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="指定value属性值" class="form_cont">
|
|
<el-input
|
|
v-model="controlData.config.value"
|
|
placeholder="返回数据中没有value时可设置"
|
|
/>
|
|
</el-form-item>
|
|
</template>
|
|
<el-form-item
|
|
v-if="controlData.config.optionsType === 1"
|
|
class="form_cont"
|
|
>
|
|
<el-button
|
|
@click="
|
|
optionsEvent(
|
|
'optionsParams',
|
|
'请求前处理事件,参数(data,route,form) data请求参数,route页面路由,form表单值'
|
|
)
|
|
"
|
|
>beforeRequest</el-button
|
|
>
|
|
<el-button
|
|
@click="
|
|
optionsEvent(
|
|
'optionsResult',
|
|
'请求返回结束处理;,也可为字符串,如opt=formatTest'
|
|
)
|
|
"
|
|
>afterResponse</el-button
|
|
>
|
|
</el-form-item>
|
|
</template>
|
|
<el-form-item label="尝试转换value值为" class="form_cont">
|
|
<el-select
|
|
v-model="controlData.config.transformData"
|
|
placeholder="默认为number"
|
|
>
|
|
<el-option value="none">不转换</el-option>
|
|
<el-option value="number">number</el-option>
|
|
<el-option value="string">string</el-option>
|
|
</el-select>
|
|
</el-form-item>
|
|
</div>
|
|
<template
|
|
v-if="
|
|
!state.isSearch &&
|
|
showHide([
|
|
'txt',
|
|
'title',
|
|
'table',
|
|
'grid',
|
|
'tabs',
|
|
'card',
|
|
'switch',
|
|
'gridChild',
|
|
'tableColumn',
|
|
'divider',
|
|
'div',
|
|
'button',
|
|
])
|
|
"
|
|
>
|
|
<el-divider content-position="left">校验设置</el-divider>
|
|
<div v-if="showHide(['input', 'password', 'component'], true)">
|
|
<el-form-item
|
|
v-for="(item, index) in controlData.customRules"
|
|
:key="item.type"
|
|
class="form_cont"
|
|
>
|
|
<el-input v-model="item.message" placeholder="校验提示信息">
|
|
<template #prepend>
|
|
<el-select
|
|
v-model="item.type"
|
|
style="width: 80px"
|
|
@change="rulesSelectChange(item, $event)"
|
|
>
|
|
<el-option
|
|
v-for="list in state.customRulesList"
|
|
:key="list.type"
|
|
:label="list.label"
|
|
:value="list.type"
|
|
/>
|
|
</el-select>
|
|
</template>
|
|
<template #append>
|
|
<i class="icon-del" @click="delAddRules(index as number)"></i>
|
|
</template>
|
|
</el-input>
|
|
<el-input
|
|
v-if="item.type === 'rules'"
|
|
v-model="item.rules"
|
|
placeholder="正则表达式"
|
|
/>
|
|
<el-input
|
|
v-if="item.type === 'methods'"
|
|
v-model="item.methods"
|
|
placeholder="方法名称,此方法仅适用于导出vue文件"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item class="form_cont">
|
|
<el-button @click="addRulesFast">快速添加</el-button>
|
|
<el-button @click="addRules(state.tooltip.rules)"
|
|
>编写校验规则
|
|
<el-tooltip
|
|
:content="state.tooltip.rules"
|
|
placement="top"
|
|
raw-content
|
|
>
|
|
<el-icon>
|
|
<QuestionFilled />
|
|
</el-icon>
|
|
</el-tooltip>
|
|
</el-button>
|
|
</el-form-item>
|
|
</div>
|
|
<el-form-item class="form_cont" v-else>
|
|
<el-checkbox :model-value="checkboxRequired" @change="requiredChange"
|
|
>必填
|
|
</el-checkbox>
|
|
<el-input
|
|
v-if="controlData.item?.rules && controlData.item?.rules[0]"
|
|
v-model="controlData.item.rules[0].message"
|
|
placeholder="自定义必填错误提示"
|
|
/>
|
|
</el-form-item>
|
|
</template>
|
|
<!-- <el-divider content-position="left">其他属性</el-divider>
|
|
<div v-if="showHide(['grid', 'card', 'gridChild', 'divider', 'div'])" class="form_cont">
|
|
|
|
|
|
<el-button
|
|
size="small"
|
|
@click="openAttrDialog('', state.tooltip.props)"
|
|
>编辑属性
|
|
<el-tooltip :content="state.tooltip.props" placement="top">
|
|
<el-icon>
|
|
<QuestionFilled />
|
|
</el-icon>
|
|
</el-tooltip>
|
|
</el-button>
|
|
</div> -->
|
|
<el-divider content-position="left">高级属性</el-divider>
|
|
|
|
<LayoutPage
|
|
v-if="cssIsShouw(attrList)"
|
|
v-model:styles-val="controlDataStyls"
|
|
:place="controlData.type"
|
|
/>
|
|
</el-form>
|
|
</el-scrollbar>
|
|
</el-tab-pane>
|
|
<el-tab-pane label="表单配置" name="second">
|
|
<el-scrollbar class="formAttributeBox">
|
|
<el-form size="small" class="form">
|
|
<el-divider content-position="left">基础配置</el-divider>
|
|
<el-form-item class="form_cont">
|
|
<template #label> 归属分组 </template>
|
|
<el-select
|
|
id="groupForm"
|
|
v-model="formConfig.groupKey"
|
|
placeholder="Select"
|
|
ref="groupForm"
|
|
>
|
|
<el-option
|
|
v-for="item in formGroup.list"
|
|
:key="item.idStr"
|
|
:label="item.title"
|
|
:value="item.idStr"
|
|
/>
|
|
<p v-if="loadingmore">加载中</p>
|
|
<p v-if="loadingnomore">无数据</p>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item
|
|
v-for="(item, index) in formControlProject.filter((item) => !item.hide)"
|
|
:label="item.label"
|
|
:key="index"
|
|
class="form_cont"
|
|
>
|
|
<el-select
|
|
v-if="item.type === 'select'"
|
|
v-model="item.value"
|
|
:filterable="item.key === 'class'"
|
|
:allow-create="item.key === 'class'"
|
|
:placeholder="item.placeholder"
|
|
:clearable="item.clearable"
|
|
@change="formAttrChange(item)"
|
|
>
|
|
<el-option
|
|
v-for="opt in item.options"
|
|
:key="opt.label || opt.name"
|
|
:label="opt.label || opt.name"
|
|
:value="formatNumber(opt.value ?? opt.id)"
|
|
/>
|
|
</el-select>
|
|
<el-switch
|
|
v-else-if="item.type === 'switch'"
|
|
v-model="item.value"
|
|
@input="formAttrChange(item)"
|
|
/>
|
|
<el-input
|
|
v-else
|
|
v-model="item.value"
|
|
:placeholder="item.placeholder"
|
|
:disabled="isNotWrite(item)"
|
|
@input="formAttrChange(item)"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item class="form_cont">
|
|
<template #label> 表单图标 </template>
|
|
<el-upload
|
|
class="avatar-uploader"
|
|
:action="imgUploadApiUrl"
|
|
:show-file-list="false"
|
|
:on-success="handleAvatarSuccess"
|
|
:before-upload="beforeAvatarUpload"
|
|
>
|
|
<img
|
|
v-if="formConfig.imageUrl"
|
|
:src="formConfig.imageUrl"
|
|
class="avatar"
|
|
/>
|
|
<el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
|
|
</el-upload>
|
|
</el-form-item>
|
|
<template v-if="!state.isSearch">
|
|
<el-divider content-position="left">接口数据事件</el-divider>
|
|
<el-form-item v-if="!state.isSearch" class="form_cont">
|
|
<template #label>
|
|
添加时获取请求
|
|
<el-tooltip
|
|
content="新增表单数据时,从接口获取新增初始数据"
|
|
placement="top"
|
|
>
|
|
<el-icon><QuestionFilled /></el-icon>
|
|
</el-tooltip>
|
|
</template>
|
|
<el-switch
|
|
v-model="formConfig.addLoad"
|
|
@change="formAttrChange({ key: 'addLoad', path: 'config' }, $event)"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="新增数据保存url" class="form_cont">
|
|
<el-input
|
|
v-model="formConfig.addUrl"
|
|
placeholder="表单提交的url,非特殊不需要设置"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="修改数据保存url" class="form_cont">
|
|
<el-input
|
|
v-model="formConfig.editUrl"
|
|
placeholder="修改提交的url,非特殊不需要设置"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="获取表单数据url" class="form_cont">
|
|
<el-input
|
|
v-model="formConfig.requestUrl"
|
|
placeholder="获取表单数据url,非特殊不需要设置"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item class="event-btn form_cont">
|
|
<el-button
|
|
@click="
|
|
eventClick('beforeRequest', '获取表单初始数据前事件,可修改请求参数')
|
|
"
|
|
>
|
|
beforeRequest
|
|
</el-button>
|
|
<el-button
|
|
@click="
|
|
eventClick(
|
|
'afterResponse',
|
|
'获取表单初始数据后事件,可对请求返回数据进行处理;也可为字符串,如opt=formatTest'
|
|
)
|
|
"
|
|
>afterResponse
|
|
</el-button>
|
|
<el-button
|
|
@click="
|
|
eventClick(
|
|
'beforeSubmit',
|
|
'表单数据提交前事件,可对提交数据进行处理;也可为字符串,如opt=formatTest'
|
|
)
|
|
"
|
|
>beforeSubmit
|
|
</el-button>
|
|
<el-button @click="eventClick('afterSubmit', '表单数据提交成功事件')"
|
|
>afterSubmit
|
|
</el-button>
|
|
<el-button
|
|
@click="
|
|
eventClick(
|
|
'change',
|
|
'表单组件值改变事件。当表单某值改变时,可修改其他组件的值;也可为字符串,如opt=formChange,字符串即为/utils/formChangeValue(name,model,key)中的key值'
|
|
)
|
|
"
|
|
>表单组件改变事件change
|
|
</el-button>
|
|
</el-form-item>
|
|
</template>
|
|
<el-divider content-position="left">表单整体布局</el-divider>
|
|
<el-form-item label="组件尺寸" class="form_cont">
|
|
<el-radio-group v-model="formData.size">
|
|
<el-radio-button label="large">大</el-radio-button>
|
|
<el-radio-button label="default">适中</el-radio-button>
|
|
<el-radio-button label="small">小</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="表单样式名称" class="form_cont">
|
|
<el-select
|
|
v-model="formData.class"
|
|
class="m-2"
|
|
placeholder="额外添加的表单class类名"
|
|
>
|
|
<el-option
|
|
v-for="item in optionsCss"
|
|
:key="item.value"
|
|
:label="item.label"
|
|
:value="item.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
<el-form-item label="行内表单模式" class="form_cont">
|
|
<el-switch
|
|
v-model="formData.inline"
|
|
active-text="开启"
|
|
inactive-text="关闭"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="标签宽度" class="form_cont">
|
|
<el-input
|
|
v-model="formData.labelWidth"
|
|
clearable
|
|
placeholder="表单标签宽度"
|
|
>
|
|
<template #suffix>PX</template>
|
|
</el-input>
|
|
</el-form-item>
|
|
<el-form-item label="标签后缀" class="form_cont">
|
|
<el-input v-model="formData.labelSuffix" placeholder="表单标签后缀" />
|
|
</el-form-item>
|
|
<el-form-item label="表单标签对齐方式" class="form_cont">
|
|
<el-radio-group v-model="formData.labelPosition">
|
|
<el-radio-button label="left">左</el-radio-button>
|
|
<el-radio-button label="right">右</el-radio-button>
|
|
<el-radio-button label="top">上</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="必填项星号位置" class="form_cont">
|
|
<el-radio-group v-model="formData.requireAsteriskPosition">
|
|
<el-radio-button label="left">左</el-radio-button>
|
|
<el-radio-button label="right">右</el-radio-button>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
<el-form-item label="是否隐藏星号" class="form_cont">
|
|
<el-switch
|
|
v-model="formData.hideRequiredAsterisk"
|
|
active-text="隐藏"
|
|
inactive-text="显示"
|
|
style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="校验错误信息" class="form_cont">
|
|
<el-switch
|
|
v-model="formData.showMessage"
|
|
active-text="显示"
|
|
inactive-text="隐藏"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="以行内形式展示校验信息" class="form_cont">
|
|
<el-switch
|
|
v-model="formData.inlineMessage"
|
|
active-text="显示"
|
|
inactive-text="隐藏"
|
|
/>
|
|
</el-form-item>
|
|
<el-form-item label="是否显示校验结果反馈图标" class="form_cont">
|
|
<el-switch
|
|
v-model="formData.statusIcon"
|
|
active-text="显示"
|
|
inactive-text="隐藏"
|
|
/>
|
|
</el-form-item>
|
|
<el-divider content-position="left">表单功能补充</el-divider>
|
|
<el-form-item class="form_cont">
|
|
<el-button @click="editFormStyle(state.tooltip.css)">
|
|
编辑表单样式
|
|
<el-tooltip :content="state.tooltip.css" placement="top">
|
|
<el-icon>
|
|
<QuestionFilled />
|
|
</el-icon>
|
|
</el-tooltip>
|
|
</el-button>
|
|
<el-button @click="editFormDict(state.tooltip.dict)">
|
|
设置数据字典
|
|
<el-tooltip :content="state.tooltip.dict" placement="top">
|
|
<el-icon>
|
|
<QuestionFilled />
|
|
</el-icon>
|
|
</el-tooltip>
|
|
</el-button>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-scrollbar>
|
|
</el-tab-pane>
|
|
</el-tabs>
|
|
</div>
|
|
</template>
|
|
<style lang="scss" scoped>
|
|
.formAttributeBox {
|
|
height: calc(100vh - 105px);
|
|
}
|
|
li::before {
|
|
content: "";
|
|
display: inline-block;
|
|
width: 4px;
|
|
height: 4px;
|
|
border-radius: 50%;
|
|
background-color: gray;
|
|
margin-right: 5px;
|
|
margin-left: 5px;
|
|
margin-bottom: 3.5px;
|
|
}
|
|
|
|
.sidebar-tools_e .el-tabs__content {
|
|
padding: 0;
|
|
}
|
|
.el-collapse-item__header {
|
|
padding-left: 10px;
|
|
background-color: rgb(229, 229, 229);
|
|
}
|
|
.el-collapse-item__header {
|
|
padding-left: 10px;
|
|
background-color: rgb(229, 229, 229);
|
|
}
|
|
|
|
.form_cont {
|
|
padding: 0 10px;
|
|
}
|
|
.avatar-uploader {
|
|
width: 100px;
|
|
height: 100px;
|
|
.avatar {
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
.avatar-uploader-icon {
|
|
width: 100px;
|
|
height: 100px;
|
|
}
|
|
}
|
|
.custom-tree-node {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
font-size: 14px;
|
|
padding-right: 8px;
|
|
}
|
|
.custom-tree-node:hover {
|
|
background-color: antiquewhite;
|
|
}
|
|
|
|
.associatedFormsHideDialogMain7 {
|
|
display: flex;
|
|
}
|
|
.el-main {
|
|
--el-main-padding: 5px;
|
|
}
|
|
</style>
|
|
|