|
|
|
@@ -98,6 +98,16 @@ a{color:#3370ff;text-decoration:none}
|
|
|
|
.widget-item{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--radius-sm);cursor:pointer;transition:all .15s;margin-bottom:2px;font-size:13px;color:var(--text)}
|
|
|
|
.widget-item{display:flex;align-items:center;gap:10px;padding:9px 10px;border-radius:var(--radius-sm);cursor:pointer;transition:all .15s;margin-bottom:2px;font-size:13px;color:var(--text)}
|
|
|
|
.widget-item:hover{background:var(--primary-light);color:var(--primary)}
|
|
|
|
.widget-item:hover{background:var(--primary-light);color:var(--primary)}
|
|
|
|
.widget-item .icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:14px}
|
|
|
|
.widget-item .icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:14px}
|
|
|
|
|
|
|
|
.widget-item.is-limited{position:relative;color:var(--text-caption);cursor:not-allowed}
|
|
|
|
|
|
|
|
.widget-item.is-limited:hover{background:var(--bg);color:var(--text-caption)}
|
|
|
|
|
|
|
|
.widget-item.is-limited::after{content:attr(data-limited-tip);position:absolute;left:10px;top:calc(100% + 4px);z-index:20;width:max-content;max-width:210px;padding:6px 8px;border-radius:var(--radius-sm);background:#1f2937;color:#fff;font-size:12px;line-height:1.4;box-shadow:var(--shadow);opacity:0;pointer-events:none;transform:translateY(-2px);transition:opacity .15s,transform .15s}
|
|
|
|
|
|
|
|
.widget-item.is-limited:hover::after{opacity:1;transform:translateY(0)}
|
|
|
|
|
|
|
|
.tip-dialog-mask{position:fixed;inset:0;z-index:1000;display:flex;align-items:center;justify-content:center;background:rgba(15,23,42,.35)}
|
|
|
|
|
|
|
|
.tip-dialog-mask.hidden{display:none}
|
|
|
|
|
|
|
|
.tip-dialog{width:320px;max-width:calc(100vw - 32px);padding:20px;border-radius:var(--radius);background:var(--surface);box-shadow:var(--shadow-lg)}
|
|
|
|
|
|
|
|
.tip-dialog-title{font-size:16px;font-weight:600;color:var(--text);margin-bottom:12px}
|
|
|
|
|
|
|
|
.tip-dialog-content{font-size:14px;line-height:1.6;color:var(--text-secondary);margin-bottom:20px}
|
|
|
|
|
|
|
|
.tip-dialog-actions{display:flex;justify-content:flex-end}
|
|
|
|
|
|
|
|
|
|
|
|
.form-design-right{width:360px;background:var(--surface);border-left:1px solid var(--border);overflow-y:auto;flex-shrink:0}
|
|
|
|
.form-design-right{width:360px;background:var(--surface);border-left:1px solid var(--border);overflow-y:auto;flex-shrink:0}
|
|
|
|
|
|
|
|
|
|
|
|
@@ -493,7 +503,7 @@ document.documentElement.setAttribute('data-app-mode', window.APP_MODE);
|
|
|
|
<div class="flex items-center gap-2"><span class="widget-group-count">1</span><span class="arrow">▾</span></div>
|
|
|
|
<div class="flex items-center gap-2"><span class="widget-group-count">1</span><span class="arrow">▾</span></div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="widget-group-items">
|
|
|
|
<div class="widget-group-items">
|
|
|
|
<div class="widget-item" onclick="addFormField('cloud_doc')" draggable="true" ondragstart="dragWidget(event,'cloud_doc')">
|
|
|
|
<div class="widget-item" id="widget-cloud-doc" onclick="handleCloudDocWidgetClick()" draggable="true" ondragstart="dragWidget(event,'cloud_doc')">
|
|
|
|
<span class="icon">📄</span><span>云文档</span>
|
|
|
|
<span class="icon">📄</span><span>云文档</span>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
@@ -703,6 +713,7 @@ let startCcRecipients = [];
|
|
|
|
let endCcRecipients = [{ id: 'end_cc_1', approverType: 'self', approverName: '', approverLevel: 1, roleName: '', userGroupName: '', formContactField: '', formDeptField: '' }];
|
|
|
|
let endCcRecipients = [{ id: 'end_cc_1', approverType: 'self', approverName: '', approverLevel: 1, roleName: '', userGroupName: '', formContactField: '', formDeptField: '' }];
|
|
|
|
let startFormPermissions = {};
|
|
|
|
let startFormPermissions = {};
|
|
|
|
let endFormPermissions = {};
|
|
|
|
let endFormPermissions = {};
|
|
|
|
|
|
|
|
const CLOUD_DOC_LIMIT_MESSAGE = '表单中只能放置一个文档类型的字段';
|
|
|
|
|
|
|
|
|
|
|
|
const submitterTypeLabels = { all: '全员', dept: '指定部门', member: '指定成员' };
|
|
|
|
const submitterTypeLabels = { all: '全员', dept: '指定部门', member: '指定成员' };
|
|
|
|
const approverTypeLabels = { superior: '上级', dept_head: '部门负责人', role: '角色', user_group: '用户组', member: '指定成员', self_select: '提交人自选', self: '提交人本人', form_contact: '表单内联系人', form_dept: '表单内部门', node_approver: '节点审批人', node_cc: '节点抄送人', multi_level_superior: '连续多级上级', multi_level_dept_head: '连续多级部门负责人' };
|
|
|
|
const approverTypeLabels = { superior: '上级', dept_head: '部门负责人', role: '角色', user_group: '用户组', member: '指定成员', self_select: '提交人自选', self: '提交人本人', form_contact: '表单内联系人', form_dept: '表单内部门', node_approver: '节点审批人', node_cc: '节点抄送人', multi_level_superior: '连续多级上级', multi_level_dept_head: '连续多级部门负责人' };
|
|
|
|
@@ -861,6 +872,71 @@ function getSelectedDetailParent() {
|
|
|
|
return null;
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function hasFormFieldType(type) {
|
|
|
|
|
|
|
|
for (const f of formFields) {
|
|
|
|
|
|
|
|
if (f.type === type) return true;
|
|
|
|
|
|
|
|
if (f.detailChildren?.some(c => c.type === type)) return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function canAddFormFieldType(type, showMessage) {
|
|
|
|
|
|
|
|
if (type === 'cloud_doc' && hasFormFieldType('cloud_doc')) {
|
|
|
|
|
|
|
|
if (showMessage) showTipDialog(CLOUD_DOC_LIMIT_MESSAGE);
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function showTipDialog(message) {
|
|
|
|
|
|
|
|
let mask = document.getElementById('tip-dialog-mask');
|
|
|
|
|
|
|
|
if (!mask) {
|
|
|
|
|
|
|
|
mask = document.createElement('div');
|
|
|
|
|
|
|
|
mask.id = 'tip-dialog-mask';
|
|
|
|
|
|
|
|
mask.className = 'tip-dialog-mask hidden';
|
|
|
|
|
|
|
|
mask.setAttribute('role', 'dialog');
|
|
|
|
|
|
|
|
mask.setAttribute('aria-modal', 'true');
|
|
|
|
|
|
|
|
mask.onclick = e => {
|
|
|
|
|
|
|
|
if (e.target === mask) closeTipDialog();
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
mask.innerHTML = `
|
|
|
|
|
|
|
|
<div class="tip-dialog">
|
|
|
|
|
|
|
|
<div class="tip-dialog-title">提示:</div>
|
|
|
|
|
|
|
|
<div class="tip-dialog-content" id="tip-dialog-content"></div>
|
|
|
|
|
|
|
|
<div class="tip-dialog-actions"><button type="button" class="ud-btn ud-btn--filled" onclick="closeTipDialog()">确定</button></div>
|
|
|
|
|
|
|
|
</div>`;
|
|
|
|
|
|
|
|
document.body.appendChild(mask);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const content = document.getElementById('tip-dialog-content');
|
|
|
|
|
|
|
|
if (content) content.textContent = message;
|
|
|
|
|
|
|
|
mask.classList.remove('hidden');
|
|
|
|
|
|
|
|
mask.querySelector('button')?.focus();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function closeTipDialog() {
|
|
|
|
|
|
|
|
document.getElementById('tip-dialog-mask')?.classList.add('hidden');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function syncCloudDocWidgetState() {
|
|
|
|
|
|
|
|
const el = document.getElementById('widget-cloud-doc');
|
|
|
|
|
|
|
|
if (!el) return;
|
|
|
|
|
|
|
|
const limited = hasFormFieldType('cloud_doc');
|
|
|
|
|
|
|
|
el.classList.toggle('is-limited', limited);
|
|
|
|
|
|
|
|
el.draggable = !limited;
|
|
|
|
|
|
|
|
if (limited) {
|
|
|
|
|
|
|
|
el.setAttribute('title', CLOUD_DOC_LIMIT_MESSAGE);
|
|
|
|
|
|
|
|
el.setAttribute('data-limited-tip', CLOUD_DOC_LIMIT_MESSAGE);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
el.removeAttribute('title');
|
|
|
|
|
|
|
|
el.removeAttribute('data-limited-tip');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function handleCloudDocWidgetClick() {
|
|
|
|
|
|
|
|
if (!canAddFormFieldType('cloud_doc', true)) return;
|
|
|
|
|
|
|
|
addFormField('cloud_doc');
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function syncHeaderName() {
|
|
|
|
function syncHeaderName() {
|
|
|
|
const name = document.getElementById('approval-name')?.value || '审批配置';
|
|
|
|
const name = document.getElementById('approval-name')?.value || '审批配置';
|
|
|
|
const header = document.getElementById('header-approval-name');
|
|
|
|
const header = document.getElementById('header-approval-name');
|
|
|
|
@@ -1328,7 +1404,7 @@ function renderOtherOptionsSection(field) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
let printExtra = '';
|
|
|
|
let printExtra = '';
|
|
|
|
if (field.type === 'attachment' && field.printable) {
|
|
|
|
if (field.type === 'attachment' && field.printable) {
|
|
|
|
printExtra = '<div class="config-sub-hint">打印附件中的图片</div>';
|
|
|
|
printExtra = `<label class="form-other-item"><input type="checkbox" class="form-other-item-checkbox" ${field.printAttachmentImages ? 'checked' : ''} onchange="updateField('${field.id}','printAttachmentImages',this.checked)"><span class="form-other-item-label">打印附件中的图片</span></label>`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return `<div class="base-form-item">
|
|
|
|
return `<div class="base-form-item">
|
|
|
|
<div class="base-form-item-label-parent"><label class="base-form-item-label">其他可选</label></div>
|
|
|
|
<div class="base-form-item-label-parent"><label class="base-form-item-label">其他可选</label></div>
|
|
|
|
@@ -1425,6 +1501,7 @@ function createFormFieldData(type) {
|
|
|
|
if (type === 'single_choice') field.linkage = { enabled: false, targetId: '', mappings: {} };
|
|
|
|
if (type === 'single_choice') field.linkage = { enabled: false, targetId: '', mappings: {} };
|
|
|
|
if (type === 'bitable') { field.bitableTitle = ''; field.tableName = ''; field.refFields = []; }
|
|
|
|
if (type === 'bitable') { field.bitableTitle = ''; field.tableName = ''; field.refFields = []; }
|
|
|
|
if (type === 'image') { field.allowImage = true; field.allowVideo = true; field.mobileOnlyCapture = false; }
|
|
|
|
if (type === 'image') { field.allowImage = true; field.allowVideo = true; field.mobileOnlyCapture = false; }
|
|
|
|
|
|
|
|
if (type === 'attachment') field.printAttachmentImages = false;
|
|
|
|
if (type === 'department') { field.deptSelectionMode = 'single'; field.deptDisplayMode = 'leaf_only'; }
|
|
|
|
if (type === 'department') { field.deptSelectionMode = 'single'; field.deptDisplayMode = 'leaf_only'; }
|
|
|
|
if (type === 'contact' || type === 'member') { field.contactSelectionMode = 'single'; field.allowSelectSelf = true; }
|
|
|
|
if (type === 'contact' || type === 'member') { field.contactSelectionMode = 'single'; field.allowSelectSelf = true; }
|
|
|
|
if (type === 'related_approval') { field.scopeConfig = ''; field.onlyApproved = false; }
|
|
|
|
if (type === 'related_approval') { field.scopeConfig = ''; field.onlyApproved = false; }
|
|
|
|
@@ -1480,6 +1557,7 @@ function normalizeFormField(field) {
|
|
|
|
if (field.allowVideo === undefined) field.allowVideo = true;
|
|
|
|
if (field.allowVideo === undefined) field.allowVideo = true;
|
|
|
|
if (field.mobileOnlyCapture === undefined) field.mobileOnlyCapture = false;
|
|
|
|
if (field.mobileOnlyCapture === undefined) field.mobileOnlyCapture = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (field.type === 'attachment' && field.printAttachmentImages === undefined) field.printAttachmentImages = false;
|
|
|
|
if (field.type === 'department') {
|
|
|
|
if (field.type === 'department') {
|
|
|
|
if (!field.deptSelectionMode) field.deptSelectionMode = 'single';
|
|
|
|
if (!field.deptSelectionMode) field.deptSelectionMode = 'single';
|
|
|
|
if (!field.deptDisplayMode) field.deptDisplayMode = 'leaf_only';
|
|
|
|
if (!field.deptDisplayMode) field.deptDisplayMode = 'leaf_only';
|
|
|
|
@@ -1507,6 +1585,7 @@ function normalizeFormField(field) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function addFormField(type, index) {
|
|
|
|
function addFormField(type, index) {
|
|
|
|
|
|
|
|
if (!canAddFormFieldType(type, true)) return;
|
|
|
|
if (type === 'detail') {
|
|
|
|
if (type === 'detail') {
|
|
|
|
const field = createFormFieldData(type);
|
|
|
|
const field = createFormFieldData(type);
|
|
|
|
if (!field) return;
|
|
|
|
if (!field) return;
|
|
|
|
@@ -1538,6 +1617,7 @@ function addFormField(type, index) {
|
|
|
|
|
|
|
|
|
|
|
|
function addFormFieldToDetail(detailId, type) {
|
|
|
|
function addFormFieldToDetail(detailId, type) {
|
|
|
|
if (type === 'detail' || !fieldMeta[type]) return;
|
|
|
|
if (type === 'detail' || !fieldMeta[type]) return;
|
|
|
|
|
|
|
|
if (!canAddFormFieldType(type, true)) return;
|
|
|
|
const detail = formFields.find(f => f.id === detailId && f.type === 'detail');
|
|
|
|
const detail = formFields.find(f => f.id === detailId && f.type === 'detail');
|
|
|
|
if (!detail) return;
|
|
|
|
if (!detail) return;
|
|
|
|
if (!detail.detailChildren) detail.detailChildren = [];
|
|
|
|
if (!detail.detailChildren) detail.detailChildren = [];
|
|
|
|
@@ -1551,6 +1631,11 @@ function addFormFieldToDetail(detailId, type) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function dragWidget(ev, type) {
|
|
|
|
function dragWidget(ev, type) {
|
|
|
|
|
|
|
|
if (!canAddFormFieldType(type, true)) {
|
|
|
|
|
|
|
|
ev.preventDefault();
|
|
|
|
|
|
|
|
ev.stopPropagation();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
ev.dataTransfer.setData('widgetType', type);
|
|
|
|
ev.dataTransfer.setData('widgetType', type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function allowDrop(ev) { ev.preventDefault(); }
|
|
|
|
function allowDrop(ev) { ev.preventDefault(); }
|
|
|
|
@@ -1626,6 +1711,7 @@ function commitFieldName(id, key) {
|
|
|
|
function renderFormFields() {
|
|
|
|
function renderFormFields() {
|
|
|
|
const list = document.getElementById('field-list');
|
|
|
|
const list = document.getElementById('field-list');
|
|
|
|
if (!list) return;
|
|
|
|
if (!list) return;
|
|
|
|
|
|
|
|
syncCloudDocWidgetState();
|
|
|
|
if (formFields.length === 0) {
|
|
|
|
if (formFields.length === 0) {
|
|
|
|
list.innerHTML = FIELD_EMPTY_TIP_HTML;
|
|
|
|
list.innerHTML = FIELD_EMPTY_TIP_HTML;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
@@ -2331,6 +2417,7 @@ function updateField(id, key, val) {
|
|
|
|
const f = findFormField(id);
|
|
|
|
const f = findFormField(id);
|
|
|
|
if (!f) return;
|
|
|
|
if (!f) return;
|
|
|
|
f[key] = val;
|
|
|
|
f[key] = val;
|
|
|
|
|
|
|
|
if (key === 'printable' && f.type === 'attachment' && !val) f.printAttachmentImages = false;
|
|
|
|
const liveTextKeys = ['title', 'startTitle', 'endTitle', 'durationTitle', 'placeholder', 'defaultValue', 'unit', 'minValue', 'maxValue', 'formula', 'bitableTitle', 'tableName', 'scopeConfig', 'archiveLocation', 'customDateStart', 'customDateEnd'];
|
|
|
|
const liveTextKeys = ['title', 'startTitle', 'endTitle', 'durationTitle', 'placeholder', 'defaultValue', 'unit', 'minValue', 'maxValue', 'formula', 'bitableTitle', 'tableName', 'scopeConfig', 'archiveLocation', 'customDateStart', 'customDateEnd'];
|
|
|
|
if (liveTextKeys.includes(key)) {
|
|
|
|
if (liveTextKeys.includes(key)) {
|
|
|
|
if (['title', 'startTitle', 'endTitle', 'durationTitle'].includes(key)) {
|
|
|
|
if (['title', 'startTitle', 'endTitle', 'durationTitle'].includes(key)) {
|
|
|
|
@@ -2346,7 +2433,7 @@ function updateField(id, key, val) {
|
|
|
|
autoSave();
|
|
|
|
autoSave();
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const configOnlyKeys = ['allowSelectSelf', 'deptDisplayMode', 'deptSelectionMode', 'contactSelectionMode', 'onlyApproved', 'autoLocate', 'showDetailAddress', 'fillDetailAddress', 'locationDisplayMode', 'validateBranchRequired', 'phoneType', 'allowImage', 'allowVideo', 'mobileOnlyCapture', 'printable', 'required', 'allowEditDuration', 'dateFormat', 'dateRangeOption'];
|
|
|
|
const configOnlyKeys = ['allowSelectSelf', 'deptDisplayMode', 'deptSelectionMode', 'contactSelectionMode', 'onlyApproved', 'autoLocate', 'showDetailAddress', 'fillDetailAddress', 'locationDisplayMode', 'validateBranchRequired', 'phoneType', 'allowImage', 'allowVideo', 'mobileOnlyCapture', 'printable', 'printAttachmentImages', 'required', 'allowEditDuration', 'dateFormat', 'dateRangeOption'];
|
|
|
|
if (configOnlyKeys.includes(key)) {
|
|
|
|
if (configOnlyKeys.includes(key)) {
|
|
|
|
if (key === 'deptSelectionMode' || key === 'contactSelectionMode') renderFlowConfig();
|
|
|
|
if (key === 'deptSelectionMode' || key === 'contactSelectionMode') renderFlowConfig();
|
|
|
|
renderFormConfig();
|
|
|
|
renderFormConfig();
|
|
|
|
@@ -3276,6 +3363,21 @@ function renderEmptyHandlerPanel(node) {
|
|
|
|
</div>`;
|
|
|
|
</div>`;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function renderMultiPersonModeSection(node, title, oneLabel, allLabel, extraOptions) {
|
|
|
|
|
|
|
|
ensureNodeApprovers(node);
|
|
|
|
|
|
|
|
if (node.approvers.length <= 1) return '';
|
|
|
|
|
|
|
|
const extraHtml = (extraOptions || []).map(opt =>
|
|
|
|
|
|
|
|
`<option value="${opt.value}" ${node.multiApprover === opt.value ? 'selected' : ''}>${opt.label}</option>`
|
|
|
|
|
|
|
|
).join('');
|
|
|
|
|
|
|
|
return `<div class="item-wrap"><div class="sub-title bold">${title}</div>
|
|
|
|
|
|
|
|
<select class="ant-select" onchange="updateFlowNode('${node.id}','multiApprover',this.value)">
|
|
|
|
|
|
|
|
<option value="or" ${node.multiApprover === 'or' ? 'selected' : ''}>${oneLabel}</option>
|
|
|
|
|
|
|
|
<option value="and" ${node.multiApprover === 'and' ? 'selected' : ''}>${allLabel}</option>
|
|
|
|
|
|
|
|
${extraHtml}
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>`;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
function renderNodeCcPanel(node) {
|
|
|
|
function renderNodeCcPanel(node) {
|
|
|
|
ensureNodeApprovers(node);
|
|
|
|
ensureNodeApprovers(node);
|
|
|
|
if (!node.ccRecipients) node.ccRecipients = [];
|
|
|
|
if (!node.ccRecipients) node.ccRecipients = [];
|
|
|
|
@@ -3833,12 +3935,7 @@ function renderApproverConfig(node) {
|
|
|
|
${renderNodePersonsPanel(node, '审批人', '+ 添加审批人')}
|
|
|
|
${renderNodePersonsPanel(node, '审批人', '+ 添加审批人')}
|
|
|
|
${renderEmptyApproverPanel(node)}
|
|
|
|
${renderEmptyApproverPanel(node)}
|
|
|
|
${renderSameAsSubmitterPanel(node)}
|
|
|
|
${renderSameAsSubmitterPanel(node)}
|
|
|
|
<div class="item-wrap"><div class="sub-title bold">多人审批方式</div>
|
|
|
|
${renderMultiPersonModeSection(node, '多人审批时采用的审批方式', '或签(一名审批人同意即可)', '会签(须所有审批人同意)')}
|
|
|
|
<select class="ant-select" onchange="updateFlowNode('${node.id}','multiApprover',this.value)">
|
|
|
|
|
|
|
|
<option value="or" ${node.multiApprover === 'or' ? 'selected' : ''}>或签(一名审批人同意即可)</option>
|
|
|
|
|
|
|
|
<option value="and" ${node.multiApprover === 'and' ? 'selected' : ''}>会签(须所有审批人同意)</option>
|
|
|
|
|
|
|
|
</select>
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div class="item-wrap" style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border-light)"><div class="item-key">抄送人设置</div></div>
|
|
|
|
<div class="item-wrap" style="margin-top:16px;padding-top:16px;border-top:1px solid var(--border-light)"><div class="item-key">抄送人设置</div></div>
|
|
|
|
${renderNodeCcPanel(node)}
|
|
|
|
${renderNodeCcPanel(node)}
|
|
|
|
</div>`;
|
|
|
|
</div>`;
|
|
|
|
@@ -3873,6 +3970,7 @@ function renderHandlerConfig(node) {
|
|
|
|
body = `<div class="approval-editor-form">
|
|
|
|
body = `<div class="approval-editor-form">
|
|
|
|
${renderNodePersonsPanel(node, '办理人', '+ 添加办理人')}
|
|
|
|
${renderNodePersonsPanel(node, '办理人', '+ 添加办理人')}
|
|
|
|
${renderEmptyHandlerPanel(node)}
|
|
|
|
${renderEmptyHandlerPanel(node)}
|
|
|
|
|
|
|
|
${renderMultiPersonModeSection(node, '多人办理时采用的办理方式', '或签(一名办理人处理即可)', '会签(须所有办理人处理)', [{ value: 'sequential', label: '依次办理(按顺序依次提交)' }])}
|
|
|
|
<div class="more-info-wrap"><p class="more-info-key">提示:</p><div class="more-info-content"><p>办理人不涉及审批人去重设置,不同节点相同的办理人仍需要执行。</p><p>若办理人离职,会自动转交给办理人的上级代为处理。</p></div></div>
|
|
|
|
<div class="more-info-wrap"><p class="more-info-key">提示:</p><div class="more-info-content"><p>办理人不涉及审批人去重设置,不同节点相同的办理人仍需要执行。</p><p>若办理人离职,会自动转交给办理人的上级代为处理。</p></div></div>
|
|
|
|
</div>`;
|
|
|
|
</div>`;
|
|
|
|
} else if (selectedFlowTab === 'formPerm') {
|
|
|
|
} else if (selectedFlowTab === 'formPerm') {
|
|
|
|
|