|
@@ -13,6 +13,7 @@ import {
|
|
|
type S8WatchRuleCreatePayload,
|
|
type S8WatchRuleCreatePayload,
|
|
|
type S8WizardDraftDetail,
|
|
type S8WizardDraftDetail,
|
|
|
} from '../../api/s8ConfigApi';
|
|
} from '../../api/s8ConfigApi';
|
|
|
|
|
+import InlineCreateExceptionTypeDialog from './InlineCreateExceptionTypeDialog.vue';
|
|
|
|
|
|
|
|
interface DataSourceLike {
|
|
interface DataSourceLike {
|
|
|
id: number;
|
|
id: number;
|
|
@@ -37,6 +38,7 @@ const emit = defineEmits<{
|
|
|
(e: 'saved'): void;
|
|
(e: 'saved'): void;
|
|
|
(e: 'draftSaved'): void;
|
|
(e: 'draftSaved'): void;
|
|
|
(e: 'generated'): void;
|
|
(e: 'generated'): void;
|
|
|
|
|
+ (e: 'requestReloadExceptionTypes', payload: { typeCode: string; severityDefault: string }): void;
|
|
|
}>();
|
|
}>();
|
|
|
|
|
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
@@ -163,6 +165,11 @@ const dictionaryMissing = ref(false);
|
|
|
const fallbackObjectLabel = ref('');
|
|
const fallbackObjectLabel = ref('');
|
|
|
const fallbackMetricLabel = ref('');
|
|
const fallbackMetricLabel = ref('');
|
|
|
|
|
|
|
|
|
|
+// CONFIG-WIZARD-INLINE-CREATE-MVP-1:inline 新增异常类型 dialog 状态 + 等待父组件 reload 后的回填项。
|
|
|
|
|
+const inlineCreateVisible = ref(false);
|
|
|
|
|
+const pendingTypeCode = ref<string>('');
|
|
|
|
|
+const pendingSeverity = ref<string>('');
|
|
|
|
|
+
|
|
|
function pad2(n: number) { return n < 10 ? `0${n}` : `${n}`; }
|
|
function pad2(n: number) { return n < 10 ? `0${n}` : `${n}`; }
|
|
|
function nowTimestampCompact() {
|
|
function nowTimestampCompact() {
|
|
|
const d = new Date();
|
|
const d = new Date();
|
|
@@ -263,6 +270,24 @@ watch(() => form.objectIndex, () => {
|
|
|
if (form.objectIndex >= 0) dictionaryMissing.value = false;
|
|
if (form.objectIndex >= 0) dictionaryMissing.value = false;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+// CONFIG-WIZARD-INLINE-CREATE-MVP-1:父组件 reload 后 exceptionTypes 引用变化,若有 pending 则自动选中。
|
|
|
|
|
+watch(
|
|
|
|
|
+ () => props.exceptionTypes,
|
|
|
|
|
+ (list) => {
|
|
|
|
|
+ if (!pendingTypeCode.value) return;
|
|
|
|
|
+ const found = list.find((t) => t.typeCode === pendingTypeCode.value);
|
|
|
|
|
+ if (!found) return;
|
|
|
|
|
+ form.exceptionTypeCode = found.typeCode;
|
|
|
|
|
+ form.severity = pendingSeverity.value || found.severityDefault || form.severity;
|
|
|
|
|
+ pendingTypeCode.value = '';
|
|
|
|
|
+ pendingSeverity.value = '';
|
|
|
|
|
+ if (currentDraftId.value != null) {
|
|
|
|
|
+ ElMessage.info('异常类型已新增并选中,请保存草稿以保留本次配置');
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ { deep: false },
|
|
|
|
|
+);
|
|
|
|
|
+
|
|
|
const filteredExceptionTypes = computed(() => {
|
|
const filteredExceptionTypes = computed(() => {
|
|
|
const all = props.exceptionTypes.filter((t) => t.enabled);
|
|
const all = props.exceptionTypes.filter((t) => t.enabled);
|
|
|
if (!form.stageCode) return all;
|
|
if (!form.stageCode) return all;
|
|
@@ -659,6 +684,21 @@ function goManualReport() {
|
|
|
visible.value = false;
|
|
visible.value = false;
|
|
|
router.push('/aidop/s8/report');
|
|
router.push('/aidop/s8/report');
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+// CONFIG-WIZARD-INLINE-CREATE-MVP-1:打开 inline create dialog;未选 stage 时阻止。
|
|
|
|
|
+function openInlineCreateExceptionType() {
|
|
|
|
|
+ if (!form.stageCode) {
|
|
|
|
|
+ ElMessage.warning('请先选择所属阶段');
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ inlineCreateVisible.value = true;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+function handleInlineExceptionTypeCreated(payload: { typeCode: string; typeName: string; severityDefault: string }) {
|
|
|
|
|
+ pendingTypeCode.value = payload.typeCode;
|
|
|
|
|
+ pendingSeverity.value = payload.severityDefault;
|
|
|
|
|
+ emit('requestReloadExceptionTypes', { typeCode: payload.typeCode, severityDefault: payload.severityDefault });
|
|
|
|
|
+}
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
<template>
|
|
@@ -795,14 +835,18 @@ function goManualReport() {
|
|
|
|
|
|
|
|
<el-divider />
|
|
<el-divider />
|
|
|
<el-form-item label="异常类型" required>
|
|
<el-form-item label="异常类型" required>
|
|
|
- <el-select v-model="form.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="width: 100%">
|
|
|
|
|
- <el-option
|
|
|
|
|
- v-for="t in filteredExceptionTypes"
|
|
|
|
|
- :key="t.typeCode"
|
|
|
|
|
- :label="t.typeName"
|
|
|
|
|
- :value="t.typeCode"
|
|
|
|
|
- />
|
|
|
|
|
- </el-select>
|
|
|
|
|
|
|
+ <div class="wizard-exception-type-row">
|
|
|
|
|
+ <el-select v-model="form.exceptionTypeCode" filterable clearable placeholder="选择异常类型" style="flex: 1; min-width: 0">
|
|
|
|
|
+ <el-option
|
|
|
|
|
+ v-for="t in filteredExceptionTypes"
|
|
|
|
|
+ :key="t.typeCode"
|
|
|
|
|
+ :label="t.typeName"
|
|
|
|
|
+ :value="t.typeCode"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-select>
|
|
|
|
|
+ <el-button :disabled="!form.stageCode" @click="openInlineCreateExceptionType">新增异常类型</el-button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <span v-if="!form.stageCode" class="wizard-hint">请先在第 2 步选择阶段维度后再新增异常类型</span>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
|
|
|
|
|
<el-alert type="success" :closable="false" style="margin-top: 8px">
|
|
<el-alert type="success" :closable="false" style="margin-top: 8px">
|
|
@@ -863,6 +907,16 @@ function goManualReport() {
|
|
|
</template>
|
|
</template>
|
|
|
</template>
|
|
</template>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
|
+
|
|
|
|
|
+ <!-- CONFIG-WIZARD-INLINE-CREATE-MVP-1:inline 新增异常类型 dialog -->
|
|
|
|
|
+ <InlineCreateExceptionTypeDialog
|
|
|
|
|
+ v-model="inlineCreateVisible"
|
|
|
|
|
+ :tenant-id="tenantId ?? 1"
|
|
|
|
|
+ :factory-id="factoryId ?? 1"
|
|
|
|
|
+ :stage-code="form.stageCode"
|
|
|
|
|
+ :stage-label="stageNodeLabel"
|
|
|
|
|
+ @created="handleInlineExceptionTypeCreated"
|
|
|
|
|
+ />
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -902,4 +956,10 @@ function goManualReport() {
|
|
|
color: var(--el-text-color-secondary);
|
|
color: var(--el-text-color-secondary);
|
|
|
font-size: 12px;
|
|
font-size: 12px;
|
|
|
}
|
|
}
|
|
|
|
|
+.wizard-exception-type-row {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ gap: 8px;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
</style>
|
|
</style>
|