|
|
@@ -202,6 +202,39 @@ function parseRuleBizFields(row: S8WatchRuleConfigRow): { objectLabel: string; m
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+// CONFIG-RULE-EDIT-BIZ-VIEW-MVP-1:从 paramsJson 推导业务判定标准的中文展示(编辑抽屉摘要使用)。
|
|
|
+function summarizeBizCondition(row: S8WatchRuleConfigRow | null): string {
|
|
|
+ if (!row) return '—';
|
|
|
+ const explicit = parseRuleBizFields(row).thresholdDisplay;
|
|
|
+ if (explicit && explicit !== '未配置') return explicit;
|
|
|
+ let p: Record<string, unknown> = {};
|
|
|
+ try { if (row.paramsJson) p = JSON.parse(row.paramsJson); } catch { /* fallthrough */ }
|
|
|
+ const unit = typeof p.unit === 'string' ? p.unit : '';
|
|
|
+ const mech = row.ruleMechanism;
|
|
|
+ if (mech === 'DATE') {
|
|
|
+ const grace = typeof p.graceMinutes === 'number' ? p.graceMinutes : 0;
|
|
|
+ const states = Array.isArray(p.completedStates) ? p.completedStates.join('/') : '';
|
|
|
+ const segs: string[] = [];
|
|
|
+ segs.push(grace > 0 ? `宽限 ${grace} 分钟后触发` : '到期立即触发');
|
|
|
+ if (states) segs.push(`完成状态:${states}`);
|
|
|
+ return segs.join(';');
|
|
|
+ }
|
|
|
+ if (mech === 'RATIO') {
|
|
|
+ const tgt = typeof p.lowerBound === 'number' ? p.lowerBound : null;
|
|
|
+ if (tgt != null) return `低于 ${tgt}${unit || '%'} 触发`;
|
|
|
+ return '未配置目标比例';
|
|
|
+ }
|
|
|
+ if (mech === 'VALUE_RANGE') {
|
|
|
+ const lo = typeof p.lowerBound === 'number' ? p.lowerBound : null;
|
|
|
+ const up = typeof p.upperBound === 'number' ? p.upperBound : null;
|
|
|
+ const segs: string[] = [];
|
|
|
+ if (lo != null) segs.push(`下限 ${lo}${unit}`);
|
|
|
+ if (up != null) segs.push(`上限 ${up}${unit}`);
|
|
|
+ return segs.length > 0 ? segs.join(' / ') + ' 超出触发' : '未配置上下限';
|
|
|
+ }
|
|
|
+ return '—';
|
|
|
+}
|
|
|
+
|
|
|
const filteredRows = computed(() => {
|
|
|
let r = rows.value;
|
|
|
const kw = searchKeyword.value.trim().toLowerCase();
|
|
|
@@ -280,8 +313,8 @@ const ruleTypeOf = (row: S8WatchRuleConfigRow | null): S8WatchRuleType | '' =>
|
|
|
(row?.ruleType ?? '').toUpperCase();
|
|
|
|
|
|
const formTitle = computed(() => {
|
|
|
- if (!editingRow.value) return '编辑规则参数';
|
|
|
- return `编辑规则参数 — ${watchRuleDisplayName(editingRow.value.ruleCode)}`;
|
|
|
+ if (!editingRow.value) return '编辑规则';
|
|
|
+ return `编辑规则 — ${watchRuleDisplayName(editingRow.value.ruleCode)}`;
|
|
|
});
|
|
|
|
|
|
// S8-CONFIG-POLISH-SCENE-RULE-LIST-1:rule_code 展示层中文化(不进 DB / 不写 params_json)。
|
|
|
@@ -721,6 +754,12 @@ function closeDrawer() {
|
|
|
}
|
|
|
|
|
|
function buildPayloadParamsJson(): string | null {
|
|
|
+ // CONFIG-RULE-EDIT-BIZ-VIEW-MVP-1:merge 原 paramsJson,保留 objectLabel/metricLabel/unit/thresholdDisplay 等业务展示字段及任何后续新增的未知 key。
|
|
|
+ let original: Record<string, unknown> = {};
|
|
|
+ if (rawParamsJson.value) {
|
|
|
+ try { original = JSON.parse(rawParamsJson.value) as Record<string, unknown>; }
|
|
|
+ catch { original = {}; }
|
|
|
+ }
|
|
|
const t = ruleTypeOf(editingRow.value);
|
|
|
if (t === 'TIMEOUT') {
|
|
|
const states = timeoutForm.completedStates
|
|
|
@@ -728,6 +767,7 @@ function buildPayloadParamsJson(): string | null {
|
|
|
.map((s) => s.trim())
|
|
|
.filter(Boolean);
|
|
|
return JSON.stringify({
|
|
|
+ ...original,
|
|
|
dueAtField: timeoutForm.dueAtField,
|
|
|
statusField: timeoutForm.statusField,
|
|
|
completedStates: states,
|
|
|
@@ -739,18 +779,19 @@ function buildPayloadParamsJson(): string | null {
|
|
|
}
|
|
|
if (t === 'SHORTAGE') {
|
|
|
return JSON.stringify({
|
|
|
+ ...original,
|
|
|
targetQtyField: shortageForm.targetQtyField,
|
|
|
actualQtyField: shortageForm.actualQtyField,
|
|
|
objectCodeField: shortageForm.objectCodeField,
|
|
|
objectIdField: shortageForm.objectIdField,
|
|
|
toleranceAbs: Number(shortageForm.toleranceAbs) || 0,
|
|
|
- // A-06: convert 0–100 back to 0–1 for storage
|
|
|
toleranceRatio: percentToRatio(shortageForm.toleranceRatioPct),
|
|
|
exceptionTypeCode: shortageForm.exceptionTypeCode,
|
|
|
});
|
|
|
}
|
|
|
if (t === 'OUT_OF_RANGE') {
|
|
|
return JSON.stringify({
|
|
|
+ ...original,
|
|
|
measuredValueField: outOfRangeForm.measuredValueField,
|
|
|
objectCodeField: outOfRangeForm.objectCodeField,
|
|
|
objectIdField: outOfRangeForm.objectIdField,
|
|
|
@@ -759,7 +800,6 @@ function buildPayloadParamsJson(): string | null {
|
|
|
lowerBoundField: outOfRangeForm.lowerBoundField || undefined,
|
|
|
upperBoundField: outOfRangeForm.upperBoundField || undefined,
|
|
|
toleranceAbs: Number(outOfRangeForm.toleranceAbs) || 0,
|
|
|
- // A-06: convert 0–100 back to 0–1 for storage
|
|
|
toleranceRatio: percentToRatio(outOfRangeForm.toleranceRatioPct),
|
|
|
exceptionTypeCode: outOfRangeForm.exceptionTypeCode,
|
|
|
});
|
|
|
@@ -1183,23 +1223,25 @@ onDeactivated(() => stopAutoRefresh());
|
|
|
<el-drawer v-model="drawerOpen" :title="formTitle" size="540px" direction="rtl" :before-close="(done: () => void) => { closeDrawer(); done(); }">
|
|
|
<div v-if="editingRow" class="rule-edit">
|
|
|
|
|
|
- <!-- A-07: rule summary block -->
|
|
|
- <div class="rule-summary" :class="{ 'rule-summary--incomplete': !ruleSummary.complete }">
|
|
|
- <span class="rule-summary__label">规则摘要:</span>{{ ruleSummary.text }}
|
|
|
- </div>
|
|
|
-
|
|
|
- <el-divider content-position="left">基本信息</el-divider>
|
|
|
+ <!-- CONFIG-RULE-EDIT-BIZ-VIEW-MVP-1:业务摘要卡(默认主视图) -->
|
|
|
+ <el-divider content-position="left">业务摘要</el-divider>
|
|
|
<el-descriptions :column="1" size="small" border class="rule-meta">
|
|
|
- <el-descriptions-item label="规则编码">{{ editingRow.ruleCode }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="规则类型">{{ ruleTypeLabel(editingRow.ruleType) }}</el-descriptions-item>
|
|
|
- <!-- A-04: severity readonly display -->
|
|
|
- <el-descriptions-item label="严重度">
|
|
|
- <el-tag v-if="editingRow.severity" :type="severityTagType(editingRow.severity)" size="small">{{ severityLabel(editingRow.severity) }}</el-tag>
|
|
|
+ <el-descriptions-item label="报警机制">
|
|
|
+ <el-tag v-if="editingRow.ruleMechanism" size="small" type="info">{{ ruleMechanismLabel(editingRow.ruleMechanism) }}</el-tag>
|
|
|
<span v-else>—</span>
|
|
|
- <span class="rule-hint">如需调整严重度,请联系实施人员</span>
|
|
|
</el-descriptions-item>
|
|
|
- <el-descriptions-item label="场景">{{ editingRow.sceneCode ?? '—' }}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="源对象">{{ editingRow.sourceObjectType ?? editingRow.watchObjectType ?? '—' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="阶段维度">{{ stageNodeLabel(editingRow.stageCode) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="订单流程">{{ orderFlowNodeLabel(editingRow.orderFlowCode) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="监控对象">
|
|
|
+ <span :class="{ 'rule-biz-empty': parseRuleBizFields(editingRow).objectLabel === '未配置' }">{{ parseRuleBizFields(editingRow).objectLabel }}</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="监控指标">
|
|
|
+ <span :class="{ 'rule-biz-empty': parseRuleBizFields(editingRow).metricLabel === '未配置' }">{{ parseRuleBizFields(editingRow).metricLabel }}</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="判定标准">{{ summarizeBizCondition(editingRow) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="当前状态">
|
|
|
+ <el-tag :type="editingRow.enabled ? 'success' : 'info'" size="small">{{ editingRow.enabled ? '启用' : '停用' }}</el-tag>
|
|
|
+ </el-descriptions-item>
|
|
|
</el-descriptions>
|
|
|
|
|
|
<el-divider content-position="left">维度归属与机制</el-divider>
|
|
|
@@ -1222,31 +1264,13 @@ onDeactivated(() => stopAutoRefresh());
|
|
|
</el-form-item>
|
|
|
</el-form>
|
|
|
|
|
|
- <el-divider content-position="left">触发条件</el-divider>
|
|
|
+ <el-divider content-position="left">业务判定标准</el-divider>
|
|
|
|
|
|
<!-- TIMEOUT form -->
|
|
|
<el-form v-if="ruleTypeOf(editingRow) === 'TIMEOUT'" label-position="top" size="small">
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 到期时间字段名
|
|
|
- <el-tooltip content="填写 SQL 结果集中表示到期时间的列名,如 due_date、expected_finish_time" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="timeoutForm.dueAtField" placeholder="如 due_date" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 状态字段名
|
|
|
- <el-tooltip content="填写 SQL 结果集中表示当前状态的列名,如 status、order_status" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="timeoutForm.statusField" placeholder="如 status" />
|
|
|
- </el-form-item>
|
|
|
<!-- B-04: completedStates risk tip -->
|
|
|
<div class="rule-tip">
|
|
|
- 注意:<strong>完成状态值</strong>必须与数据库中实际值完全匹配(区分大小写)。拼写错误将导致规则持续命中,产生大量误报异常。
|
|
|
+ 到期后仍未到达「完成状态」即触发。完成状态值必须与数据库中实际值完全匹配(区分大小写)。
|
|
|
</div>
|
|
|
<el-form-item>
|
|
|
<template #label>
|
|
|
@@ -1266,27 +1290,21 @@ onDeactivated(() => stopAutoRefresh());
|
|
|
<el-option v-for="o in exceptionTypeOptions" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <!-- B-05: advanced fields collapse -->
|
|
|
- <div class="rule-advanced-toggle" @click="advancedExpanded = !advancedExpanded">
|
|
|
- {{ advancedExpanded ? '▲ 收起高级字段' : '▼ 展开高级字段(对象编码/ID 映射)' }}
|
|
|
- </div>
|
|
|
<template v-if="advancedExpanded">
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象编码字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象编码的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>到期时间字段名(实施人员使用)</template>
|
|
|
+ <el-input v-model="timeoutForm.dueAtField" placeholder="如 due_date" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>状态字段名(实施人员使用)</template>
|
|
|
+ <el-input v-model="timeoutForm.statusField" placeholder="如 status" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>对象编码字段名(实施人员使用)</template>
|
|
|
<el-input v-model="timeoutForm.objectCodeField" placeholder="如 order_code" />
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象 ID 字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象主键的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>对象 ID 字段名(实施人员使用)</template>
|
|
|
<el-input v-model="timeoutForm.objectIdField" placeholder="如 order_id" />
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
@@ -1294,152 +1312,110 @@ onDeactivated(() => stopAutoRefresh());
|
|
|
|
|
|
<!-- SHORTAGE form -->
|
|
|
<el-form v-else-if="ruleTypeOf(editingRow) === 'SHORTAGE'" label-position="top" size="small">
|
|
|
- <!-- B-02: AND logic -->
|
|
|
<el-alert type="info" :closable="false" show-icon title="触发逻辑说明">
|
|
|
<template #default>
|
|
|
- 缺料触发为 <strong>AND 逻辑</strong>:实际缺口必须同时超过绝对容差 <em>且</em> 超过比例容差,才触发异常;任一未超过则不触发。
|
|
|
+ 缺料触发为 <strong>AND 逻辑</strong>:实际缺口必须同时超过绝对容差 <em>且</em> 超过比例容差,才触发异常。
|
|
|
</template>
|
|
|
</el-alert>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 目标数量字段名
|
|
|
- <el-tooltip content="填写 SQL 结果集中表示计划/目标数量的列名,如 plan_qty、target_quantity" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="shortageForm.targetQtyField" placeholder="如 plan_qty" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 实际数量字段名
|
|
|
- <el-tooltip content="填写 SQL 结果集中表示实际/到货数量的列名,如 actual_qty、received_qty" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="shortageForm.actualQtyField" placeholder="如 actual_qty" />
|
|
|
- </el-form-item>
|
|
|
<el-form-item label="绝对容差(≥0)">
|
|
|
<el-input-number v-model="shortageForm.toleranceAbs" :min="0" :step="0.1" />
|
|
|
<span class="rule-hint">缺口不超过此值时不触发</span>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="比例容差(0–100%)">
|
|
|
<el-input-number v-model="shortageForm.toleranceRatioPct" :min="0" :max="100" :step="1" />
|
|
|
- <span class="rule-hint">% 缺口占目标数量的比例不超过此值时不触发;两项均须超过才触发</span>
|
|
|
+ <span class="rule-hint">% 缺口占目标数量的比例不超过此值时不触发</span>
|
|
|
</el-form-item>
|
|
|
<el-form-item label="异常类型">
|
|
|
<el-select v-model="shortageForm.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="width: 100%">
|
|
|
<el-option v-for="o in exceptionTypeOptions" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <!-- B-05: advanced fields collapse -->
|
|
|
- <div class="rule-advanced-toggle" @click="advancedExpanded = !advancedExpanded">
|
|
|
- {{ advancedExpanded ? '▲ 收起高级字段' : '▼ 展开高级字段(对象编码/ID 映射)' }}
|
|
|
- </div>
|
|
|
<template v-if="advancedExpanded">
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象编码字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象编码的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>目标数量字段名(实施人员使用)</template>
|
|
|
+ <el-input v-model="shortageForm.targetQtyField" placeholder="如 plan_qty" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>实际数量字段名(实施人员使用)</template>
|
|
|
+ <el-input v-model="shortageForm.actualQtyField" placeholder="如 actual_qty" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>对象编码字段名(实施人员使用)</template>
|
|
|
<el-input v-model="shortageForm.objectCodeField" placeholder="如 order_code" />
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象 ID 字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象主键的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>对象 ID 字段名(实施人员使用)</template>
|
|
|
<el-input v-model="shortageForm.objectIdField" placeholder="如 order_id" />
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
</el-form>
|
|
|
|
|
|
- <!-- OUT_OF_RANGE form -->
|
|
|
+ <!-- OUT_OF_RANGE form:mech=RATIO 时只显示目标比例;mech=VALUE_RANGE 显示上下限 -->
|
|
|
<el-form v-else-if="ruleTypeOf(editingRow) === 'OUT_OF_RANGE'" label-position="top" size="small">
|
|
|
- <!-- B-02: AND logic -->
|
|
|
- <el-alert type="info" :closable="false" show-icon title="触发逻辑说明">
|
|
|
- <template #default>
|
|
|
- 超限触发为 <strong>AND 逻辑</strong>:超限幅度必须同时超过绝对容差 <em>且</em> 超过比例容差,才触发异常;任一未超过则不触发。
|
|
|
- </template>
|
|
|
- </el-alert>
|
|
|
- <!-- B-03: bound priority -->
|
|
|
- <el-alert type="warning" :closable="false" show-icon title="上下限优先级">
|
|
|
- <template #default>
|
|
|
- <strong>行内字段优先</strong>:若填写了行内上/下限字段名,则优先取该行对应列的值作为限值;固定上下限仅在字段名为空时生效。
|
|
|
- </template>
|
|
|
- </el-alert>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 测量值字段名
|
|
|
- <el-tooltip content="填写 SQL 结果集中表示被监测数值的列名,如 measured_value、sensor_reading" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="outOfRangeForm.measuredValueField" placeholder="如 measured_value" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="固定上限(可空)">
|
|
|
- <el-input-number v-model="outOfRangeForm.upperBound" :step="0.1" />
|
|
|
- <span class="rule-hint">行内上限字段不为空时此值不生效</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="固定下限(可空)">
|
|
|
- <el-input-number v-model="outOfRangeForm.lowerBound" :step="0.1" />
|
|
|
- <span class="rule-hint">行内下限字段不为空时此值不生效</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 行内上限字段名(可空)
|
|
|
- <el-tooltip content="若每行有自己的上限列,填写该列名,优先级高于固定上限" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="outOfRangeForm.upperBoundField" placeholder="如 upper_limit_col" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item>
|
|
|
- <template #label>
|
|
|
- 行内下限字段名(可空)
|
|
|
- <el-tooltip content="若每行有自己的下限列,填写该列名,优先级高于固定下限" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
- <el-input v-model="outOfRangeForm.lowerBoundField" placeholder="如 lower_limit_col" />
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="绝对容差(≥0)">
|
|
|
- <el-input-number v-model="outOfRangeForm.toleranceAbs" :min="0" :step="0.1" />
|
|
|
- <span class="rule-hint">超限幅度不超过此值时不触发</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="比例容差(0–100%)">
|
|
|
- <el-input-number v-model="outOfRangeForm.toleranceRatioPct" :min="0" :max="100" :step="1" />
|
|
|
- <span class="rule-hint">% 超限幅度占限值的比例不超过此值时不触发;两项均须超过才触发</span>
|
|
|
- </el-form-item>
|
|
|
- <el-form-item label="异常类型">
|
|
|
- <el-select v-model="outOfRangeForm.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="width: 100%">
|
|
|
- <el-option v-for="o in exceptionTypeOptions" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- <!-- B-05: advanced fields collapse -->
|
|
|
- <div class="rule-advanced-toggle" @click="advancedExpanded = !advancedExpanded">
|
|
|
- {{ advancedExpanded ? '▲ 收起高级字段' : '▼ 展开高级字段(对象编码/ID 映射)' }}
|
|
|
- </div>
|
|
|
+ <template v-if="editingRow.ruleMechanism === 'RATIO'">
|
|
|
+ <el-alert type="info" :closable="false" show-icon title="触发逻辑说明">
|
|
|
+ <template #default>实际比例 <strong>低于目标比例</strong> 即触发异常。</template>
|
|
|
+ </el-alert>
|
|
|
+ <el-form-item label="目标比例(%)">
|
|
|
+ <el-input-number v-model="outOfRangeForm.lowerBound" :min="0" :max="100" :step="1" />
|
|
|
+ <span class="rule-hint">实际值低于此目标即触发,如交付满足率目标 95%</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="异常类型">
|
|
|
+ <el-select v-model="outOfRangeForm.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="width: 100%">
|
|
|
+ <el-option v-for="o in exceptionTypeOptions" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
+ <template v-else>
|
|
|
+ <el-alert type="info" :closable="false" show-icon title="触发逻辑说明">
|
|
|
+ <template #default>
|
|
|
+ 超限触发为 <strong>AND 逻辑</strong>:超限幅度必须同时超过绝对容差 <em>且</em> 超过比例容差,才触发异常。
|
|
|
+ </template>
|
|
|
+ </el-alert>
|
|
|
+ <el-form-item label="固定上限(可空)">
|
|
|
+ <el-input-number v-model="outOfRangeForm.upperBound" :step="0.1" />
|
|
|
+ <span class="rule-hint">行内上限字段不为空时此值不生效</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="固定下限(可空)">
|
|
|
+ <el-input-number v-model="outOfRangeForm.lowerBound" :step="0.1" />
|
|
|
+ <span class="rule-hint">行内下限字段不为空时此值不生效</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="绝对容差(≥0)">
|
|
|
+ <el-input-number v-model="outOfRangeForm.toleranceAbs" :min="0" :step="0.1" />
|
|
|
+ <span class="rule-hint">超限幅度不超过此值时不触发</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="比例容差(0–100%)">
|
|
|
+ <el-input-number v-model="outOfRangeForm.toleranceRatioPct" :min="0" :max="100" :step="1" />
|
|
|
+ <span class="rule-hint">% 超限幅度占限值的比例不超过此值时不触发</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="异常类型">
|
|
|
+ <el-select v-model="outOfRangeForm.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="width: 100%">
|
|
|
+ <el-option v-for="o in exceptionTypeOptions" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </template>
|
|
|
<template v-if="advancedExpanded">
|
|
|
+ <el-alert v-if="editingRow.ruleMechanism === 'RATIO'" type="warning" :closable="false" show-icon style="margin: 8px 0">
|
|
|
+ <template #default>RATIO 机制建议<strong>不填写行内字段</strong>,避免覆盖固定目标比例。</template>
|
|
|
+ </el-alert>
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象编码字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象编码的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>测量值字段名(实施人员使用)</template>
|
|
|
+ <el-input v-model="outOfRangeForm.measuredValueField" placeholder="如 measured_value" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>行内上限字段名(实施人员使用,可空)</template>
|
|
|
+ <el-input v-model="outOfRangeForm.upperBoundField" placeholder="如 upper_limit_col" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>行内下限字段名(实施人员使用,可空)</template>
|
|
|
+ <el-input v-model="outOfRangeForm.lowerBoundField" placeholder="如 lower_limit_col" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <template #label>对象编码字段名(实施人员使用)</template>
|
|
|
<el-input v-model="outOfRangeForm.objectCodeField" placeholder="如 device_code" />
|
|
|
</el-form-item>
|
|
|
<el-form-item>
|
|
|
- <template #label>
|
|
|
- 对象 ID 字段名
|
|
|
- <el-tooltip content="SQL 结果集中用于关联业务对象主键的列名,通常无需修改" placement="top">
|
|
|
- <span class="rule-field-hint">(?)</span>
|
|
|
- </el-tooltip>
|
|
|
- </template>
|
|
|
+ <template #label>对象 ID 字段名(实施人员使用)</template>
|
|
|
<el-input v-model="outOfRangeForm.objectIdField" placeholder="如 device_id" />
|
|
|
</el-form-item>
|
|
|
</template>
|
|
|
@@ -1450,8 +1426,28 @@ onDeactivated(() => stopAutoRefresh());
|
|
|
<pre class="rule-raw">{{ rawParamsJson || '(空)' }}</pre>
|
|
|
</el-alert>
|
|
|
|
|
|
- <el-divider content-position="left">检测 SQL(只读)</el-divider>
|
|
|
- <pre class="rule-expr">{{ editingRow.expression || '—' }}</pre>
|
|
|
+ <!-- CONFIG-RULE-EDIT-BIZ-VIEW-MVP-1:抽屉级别"高级参数配置"开关 -->
|
|
|
+ <div class="rule-advanced-toggle" @click="advancedExpanded = !advancedExpanded">
|
|
|
+ {{ advancedExpanded ? '▲ 收起高级参数配置' : '▼ 展开高级参数配置(实施人员使用)' }}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <template v-if="advancedExpanded">
|
|
|
+ <el-divider content-position="left">基本信息(实施人员使用)</el-divider>
|
|
|
+ <el-descriptions :column="1" size="small" border class="rule-meta">
|
|
|
+ <el-descriptions-item label="规则编码">{{ editingRow.ruleCode }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="规则类型">{{ ruleTypeLabel(editingRow.ruleType) }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="严重度">
|
|
|
+ <el-tag v-if="editingRow.severity" :type="severityTagType(editingRow.severity)" size="small">{{ severityLabel(editingRow.severity) }}</el-tag>
|
|
|
+ <span v-else>—</span>
|
|
|
+ <span class="rule-hint">如需调整严重度,请联系实施人员</span>
|
|
|
+ </el-descriptions-item>
|
|
|
+ <el-descriptions-item label="场景">{{ editingRow.sceneCode ?? '—' }}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="源对象">{{ editingRow.sourceObjectType ?? editingRow.watchObjectType ?? '—' }}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+
|
|
|
+ <el-divider content-position="left">检测 SQL(只读)</el-divider>
|
|
|
+ <pre class="rule-expr">{{ editingRow.expression || '—' }}</pre>
|
|
|
+ </template>
|
|
|
|
|
|
<el-divider content-position="left">检测调度</el-divider>
|
|
|
<el-form label-position="top" size="small">
|