发起变更通用footer以及保存提交统一修改
This commit is contained in:
@@ -52,7 +52,7 @@ const confirmed = ref<{[key: string]: boolean}>({
|
||||
'risk': false,
|
||||
'train': false,
|
||||
'pssr': false,
|
||||
'accept': false,
|
||||
'evaluation': false,
|
||||
'close': false,
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ const TABS = [
|
||||
{ id: "risk", name: "风险分析记录表", icon: 'proicons:alert-triangle' },
|
||||
{ id: "train", name: "变更培训内容", icon: 'lucide:graduation-cap' },
|
||||
{ id: "pssr", name: "PSSR 检查内容", icon: 'tabler:clipboard-check' },
|
||||
{ id: "accept", name: "验收评价", icon: 'material-symbols:check-circle-outline' },
|
||||
{ id: "evaluation", name: "验收评价", icon: 'material-symbols:check-circle-outline' },
|
||||
{ id: "close", name: "变更关闭确认表", icon: 'quill:folder-open' },
|
||||
];
|
||||
// 当前标签
|
||||
@@ -307,7 +307,16 @@ onMounted(() => {
|
||||
</div>
|
||||
<!-- ===== 风险分析记录表 ===== -->
|
||||
<div v-show="tab === 'risk'">
|
||||
<RiskAnalysis ref="riskAnalysisRef" :templateList="templateList" :isAiOpen="aiEnabled" :title="title" :currentId="currentId" @confirmTab="confirmTab" />
|
||||
<RiskAnalysis
|
||||
ref="riskAnalysisRef"
|
||||
:type="tab"
|
||||
:isAiOpen="aiEnabled"
|
||||
:title="title"
|
||||
:currentId="currentId"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</div>
|
||||
<!-- 变更培训内容 -->
|
||||
<div v-show="tab === 'train'">
|
||||
@@ -324,15 +333,42 @@ onMounted(() => {
|
||||
</div>
|
||||
<!-- PSSR 检查内容 -->
|
||||
<div v-show="tab === 'pssr'">
|
||||
<Pssr ref="pssrRef" :isAiOpen="aiEnabled" :title="title" :currentId="currentId" />
|
||||
<Pssr
|
||||
ref="pssrRef"
|
||||
:type="tab"
|
||||
:isAiOpen="aiEnabled"
|
||||
:title="title"
|
||||
:currentId="currentId"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</div>
|
||||
<!-- 验收评价 -->
|
||||
<div v-show="tab === 'accept'">
|
||||
<Evaluation ref="evaluationRef" :isAiOpen="aiEnabled" :title="title" :currentId="currentId" />
|
||||
<div v-show="tab === 'evaluation'">
|
||||
<Evaluation
|
||||
ref="evaluationRef"
|
||||
:type="tab"
|
||||
:isAiOpen="aiEnabled"
|
||||
:title="title"
|
||||
:currentId="currentId"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</div>
|
||||
<!-- 变更关闭确认表 -->
|
||||
<div v-show="tab === 'close'">
|
||||
<CloseConfirm ref="closeConfirmRef" :isAiOpen="aiEnabled" :title="title" :currentId="currentId" />
|
||||
<CloseConfirm
|
||||
ref="closeConfirmRef"
|
||||
:type="tab"
|
||||
:isAiOpen="aiEnabled"
|
||||
:title="title"
|
||||
:currentId="currentId"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</NCard>
|
||||
|
||||
@@ -1,26 +1,17 @@
|
||||
<!-- 变更培训内容 -->
|
||||
<!-- 变更关闭确认表 -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import ApprovalDrawer from './approvalDrawer.vue'
|
||||
import Footer from './footer.vue';
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const props = defineProps(['type','isAiOpen','title','currentId'])
|
||||
const emit = defineEmits(['save','submit','confirmTab']);
|
||||
|
||||
// 抽屉类型
|
||||
const approvalDrawerShow = ref<boolean>(false);
|
||||
const trainText = ref<string>('');
|
||||
const btnDisabled = ref<boolean>(false);
|
||||
const saveLoading = ref<boolean>(false);
|
||||
const downloadLoading = ref<boolean>(false);
|
||||
const regenerateLoading = ref<boolean>(false);
|
||||
const submitLoading = ref<boolean>(false);
|
||||
const confirmed = ref<boolean>(false);
|
||||
const approvers = ref<Record<string, string>>({
|
||||
部门审核: "李主任(一车间主任)",
|
||||
最终批准: "李主任(部门负责人 · 固定)",
|
||||
const form = ref<{ content: string }>({
|
||||
content: ''
|
||||
});
|
||||
const signers = ref<Record<string, string>>({});
|
||||
|
||||
const closeDocs = ref([
|
||||
{ name: "PID 图纸(PID-R201-03,受控最新版)", cat: "图纸与规程类", scope: "是", archived: true },
|
||||
@@ -70,30 +61,20 @@ const uploadConfirm = () => {
|
||||
uploadDoc.value = null;
|
||||
}
|
||||
|
||||
const regenerate = () => window.$message?.success(`演示:已根据变更描述重新生成变更申请表(本页内容已刷新)`);
|
||||
const download = () => window.$message?.success(`演示:变更申请表已下载(Word/PDF)`);
|
||||
|
||||
// 保存草稿
|
||||
const saveDraft = async () => {
|
||||
// if(changeApplyRules()){
|
||||
// return
|
||||
// }
|
||||
// saveLoading.value = true;
|
||||
// const {error} = await applicationSaveApi(props.currentId, form.value);
|
||||
// if(!error){
|
||||
// window.$message?.success("已保存为草稿,可在左侧「我的草稿」中继续编辑");
|
||||
// }
|
||||
// saveLoading.value = false;
|
||||
const saveDraft = () => {
|
||||
emit('save');
|
||||
}
|
||||
// ---------- 提交 ----------
|
||||
const submitApply = () => {
|
||||
|
||||
// 提交
|
||||
const submitConfirm = () => {
|
||||
emit('submit', props.type);
|
||||
}
|
||||
const confirmTab = () => {
|
||||
confirmed.value = !confirmed.value;
|
||||
// // 确认标签内容
|
||||
const confirmTab = (tab:string, val:boolean) => {
|
||||
emit('confirmTab', tab, val);
|
||||
}
|
||||
|
||||
defineExpose({trainText})
|
||||
defineExpose({form})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -173,47 +154,16 @@ defineExpose({trainText})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 border-t p-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<NButton ghost type="success" :disabled="btnDisabled" :loading="downloadLoading" @click="download">
|
||||
<Icon icon="material-symbols:download" class="size-16px" /> 下载变更关闭确认表
|
||||
</NButton>
|
||||
<NButton ghost type="warning" :disabled="btnDisabled" :loading="regenerateLoading" @click="regenerate">
|
||||
<Icon icon="tdesign:refresh" class="size-14px" /> 重新生成变关闭确认表
|
||||
</NButton>
|
||||
<NButton ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab">
|
||||
<Icon icon="ix:success" class="size-16px" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 bg-[#EAF0F9] px-4 py-2.5 shadow-[0_-2px_8px_rgba(0,0,0,0.05)]">
|
||||
<div class="flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-slate-500">
|
||||
<Icon icon="lucide:users" class="size-14px" />
|
||||
<span class="min-w-0 truncate">
|
||||
部门审核:{{ approvers.部门审核 }} → 专业会签:{{ Object.keys(signers).length ? Object.values(signers).join('、') : '未涉及专业 · 免会签' }} → 最终批准:{{ approvers.最终批准 }}
|
||||
</span>
|
||||
<NButton ghost size="small" type="primary" @click="approvalDrawerShow = true">
|
||||
<Icon icon="octicon:sliders-24" class="size-14px" />
|
||||
审批流程设置
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="ml-auto flex shrink-0 items-center gap-2">
|
||||
<NButton size="small" type="primary" :disabled="btnDisabled" :loading="saveLoading" @click="saveDraft">保存</NButton>
|
||||
<!-- <span v-if="!form" class="flex items-center text-xs text-amber-600">请先在「变更预识别」页生成变更申请单</span> -->
|
||||
<NButton size="small" type="primary" @click="submitApply" :disabled="btnDisabled" :loading="submitLoading">
|
||||
提交 <Icon icon="formkit:right" class="size-14px" />
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 审批流程设置 -->
|
||||
<NDrawer v-model:show="approvalDrawerShow" placement="right" width="28rem">
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<div class="text-base font-semibold text-slate-800">审批流程设置</div>
|
||||
</template>
|
||||
<ApprovalDrawer />
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
<Footer
|
||||
ref="footerRef"
|
||||
:type="props.type"
|
||||
:currentId="props.currentId"
|
||||
:title="props.title"
|
||||
:isAiOpen="props.isAiOpen"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
<!-- 资料上传弹窗 -->
|
||||
<NModal
|
||||
:show="uploadDoc !== null"
|
||||
|
||||
@@ -1,27 +1,18 @@
|
||||
<!-- 变更培训内容 -->
|
||||
<!-- 验收评价 -->
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { getColorWithOpacity } from "@/utils/common";
|
||||
import ApprovalDrawer from './approvalDrawer.vue'
|
||||
import Footer from './footer.vue';
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const props = defineProps(['type','isAiOpen','title','currentId'])
|
||||
const emit = defineEmits(['save','submit','confirmTab']);
|
||||
|
||||
// 抽屉类型
|
||||
const approvalDrawerShow = ref<boolean>(false);
|
||||
const trainText = ref<string>('');
|
||||
const btnDisabled = ref<boolean>(false);
|
||||
const saveLoading = ref<boolean>(false);
|
||||
const downloadLoading = ref<boolean>(false);
|
||||
const regenerateLoading = ref<boolean>(false);
|
||||
const submitLoading = ref<boolean>(false);
|
||||
const confirmed = ref<boolean>(false);
|
||||
const approvers = ref<Record<string, string>>({
|
||||
部门审核: "李主任(一车间主任)",
|
||||
最终批准: "李主任(部门负责人 · 固定)",
|
||||
const form = ref<{ content: string }>({
|
||||
content: ''
|
||||
});
|
||||
const signers = ref<Record<string, string>>({});
|
||||
|
||||
const editing = ref<any>(null);
|
||||
const acceptRows = ref([
|
||||
@@ -33,30 +24,20 @@ const acceptRows = ref([
|
||||
]);
|
||||
const acceptNote = ref("");
|
||||
|
||||
const regenerate = () => window.$message?.success(`演示:已根据变更描述重新生成变更申请表(本页内容已刷新)`);
|
||||
const download = () => window.$message?.success(`演示:变更申请表已下载(Word/PDF)`);
|
||||
|
||||
// 保存草稿
|
||||
const saveDraft = async () => {
|
||||
// if(changeApplyRules()){
|
||||
// return
|
||||
// }
|
||||
// saveLoading.value = true;
|
||||
// const {error} = await applicationSaveApi(props.currentId, form.value);
|
||||
// if(!error){
|
||||
// window.$message?.success("已保存为草稿,可在左侧「我的草稿」中继续编辑");
|
||||
// }
|
||||
// saveLoading.value = false;
|
||||
const saveDraft = () => {
|
||||
emit('save');
|
||||
}
|
||||
// ---------- 提交 ----------
|
||||
const submitApply = () => {
|
||||
|
||||
// 提交
|
||||
const submitConfirm = () => {
|
||||
emit('submit', props.type);
|
||||
}
|
||||
const confirmTab = () => {
|
||||
confirmed.value = !confirmed.value;
|
||||
// // 确认标签内容
|
||||
const confirmTab = (tab:string, val:boolean) => {
|
||||
emit('confirmTab', tab, val);
|
||||
}
|
||||
|
||||
defineExpose({trainText})
|
||||
defineExpose({form})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -197,47 +178,16 @@ defineExpose({trainText})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 border-t p-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<NButton ghost type="success" :disabled="btnDisabled" :loading="downloadLoading" @click="download">
|
||||
<Icon icon="material-symbols:download" class="size-16px" /> 下载验收评价
|
||||
</NButton>
|
||||
<NButton ghost type="warning" :disabled="btnDisabled" :loading="regenerateLoading" @click="regenerate">
|
||||
<Icon icon="tdesign:refresh" class="size-14px" /> 重新生成验收评价
|
||||
</NButton>
|
||||
<NButton ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab">
|
||||
<Icon icon="ix:success" class="size-16px" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 bg-[#EAF0F9] px-4 py-2.5 shadow-[0_-2px_8px_rgba(0,0,0,0.05)]">
|
||||
<div class="flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-slate-500">
|
||||
<Icon icon="lucide:users" class="size-14px" />
|
||||
<span class="min-w-0 truncate">
|
||||
部门审核:{{ approvers.部门审核 }} → 专业会签:{{ Object.keys(signers).length ? Object.values(signers).join('、') : '未涉及专业 · 免会签' }} → 最终批准:{{ approvers.最终批准 }}
|
||||
</span>
|
||||
<NButton ghost size="small" type="primary" @click="approvalDrawerShow = true">
|
||||
<Icon icon="octicon:sliders-24" class="size-14px" />
|
||||
审批流程设置
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="ml-auto flex shrink-0 items-center gap-2">
|
||||
<NButton size="small" type="primary" :disabled="btnDisabled" :loading="saveLoading" @click="saveDraft">保存</NButton>
|
||||
<!-- <span v-if="!form" class="flex items-center text-xs text-amber-600">请先在「变更预识别」页生成变更申请单</span> -->
|
||||
<NButton size="small" type="primary" @click="submitApply" :disabled="btnDisabled" :loading="submitLoading">
|
||||
提交 <Icon icon="formkit:right" class="size-14px" />
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 审批流程设置 -->
|
||||
<NDrawer v-model:show="approvalDrawerShow" placement="right" width="28rem">
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<div class="text-base font-semibold text-slate-800">审批流程设置</div>
|
||||
</template>
|
||||
<ApprovalDrawer />
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
<Footer
|
||||
ref="footerRef"
|
||||
:type="props.type"
|
||||
:currentId="props.currentId"
|
||||
:title="props.title"
|
||||
:isAiOpen="props.isAiOpen"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
|
||||
@@ -147,12 +147,20 @@ defineExpose({clearApprovers})
|
||||
<NButton ghost type="success" :disabled="btnDisabled" :loading="downloadLoading" @click="download">
|
||||
<Icon icon="material-symbols:download" class="size-16px" />
|
||||
<span v-if="props.type==='form'">下载变更申请表</span>
|
||||
<span v-if="props.type==='risk'">下载风险分析记录表</span>
|
||||
<span v-if="props.type==='train'">下载变更培训内容</span>
|
||||
<span v-if="props.type==='pssr'">下载PSSR检查内容</span>
|
||||
<span v-if="props.type==='evaluation'">下载验收评价</span>
|
||||
<span v-if="props.type==='close'">下载变更关闭确认表</span>
|
||||
</NButton>
|
||||
<NButton v-if="props.isAiOpen" ghost type="warning" :disabled="btnDisabled" :loading="regenerateLoading" @click="regenerate">
|
||||
<Icon icon="tdesign:refresh" class="size-14px mr-1" />
|
||||
<span v-if="props.type==='form'">重新生成变更申请表</span>
|
||||
<span v-if="props.type==='risk'">重新生成风险分析记录表</span>
|
||||
<span v-if="props.type==='train'">重新生成变更培训内容</span>
|
||||
<span v-if="props.type==='pssr'">重新生成PSSR检查内容</span>
|
||||
<span v-if="props.type==='evaluation'">重新生成验收评价</span>
|
||||
<span v-if="props.type==='close'">重新生成变更关闭确认表</span>
|
||||
</NButton>
|
||||
<NButton v-if="props.isAiOpen" ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab">
|
||||
<Icon icon="ix:success" class="size-16px mr-1" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||
|
||||
@@ -1,25 +1,17 @@
|
||||
<!-- PSSR检查内容 -->
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue';
|
||||
import { ref } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import ApprovalDrawer from './approvalDrawer.vue'
|
||||
import Footer from './footer.vue';
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
// 抽屉类型
|
||||
const approvalDrawerShow = ref<boolean>(false);
|
||||
const trainText = ref<string>('');
|
||||
const btnDisabled = ref<boolean>(false);
|
||||
const saveLoading = ref<boolean>(false);
|
||||
const downloadLoading = ref<boolean>(false);
|
||||
const regenerateLoading = ref<boolean>(false);
|
||||
const submitLoading = ref<boolean>(false);
|
||||
const confirmed = ref<boolean>(false);
|
||||
const approvers = ref<Record<string, string>>({
|
||||
部门审核: "李主任(一车间主任)",
|
||||
最终批准: "李主任(部门负责人 · 固定)",
|
||||
const props = defineProps(['type','isAiOpen','title','currentId'])
|
||||
const emit = defineEmits(['save','submit','confirmTab']);
|
||||
|
||||
const form = ref<{ content: string }>({
|
||||
content: ''
|
||||
});
|
||||
const signers = ref<Record<string, string>>({});
|
||||
|
||||
const editing = ref<any>(null);
|
||||
const pssrGroups = ref<{ g: string; items: any[] }[]>([
|
||||
@@ -46,10 +38,6 @@ const pssrGroups = ref<{ g: string; items: any[] }[]>([
|
||||
]);
|
||||
const pssrDone = ref<Record<string, { by: string; at: string }>>({});
|
||||
const pssrNa = ref<Record<string, boolean>>({});
|
||||
const pssrActive = computed(() => pssrGroups.value.filter((g:any) => !pssrNa.value[g.g]));
|
||||
const pssrTotal = computed(() => pssrActive.value.reduce((a:any, g:any) => a + g.items.length, 0));
|
||||
const pssrDoneCount = computed(() => pssrActive.value.reduce((a:any, g:any) => a + g.items.filter((it:any) => pssrDone.value[it.c]).length, 0));
|
||||
const pssrAllDone = computed(() => pssrDoneCount.value === pssrTotal.value && (pssrTotal.value > 0 || (pssrGroups.value.length > 0 && pssrGroups.value.every((g) => !!pssrNa.value[g.g]))));
|
||||
const pssrFileRef = ref<any>(null);
|
||||
const pssrSheet = ref<any>(null);
|
||||
const closeDocs = ref([
|
||||
@@ -65,6 +53,7 @@ const closeDocs = ref([
|
||||
{ name: "验收报告与化验数据", cat: "过程与结果文件类", scope: "是", archived: false },
|
||||
]);
|
||||
const today = () => new Date().toISOString().slice(0, 10);
|
||||
// 上传纸质确认表
|
||||
const onPssrFile = (e: Event) => {
|
||||
const input = e.target as HTMLInputElement;
|
||||
const f = input.files?.[0]; input.value = "";
|
||||
@@ -81,30 +70,20 @@ const onPssrFile = (e: Event) => {
|
||||
window.$message?.success(`已上传 PSSR 纸质确认表「${f.name}」:不做内容识别,上传即视为全部检查项完成确认(「不涉及」组除外),原件归档至变更档案`);
|
||||
};
|
||||
|
||||
const regenerate = () => window.$message?.success(`演示:已根据变更描述重新生成变更申请表(本页内容已刷新)`);
|
||||
const download = () => window.$message?.success(`演示:变更申请表已下载(Word/PDF)`);
|
||||
|
||||
// 保存草稿
|
||||
const saveDraft = async () => {
|
||||
// if(changeApplyRules()){
|
||||
// return
|
||||
// }
|
||||
// saveLoading.value = true;
|
||||
// const {error} = await applicationSaveApi(props.currentId, form.value);
|
||||
// if(!error){
|
||||
// window.$message?.success("已保存为草稿,可在左侧「我的草稿」中继续编辑");
|
||||
// }
|
||||
// saveLoading.value = false;
|
||||
const saveDraft = () => {
|
||||
emit('save');
|
||||
}
|
||||
// ---------- 提交 ----------
|
||||
const submitApply = () => {
|
||||
|
||||
// 提交
|
||||
const submitConfirm = () => {
|
||||
emit('submit', props.type);
|
||||
}
|
||||
const confirmTab = () => {
|
||||
confirmed.value = !confirmed.value;
|
||||
// // 确认标签内容
|
||||
const confirmTab = (tab:string, val:boolean) => {
|
||||
emit('confirmTab', tab, val);
|
||||
}
|
||||
|
||||
defineExpose({trainText})
|
||||
defineExpose({form})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -112,32 +91,25 @@ defineExpose({trainText})
|
||||
<div class="space-y-4 scroll">
|
||||
<div class="flex flex-wrap items-center gap-3">
|
||||
<span class="flex items-center gap-1.5 text-sm font-semibold text-slate-700">
|
||||
<Icon icon="tabler:clipboard-check" class="size-16px text-violet-500" />
|
||||
PSSR 投用前安全检查内容
|
||||
<Icon icon="tabler:clipboard-check" class="size-16px text-violet-500" />
|
||||
PSSR 投用前安全检查内容
|
||||
</span>
|
||||
<span class="inline-flex items-center gap-1 rounded-full border border-violet-200 bg-violet-100 px-2 py-0.5 text-xs font-medium text-violet-700">
|
||||
✨ AI 生成 · 需人工确认
|
||||
</span>
|
||||
<NTag size="small" :type="pssrAllDone ? 'success' : 'info'">
|
||||
已完成 {{ pssrDoneCount }}/{{ pssrTotal }} 项
|
||||
</NTag>
|
||||
<span class="flex items-center gap-2">
|
||||
<NButton ghost size="small" class="text-xs" title="上传 PSSR 纸质确认表照片 / 扫描件(JPG / PNG / PDF),系统不做内容识别,上传即视为全部检查项完成确认" @click="pssrFileRef?.click()">
|
||||
<Icon icon="material-symbols:upload" class="size-14px" />
|
||||
上传纸质确认表
|
||||
</NButton>
|
||||
<input ref="pssrFileRef" type="file" accept="image/*,.pdf" class="hidden" @change="onPssrFile" />
|
||||
<span class="hidden text-xs text-slate-400 xl:inline">申请阶段:点击条目内容直接编辑,可增删项,完成时点互斥选择;审批通过后逐项点击确认(PC / 移动端均可),全部完成自动推送属地负责人</span>
|
||||
<span class="hidden text-xs text-slate-400 xl:inline">申请阶段:点击条目内容直接编辑,可增删项,完成时点互斥选择;审批通过后逐项点击确认,全部完成自动推送属地负责人</span>
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="pssrSheet" class="flex items-center gap-2 rounded-lg border border-emerald-200 bg-emerald-50 px-4 py-2 text-xs text-emerald-700">
|
||||
<Icon icon="ix:success" class="size-16px" />
|
||||
已上传 PSSR 纸质确认表「{{ pssrSheet }}」:上传即视为全部检查项完成确认(未做内容识别),原件已归档至变更档案
|
||||
</div>
|
||||
<div v-if="pssrAllDone" class="flex items-center gap-2 rounded-lg border border-emerald-200 bg-emerald-50 px-4 py-2.5 text-xs text-emerald-700">
|
||||
<Icon icon="ix:success" class="size-16px" />
|
||||
全部 PSSR 检查项已确认完成,「具备投用条件」信息已自动推送属地负责人(车间 / 装置主任),可进行投用确认
|
||||
</div>
|
||||
|
||||
<div v-for="(g, gi) in pssrGroups" :key="g.g" class="border" :class="pssrNa[g.g] ? 'opacity-70' : ''" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
<div class="flex items-center bg-slate-100 px-3 py-2 text-sm font-medium text-slate-700">
|
||||
@@ -181,9 +153,9 @@ defineExpose({trainText})
|
||||
@change="pssrGroups = pssrGroups.map((x, xi) => xi === gi ? { ...x, items: x.items.map((y, yi) => yi === i ? { ...y, p: '关闭前' } : y) } : x)" />
|
||||
</span>
|
||||
<NButton text type="error" title="删除该项"
|
||||
@click="pssrGroups = pssrGroups.map((x, xi) => xi === gi ? { ...x, items: x.items.filter((_, yi) => yi !== i) } : x)"
|
||||
@click="pssrGroups = pssrGroups.map((x, xi) => xi === gi ? { ...x, items: x.items.filter((_, yi) => yi !== i) } : x)"
|
||||
>
|
||||
<Icon icon="iconamoon:trash" class="size-16px" />
|
||||
<Icon icon="iconamoon:trash" class="size-16px" />
|
||||
</NButton>
|
||||
</div>
|
||||
</template>
|
||||
@@ -192,51 +164,20 @@ defineExpose({trainText})
|
||||
完成时点说明:「投用前完成 / 关闭前完成」为互斥选择,点击即可切换。投用前完成的项未确认时属地负责人无法确认投用;关闭前完成的项不阻塞投用,但纳入关闭校验清单,未完成时变更主管部门专责无法确认关闭。
|
||||
</div>
|
||||
<div class="rounded-lg bg-violet-50/70 px-4 py-2.5 text-xs text-violet-700">
|
||||
清单由 AI 依据变更类型与风险分析自动生成,专业人员审核后随审批发布;确认方式不作硬性要求——可在 PC 端直接点击确认,也可在移动端拍照上传作为佐证(系统自动记录确认人与日期);资料归档组确认后自动同步「变更关闭确认表」显示已归档。
|
||||
清单由 AI 依据变更类型与风险分析自动生成,专业人员审核后随审批发布;确认方式不作硬性要求——可直接点击确认;资料归档组确认后自动同步「变更关闭确认表」显示已归档。
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 border-t p-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<NButton ghost type="success" :disabled="btnDisabled" :loading="downloadLoading" @click="download">
|
||||
<Icon icon="material-symbols:download" class="size-16px" /> 下载PSSR检查内容
|
||||
</NButton>
|
||||
<NButton ghost type="warning" :disabled="btnDisabled" :loading="regenerateLoading" @click="regenerate">
|
||||
<Icon icon="tdesign:refresh" class="size-14px" /> 重新生成PSSR检查内容
|
||||
</NButton>
|
||||
<NButton ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab">
|
||||
<Icon icon="ix:success" class="size-16px" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 bg-[#EAF0F9] px-4 py-2.5 shadow-[0_-2px_8px_rgba(0,0,0,0.05)]">
|
||||
<div class="flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-slate-500">
|
||||
<Icon icon="lucide:users" class="size-14px" />
|
||||
<span class="min-w-0 truncate">
|
||||
部门审核:{{ approvers.部门审核 }} → 专业会签:{{ Object.keys(signers).length ? Object.values(signers).join('、') : '未涉及专业 · 免会签' }} → 最终批准:{{ approvers.最终批准 }}
|
||||
</span>
|
||||
<NButton ghost size="small" type="primary" @click="approvalDrawerShow = true">
|
||||
<Icon icon="octicon:sliders-24" class="size-14px" />
|
||||
审批流程设置
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="ml-auto flex shrink-0 items-center gap-2">
|
||||
<NButton size="small" type="primary" :disabled="btnDisabled" :loading="saveLoading" @click="saveDraft">保存</NButton>
|
||||
<!-- <span v-if="!form" class="flex items-center text-xs text-amber-600">请先在「变更预识别」页生成变更申请单</span> -->
|
||||
<NButton size="small" type="primary" @click="submitApply" :disabled="btnDisabled" :loading="submitLoading">
|
||||
提交 <Icon icon="formkit:right" class="size-14px" />
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 审批流程设置 -->
|
||||
<NDrawer v-model:show="approvalDrawerShow" placement="right" width="28rem">
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<div class="text-base font-semibold text-slate-800">审批流程设置</div>
|
||||
</template>
|
||||
<ApprovalDrawer />
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
<Footer
|
||||
ref="footerRef"
|
||||
:type="props.type"
|
||||
:currentId="props.currentId"
|
||||
:title="props.title"
|
||||
:isAiOpen="props.isAiOpen"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
|
||||
@@ -8,23 +8,16 @@ import Hazop from "./hazop.vue";
|
||||
import Jsa from "./jsa.vue";
|
||||
import Scl from "./scl.vue";
|
||||
import RiskCheck from "./riskCheck.vue";
|
||||
import ApprovalDrawer from './approvalDrawer.vue'
|
||||
import Footer from './footer.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
// 抽屉类型
|
||||
const approvalDrawerShow = ref<boolean>(false);
|
||||
const trainText = ref<string>('');
|
||||
const btnDisabled = ref<boolean>(false);
|
||||
const saveLoading = ref<boolean>(false);
|
||||
const downloadLoading = ref<boolean>(false);
|
||||
const regenerateLoading = ref<boolean>(false);
|
||||
const submitLoading = ref<boolean>(false);
|
||||
const confirmed = ref<boolean>(false);
|
||||
const approvers = ref<Record<string, string>>({
|
||||
部门审核: "李主任(一车间主任)",
|
||||
最终批准: "李主任(部门负责人 · 固定)",
|
||||
|
||||
const props = defineProps(['type','isAiOpen','title','currentId'])
|
||||
const emit = defineEmits(['save','submit','confirmTab']);
|
||||
|
||||
const form = ref<{ content: string }>({
|
||||
content: ''
|
||||
});
|
||||
const signers = ref<Record<string, string>>({});
|
||||
const pluginDone = ref<Record<string, number>>({});
|
||||
const tools = ref<string[]>(["HAZOP","JSA", "SCL", "RISK_CHECK"]);
|
||||
const riskRecords = ref<any>([]);
|
||||
@@ -126,30 +119,20 @@ const exportAll = (items: any[], mode: "manual" | "ai") => {
|
||||
}
|
||||
}
|
||||
|
||||
const regenerate = () => window.$message?.success(`演示:已根据变更描述重新生成变更申请表(本页内容已刷新)`);
|
||||
const download = () => window.$message?.success(`演示:变更申请表已下载(Word/PDF)`);
|
||||
|
||||
// 保存草稿
|
||||
const saveDraft = async () => {
|
||||
// if(changeApplyRules()){
|
||||
// return
|
||||
// }
|
||||
// saveLoading.value = true;
|
||||
// const {error} = await applicationSaveApi(props.currentId, form.value);
|
||||
// if(!error){
|
||||
// window.$message?.success("已保存为草稿,可在左侧「我的草稿」中继续编辑");
|
||||
// }
|
||||
// saveLoading.value = false;
|
||||
const saveDraft = () => {
|
||||
emit('save');
|
||||
}
|
||||
// ---------- 提交 ----------
|
||||
const submitApply = () => {
|
||||
|
||||
// 提交
|
||||
const submitConfirm = () => {
|
||||
emit('submit', props.type);
|
||||
}
|
||||
const confirmTab = () => {
|
||||
confirmed.value = !confirmed.value;
|
||||
// // 确认标签内容
|
||||
const confirmTab = (tab:string, val:boolean) => {
|
||||
emit('confirmTab', tab, val);
|
||||
}
|
||||
|
||||
defineExpose({trainText})
|
||||
defineExpose({form})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -268,38 +251,17 @@ defineExpose({trainText})
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center justify-between gap-2 border-t p-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<NButton ghost type="success" :disabled="btnDisabled" :loading="downloadLoading" @click="download">
|
||||
<Icon icon="material-symbols:download" class="size-16px" /> 下载风险分析记录表
|
||||
</NButton>
|
||||
<NButton ghost type="warning" :disabled="btnDisabled" :loading="regenerateLoading" @click="regenerate">
|
||||
<Icon icon="tdesign:refresh" class="size-14px" /> 重新生成风险分析记录表
|
||||
</NButton>
|
||||
<NButton ghost :type="confirmed ? 'success' : 'primary'" :disabled="btnDisabled" @click="confirmTab">
|
||||
<Icon icon="ix:success" class="size-16px" /> {{ confirmed ? '已确认完毕' : '本标签内容确认完毕' }}
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-2 bg-[#EAF0F9] px-4 py-2.5 shadow-[0_-2px_8px_rgba(0,0,0,0.05)]">
|
||||
<div class="flex min-w-0 flex-1 flex-wrap items-center gap-x-2 gap-y-1 text-xs text-slate-500">
|
||||
<Icon icon="lucide:users" class="size-14px" />
|
||||
<span class="min-w-0 truncate">
|
||||
部门审核:{{ approvers.部门审核 }} → 专业会签:{{ Object.keys(signers).length ? Object.values(signers).join('、') : '未涉及专业 · 免会签' }} → 最终批准:{{ approvers.最终批准 }}
|
||||
</span>
|
||||
<NButton ghost size="small" type="primary" @click="approvalDrawerShow = true">
|
||||
<Icon icon="octicon:sliders-24" class="size-14px" />
|
||||
审批流程设置
|
||||
</NButton>
|
||||
</div>
|
||||
<div class="ml-auto flex shrink-0 items-center gap-2">
|
||||
<NButton size="small" type="primary" :disabled="btnDisabled" :loading="saveLoading" @click="saveDraft">保存</NButton>
|
||||
<!-- <span v-if="!form" class="flex items-center text-xs text-amber-600">请先在「变更预识别」页生成变更申请单</span> -->
|
||||
<NButton size="small" type="primary" @click="submitApply" :disabled="btnDisabled" :loading="submitLoading">
|
||||
提交 <Icon icon="formkit:right" class="size-14px" />
|
||||
</NButton>
|
||||
</div>
|
||||
</div>
|
||||
<Footer
|
||||
ref="footerRef"
|
||||
:type="props.type"
|
||||
:currentId="props.currentId"
|
||||
:title="props.title"
|
||||
:isAiOpen="props.isAiOpen"
|
||||
:currentForm="form"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
/>
|
||||
<!-- 插件抽屉 -->
|
||||
<NDrawer v-model:show="pluginDrawer" :width="1200" placement="right">
|
||||
<NDrawerContent>
|
||||
@@ -317,15 +279,6 @@ defineExpose({trainText})
|
||||
</template>
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
<!-- 审批流程设置 -->
|
||||
<NDrawer v-model:show="approvalDrawerShow" placement="right" width="28rem">
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<div class="text-base font-semibold text-slate-800">审批流程设置</div>
|
||||
</template>
|
||||
<ApprovalDrawer />
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
.scroll {
|
||||
|
||||
Reference in New Issue
Block a user