| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236 |
- <!--
- TODO: 优化项
- 会先加载流程信息 再加载业务表单信息
- -->
- <script setup lang="ts">
- import type { ApprovalType } from './type';
- import type { FlowInfoResponse } from '#/api/workflow/instance/model';
- import type { TaskInfo } from '#/api/workflow/task/model';
- import { computed, ref, watch } from 'vue';
- import { Fallback, VbenAvatar } from '@vben/common-ui';
- import { DictEnum } from '@vben/constants';
- import { cn } from '@vben/utils';
- // import { Copy } from '@element-plus/icons-vue';
- import { CopyDocument } from '@element-plus/icons-vue';
- import { useClipboard } from '@vueuse/core';
- import { ElCard, ElMessage, ElTabPane, ElTabs } from 'element-plus';
- import { renderDict } from '#/utils/render';
- import { FlowActions } from './actions';
- import ApprovalDetails from './approval-details.vue';
- defineOptions({
- name: 'ApprovalPanel',
- inheritAttrs: false,
- });
- const props = defineProps<Props>();
- /**
- * 下面按钮点击后会触发的事件
- */
- defineEmits<{ reload: [] }>();
- interface Props {
- /**
- * 行数据(list)的info
- */
- task?: TaskInfo;
- /**
- * 工单详情
- */
- workOrderDetail?: any;
- /**
- * 审批类型
- */
- type: ApprovalType;
- /**
- * 按钮权限(可选,外部传入覆盖内部计算)
- */
- buttonPermissions?: Record<string, boolean>;
- }
- /**
- * 目前的作用只为了获取按钮权限 因为list接口(行数据)获取为空
- */
- const onlyForBtnPermissionTask = ref<TaskInfo>();
- /**
- * 按钮权限
- */
- const buttonPermissions = computed(() => {
- // 如果外部传入了buttonPermissions,优先使用
- if (props.buttonPermissions) {
- return props.buttonPermissions;
- }
-
- const record: Record<string, boolean> = {};
- if (!onlyForBtnPermissionTask.value) {
- return record;
- }
- onlyForBtnPermissionTask.value.buttonList.forEach((item) => {
- record[item.code] = item.show;
- });
- return record;
- });
- const showFooter = computed(() => {
- if (props.type === 'readonly') {
- return false;
- }
- // 我发起的 && [已完成, 已作废] 不显示
- if (
- props.type === 'myself' &&
- ['finish', 'invalid'].includes(props.task?.flowStatus ?? '')
- ) {
- return false;
- }
- return true;
- });
- const currentFlowInfo = ref<FlowInfoResponse>();
- /**
- * card的loading状态
- */
- const loading = ref(false);
- async function handleLoadInfo(task: TaskInfo | undefined) {
- if (!task) {
- return null;
- }
- try {
- loading.value = true;
- /**
- * 不为审批不需要调用`getTaskByTaskId`接口
- */
- // if (props.type !== 'approve') {
- // const flowResp = await flowInfo(task.businessId);
- // currentFlowInfo.value = flowResp;
- // return;
- // }
- /**
- * getTaskByTaskId主要为了获取按钮权限 目前没有其他功能
- * 行数据(即props.task)获取的是没有按钮权限的
- */
- // const [flowResp, taskResp] = await Promise.all([
- // flowInfo(task.businessId),
- // getTaskByTaskId(task.id),
- // ]);
- // currentFlowInfo.value = flowResp;
- // onlyForBtnPermissionTask.value = taskResp;
- } catch (error) {
- console.error(error);
- } finally {
- loading.value = false;
- }
- }
- watch(() => props.task, handleLoadInfo);
- /**
- * 不加legacy在本地开发没有问题
- * 打包后在一些设备会无法复制 使用legacy来保证兼容性
- */
- const { copy } = useClipboard({ legacy: true });
- async function handleCopy(text: string) {
- await copy(text);
- ElMessage.success('复制成功');
- }
- </script>
- <template>
- <div :class="cn('thin-scrollbar', 'flex flex-1 overflow-y-hidden')">
- <ElCard
- v-if="workOrderDetail"
- :body-style="{ overflowY: 'auto', height: '100%' }"
- :loading="loading"
- class="thin-scrollbar flex-1 overflow-y-hidden"
- size="small"
- >
- <template #extra>
- <el-button size="small" @click="() => handleLoadInfo(workOrderDetail)">
- <div class="flex items-center justify-center">
- <span class="icon-[material-symbols--refresh] size-24px"></span>
- </div>
- </el-button>
- </template>
- <div class="flex flex-col gap-5 p-4">
- <div class="flex flex-col gap-3">
- <div class="flex items-center gap-2">
- <div class="text-2xl font-bold">
- {{ workOrderDetail.orderNo }}
- </div>
- <el-icon @click="() => handleCopy(workOrderDetail.orderNo)">
- <CopyDocument />
- </el-icon>
- <div>
- <component
- :is="renderDict(workOrderDetail.status, DictEnum.TICKET_STATUS)"
- />
- </div>
- </div>
- <div class="flex items-center gap-2">
- <VbenAvatar
- :alt="workOrderDetail?.createBy ?? ''"
- class="bg-primary size-[28px] rounded-full text-white"
- src=""
- />
- <span>{{ workOrderDetail.createBy }}</span>
- <div class="flex items-center opacity-50">
- <div class="flex items-center gap-1">
- <span class="icon-[bxs--category-alt] size-[16px]"></span>
- 流程分类: {{ workOrderDetail.ticketTypeName }}
- </div>
- <div class="flex items-center gap-1">
- <span class="icon-[mdi--clock-outline] size-[16px]"></span>
- 提交时间: {{ workOrderDetail.createTime }}
- </div>
- </div>
- </div>
- </div>
- <ElTabs class="flex-1">
- <ElTabPane key="1" label="工单详情">
- <ApprovalDetails
- :current-flow-info="currentFlowInfo"
- :work-order-detail="workOrderDetail"
- />
- </ElTabPane>
- <!-- <ElTabPane key="2" label="审批流程图">
- <FlowPreview :instance-id="currentFlowInfo.instanceId" />
- </ElTabPane> -->
- </ElTabs>
- </div>
- <!-- 固定底部 占位高度 -->
- <div class="h-[58px]"></div>
- <FlowActions
- v-if="showFooter"
- :type="type"
- :task="task"
- :work-order-detail="workOrderDetail"
- :button-permissions="buttonPermissions"
- @reload="$emit('reload')"
- />
- </ElCard>
- <slot v-else name="empty">
- <Fallback title="点击左侧选择" />
- </slot>
- </div>
- </template>
|