|
@@ -206,13 +206,24 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
mode = props.param.mode;
|
|
mode = props.param.mode;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 功能说明:只有存在非空校验(notNull)且值为空时,才显示红线 by xu 20260402
|
|
|
|
|
+ const hasNotNullRule = () => {
|
|
|
|
|
+ const validations = window.ssVm?.validations?.get(props.name);
|
|
|
|
|
+ if (!validations || validations.length === 0) return false;
|
|
|
|
|
+ return validations.some(v => v.ruleName && v.ruleName.includes('notNull'));
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
const showRequired = computed(() => {
|
|
const showRequired = computed(() => {
|
|
|
- // 检查是否有验证规则(通过 window.ssVm 判断)
|
|
|
|
|
- const hasValidationRule = window.ssVm?.validations?.has(props.name);
|
|
|
|
|
|
|
+ const validations = window.ssVm?.validations?.get(props.name);
|
|
|
|
|
+ if (!validations || validations.length === 0) return false;
|
|
|
|
|
+
|
|
|
|
|
+ // 检查是否存在 notNull 规则
|
|
|
|
|
+ const hasNotNull = validations.some(v => v.ruleName && v.ruleName.includes('notNull'));
|
|
|
|
|
|
|
|
- if (!hasValidationRule) return false;
|
|
|
|
|
- if (errMsg.value) return true;
|
|
|
|
|
- if (!inputValue.value) return true;
|
|
|
|
|
|
|
+ // 有非空规则且值为空时显示红线
|
|
|
|
|
+ if (hasNotNull && !inputValue.value) {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
return false;
|
|
return false;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
@@ -259,8 +270,6 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const validate = () => {
|
|
const validate = () => {
|
|
|
if (window.ssVm) {
|
|
if (window.ssVm) {
|
|
|
const result = window.ssVm.validateField(props.name);
|
|
const result = window.ssVm.validateField(props.name);
|
|
|
- console.log(result);
|
|
|
|
|
-
|
|
|
|
|
errMsg.value = result.valid ? "" : result.message;
|
|
errMsg.value = result.valid ? "" : result.message;
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
@@ -573,7 +582,6 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
]
|
|
]
|
|
|
)
|
|
)
|
|
|
: null,
|
|
: null,
|
|
|
- // this.showRequired ? h("div", { class: "required" }) : null,
|
|
|
|
|
]),
|
|
]),
|
|
|
this.contentFloatingDiv || ""
|
|
this.contentFloatingDiv || ""
|
|
|
? h(
|
|
? h(
|
|
@@ -728,7 +736,6 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
...this.$attrs,
|
|
...this.$attrs,
|
|
|
autocomplete: "off",
|
|
autocomplete: "off",
|
|
|
}),
|
|
}),
|
|
|
- this.required ? h("div", { class: "required" }) : null,
|
|
|
|
|
]),
|
|
]),
|
|
|
]),
|
|
]),
|
|
|
]);
|
|
]);
|
|
@@ -3474,6 +3481,10 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
type: Boolean,
|
|
type: Boolean,
|
|
|
default: false,
|
|
default: false,
|
|
|
},
|
|
},
|
|
|
|
|
+ mode: {
|
|
|
|
|
+ type: String,
|
|
|
|
|
+ default: "edit", // 'edit' | 'view'
|
|
|
|
|
+ },
|
|
|
uploadUrl: {
|
|
uploadUrl: {
|
|
|
type: String,
|
|
type: String,
|
|
|
default: "/ulByHttp", //原值为“upload” Ben(20251205)
|
|
default: "/ulByHttp", //原值为“upload” Ben(20251205)
|
|
@@ -3497,6 +3508,9 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const uniqueId = "editor-" + Date.now();
|
|
const uniqueId = "editor-" + Date.now();
|
|
|
const errMsg = Vue.ref("");
|
|
const errMsg = Vue.ref("");
|
|
|
|
|
|
|
|
|
|
+ // 计算是否只读:mode='play' 表示只读 by xu 20250402
|
|
|
|
|
+ const isReadonly = computed(() => props.mode === "play");
|
|
|
|
|
+
|
|
|
// button 支持对象(旧格式,单个附件按钮)或数组(新格式,多个按钮)by xu 20250331
|
|
// button 支持对象(旧格式,单个附件按钮)或数组(新格式,多个按钮)by xu 20250331
|
|
|
const buttonConfigRaw = props.param && props.param.button ? props.param.button : null;
|
|
const buttonConfigRaw = props.param && props.param.button ? props.param.button : null;
|
|
|
const buttonArray = Array.isArray(buttonConfigRaw)
|
|
const buttonArray = Array.isArray(buttonConfigRaw)
|
|
@@ -3680,6 +3694,44 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
|
validate();
|
|
validate();
|
|
|
|
|
|
|
|
|
|
+ // 只读模式下不初始化 Jodit,直接设置内容 by xu 20250402
|
|
|
|
|
+ if (isReadonly) {
|
|
|
|
|
+ if (props.html) {
|
|
|
|
|
+ setEditorHtml(props.html);
|
|
|
|
|
+ } else if (props.url) {
|
|
|
|
|
+ const params = new URLSearchParams();
|
|
|
|
|
+ if (mode) params.append("mode", mode);
|
|
|
|
|
+ if (props.modelValue) params.append("path", props.modelValue);
|
|
|
|
|
+
|
|
|
|
|
+ axios
|
|
|
|
|
+ .post(props.url, params, {
|
|
|
|
|
+ headers: {
|
|
|
|
|
+ "Content-Type": "application/x-www-form-urlencoded",
|
|
|
|
|
+ },
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((response) => {
|
|
|
|
|
+ if ("timeout" == response.data.statusText) {
|
|
|
|
|
+ alert("网络超时!");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const content = response.data.content;
|
|
|
|
|
+ if (content != null) {
|
|
|
|
|
+ setEditorHtml(content);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const filePath = response.data.path;
|
|
|
|
|
+ if (filePath) {
|
|
|
|
|
+ currentModelValue.value = filePath;
|
|
|
|
|
+ emit("update:modelValue", filePath);
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ setEditorHtml(props.html);
|
|
|
|
|
+ }
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 如果 prop 为空,尝试从各种来源读取按钮配置
|
|
// 如果 prop 为空,尝试从各种来源读取按钮配置
|
|
|
let buttonsToUse = props.customButtons;
|
|
let buttonsToUse = props.customButtons;
|
|
|
if (!buttonsToUse || buttonsToUse.length === 0) {
|
|
if (!buttonsToUse || buttonsToUse.length === 0) {
|
|
@@ -3742,7 +3794,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
const editor = Jodit.make(`#${uniqueId}`, {
|
|
const editor = Jodit.make(`#${uniqueId}`, {
|
|
|
height: props.height,
|
|
height: props.height,
|
|
|
placeholder: props.placeholder,
|
|
placeholder: props.placeholder,
|
|
|
- readonly: props.readonly,
|
|
|
|
|
|
|
+ readonly: isReadonly,
|
|
|
language: "zh_cn",
|
|
language: "zh_cn",
|
|
|
i18n: {
|
|
i18n: {
|
|
|
zh_cn: {
|
|
zh_cn: {
|
|
@@ -4056,10 +4108,10 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
watch(
|
|
watch(
|
|
|
- () => props.readonly,
|
|
|
|
|
- (newValue) => {
|
|
|
|
|
|
|
+ () => props.mode,
|
|
|
|
|
+ (newMode) => {
|
|
|
if (editorRef.value) {
|
|
if (editorRef.value) {
|
|
|
- editorRef.value.setReadOnly(newValue);
|
|
|
|
|
|
|
+ editorRef.value.setReadOnly(newMode === "play");
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
);
|
|
);
|
|
@@ -4110,8 +4162,91 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
}
|
|
}
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- return () =>
|
|
|
|
|
- h("div", { class: "ss-editor-container" }, [
|
|
|
|
|
|
|
+ // 只读模式:打开附件弹窗 by xu 20250402
|
|
|
|
|
+ const openAttachmentDialog = () => {
|
|
|
|
|
+ if (!fjButton.cmsAddUrl || !fjButton.cmsUpdUrl) {
|
|
|
|
|
+ console.warn("ss-editor 未配置附件按钮地址,忽略附件操作");
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ if (fjid.value == null || fjid.value === "") {
|
|
|
|
|
+ $.ajax({
|
|
|
|
|
+ type: "post",
|
|
|
|
|
+ url: fjButton.cmsAddUrl,
|
|
|
|
|
+ async: false,
|
|
|
|
|
+ data: {
|
|
|
|
|
+ name: "fjid",
|
|
|
|
|
+ ssNrObjName: "sh",
|
|
|
|
|
+ ssNrObjId: "",
|
|
|
|
|
+ },
|
|
|
|
|
+ success: function (_fjid) {
|
|
|
|
|
+ console.log("cmsAddUrl success", _fjid);
|
|
|
|
|
+ fjid.value = _fjid;
|
|
|
|
|
+ },
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ var str =
|
|
|
|
|
+ "&nrid=T-" +
|
|
|
|
|
+ fjid.value +
|
|
|
|
|
+ "&objectId=" +
|
|
|
|
|
+ fjid.value +
|
|
|
|
|
+ "&objectName=" +
|
|
|
|
|
+ fjName +
|
|
|
|
|
+ "&callback=" +
|
|
|
|
|
+ (window["fjidCallbackName"] || "");
|
|
|
|
|
+ console.log("str", str);
|
|
|
|
|
+ SS.openDialog({
|
|
|
|
|
+ src: fjButton.cmsUpdUrl + str,
|
|
|
|
|
+ headerTitle: "编辑",
|
|
|
|
|
+ width: 900,
|
|
|
|
|
+ high: 664,
|
|
|
|
|
+ zIndex: 51,
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ return () => {
|
|
|
|
|
+ // 只读模式:不初始化 Jodit,直接渲染 HTML + 附件按钮 by xu 20250402
|
|
|
|
|
+ if (isReadonly) {
|
|
|
|
|
+ return h("div", { class: "ss-editor-container ss-editor-readonly" }, [
|
|
|
|
|
+ fjid.value &&
|
|
|
|
|
+ h("input", {
|
|
|
|
|
+ type: "hidden",
|
|
|
|
|
+ name: "fjid",
|
|
|
|
|
+ value: fjid.value,
|
|
|
|
|
+ }),
|
|
|
|
|
+ h("input", {
|
|
|
|
|
+ type: "hidden",
|
|
|
|
|
+ name: props.name.replace(/wj$/, "") + "Edit",
|
|
|
|
|
+ value: editorContent.value,
|
|
|
|
|
+ }),
|
|
|
|
|
+ h("input", {
|
|
|
|
|
+ type: "hidden",
|
|
|
|
|
+ name: props.name.replace(/wj$/, "") + "wj",
|
|
|
|
|
+ value: currentModelValue.value,
|
|
|
|
|
+ }),
|
|
|
|
|
+ h("input", {
|
|
|
|
|
+ type: "hidden",
|
|
|
|
|
+ name: "ueditorpath",
|
|
|
|
|
+ value: "mswj",
|
|
|
|
|
+ }),
|
|
|
|
|
+ // 附件按钮(只读模式下仍显示)
|
|
|
|
|
+ fjButton.cmsAddUrl && fjButton.cmsUpdUrl &&
|
|
|
|
|
+ h("div", {
|
|
|
|
|
+ class: "ss-editor-attach-btn",
|
|
|
|
|
+ onClick: openAttachmentDialog,
|
|
|
|
|
+ }, [
|
|
|
|
|
+ h("span", { class: "editor-icon editor-icon-file" }),
|
|
|
|
|
+ h("span", { class: "ss-editor-attach-text" }, "附件")
|
|
|
|
|
+ ]),
|
|
|
|
|
+ // HTML 内容展示
|
|
|
|
|
+ h("div", {
|
|
|
|
|
+ class: "ss-editor-readonly-content",
|
|
|
|
|
+ innerHTML: editorContent.value,
|
|
|
|
|
+ }),
|
|
|
|
|
+ ]);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // 正常编辑模式:渲染 textarea 供 Jodit 初始化
|
|
|
|
|
+ return h("div", { class: "ss-editor-container" }, [
|
|
|
fjid.value &&
|
|
fjid.value &&
|
|
|
h("input", {
|
|
h("input", {
|
|
|
type: "hidden",
|
|
type: "hidden",
|
|
@@ -4135,6 +4270,7 @@ import { EVEN_VAR } from "./EventBus.js";
|
|
|
}),
|
|
}),
|
|
|
h("textarea", { id: uniqueId }),
|
|
h("textarea", { id: uniqueId }),
|
|
|
]);
|
|
]);
|
|
|
|
|
+ };
|
|
|
},
|
|
},
|
|
|
};
|
|
};
|
|
|
// 弹窗右边图标
|
|
// 弹窗右边图标
|