|
|
|
|
@ -21,6 +21,63 @@ function isJSON(str) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// radio 统一按 string 做存储与比较,避免 "1" vs 1 导致回显不勾选
|
|
|
|
|
function normalizeRadioValue(v) {
|
|
|
|
|
if (v === null || v === undefined) return "";
|
|
|
|
|
return String(v);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function getRadioOptionValue(option) {
|
|
|
|
|
const raw = typeof option === "object" ? option?.id : option;
|
|
|
|
|
return normalizeRadioValue(raw);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 支持 radio 选项含“下级勾选项”的简单格式:
|
|
|
|
|
// 例:分散采购['委托社会中介代理机构','自行采购']
|
|
|
|
|
// 或:分散采购{'委托社会中介代理机构','自行采购'}
|
|
|
|
|
function parseNestedRadioOption(option) {
|
|
|
|
|
if (typeof option !== "string") {
|
|
|
|
|
return { label: typeof option === "object" ? option?.name : option, children: [] };
|
|
|
|
|
}
|
|
|
|
|
const match = option.match(/^(.*?)\s*(?:\[(.*)\]|\{(.*)\})\s*$/);
|
|
|
|
|
if (!match) return { label: option, children: [] };
|
|
|
|
|
const label = (match[1] || "").trim();
|
|
|
|
|
const rawList = match[2] ?? match[3] ?? "";
|
|
|
|
|
// 提取引号内内容,兼容单引号/双引号
|
|
|
|
|
const children = Array.from(rawList.matchAll(/'([^']*)'|"([^"]*)"/g))
|
|
|
|
|
.map((m) => (m[1] ?? m[2] ?? "").trim())
|
|
|
|
|
.filter(Boolean);
|
|
|
|
|
return { label: label || option, children };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// nested radio(父+子)存储(方案 c):JSON 字符串
|
|
|
|
|
// 例:{"parent":"分散采购","children":["委托社会中介代理机构"]}
|
|
|
|
|
function parseNestedRadioStoredValue(v) {
|
|
|
|
|
const raw = v === null || v === undefined ? "" : v;
|
|
|
|
|
if (typeof raw !== "string") {
|
|
|
|
|
return { parent: normalizeRadioValue(raw), child: "" };
|
|
|
|
|
}
|
|
|
|
|
try {
|
|
|
|
|
const obj = JSON.parse(raw);
|
|
|
|
|
if (obj && typeof obj === "object" && (obj.parent || obj.children || obj.child)) {
|
|
|
|
|
const parent = normalizeRadioValue(obj.parent);
|
|
|
|
|
const childArr = Array.isArray(obj.children) ? obj.children : [];
|
|
|
|
|
const child = normalizeRadioValue(obj.child ?? childArr?.[0] ?? "");
|
|
|
|
|
return { parent, child };
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
// ignore
|
|
|
|
|
}
|
|
|
|
|
return { parent: normalizeRadioValue(raw), child: "" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function buildNestedRadioStoredValue(parent, child) {
|
|
|
|
|
return JSON.stringify({
|
|
|
|
|
parent: normalizeRadioValue(parent),
|
|
|
|
|
children: child ? [normalizeRadioValue(child)] : [],
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @param {String} device 'desktop' | 'mobile'
|
|
|
|
|
* @param {Object} info field参数
|
|
|
|
|
@ -205,32 +262,128 @@ export default function formBuilder(
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "radio":
|
|
|
|
|
// 支持父 radio + 子 radio(单选),子项存储为 JSON(方案 c)
|
|
|
|
|
const { parent: radioParent, child: radioChild } = parseNestedRadioStoredValue(target[info.name]);
|
|
|
|
|
|
|
|
|
|
const nestedOptions = options.map((option) => {
|
|
|
|
|
const parsed = parseNestedRadioOption(option);
|
|
|
|
|
const label = typeof option === "object" ? option.name : parsed.label;
|
|
|
|
|
const value = normalizeRadioValue(label);
|
|
|
|
|
const children = typeof option === "string" ? parsed.children : [];
|
|
|
|
|
return { option, label, value, children };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onParentChange = (parentValue) => {
|
|
|
|
|
const nextParent = normalizeRadioValue(parentValue);
|
|
|
|
|
const hit = nestedOptions.find((i) => i.value === nextParent);
|
|
|
|
|
if (hit && hit.children && hit.children.length > 0) {
|
|
|
|
|
const keepChild = hit.children.includes(radioChild) ? radioChild : "";
|
|
|
|
|
this.$set(target, info.name, buildNestedRadioStoredValue(nextParent, keepChild));
|
|
|
|
|
} else {
|
|
|
|
|
this.$set(target, info.name, nextParent);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onChildChange = (parentValue, childValue) => {
|
|
|
|
|
this.$set(
|
|
|
|
|
target,
|
|
|
|
|
info.name,
|
|
|
|
|
buildNestedRadioStoredValue(parentValue, normalizeRadioValue(childValue))
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
formItem = h(
|
|
|
|
|
"el-radio-group",
|
|
|
|
|
{
|
|
|
|
|
props: {
|
|
|
|
|
value: target[info.name],
|
|
|
|
|
value: radioParent,
|
|
|
|
|
},
|
|
|
|
|
attrs: {
|
|
|
|
|
placeholder: info.help_text,
|
|
|
|
|
},
|
|
|
|
|
on: {
|
|
|
|
|
input: (e) => {
|
|
|
|
|
this.$set(target, info.name, e);
|
|
|
|
|
},
|
|
|
|
|
input: onParentChange,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
options.map((option) =>
|
|
|
|
|
h(
|
|
|
|
|
nestedOptions.map((item) => {
|
|
|
|
|
const checked = item.value === radioParent;
|
|
|
|
|
const showChildren = checked && item.children && item.children.length > 0;
|
|
|
|
|
return h(
|
|
|
|
|
"el-radio",
|
|
|
|
|
{
|
|
|
|
|
key: item.value,
|
|
|
|
|
props: {
|
|
|
|
|
label: typeof option === "object" ? option.id : option,
|
|
|
|
|
label: item.value,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
typeof option === "object" ? option.name : option
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
item.label
|
|
|
|
|
),
|
|
|
|
|
showChildren
|
|
|
|
|
? h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
marginLeft: "6px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
"("
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
showChildren
|
|
|
|
|
? h(
|
|
|
|
|
"el-radio-group",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
marginLeft: "2px",
|
|
|
|
|
marginRight: "2px",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
value: radioChild,
|
|
|
|
|
},
|
|
|
|
|
on: {
|
|
|
|
|
input: (v) => onChildChange(item.value, v),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
item.children.map((c) =>
|
|
|
|
|
h(
|
|
|
|
|
"el-radio",
|
|
|
|
|
{
|
|
|
|
|
key: `${item.value}__${c}`,
|
|
|
|
|
props: {
|
|
|
|
|
label: normalizeRadioValue(c),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
c
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
showChildren
|
|
|
|
|
? h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
")"
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "budget-source":
|
|
|
|
|
@ -938,6 +1091,127 @@ export default function formBuilder(
|
|
|
|
|
getDetailSelectValue()
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "radio":
|
|
|
|
|
// 只读模式:用“方框 + 勾号”展示全部选项,并高亮已选项(不使用禁用 radio,避免灰色字体)
|
|
|
|
|
const { parent: readonlyParent, child: readonlyChild } = parseNestedRadioStoredValue(target[info.name]);
|
|
|
|
|
formItem = h(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
flexWrap: "wrap",
|
|
|
|
|
gap: "10px 16px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
lineHeight: "20px",
|
|
|
|
|
minHeight: "40px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
options.map((option) => {
|
|
|
|
|
const parsed = parseNestedRadioOption(option);
|
|
|
|
|
const labelText = typeof option === "object" ? option.name : parsed.label;
|
|
|
|
|
const optValue = normalizeRadioValue(labelText);
|
|
|
|
|
const checked = optValue === readonlyParent;
|
|
|
|
|
const children = typeof option === "string" ? parsed.children : [];
|
|
|
|
|
return h(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
cursor: "default",
|
|
|
|
|
userSelect: "none",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
width: "14px",
|
|
|
|
|
height: "14px",
|
|
|
|
|
border: "1px solid rgb(51, 51, 51)",
|
|
|
|
|
borderRadius: "2px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
marginRight: "6px",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
fontSize: "12px",
|
|
|
|
|
lineHeight: "12px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
checked ? "✓" : ""
|
|
|
|
|
),
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
labelText
|
|
|
|
|
),
|
|
|
|
|
checked && children.length > 0
|
|
|
|
|
? h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
marginLeft: "6px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h("span", "("),
|
|
|
|
|
...children.map((c) => {
|
|
|
|
|
const cVal = normalizeRadioValue(c);
|
|
|
|
|
const cChecked = cVal === readonlyChild;
|
|
|
|
|
return h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
key: `${optValue}__${cVal}`,
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "6px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
width: "14px",
|
|
|
|
|
height: "14px",
|
|
|
|
|
border: "1px solid rgb(51, 51, 51)",
|
|
|
|
|
borderRadius: "2px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
fontSize: "12px",
|
|
|
|
|
lineHeight: "12px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
cChecked ? "✓" : ""
|
|
|
|
|
),
|
|
|
|
|
h("span", c),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
h("span", ")"),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "relation-flow":
|
|
|
|
|
console.log("info",info,target)
|
|
|
|
|
if (!this.flows[info.name]) {
|
|
|
|
|
@ -1162,32 +1436,45 @@ export default function formBuilder(
|
|
|
|
|
h("br"),
|
|
|
|
|
info.is_sign
|
|
|
|
|
? log.user?.sign_file?.url
|
|
|
|
|
? h("el-image", {
|
|
|
|
|
? h("div", {
|
|
|
|
|
style: {
|
|
|
|
|
"max-height": "80px",
|
|
|
|
|
"max-width": "120px",
|
|
|
|
|
display: "block",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
fit: "contain",
|
|
|
|
|
alt: log.user?.name || "",
|
|
|
|
|
"preview-src-list": [log.user.sign_file.url],
|
|
|
|
|
lazy: false,
|
|
|
|
|
},
|
|
|
|
|
attrs: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
display: "flex",
|
|
|
|
|
"align-items": "center",
|
|
|
|
|
gap: "8px",
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
h("el-image", {
|
|
|
|
|
style: {
|
|
|
|
|
"max-height": "80px",
|
|
|
|
|
"max-width": "100px",
|
|
|
|
|
display: "block",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
fit: "contain",
|
|
|
|
|
alt: log.user?.name || "",
|
|
|
|
|
"preview-src-list": [log.user.sign_file.url],
|
|
|
|
|
lazy: false,
|
|
|
|
|
},
|
|
|
|
|
attrs: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
"font-size": "16px",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
log.updated_at
|
|
|
|
|
? this.$moment(log.updated_at).format("YYYY年MM月DD日")
|
|
|
|
|
: ""
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
: h("span", log.user?.name || "")
|
|
|
|
|
: "",
|
|
|
|
|
info.is_sign ? h("br") : "",
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
log.updated_at
|
|
|
|
|
? this.$moment(log.updated_at).format("YYYY年MM月DD日")
|
|
|
|
|
: ""
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
@ -1291,12 +1578,15 @@ export default function formBuilder(
|
|
|
|
|
return h("div", {
|
|
|
|
|
style: {
|
|
|
|
|
"margin-top": "8px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
"align-items": "center",
|
|
|
|
|
gap: "8px",
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
h("el-image", {
|
|
|
|
|
style: {
|
|
|
|
|
"max-height": "80px",
|
|
|
|
|
"max-width": "120px",
|
|
|
|
|
"max-width": "100px",
|
|
|
|
|
display: "block",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
@ -1314,9 +1604,8 @@ export default function formBuilder(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
"font-size": "12px",
|
|
|
|
|
color: "#909399",
|
|
|
|
|
"margin-top": "4px",
|
|
|
|
|
"font-size": "16px",
|
|
|
|
|
color: "#000",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
log.updated_at
|
|
|
|
|
@ -1371,30 +1660,109 @@ export default function formBuilder(
|
|
|
|
|
});
|
|
|
|
|
break;
|
|
|
|
|
case "radio":
|
|
|
|
|
// 支持父 radio + 子 radio(单选),子项存储为 JSON(方案 c)
|
|
|
|
|
const { parent: mRadioParent, child: mRadioChild } = parseNestedRadioStoredValue(target[info.name]);
|
|
|
|
|
|
|
|
|
|
const mNestedOptions = options.map((option) => {
|
|
|
|
|
const parsed = parseNestedRadioOption(option);
|
|
|
|
|
const label = typeof option === "object" ? option.name : parsed.label;
|
|
|
|
|
const value = normalizeRadioValue(label);
|
|
|
|
|
const children = typeof option === "string" ? parsed.children : [];
|
|
|
|
|
return { option, label, value, children };
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
const onMParentChange = (parentValue) => {
|
|
|
|
|
const nextParent = normalizeRadioValue(parentValue);
|
|
|
|
|
const hit = mNestedOptions.find((i) => i.value === nextParent);
|
|
|
|
|
if (hit && hit.children && hit.children.length > 0) {
|
|
|
|
|
const keepChild = hit.children.includes(mRadioChild) ? mRadioChild : "";
|
|
|
|
|
this.$set(target, info.name, buildNestedRadioStoredValue(nextParent, keepChild));
|
|
|
|
|
} else {
|
|
|
|
|
this.$set(target, info.name, nextParent);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const onMChildChange = (parentValue, childValue) => {
|
|
|
|
|
this.$set(
|
|
|
|
|
target,
|
|
|
|
|
info.name,
|
|
|
|
|
buildNestedRadioStoredValue(parentValue, normalizeRadioValue(childValue))
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
formItem = h(
|
|
|
|
|
"van-radio-group",
|
|
|
|
|
{
|
|
|
|
|
props: {
|
|
|
|
|
value: target[info.name],
|
|
|
|
|
value: mRadioParent,
|
|
|
|
|
},
|
|
|
|
|
on: {
|
|
|
|
|
input: (e) => {
|
|
|
|
|
this.$set(target, info.name, e);
|
|
|
|
|
},
|
|
|
|
|
input: onMParentChange,
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
options.map((option) =>
|
|
|
|
|
h(
|
|
|
|
|
"van-radio",
|
|
|
|
|
mNestedOptions.map((item) => {
|
|
|
|
|
const checked = item.value === mRadioParent;
|
|
|
|
|
const showChildren = checked && item.children && item.children.length > 0;
|
|
|
|
|
return h(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
props: {
|
|
|
|
|
name: typeof option === "object" ? option.id : option,
|
|
|
|
|
"checked-color": "var(--theme-color)",
|
|
|
|
|
key: item.value,
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
flexWrap: "wrap",
|
|
|
|
|
gap: "6px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
marginRight: "12px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
typeof option === "object" ? option.name : option
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"van-radio",
|
|
|
|
|
{
|
|
|
|
|
props: {
|
|
|
|
|
name: item.value,
|
|
|
|
|
"checked-color": "var(--theme-color)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
item.label
|
|
|
|
|
),
|
|
|
|
|
showChildren ? h("span", { style: { color: "rgb(51, 51, 51)" } }, "(") : null,
|
|
|
|
|
showChildren
|
|
|
|
|
? h(
|
|
|
|
|
"van-radio-group",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
value: mRadioChild,
|
|
|
|
|
},
|
|
|
|
|
on: {
|
|
|
|
|
input: (v) => onMChildChange(item.value, v),
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
item.children.map((c) =>
|
|
|
|
|
h(
|
|
|
|
|
"van-radio",
|
|
|
|
|
{
|
|
|
|
|
key: `${item.value}__${c}`,
|
|
|
|
|
props: {
|
|
|
|
|
name: normalizeRadioValue(c),
|
|
|
|
|
"checked-color": "var(--theme-color)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
c
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
showChildren ? h("span", { style: { color: "rgb(51, 51, 51)" } }, ")") : null,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "date":
|
|
|
|
|
@ -1970,6 +2338,127 @@ export default function formBuilder(
|
|
|
|
|
)
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "radio":
|
|
|
|
|
// 只读模式:用“方框 + 勾号”展示全部选项,并高亮已选项(不使用禁用 radio,避免灰色字体)
|
|
|
|
|
const { parent: readonlyMParent, child: readonlyMChild } = parseNestedRadioStoredValue(target[info.name]);
|
|
|
|
|
formItem = h(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
flexWrap: "wrap",
|
|
|
|
|
gap: "10px 16px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
lineHeight: "20px",
|
|
|
|
|
minHeight: "40px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
options.map((option) => {
|
|
|
|
|
const parsed = parseNestedRadioOption(option);
|
|
|
|
|
const labelText = typeof option === "object" ? option.name : parsed.label;
|
|
|
|
|
const optValue = normalizeRadioValue(labelText);
|
|
|
|
|
const checked = optValue === readonlyMParent;
|
|
|
|
|
const children = typeof option === "string" ? parsed.children : [];
|
|
|
|
|
return h(
|
|
|
|
|
"div",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
cursor: "default",
|
|
|
|
|
userSelect: "none",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
width: "14px",
|
|
|
|
|
height: "14px",
|
|
|
|
|
border: "1px solid rgb(51, 51, 51)",
|
|
|
|
|
borderRadius: "2px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
marginRight: "6px",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
fontSize: "12px",
|
|
|
|
|
lineHeight: "12px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
checked ? "✓" : ""
|
|
|
|
|
),
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
labelText
|
|
|
|
|
),
|
|
|
|
|
checked && children.length > 0
|
|
|
|
|
? h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
marginLeft: "6px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "10px",
|
|
|
|
|
color: "rgb(51, 51, 51)",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h("span", "("),
|
|
|
|
|
...children.map((c) => {
|
|
|
|
|
const cVal = normalizeRadioValue(c);
|
|
|
|
|
const cChecked = cVal === readonlyMChild;
|
|
|
|
|
return h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
key: `${optValue}__${cVal}`,
|
|
|
|
|
style: {
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
gap: "6px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
[
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
width: "14px",
|
|
|
|
|
height: "14px",
|
|
|
|
|
border: "1px solid rgb(51, 51, 51)",
|
|
|
|
|
borderRadius: "2px",
|
|
|
|
|
display: "inline-flex",
|
|
|
|
|
alignItems: "center",
|
|
|
|
|
justifyContent: "center",
|
|
|
|
|
boxSizing: "border-box",
|
|
|
|
|
fontSize: "12px",
|
|
|
|
|
lineHeight: "12px",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
cChecked ? "✓" : ""
|
|
|
|
|
),
|
|
|
|
|
h("span", c),
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
}),
|
|
|
|
|
h("span", ")"),
|
|
|
|
|
]
|
|
|
|
|
)
|
|
|
|
|
: null,
|
|
|
|
|
]
|
|
|
|
|
);
|
|
|
|
|
})
|
|
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
case "relation":
|
|
|
|
|
console.log("this.form[info.name]",this.form[info.name])
|
|
|
|
|
formItem = h("div", [
|
|
|
|
|
@ -2146,32 +2635,45 @@ export default function formBuilder(
|
|
|
|
|
h("br"),
|
|
|
|
|
info.is_sign
|
|
|
|
|
? log.user?.sign_file?.url
|
|
|
|
|
? h("el-image", {
|
|
|
|
|
? h("div", {
|
|
|
|
|
style: {
|
|
|
|
|
"max-height": "40px",
|
|
|
|
|
"max-width": "60px",
|
|
|
|
|
display: "block",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
fit: "contain",
|
|
|
|
|
alt: log.user?.name || "",
|
|
|
|
|
"preview-src-list": [log.user.sign_file.url],
|
|
|
|
|
lazy: false,
|
|
|
|
|
},
|
|
|
|
|
attrs: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
},
|
|
|
|
|
})
|
|
|
|
|
display: "flex",
|
|
|
|
|
"align-items": "center",
|
|
|
|
|
gap: "8px",
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
h("el-image", {
|
|
|
|
|
style: {
|
|
|
|
|
"max-height": "40px",
|
|
|
|
|
"max-width": "60px",
|
|
|
|
|
display: "block",
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
fit: "contain",
|
|
|
|
|
alt: log.user?.name || "",
|
|
|
|
|
"preview-src-list": [log.user.sign_file.url],
|
|
|
|
|
lazy: false,
|
|
|
|
|
},
|
|
|
|
|
attrs: {
|
|
|
|
|
src: log.user.sign_file.url,
|
|
|
|
|
},
|
|
|
|
|
}),
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
{
|
|
|
|
|
style: {
|
|
|
|
|
"font-size": "12px",
|
|
|
|
|
color: "#909399",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
log.updated_at
|
|
|
|
|
? this.$moment(log.updated_at).format("YYYY年MM月DD日")
|
|
|
|
|
: ""
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
: h("span", log.user?.name || "")
|
|
|
|
|
: "",
|
|
|
|
|
info.is_sign ? h("br") : "",
|
|
|
|
|
h(
|
|
|
|
|
"span",
|
|
|
|
|
log.updated_at
|
|
|
|
|
? this.$moment(log.updated_at).format("YYYY年MM月DD日")
|
|
|
|
|
: ""
|
|
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
@ -2266,6 +2768,9 @@ export default function formBuilder(
|
|
|
|
|
return h("div", {
|
|
|
|
|
style: {
|
|
|
|
|
"margin-top": "8px",
|
|
|
|
|
display: "flex",
|
|
|
|
|
"align-items": "center",
|
|
|
|
|
gap: "8px",
|
|
|
|
|
}
|
|
|
|
|
}, [
|
|
|
|
|
h("el-image", {
|
|
|
|
|
@ -2291,7 +2796,6 @@ export default function formBuilder(
|
|
|
|
|
style: {
|
|
|
|
|
"font-size": "12px",
|
|
|
|
|
color: "#909399",
|
|
|
|
|
"margin-top": "4px",
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
log.updated_at
|
|
|
|
|
|