|
|
@@ -0,0 +1,143 @@
|
|
|
+<script setup lang="ts" name="aidopS8InlineCreateExceptionTypeDialog">
|
|
|
+// CONFIG-WIZARD-INLINE-CREATE-MVP-1:在统一配置器内 inline 新增异常类型。
|
|
|
+// 复用 POST /api/aidop/s8/config/exception-types,sceneCode 强制等于当前 stageCode,enabled=true。
|
|
|
+import { computed, reactive, ref, watch } from 'vue';
|
|
|
+import { ElMessage } from 'element-plus';
|
|
|
+import { s8ConfigApi, type S8ExceptionTypeConfigPayload, type S8ExceptionTypeConfigRow } from '../../api/s8ConfigApi';
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ modelValue: boolean;
|
|
|
+ tenantId: number;
|
|
|
+ factoryId: number;
|
|
|
+ stageCode: string;
|
|
|
+ stageLabel?: string;
|
|
|
+}>();
|
|
|
+
|
|
|
+const emit = defineEmits<{
|
|
|
+ (e: 'update:modelValue', value: boolean): void;
|
|
|
+ (e: 'created', payload: { typeCode: string; typeName: string; severityDefault: string }): void;
|
|
|
+}>();
|
|
|
+
|
|
|
+const visible = computed({
|
|
|
+ get: () => props.modelValue,
|
|
|
+ set: (v) => emit('update:modelValue', v),
|
|
|
+});
|
|
|
+
|
|
|
+const SEVERITY_OPTIONS = [
|
|
|
+ { value: 'FOLLOW', label: '关注' },
|
|
|
+ { value: 'SERIOUS', label: '严重' },
|
|
|
+];
|
|
|
+
|
|
|
+const form = reactive({
|
|
|
+ typeName: '',
|
|
|
+ typeCode: '',
|
|
|
+ severityDefault: 'FOLLOW',
|
|
|
+ slaMinutes: 1440,
|
|
|
+ remark: '',
|
|
|
+});
|
|
|
+
|
|
|
+const saving = ref(false);
|
|
|
+
|
|
|
+function pad2(n: number) { return n < 10 ? `0${n}` : `${n}`; }
|
|
|
+function nowTimestampCompact() {
|
|
|
+ const d = new Date();
|
|
|
+ return `${d.getFullYear()}${pad2(d.getMonth() + 1)}${pad2(d.getDate())}${pad2(d.getHours())}${pad2(d.getMinutes())}${pad2(d.getSeconds())}`;
|
|
|
+}
|
|
|
+function generateTypeCode(stageCode: string): string {
|
|
|
+ if (!stageCode) return '';
|
|
|
+ const stage = stageCode.trim().toUpperCase().replace(/\s+/g, '');
|
|
|
+ return `CUSTOM_${stage}_${nowTimestampCompact()}`;
|
|
|
+}
|
|
|
+
|
|
|
+function resetForm() {
|
|
|
+ form.typeName = '';
|
|
|
+ form.typeCode = generateTypeCode(props.stageCode);
|
|
|
+ form.severityDefault = 'FOLLOW';
|
|
|
+ form.slaMinutes = 1440;
|
|
|
+ form.remark = '';
|
|
|
+}
|
|
|
+
|
|
|
+watch(visible, (v) => {
|
|
|
+ if (v) resetForm();
|
|
|
+});
|
|
|
+
|
|
|
+async function handleSave() {
|
|
|
+ if (!props.stageCode) { ElMessage.warning('请先选择所属阶段'); return; }
|
|
|
+ if (!form.typeName.trim()) { ElMessage.warning('请输入异常类型名称'); return; }
|
|
|
+ const code = form.typeCode.trim().toUpperCase().replace(/\s+/g, '');
|
|
|
+ if (!code) { ElMessage.warning('请输入内部编码'); return; }
|
|
|
+
|
|
|
+ const payload: S8ExceptionTypeConfigPayload = {
|
|
|
+ tenantId: props.tenantId,
|
|
|
+ factoryId: props.factoryId,
|
|
|
+ typeCode: code,
|
|
|
+ typeName: form.typeName.trim(),
|
|
|
+ sceneCode: props.stageCode,
|
|
|
+ severityDefault: form.severityDefault,
|
|
|
+ slaMinutes: Number(form.slaMinutes) || 0,
|
|
|
+ statsMode: 'ALL',
|
|
|
+ mobileVisible: true,
|
|
|
+ enabled: true,
|
|
|
+ sortNo: 900,
|
|
|
+ remark: form.remark.trim() || null,
|
|
|
+ };
|
|
|
+
|
|
|
+ saving.value = true;
|
|
|
+ try {
|
|
|
+ const created: S8ExceptionTypeConfigRow = await s8ConfigApi.exceptionTypes.create(payload);
|
|
|
+ ElMessage.success('异常类型已新增并选中');
|
|
|
+ emit('created', {
|
|
|
+ typeCode: created.typeCode,
|
|
|
+ typeName: created.typeName,
|
|
|
+ severityDefault: created.severityDefault || form.severityDefault,
|
|
|
+ });
|
|
|
+ visible.value = false;
|
|
|
+ } catch (e: any) {
|
|
|
+ const msg = e?.response?.data?.message ?? e?.message ?? '新增异常类型失败';
|
|
|
+ ElMessage.error(msg);
|
|
|
+ } finally {
|
|
|
+ saving.value = false;
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <el-dialog v-model="visible" title="新增异常类型" width="520px" :close-on-click-modal="false" destroy-on-close append-to-body>
|
|
|
+ <el-form label-position="top" size="small">
|
|
|
+ <el-form-item label="异常类型名称" required>
|
|
|
+ <el-input v-model="form.typeName" placeholder="如 客户加单延迟" maxlength="128" show-word-limit />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="内部编码" required>
|
|
|
+ <el-input v-model="form.typeCode" maxlength="64" show-word-limit />
|
|
|
+ <span class="inline-create-hint">建议保留默认;同一工厂下不能重复</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="所属阶段">
|
|
|
+ <el-input :model-value="stageLabel || stageCode || '—'" disabled />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="默认严重度">
|
|
|
+ <el-select v-model="form.severityDefault" style="width: 100%">
|
|
|
+ <el-option v-for="o in SEVERITY_OPTIONS" :key="o.value" :label="o.label" :value="o.value" />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="SLA 分钟">
|
|
|
+ <el-input-number v-model="form.slaMinutes" :min="0" :max="100000" :step="60" />
|
|
|
+ <span class="inline-create-hint">SLA 默认 1440(24 小时),可按业务调整</span>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="备注">
|
|
|
+ <el-input v-model="form.remark" type="textarea" :rows="2" maxlength="500" show-word-limit />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="visible = false">取消</el-button>
|
|
|
+ <el-button type="primary" :loading="saving" @click="handleSave">保存</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.inline-create-hint {
|
|
|
+ margin-left: 8px;
|
|
|
+ color: var(--el-text-color-secondary);
|
|
|
+ font-size: 12px;
|
|
|
+}
|
|
|
+</style>
|