|
|
@@ -0,0 +1,332 @@
|
|
|
+<template>
|
|
|
+ <div class="p-2">
|
|
|
+ <el-card shadow="always" style="height: 50px">
|
|
|
+ <div style="display: flex; justify-content: space-between">
|
|
|
+ <div>
|
|
|
+ <!-- <el-button v-if="submitButtonShow" :loading="buttonLoading" type="info" @click="submitForm('draft')">暂存</el-button>-->
|
|
|
+ <!-- <el-button v-if="submitButtonShow" :loading="buttonLoading" type="primary" @click="submitForm('submit')">提 交</el-button>-->
|
|
|
+ <el-button v-if="approvalButtonShow" :loading="buttonLoading" type="primary" @click="approvalVerifyOpen"> 审批
|
|
|
+ </el-button>
|
|
|
+ <el-button v-if="itemPushBase && itemPushBase.id && itemPushBase.status !== 'draft'" type="primary"
|
|
|
+ @click="handleApprovalRecord">
|
|
|
+ 流程进度
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ <div>
|
|
|
+ <el-button style="float: right" @click="goBack()">返回</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <!-- push base -->
|
|
|
+ <el-card shadow="always" class="custom-card">
|
|
|
+ <div v-if="loading" class="loading-text">数据加载中...</div>
|
|
|
+ <div v-else class="card-content">
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>名称:</strong>
|
|
|
+ <el-text>{{ itemPushBase.name }}</el-text>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>类型:</strong>
|
|
|
+ <el-text v-for="dict in smsb_push_type" :key="dict.value" :label="dict.label" :value="dict.value">
|
|
|
+ <div v-if="parseInt(dict.value) === itemPushBase.itemType">
|
|
|
+ {{ dict.label }}
|
|
|
+ </div>
|
|
|
+ </el-text>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>优先级:</strong>
|
|
|
+ <el-text v-for="dict in smsb_push_level" :key="dict.value" :label="dict.label" :value="dict.value">
|
|
|
+ <div v-if="parseInt(dict.value) === itemPushBase.level">
|
|
|
+ {{ dict.label }}
|
|
|
+ </div>
|
|
|
+ </el-text>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>发布时间:</strong>
|
|
|
+ <el-text>{{ itemPushBase.createTime }}</el-text>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>发布人:</strong>
|
|
|
+ <el-text>{{ itemPushBase.createUser }}</el-text>
|
|
|
+ </div>
|
|
|
+ <div class="info-item">
|
|
|
+ <strong>状态:</strong>
|
|
|
+ <el-text v-for="dict in smsb_push_state" :key="dict.value" :label="dict.label" :value="dict.value">
|
|
|
+ <div v-if="dict.value === itemPushBase.status">
|
|
|
+ {{ dict.label }}
|
|
|
+ </div>
|
|
|
+ </el-text>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <!-- deviceList timeList sourceList -->
|
|
|
+ <el-card shadow="always" class="custom-card" style="height: 70vh; overflow-y: auto; margin-top: 10px">
|
|
|
+ <div class="card-section">
|
|
|
+ <!-- 第一部分 时间排期 -->
|
|
|
+ <div class="section-content">
|
|
|
+ <div v-for="(item, index) in timeList" :key="index">{{ item.start }} - {{ item.end }}</div>
|
|
|
+ </div>
|
|
|
+ <!-- 第二部分内容 -->
|
|
|
+ <div class="section-content">
|
|
|
+ <el-table v-loading="loading" :data="deviceList">
|
|
|
+ <el-table-column label="设备名称" align="left" prop="name" :show-overflow-tooltip="true"/>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ <!-- 第三部分内容 -->
|
|
|
+ <div class="section-content">
|
|
|
+ <el-table v-loading="loading" :data="sourceList">
|
|
|
+ <el-table-column label="原名" align="left" prop="originalName" width="150" :show-overflow-tooltip="true"/>
|
|
|
+ <el-table-column label="类型" align="center" prop="type" width="80">
|
|
|
+ <template #default="scope">
|
|
|
+ <dict-tag :options="smsb_source_type" :value="scope.row.type"/>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="大小" align="center" prop="size"/>
|
|
|
+ <el-table-column label="截图" align="center" prop="screenshot">
|
|
|
+ <template #default="scope">
|
|
|
+ <image-preview :src="scope.row.screenshot" style="width: 40px; height: 40px; cursor: pointer"/>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+ <!-- 提交组件 -->
|
|
|
+ <SubmitVerifySmsb ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback"/>
|
|
|
+ <!-- 审批记录 -->
|
|
|
+ <approvalRecordSmsb ref="approvalRecordRef"/>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup name="Leave" lang="ts">
|
|
|
+import {addLeave, updateLeave} from '@/api/workflow/leave';
|
|
|
+import {LeaveVO} from '@/api/workflow/leave/types';
|
|
|
+import {startWorkFlow} from '@/api/workflow/task';
|
|
|
+import SubmitVerifySmsb from '@/views/smsb/itemReview/submitVerifySmsb.vue';
|
|
|
+import ApprovalRecordSmsb from '@/views/smsb/itemReview/approvalRecordSmsb.vue';
|
|
|
+import {AxiosResponse} from 'axios';
|
|
|
+import {StartProcessBo} from '@/api/workflow/workflowCommon/types';
|
|
|
+import {getItemPushReview} from '@/api/smsb/source/item_push';
|
|
|
+import {ItemPushForm, ItemPushQuery, ItemPushTimeRangeVO, ItemPushVO} from '@/api/smsb/source/item_push_type';
|
|
|
+import {DeviceVO} from '@/api/smsb/device/device_type';
|
|
|
+import {MinioDataVO} from '@/api/smsb/source/minioData_type';
|
|
|
+import {ElTable} from 'element-plus';
|
|
|
+
|
|
|
+const {proxy} = getCurrentInstance() as ComponentInternalInstance;
|
|
|
+const {smsb_push_type, smsb_push_level, smsb_push_state, smsb_source_type} = toRefs<any>(
|
|
|
+ proxy?.useDict('smsb_push_type', 'smsb_push_level', 'smsb_push_state', 'smsb_source_type')
|
|
|
+);
|
|
|
+const approvalButtonShow = ref(false);
|
|
|
+const buttonLoading = ref(false);
|
|
|
+const loading = ref(true);
|
|
|
+//路由参数
|
|
|
+const routeParams = ref<Record<string, any>>({});
|
|
|
+const itemPushBase = ref<ItemPushVO>();
|
|
|
+const deviceList = ref<DeviceVO[]>([]);
|
|
|
+const sourceList = ref<MinioDataVO[]>([]);
|
|
|
+const timeList = ref<ItemPushTimeRangeVO[]>([]);
|
|
|
+
|
|
|
+//提交组件
|
|
|
+const submitVerifyRef = ref<InstanceType<typeof SubmitVerifySmsb>>();
|
|
|
+//审批记录组件
|
|
|
+const approvalRecordRef = ref<InstanceType<typeof ApprovalRecordSmsb>>();
|
|
|
+
|
|
|
+const itemPushFormRef = ref<ElFormInstance>();
|
|
|
+
|
|
|
+const submitFormData = ref<StartProcessBo>({
|
|
|
+ businessKey: '',
|
|
|
+ tableName: '',
|
|
|
+ variables: {}
|
|
|
+});
|
|
|
+const taskVariables = ref<Record<string, any>>({});
|
|
|
+
|
|
|
+const initFormData: ItemPushForm = {
|
|
|
+ name: undefined,
|
|
|
+ level: undefined,
|
|
|
+ itemType: undefined,
|
|
|
+ deviceIds: undefined,
|
|
|
+ itemIds: undefined,
|
|
|
+ dateRange: undefined,
|
|
|
+ weekDays: ['1', '2', '3', '4', '5', '6', '7'],
|
|
|
+ timeRange: [],
|
|
|
+ status: undefined
|
|
|
+};
|
|
|
+const data = reactive<PageData<ItemPushForm, ItemPushQuery>>({
|
|
|
+ form: {...initFormData},
|
|
|
+ queryParams: {
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10
|
|
|
+ },
|
|
|
+ rules: {}
|
|
|
+});
|
|
|
+
|
|
|
+const {form, rules} = toRefs(data);
|
|
|
+
|
|
|
+/** 表单重置 */
|
|
|
+const reset = () => {
|
|
|
+ form.value = {...initFormData}
|
|
|
+};
|
|
|
+
|
|
|
+/** 获取详情 */
|
|
|
+const getInfo = () => {
|
|
|
+ loading.value = true;
|
|
|
+ buttonLoading.value = false;
|
|
|
+ nextTick(async () => {
|
|
|
+ const res = await getItemPushReview(routeParams.value.id);
|
|
|
+ itemPushBase.value = res.data;
|
|
|
+ deviceList.value = res.data.deviceList;
|
|
|
+ sourceList.value = res.data.resourceList;
|
|
|
+ timeList.value = res.data.timeList;
|
|
|
+ loading.value = false;
|
|
|
+ buttonLoading.value = false;
|
|
|
+ if (itemPushBase.value.status && itemPushBase.value.status === 'waiting') {
|
|
|
+ approvalButtonShow.value = true;
|
|
|
+ } else {
|
|
|
+ approvalButtonShow.value = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+};
|
|
|
+
|
|
|
+/** 提交按钮 */
|
|
|
+const submitForm = (status: string) => {
|
|
|
+ try {
|
|
|
+ itemPushFormRef.value?.validate(async (valid: boolean) => {
|
|
|
+ if (valid) {
|
|
|
+ buttonLoading.value = true;
|
|
|
+ let res: AxiosResponse<LeaveVO>;
|
|
|
+ if (form.value.id) {
|
|
|
+ res = await updateLeave(form.value);
|
|
|
+ } else {
|
|
|
+ res = await addLeave(form.value);
|
|
|
+ }
|
|
|
+ form.value = res.data;
|
|
|
+ if (status === 'draft') {
|
|
|
+ buttonLoading.value = false;
|
|
|
+ proxy?.$modal.msgSuccess('暂存成功');
|
|
|
+ proxy.$tab.closePage(proxy.$route);
|
|
|
+ proxy.$router.go(-1);
|
|
|
+ } else {
|
|
|
+ await handleStartWorkFlow(res.data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } finally {
|
|
|
+ buttonLoading.value = false;
|
|
|
+ goBack();
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+//提交申请
|
|
|
+const handleStartWorkFlow = async (data: LeaveVO) => {
|
|
|
+ try {
|
|
|
+ submitFormData.value.tableName = 'test_leave';
|
|
|
+ submitFormData.value.businessKey = data.id;
|
|
|
+ //流程变量
|
|
|
+ taskVariables.value = {
|
|
|
+ entity: data,
|
|
|
+ leaveDays: data.leaveDays,
|
|
|
+ userList: ['1', '3'],
|
|
|
+ userList2: ['1', '3']
|
|
|
+ };
|
|
|
+ submitFormData.value.variables = taskVariables.value;
|
|
|
+ const resp = await startWorkFlow(submitFormData.value);
|
|
|
+ if (submitVerifyRef.value) {
|
|
|
+ buttonLoading.value = false;
|
|
|
+ submitVerifyRef.value.openDialog(resp.data.taskId);
|
|
|
+ }
|
|
|
+ } finally {
|
|
|
+ buttonLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+//审批记录
|
|
|
+const handleApprovalRecord = () => {
|
|
|
+ approvalRecordRef.value.init(itemPushBase.value.id);
|
|
|
+};
|
|
|
+//提交回调
|
|
|
+const submitCallback = async () => {
|
|
|
+ await proxy.$tab.closePage(proxy.$route);
|
|
|
+ proxy.$router.go(-1);
|
|
|
+};
|
|
|
+
|
|
|
+//返回
|
|
|
+const goBack = () => {
|
|
|
+ proxy.$tab.closePage(proxy.$route);
|
|
|
+ proxy.$router.go(-1);
|
|
|
+};
|
|
|
+//审批
|
|
|
+const approvalVerifyOpen = async () => {
|
|
|
+ submitVerifyRef.value.openDialog(routeParams.value.taskId);
|
|
|
+};
|
|
|
+//校验提交按钮是否显示
|
|
|
+const submitButtonShow = computed(() => {
|
|
|
+ return (
|
|
|
+ routeParams.value.type === 'add' ||
|
|
|
+ (routeParams.value.type === 'update' &&
|
|
|
+ form.value.status &&
|
|
|
+ (form.value.status === 'draft' || form.value.status === 'cancel' || form.value.status === 'back'))
|
|
|
+ );
|
|
|
+});
|
|
|
+
|
|
|
+//校验审批按钮是否显示
|
|
|
+/*const approvalButtonShow = computed(() => {
|
|
|
+ return routeParams.value.type === 'approval';
|
|
|
+});*/
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ nextTick(async () => {
|
|
|
+ routeParams.value = proxy.$route.query;
|
|
|
+ reset();
|
|
|
+ loading.value = false;
|
|
|
+ if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') {
|
|
|
+ getInfo();
|
|
|
+ }
|
|
|
+ });
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.custom-card {
|
|
|
+ margin-top: 20px;
|
|
|
+ border-radius: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.card-content {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ justify-content: space-between;
|
|
|
+}
|
|
|
+
|
|
|
+.info-item {
|
|
|
+ flex: 1 1 16%; /* 每个项目至少占容器的16%,允许伸缩 */
|
|
|
+ margin: 5px 0;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding-right: 10px; /* 避免内容重叠 */
|
|
|
+}
|
|
|
+
|
|
|
+.info-item strong {
|
|
|
+ display: block; /* 将 strong 标签换行,以便内容更易读 */
|
|
|
+}
|
|
|
+
|
|
|
+.loading-text {
|
|
|
+ padding: 10px;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #909399;
|
|
|
+}
|
|
|
+
|
|
|
+.card-section {
|
|
|
+ display: flex;
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.section-content {
|
|
|
+ flex: 1;
|
|
|
+ padding: 10px;
|
|
|
+ border-right: 1px solid #ebeef5; /* 可选:添加分隔线 */
|
|
|
+}
|
|
|
+
|
|
|
+.section-content:last-child {
|
|
|
+ border-right: none; /* 移除最后一个元素的分隔线 */
|
|
|
+}
|
|
|
+</style>
|