预览文件统一修改
This commit is contained in:
@@ -8,7 +8,7 @@ import { getColorWithOpacity, tagTextColor, tagBgColor, tagBorderColor, download
|
||||
import { AiError, aiTypeJudge } from "@/service/api/ai";
|
||||
import { systemConfigApi } from '@/service/api/system';
|
||||
import { getChangeDetailApi } from '@/service/api/change';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
import { rejectApi,agreeApi } from '@/service/api/myTasks';
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
@@ -9,7 +9,7 @@ import { uploadFileApi, deleteFileApi, fileListApi } from "@/service/api/file";
|
||||
import { systemConfigApi, peopleListApi, templateListApi } from '@/service/api/system';
|
||||
import { getChangeDetailApi } from '@/service/api/change';
|
||||
import { myTasksCloseMaterialApi } from '@/service/api/myTasks';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
@@ -170,7 +170,7 @@ const chooseFiles = () => {
|
||||
const ids = new Set(checkedFiles.value);
|
||||
const result = fileList.value.filter((item:any) => ids.has(item.id));
|
||||
// 合并文件列表
|
||||
let files = list.value[currentRowIndex.value]?.attachments.concat(result);
|
||||
const files = list.value[currentRowIndex.value]?.attachments.concat(result);
|
||||
// 按id去重
|
||||
const uniqueList = [
|
||||
...new Map(files.map((item:any) => [item.id, item])).values(),
|
||||
@@ -349,7 +349,7 @@ const togglePicker = (s: any) => {
|
||||
// 添加审批步骤人员
|
||||
const addMember = (s: any, v: string | null) => {
|
||||
if (v && !s.members.some((m:any) => m.user_name === v)){
|
||||
let info = findUserInTree(memberList.value, v);
|
||||
const info = findUserInTree(memberList.value, v);
|
||||
s.members.push({ user_id: Number(v), user_name: info?.user_name || '', org_id: info?.org_id || '', org_name: info?.org_name || '', specialty: "", is_sign: 0 });
|
||||
pick.value = null;
|
||||
pickerStepId.value = null;
|
||||
@@ -397,7 +397,7 @@ onMounted(async () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<NSpace vertical :size="16">
|
||||
<NSpace vertical :size="16">
|
||||
<!-- 资料关闭详情-->
|
||||
<NSpin :show="loading" size="small">
|
||||
<NCard :bordered="false" size="small" :style="{ borderRadius: themeStore.themeRadius + 'px' }">
|
||||
@@ -434,13 +434,13 @@ onMounted(async () => {
|
||||
class="text-11px flex items-center gap-2 border py-0.5 px-1.5 rounded-md text-[#17407F] border-[#ACC6E5] bg-[#EAF0F9]"
|
||||
>
|
||||
<Icon icon="akar-icons:file" class="size-12px" />
|
||||
{{file.file_name}}
|
||||
{{ file.file_name }}
|
||||
<NButton text type="primary" class="text-11px" @click="preview(file)">预览</NButton>
|
||||
<NButton text type="primary" class="text-11px" @click="downloadFile(file,'train')">下载</NButton>
|
||||
<NPopconfirm
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="removeFileReal('3', Number(fileIndex))"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -456,8 +456,8 @@ onMounted(async () => {
|
||||
下载培训签到表
|
||||
</NButton>
|
||||
<NUpload
|
||||
class="w-auto"
|
||||
:key="trainFiles.length?'train_'+trainFiles.length+1:'train'"
|
||||
class="w-auto"
|
||||
accept="image/*,.pdf,.docx,.xlsx,.pptx"
|
||||
:default-upload="false"
|
||||
:show-file-list="false"
|
||||
@@ -481,13 +481,13 @@ onMounted(async () => {
|
||||
class="text-11px flex items-center gap-2 border py-0.5 px-1.5 rounded-md text-[#17407F] border-[#ACC6E5] bg-[#EAF0F9]"
|
||||
>
|
||||
<Icon icon="akar-icons:file" class="size-12px" />
|
||||
{{file.file_name}}
|
||||
{{ file.file_name }}
|
||||
<NButton text type="primary" class="text-11px" @click="preview(file)">预览</NButton>
|
||||
<NButton text type="primary" class="text-11px" @click="downloadFile(file,'pssr')">下载</NButton>
|
||||
<NPopconfirm
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="removeFileReal('4', Number(fileIndex))"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -503,8 +503,8 @@ onMounted(async () => {
|
||||
下载PSSR检查表
|
||||
</NButton>
|
||||
<NUpload
|
||||
class="w-auto"
|
||||
:key="pssrFiles.length?'pssr_'+pssrFiles.length+1:'pssr'"
|
||||
class="w-auto"
|
||||
accept="image/*,.pdf,.docx,.xlsx,.pptx"
|
||||
:default-upload="false"
|
||||
:show-file-list="false"
|
||||
@@ -551,13 +551,13 @@ onMounted(async () => {
|
||||
class="text-11px flex items-center gap-2 border py-0.5 px-1.5 rounded-md text-[#17407F] border-[#ACC6E5] bg-[#EAF0F9]"
|
||||
>
|
||||
<Icon icon="akar-icons:file" class="size-12px" />
|
||||
{{file.file_name}}
|
||||
{{ file.file_name }}
|
||||
<NButton text type="primary" class="text-11px" @click="preview(file)">预览</NButton>
|
||||
<NButton text type="primary" class="text-11px" @click="downloadFile(file,'accept')">下载</NButton>
|
||||
<NPopconfirm
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="removeFileReal('5', Number(fileIndex))"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -573,8 +573,8 @@ onMounted(async () => {
|
||||
下载验收表
|
||||
</NButton>
|
||||
<NUpload
|
||||
class="w-auto"
|
||||
:key="acceptFiles.length?'accept_'+acceptFiles.length+1:'accept'"
|
||||
class="w-auto"
|
||||
accept="image/*,.pdf,.docx,.xlsx,.pptx"
|
||||
:default-upload="false"
|
||||
:show-file-list="false"
|
||||
@@ -622,7 +622,7 @@ onMounted(async () => {
|
||||
<tbody>
|
||||
<tr v-for="(item, index) in list" :key="index">
|
||||
<td>
|
||||
<p>{{item.doc_name}}</p>
|
||||
<p>{{ item.doc_name }}</p>
|
||||
<div v-if="item.attachments.length" class="flex flex-wrap gap-2">
|
||||
<div
|
||||
v-for="(file, fileIndex) in item.attachments"
|
||||
@@ -630,13 +630,13 @@ onMounted(async () => {
|
||||
class="text-11px flex items-center gap-2 border py-0.5 px-1.5 rounded-md text-[#17407F] border-[#ACC6E5] bg-[#EAF0F9]"
|
||||
>
|
||||
<Icon icon="akar-icons:file" class="size-12px" />
|
||||
{{file.file_name}}
|
||||
{{ file.file_name }}
|
||||
<NButton text type="primary" class="text-11px" @click="preview(file)">预览</NButton>
|
||||
<NButton text type="primary" class="text-11px" @click="downloadFile(file,'close')">下载</NButton>
|
||||
<NPopconfirm
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="removeFileReal(item.doc_name, Number(fileIndex), Number(index))"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -657,8 +657,8 @@ onMounted(async () => {
|
||||
<div v-if="item.status === 1" class="flex justify-center gap-2">
|
||||
<NButton size="small" class="text-xs" @click="openFileList(Number(index))">从变更附件选择</NButton>
|
||||
<NUpload
|
||||
class="w-auto"
|
||||
:key="item.id"
|
||||
class="w-auto"
|
||||
accept="image/*,.pdf,.docx,.xlsx,.pptx"
|
||||
:default-upload="false"
|
||||
:show-file-list="false"
|
||||
@@ -697,12 +697,12 @@ onMounted(async () => {
|
||||
<p class="text-xs leading-relaxed text-slate-400">审批链:{{ approvalFlowText }}。专业会签人由申请表「涉及专业」勾选自动增减,可在此调整人选;重要变更自动追加安全审查与分管领导终批。</p>
|
||||
<div v-for="(s, idx) in flowList" :key="s.id" class="rounded-lg border border-slate-100 bg-slate-50/40 p-3">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<NTag type="info" size="small">{{Number(idx)+1}}</NTag>
|
||||
<p class="text-sm">{{s.name}}</p>
|
||||
<NTag type="info" size="small">{{ Number(idx)+1 }}</NTag>
|
||||
<p class="text-sm">{{ s.name }}</p>
|
||||
<NCheckbox :checked="s.countersign" size="small" @update:checked="(v) => setStepCountersign(s, v)">
|
||||
<span class="text-xs text-slate-500">专业会签步骤</span>
|
||||
</NCheckbox>
|
||||
<NButton ghost type="primary" size="tiny" @click="togglePicker(s)" title="添加预设人员" class="ml-auto">
|
||||
<NButton ghost type="primary" size="tiny" title="添加预设人员" class="ml-auto" @click="togglePicker(s)">
|
||||
<Icon icon="ic:round-plus" class="size-16px" />
|
||||
</NButton>
|
||||
</div>
|
||||
@@ -714,11 +714,13 @@ onMounted(async () => {
|
||||
<span class="shrink-0 truncate text-xs font-medium text-slate-700">{{ m.user_name }}</span>
|
||||
<template v-if="s.countersign">
|
||||
<span class="text-xs text-slate-400"><span class="text-red-500">*</span>专业:</span>
|
||||
<NSelect :value="m.specialty || null" clearable size="small" placeholder="请选择专业" class="w-28"
|
||||
<NSelect
|
||||
:value="m.specialty || null" clearable size="small" placeholder="请选择专业" class="w-28"
|
||||
:options="SPECIALTIES"
|
||||
@update:value="(v) => selectSpecialty(Number(idx), Number(mIdx), v)"
|
||||
/>
|
||||
<NCheckbox :checked="m.is_sign" size="small"
|
||||
<NCheckbox
|
||||
:checked="m.is_sign" size="small"
|
||||
:checked-value="1"
|
||||
:unchecked-value="0"
|
||||
@update:checked="(v) => selectSign(Number(idx), Number(mIdx), v)"
|
||||
@@ -726,16 +728,18 @@ onMounted(async () => {
|
||||
<span class="text-xs text-slate-500">必须参与会签</span>
|
||||
</NCheckbox>
|
||||
</template>
|
||||
<NButton text type="error" @click="delMember(s, m.user_id)" title="删除该人员">
|
||||
<NButton text type="error" title="删除该人员" @click="delMember(s, m.user_id)">
|
||||
<Icon icon="iconamoon:trash" class="size-16px" />
|
||||
</NButton>
|
||||
</div>
|
||||
<p v-if="s.countersign && s.members.length" class="text-[11px] leading-5 text-slate-400">
|
||||
必须参与会签:勾选的人员必须参与专业会签,未勾选的人员为可选会签(按需参加)
|
||||
</p>
|
||||
<NCascader v-if="pickerStepId === s.id" :value="pick" :options="memberList"
|
||||
<NCascader
|
||||
v-if="pickerStepId === s.id" :value="pick" :options="memberList"
|
||||
placeholder="请选择人员" size="small" check-strategy="child" :show-path="false" expand-trigger="click"
|
||||
class="w-56" :on-update:value="(v) => addMember(s, v)" />
|
||||
class="w-56" :on-update:value="(v) => addMember(s, v)"
|
||||
/>
|
||||
|
||||
<span v-if="s.members.length === 0" class="text-xs leading-7 text-slate-300">未预设</span>
|
||||
</div>
|
||||
@@ -795,13 +799,13 @@ onMounted(async () => {
|
||||
<span>上传时间:{{ previewFile?.created_at }}</span>
|
||||
<span v-if="previewFile?.version">{{ `版本:${previewFile?.version}(受控)` }}</span>
|
||||
</div>
|
||||
<previewComponent v-if="previewFile" :previewFile="previewFile" />
|
||||
<PreviewComponent v-if="previewFile" :preview-file="previewFile" />
|
||||
</div>
|
||||
</template>
|
||||
</NModal>
|
||||
</NCard>
|
||||
</NSpin>
|
||||
</NSpace>
|
||||
</NSpace>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -9,7 +9,7 @@ import { AiError, aiTypeJudge } from "@/service/api/ai";
|
||||
import { systemConfigApi, peopleListApi, templateListApi } from '@/service/api/system';
|
||||
import { getChangeDetailApi, urgeApi } from '@/service/api/change';
|
||||
import { myTasksDisposalSubmitApi, myTasksAddItemApi } from '@/service/api/myTasks';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { tagTextColor, tagBgColor, tagBorderColor, downloadFileFun } from '@/uti
|
||||
import { AiError, aiTypeJudge } from "@/service/api/ai";
|
||||
import { systemConfigApi } from '@/service/api/system';
|
||||
import { getChangeDetailApi, urgeApi } from '@/service/api/change';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ref, onMounted, h } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { NButton, NTag, NDropdown, useDialog } from 'naive-ui';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
import { downloadFileFun } from '@/utils/common';
|
||||
import {
|
||||
docTreeListApi,
|
||||
|
||||
@@ -3,7 +3,7 @@ import { ref, onMounted, h } from 'vue';
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { formatTimestamp, getTimeRangeStamp, downloadFileFun } from "@/utils/common";
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
import { systemConfigApi } from '@/service/api/system';
|
||||
import { orgListApi } from '@/service/api/user';
|
||||
import { docArchiveTreeListApi, docArchiveDetailsApi } from "@/service/api/doc";
|
||||
|
||||
@@ -6,7 +6,7 @@ import { useRouterPush } from '@/hooks/common/router';
|
||||
import { getColorWithOpacity, tagTextColor, tagBgColor, tagBorderColor, downloadFileFun } from '@/utils/common';
|
||||
import { systemConfigApi } from "@/service/api/system";
|
||||
import { homeSafeApi } from "@/service/api/statistics";
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
const { routerPushByKey } = useRouterPush();
|
||||
|
||||
@@ -8,7 +8,7 @@ import { localStg } from '@/utils/storage';
|
||||
import { AiError, aiTypeJudge, aiLevelScore, aiApplication } from "@/service/api/ai";
|
||||
import { uploadFileApi, deleteFileApi } from "@/service/api/file";
|
||||
import Footer from './footer.vue'
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
@@ -232,7 +232,7 @@ const filterMembersBySpecialties = (steps: any, specialties: string[]) => {
|
||||
}
|
||||
// 更新当前模板步骤
|
||||
const updateCurrentTemplate = () => {
|
||||
let template = props.templateList.find((item: any) =>
|
||||
const template = props.templateList.find((item: any) =>
|
||||
item.level === form.value?.change_level &&
|
||||
item.category === form.value?.change_type &&
|
||||
item.duration === form.value?.duration_type
|
||||
@@ -266,7 +266,7 @@ const typeAi = ref<{ type: string; confidence: number; conclusion: string; hit_r
|
||||
const typeAiLoading = ref<boolean>(false);
|
||||
// 打开变更类型抽屉
|
||||
const openTypeSheet = async () => {
|
||||
let form = props.formInfo;
|
||||
const form = props.formInfo;
|
||||
if (!form?.description) {
|
||||
return window.$message?.warning("缺少变更描述,请先在 [变更预识别] 里面输入变更描述");
|
||||
}
|
||||
@@ -296,7 +296,7 @@ const levelAiBasis = ref<string[]>([]);
|
||||
const levelAiLoading = ref<boolean>(false);
|
||||
// 打开等级判定表抽屉
|
||||
const openLevelSheet = async () => {
|
||||
let form = props.formInfo;
|
||||
const form = props.formInfo;
|
||||
if (!form?.description && props.isAiOpen) {
|
||||
return window.$message?.warning("缺少变更描述,请先在 [变更预识别] 里面输入变更描述");
|
||||
}
|
||||
@@ -305,7 +305,7 @@ const openLevelSheet = async () => {
|
||||
};
|
||||
// 使用AI 评分
|
||||
const useAiLevel = async () => {
|
||||
let form = props.formInfo;
|
||||
const form = props.formInfo;
|
||||
if (levelAiLoading.value) return;
|
||||
levelAiLoading.value = true;
|
||||
try {
|
||||
@@ -447,7 +447,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="p-4">
|
||||
<div class="p-4">
|
||||
<div class="space-y-4 scroll">
|
||||
<!-- 申请部门 / 申请人 -->
|
||||
<div class="grid gap-4 grid-cols-2">
|
||||
@@ -482,7 +482,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<!-- 预期效果 -->
|
||||
<div class="flex gap-3">
|
||||
<div class="w-24 shrink-0 pt-2 text-sm font-medium text-slate-600 text-right">预期效果</div>
|
||||
<NInput type="textarea" v-model:value="form.effect" rows="2" placeholder="" />
|
||||
<NInput v-model:value="form.effect" type="textarea" rows="2" placeholder="" />
|
||||
</div>
|
||||
<!-- 主要变更内容 -->
|
||||
<div class="flex gap-3">
|
||||
@@ -494,8 +494,8 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<NPopconfirm
|
||||
v-if="form.main_changes.length > 1"
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="form.main_changes.splice(i, 1)"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -521,8 +521,8 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<NPopconfirm
|
||||
v-if="form.related_changes.length > 1"
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="form.related_changes.splice(i, 1)"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -546,7 +546,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<div class="flex flex-1 items-center gap-4 rounded-lg bg-slate-50 px-3 py-2">
|
||||
<NRadioGroup v-model:value="form.change_type">
|
||||
<div class="flex gap-x-2">
|
||||
<NRadio v-for="t in props.typeList" :key="t.value" :value="t.value">{{t.label}}</NRadio>
|
||||
<NRadio v-for="t in props.typeList" :key="t.value" :value="t.value">{{ t.label }}</NRadio>
|
||||
</div>
|
||||
</NRadioGroup>
|
||||
<NButton v-if="props.isAiOpen" text type="primary" class="ml-auto text-xs hover:underline" @click="openTypeSheet">
|
||||
@@ -561,7 +561,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<div class="flex flex-1 items-center gap-4 rounded-lg bg-slate-50 px-3 py-2">
|
||||
<NRadioGroup v-model:value="form.change_level" disabled>
|
||||
<div class="flex gap-x-2">
|
||||
<NRadio v-for="t in props.levelList" :key="t.value" :value="t.value">{{t.label}}</NRadio>
|
||||
<NRadio v-for="t in props.levelList" :key="t.value" :value="t.value">{{ t.label }}</NRadio>
|
||||
</div>
|
||||
</NRadioGroup>
|
||||
<NButton text type="primary" class="ml-auto text-xs hover:underline" @click="openLevelSheet">
|
||||
@@ -588,14 +588,15 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<div class="flex gap-3">
|
||||
<div class="w-24 shrink-0 pt-2 text-sm font-medium text-slate-600 text-right">风险分析</div>
|
||||
<div class="flex flex-1 flex-wrap items-center gap-2 rounded-lg bg-slate-50 px-3 py-2">
|
||||
<NButton size="small" round v-for="t in RISK_TOOLS_FORM" :key="t.key" @click="toggleTool(t)" title="点击选用 / 取消;AI 辅助分析在各工具插件内使用"
|
||||
class="text-sm"
|
||||
<NButton
|
||||
v-for="t in RISK_TOOLS_FORM" :key="t.key" size="small" round title="点击选用 / 取消;AI 辅助分析在各工具插件内使用" class="text-sm"
|
||||
:ghost="form.risk_tools?.includes(t.key) ? false : true"
|
||||
:type="form.risk_tools?.includes(t.key) ? 'primary' : 'default'"
|
||||
@click="toggleTool(t)"
|
||||
>
|
||||
{{ t.label }}
|
||||
</NButton>
|
||||
<NButton type="primary" ghost dashed size="small" round @click="recommendTools" class="text-xs">
|
||||
<NButton type="primary" ghost dashed size="small" round class="text-xs" @click="recommendTools">
|
||||
按等级重新推荐
|
||||
</NButton>
|
||||
</div>
|
||||
@@ -623,7 +624,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<div class="w-24 shrink-0 pt-2 text-sm font-medium text-slate-600 text-right">所需材料</div>
|
||||
<div class="flex-1 space-y-2">
|
||||
<div class="text-[11px] text-slate-400">施工所需材料(生成变更申请表时系统自动生成,支持手动修改)</div>
|
||||
<NInput type="textarea" v-model:value="form.materials" rows="4" placeholder="点击「生成变更申请单」后由系统按变更内容自动生成,也可直接填写" />
|
||||
<NInput v-model:value="form.materials" type="textarea" rows="4" placeholder="点击「生成变更申请单」后由系统按变更内容自动生成,也可直接填写" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 资料上传 -->
|
||||
@@ -631,9 +632,9 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<div class="w-24 shrink-0 pt-2 text-sm font-medium text-slate-600 text-right">资料上传</div>
|
||||
<div class="flex flex-1 flex-wrap items-center gap-2 rounded-lg border border-dashed p-3">
|
||||
<div
|
||||
class="relative"
|
||||
:style="{'--theme-color':themeStore.themeColor}"
|
||||
v-for="(f,index) in uploadFile" :key="f.id"
|
||||
v-for="(f,index) in uploadFile"
|
||||
:key="f.id"
|
||||
class="relative" :style="{'--theme-color':themeStore.themeColor}"
|
||||
>
|
||||
<div
|
||||
class="text-xs cursor-pointer flex items-center border py-1.5 px-2 rounded-md hover:border-[var(--theme-color)] hover:text-[var(--theme-color)]"
|
||||
@@ -644,8 +645,8 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
</div>
|
||||
<NPopconfirm
|
||||
positive-text="确定"
|
||||
:positiveButtonProps="{ size: 'tiny' }"
|
||||
:negativeButtonProps="{ size: 'tiny' }"
|
||||
:positive-button-props="{ size: 'tiny' }"
|
||||
:negative-button-props="{ size: 'tiny' }"
|
||||
@positive-click="removeFile(index)"
|
||||
>
|
||||
<template #trigger>
|
||||
@@ -691,30 +692,30 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
</div>
|
||||
<div v-if="signers && signers.length" class="mt-1.5 flex flex-wrap items-center gap-1.5 text-xs text-slate-500">
|
||||
<Icon icon="lucide:users" class="size-12px" />已联动专业会签:
|
||||
<NTag size="small" type="info" v-for="(p, d) in signers" :key="d">{{ p?.member?.specialty }} · {{ p?.member?.user_name }}{{p?.stepName ? ` (${p.stepName})` : ''}}</NTag>
|
||||
<NTag v-for="(p, d) in signers" :key="d" size="small" type="info">{{ p?.member?.specialty }} · {{ p?.member?.user_name }}{{ p?.stepName ? ` (${p.stepName})` : '' }}</NTag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer
|
||||
</div>
|
||||
<Footer
|
||||
ref="footerRef"
|
||||
:type="props.type"
|
||||
:currentId="props.currentId"
|
||||
:current-id="props.currentId"
|
||||
:title="props.title"
|
||||
:isAiOpen="props.isAiOpen"
|
||||
:currentForm="form"
|
||||
:is-ai-open="props.isAiOpen"
|
||||
:current-form="form"
|
||||
:confirmed="props.confirmed"
|
||||
:members="props.members"
|
||||
:steps="currentSteps"
|
||||
@save="saveDraft"
|
||||
@submit="submitConfirm"
|
||||
@confirmTab="confirmTab"
|
||||
@confirm-tab="confirmTab"
|
||||
@regenerate="onRegenerate"
|
||||
@update:steps="updateSteps"
|
||||
/>
|
||||
<!-- 侧边抽屉:AI 类型判定 / 等级判定表 -->
|
||||
<NDrawer :show="sheet !== ''" @update:show="(v) => !v && (sheet = '')" placement="right" :width="sheet === 'level' ? '45rem' : '28rem'" :auto-focus="false">
|
||||
/>
|
||||
<!-- 侧边抽屉:AI 类型判定 / 等级判定表 -->
|
||||
<NDrawer :show="sheet !== ''" placement="right" :width="sheet === 'level' ? '45rem' : '28rem'" :auto-focus="false" @update:show="(v) => !v && (sheet = '')">
|
||||
<NDrawerContent>
|
||||
<template #header>
|
||||
<div v-if="sheet === 'type'" class="text-base font-semibold text-slate-800">AI 变更类型判定说明</div>
|
||||
@@ -813,17 +814,17 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
</template>
|
||||
</div>
|
||||
</NDrawerContent>
|
||||
</NDrawer>
|
||||
</NDrawer>
|
||||
|
||||
<!-- 附件在线预览弹窗 -->
|
||||
<NModal
|
||||
<!-- 附件在线预览弹窗 -->
|
||||
<NModal
|
||||
:show="previewFile !== null"
|
||||
preset="card"
|
||||
:auto-focus="false"
|
||||
:style="{ width: '80%', height: 'auto' }"
|
||||
:segmented="{ content: true, footer: true }"
|
||||
@update:show="(v) => !v && (previewFile = null)"
|
||||
>
|
||||
>
|
||||
<template #header>
|
||||
<div class="flex items-center gap-2 text-base font-semibold text-slate-800">
|
||||
<Icon icon="akar-icons:file" class="size-18px" /> {{ previewFile?.file_name }}
|
||||
@@ -836,7 +837,7 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<span>上传时间:{{ previewFile?.created_at }}</span>
|
||||
<span v-if="previewFile?.version">{{ `版本:${previewFile?.version}(受控)` }}</span>
|
||||
</div>
|
||||
<previewComponent v-if="previewFile" :previewFile="previewFile" />
|
||||
<PreviewComponent v-if="previewFile" :preview-file="previewFile" />
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
@@ -847,8 +848,9 @@ defineExpose({form, questions, applyAiResult, generateLevel: useAiLevel})
|
||||
<NButton size="small" type="primary" @click="previewFile = null">关闭</NButton>
|
||||
</div>
|
||||
</template>
|
||||
</NModal>
|
||||
</NModal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
:deep(.n-radio) {
|
||||
display: flex;
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Icon } from '@iconify/vue'
|
||||
import { useThemeStore } from '@/store/modules/theme';
|
||||
import { useRouterPush } from '@/hooks/common/router';
|
||||
import { formatTimestamp, getTimeRangeStamp, downloadFileFun } from '@/utils/common';
|
||||
import previewComponent from '@/components/previewFile/index.vue'
|
||||
import PreviewComponent from '@/components/previewFile/index.vue'
|
||||
import { pssrListApi } from '@/service/api/pssr';
|
||||
|
||||
const themeStore = useThemeStore();
|
||||
|
||||
Reference in New Issue
Block a user