<!-- 设备借用申请详情 --> <script lang="ts" setup name="BorrowApplyDetail"> import { onMounted, reactive, ref } from 'vue' import type { Ref } from 'vue' import dayjs from 'dayjs' import type { FormInstance, FormRules } from 'element-plus' import { ElLoading, ElMessage, ElMessageBox } from 'element-plus' import { useRoute, useRouter } from 'vue-router' import SelectDeviceDialog from '@/views/device/receive/selectDeviceDialog.vue' import type { IdeviceList, IdeviceListQuery } from '@/views/device/receive/receive' import { toTreeList } from '@/utils/structure' import { SCHEDULE } from '@/utils/scheduleDict' import type { TableColumn } from '@/components/NormalTable/table_interface' import { failUpdateEquipmentApply, getReceiveApplyListDetail, saveAddReceiveApplyList, saveEditReceiveApplyList, submitReceiveApplyList, } from '@/api/device/receive' import type { userType } from '@/views/system/user/user-interface' import type { deptType } from '@/views/device/standingBook/standingBook-interface' import { getDeptTreeList } from '@/api/system/dept' import { getUserList } from '@/api/system/user' import { cancelApproval, fetchApproval, submitApproval } from '@/api/approval' import ApprovalRecord from '@/components/ApprovalRecord/ApprovalRecord.vue' import useUserStore from '@/store/modules/user' import ApprovalDialog from '@/components/Approval/ApprovalDialog.vue' const decisionItem = ref('') // 同意、驳回、拒绝按钮权限 const taskId = ref('') // 任务id,用于同意、驳回、拒绝审批 const processId = ref('') // 流程实例id const user = useUserStore() // 用户信息 const $route = useRoute() const approvalDialog = ref() // 审批对话框显隐 const typeValue = ref() // add、edit、detail const approvalStatus = ref() // 审批类型 const approvalStatusName = ref() // 审批类型名称 const useDeptList = ref<deptType[]>([]) // 部门列表 const usePersonList = ref<userType[]>([]) // 申请人列表(用户) const usePersonOptions = ref<userType[]>([]) // 申请人列表(用户)--模糊搜索数据 const applyPersonLoading = ref(false) const isMulti = ref(false) // 是否批量添加(允许多选) const selectIndex = ref() // 点击选择的index--点击第几行 const dialogSelectDiviceVisible = ref(false) // 控制选择设备对话框显隐 const textMap: { [key: string]: string } = { edit: '编辑', add: '新建', detail: '详情', }// 字典 // 选中的内容 const checkoutList = ref([]) // 表单数据 const form = ref({ taskId: '', // 任务id(审批用) id: '', processId: '', // 流程id--查询审批记录使用 applyNo: '', // 申请编号 applyName: '', // 申请名称 applyUnit: '', // 申请单位 applyUnitName: '', // 申请单位名称 applyPerson: '', // 申请人 applyPersonName: '', // 申请人名称 time: '', // 借用时间 applyDesc: '', // 申请说明 rejectRemark: '', // 历次驳回日志 }) const ruleFormRef = ref<FormInstance>() as any const list = ref<IdeviceList[]>([])// 表格数据 // 表头 const columns = ref<TableColumn[]>([ { text: '设备编号', value: 'equipmentNo', align: 'center', width: '230' }, { text: '设备名称', value: 'equipmentName', align: 'center' }, { text: '型号', value: 'modelNo', align: 'center' }, { text: '测量范围', value: 'mesureRange', align: 'center' }, { text: '使用部门', value: 'useDeptName', align: 'center' }, { text: '使用人', value: 'usePersonName', align: 'center' }, { text: '管理状态', value: 'managerStateName', align: 'center' }, { text: '有效日期', value: 'validDate', align: 'center' }, ]) // 表单校验规则 const rules = reactive<FormRules>({ applyName: [{ required: true, message: '申请名称必填', trigger: 'blur' }], applyUnitName: [{ required: true, message: '申请单位必填', trigger: 'change' }], applyPersonName: [{ required: true, message: '申请人必填', trigger: 'change' }], time: [{ type: 'date', required: true, message: '借用时间必填', trigger: 'change' }], applyDesc: [{ required: true, message: '申请说明必填', trigger: 'blur' }], }) const $router = useRouter() // 点击关闭 const close = () => { $router.back() } const handleClick = (val: string) => { if (val === 'agree') { // 同意 approvalDialog.value.initDialog('agree', form.value.taskId) } else if (val === 'reject') { // 驳回 approvalDialog.value.initDialog('reject', form.value.taskId) } else if (val === 'refuse') { // 拒绝 approvalDialog.value.initDialog('refuse', form.value.taskId) } else if (val === 'revoke') { const params = { taskId: form.value.taskId!, comments: '', } ElMessageBox.confirm( '确认撤回该审批吗?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }, ) .then(() => { submitApproval('revoke', params).then((res) => { ElMessage({ type: 'success', message: '已撤回', }) }) close() }) } } // 多选发生改变时 const handleSelectionChange = (e: any) => { checkoutList.value = e } // 删除行 const delRow = () => { if (checkoutList.value.length <= 0) { ElMessage({ message: '请选中要删除的行', type: 'warning', }) } else { checkoutList.value.forEach((item: IdeviceListQuery) => { list.value.forEach((element, index) => { if (element.equipmentNo === item.equipmentNo) { list.value.splice(index, 1) } }) }) } } // 增加行 const addRow = () => { const index = list.value.findIndex(item => !item.equipmentNo) if (index !== -1) { ElMessage.warning('请完善上一条设备信息') return } list.value.push({ equipmentName: '', // 设备名称 equipmentNo: '', // 设备编号 modelNo: '', // 型号 mesureRange: '', // 测量范围 useDeptName: '', // 使用部门 usePersonName: '', // 使用人 managerStateName: '', // 管理状态 validDate: '', // 有效日期 equipmentId: '', // 设备ID }) } // 点击选择 const handleSelect = (index: number, row: IdeviceList) => { dialogSelectDiviceVisible.value = true // 选择设备对话框显隐 isMulti.value = false // 是否单选, false单选、true表格多选 selectIndex.value = index } // 点击批量添加 const multiAdd = () => { dialogSelectDiviceVisible.value = true isMulti.value = true } // 选择设备对话框关闭 const closeDialog = () => { dialogSelectDiviceVisible.value = false } // 选择好设备了, 添加选好的设备到表格中 const updateDeviceConfirm = (val: Array<IdeviceList>) => { if (isMulti.value) { // 批量增加时push val.forEach((item: IdeviceList) => { // 只添加列表里不存在的 const index = list.value.findIndex((i: IdeviceList) => item.equipmentNo === i.equipmentNo) if (index === -1) { list.value.push(item) } }) } else { // 单选替换 const index = list.value.findIndex((i: IdeviceList) => val[0].equipmentNo === i.equipmentNo) if (index !== -1) { ElMessage.warning('此设备已添加过') return } list.value.splice(selectIndex.value, 1, val[0]) } } // 保存 const save = () => { if (!list.value.length) { ElMessage.warning('设备借用列表不能为空') return } ruleFormRef.value.validate((valid: boolean) => { if (valid) { const loading = ElLoading.service({ lock: true, background: 'rgba(255, 255, 255, 0.8)', }) // 保存之前清除空行、避免传给后端无用空对象 const index = list.value.findIndex((item: IdeviceList) => !item.equipmentNo) if (index !== -1) { list.value.splice(index, 1) } const params = { applyName: form.value.applyName, // 申请名称 applyUnit: form.value.applyUnit, // 申请单位 applyUnitName: form.value.applyUnitName, // 申请单位名称 processId: form.value.processId, // 流程实例id applyPerson: form.value.applyPerson, // 申请人 applyPersonName: form.value.applyPersonName, // 申请人名称 time: form.value.time, // 借用时间 applyDesc: form.value.applyDesc, // 申请说明 applyType: '2', // 申请类型 借用2 id: form.value.id, equipmentList: list.value.map((item) => { return { equipmentId: item.id!, } }), } // 新建 if (typeValue.value === 'add') { saveAddReceiveApplyList(params).then((res) => { form.value.id = res.data ElMessage.success('保存成功') loading.close() }) } // 保存 else if (typeValue.value === 'edit') { if (approvalStatusName.value === '未通过-驳回') { failUpdateEquipmentApply(params).then((res) => { form.value.id = res.data ElMessage.success('保存成功') loading.close() close() }) } else { saveEditReceiveApplyList(params).then((res) => { form.value.id = res.data ElMessage.success('保存成功') loading.close() close() }) } } } else { console.log('表单校验不通过') } }) } // 提交表单 const submit = () => { if (form.value.id) { const loading = ElLoading.service({ lock: true, background: 'rgba(255, 255, 255, 0.8)', }) const params = { id: form.value.id, formId: SCHEDULE.DEVICE_BORROW_APPROVAL, // 表单id } submitReceiveApplyList(params).then(() => { ElMessage.success('提交成功') loading.close() close() }) } else { ElMessage.warning('请先保存再提交!') } } // 获取用户列表--(是否有不分页接口?) const fetchUserList = () => { getUserList({ offset: 1, limit: 999999 }).then((res: any) => { usePersonList.value = res.data.rows usePersonOptions.value = res.data.rows }) } // 获取使用部门 const fetchDeptTreeList = () => { getDeptTreeList().then((res: any) => { if (res.data) { // 将列表转树结构 useDeptList.value = toTreeList(res.data, '0', true) } }) } // 编辑、详情--获取详细信息 const fetchReceiveApplyListDetail = async () => { const res = await getReceiveApplyListDetail({ id: form.value.id }) form.value.applyUnit = res.data.applyUnit // 部门 form.value.applyUnitName = res.data.applyUnitName || user.deptName // 部门名称 form.value.applyName = res.data.applyName // 申请名称 form.value.applyPerson = res.data.applyPerson// 申请人 form.value.applyPersonName = res.data.applyPersonName || user.name// 申请人名称 form.value.applyNo = res.data.applyNo// 申请编号 form.value.time = res.data.time // 借用时间 form.value.applyDesc = res.data.applyDesc // 申请说明 list.value = res.data.equipmentInfoList.map((item: IdeviceList) => { return { ...item, validDate: dayjs(item.validDate).format('YYYY-MM-DD'), } }) } // 选择器模糊查询 const remoteMethod = (query: string) => { if (query) { applyPersonLoading.value = true setTimeout(() => { applyPersonLoading.value = false usePersonOptions.value = usePersonList.value.filter((item) => { return item.name.toLowerCase().includes(query.toLowerCase()) }) }, 200) } else { usePersonOptions.value = usePersonList.value } } // --------------------------------------------审批--------------------------------------- const approvalRecordData = ref([]) // 审批流程数据 // 查询审批记录 function getApprovalRecord(processId: string) { if (typeValue.value !== 'add') { if (processId) { fetchApproval(processId).then((res) => { approvalRecordData.value = res.data }) } else { ElMessage.warning('流程实例id为空') } } } // 审批结束回调 const approvalSuccess = () => { close() // 返回上一页 } // 审批 const handleApprove = (val: string, title = '') => { if (val === '取消') { const params = { processInstanceId: processId.value!, comments: '', } ElMessageBox.confirm( '确认取消该审批吗?', '提示', { confirmButtonText: '确认', cancelButtonText: '取消', type: 'warning', }, ) .then(() => { cancelApproval(params).then((res) => { ElMessage({ type: 'success', message: '取消成功', }) close() }) }) } else if (val === '同意') { approvalDialog.value.initDialog('agree', taskId.value) } else if (val === '驳回') { approvalDialog.value.initDialog('reject', taskId.value) } else if (val === '拒绝') { approvalDialog.value.initDialog('refuse', taskId.value) } } // -------------------------------------------------------------------------------------- onMounted(async () => { typeValue.value = $route.query.typeValue // 类型add、edit、detail form.value.id = $route.query.id as string // id form.value.taskId = $route.query.taskId as string // 任务id taskId.value = $route.query.taskId as string // 任务id form.value.processId = $route.query.processId as string // 任务id processId.value = $route.query.processId as string // 任务id approvalStatus.value = $route.query.approvalStatus // 审批类型 approvalStatusName.value = $route.query.approvalStatusName // 审批类型名称 decisionItem.value = $route.query.decisionItem as string // 同意、驳回、拒绝按钮权限 form.value.applyName = '设备借用申请' // 申请名称固定 form.value.applyUnit = user.deptId // 申请单位 form.value.applyUnitName = user.deptName // 申请单位名称 form.value.applyPerson = user.id // 申请人 form.value.applyPersonName = user.name // 申请人名称 form.value.time = dayjs().format('YYYY-MM-DD HH:mm:ss') // 申请时间 // 编辑、详情获取详情页信息 if (typeValue.value === 'edit' || typeValue.value === 'detail') { await fetchReceiveApplyListDetail() // 获取详细信息 } if (approvalStatusName.value !== '草稿箱') { getApprovalRecord(form.value.processId) // 查询审批记录 } // 获取部门信息 fetchDeptTreeList() // 获取人员列表--申请人使用 fetchUserList() }) // 监听到驳回原因 const giveRejectRemark = (reason: string) => { if (form.value.rejectRemark) { const lastIndex = form.value.rejectRemark.lastIndexOf(reason) if (lastIndex === -1) { // 本次原因和上次最后一次原因不同才去拼接 form.value.rejectRemark = `${form.value.rejectRemark};${reason}` } } else { form.value.rejectRemark = reason } } </script> <template> <app-container> <detail-page :title="`设备借用申请-${textMap[typeValue]}`"> <template #btns> <el-button v-if="typeValue === 'detail' && approvalStatusName === '待审批'" type="primary" @click="handleApprove('同意')"> 同意 </el-button> <el-button v-if="typeValue === 'detail' && approvalStatusName === '待审批' && decisionItem !== '3'" type="primary" @click="handleApprove('驳回')"> 驳回 </el-button> <el-button v-if="typeValue === 'detail' && approvalStatusName === '待审批' && decisionItem !== '2'" type="danger" @click="handleApprove('拒绝')"> 拒绝 </el-button> <el-button v-if="typeValue === 'detail' && approvalStatusName === '审批中'" type="info" @click="handleApprove('取消')"> 取消 </el-button> <el-button v-if="typeValue === 'add'" type="primary" @click="submit"> 提交 </el-button> <el-button v-if="typeValue === 'add' || typeValue === 'edit'" type="primary" @click="save"> 保存 </el-button> <el-button type="info" @click="close"> 关闭 </el-button> </template> </detail-page> <div class="create-check"> <div class="top-info"> <!-- 表单 --> <div class="form-area"> <el-form ref="ruleFormRef" :model="form" label-width="120px" :rules="rules" > <el-row :gutter="24"> <el-col :span="6"> <el-form-item label="申请编号:"> <el-input v-model="form.applyNo" :placeholder="typeValue === 'detail' ? '' : '系统自动生成'" :class="{ 'detail-input': typeValue === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="申请名称"> <el-input v-model="form.applyName" :placeholder="typeValue === 'detail' ? '' : '请输入申请名称'" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="申请单位"> <!-- <dept-select v-model="form.applyUnitName" placeholder="请选择申请单位" :data="useDeptList" :disabled="typeValue === 'detail'" /> --> <el-input v-model="form.applyUnitName" :class="{ 'detail-input': typeValue === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="申请人"> <!-- <el-select v-model="form.applyPersonName" :disabled="typeValue === 'detail'" placeholder="请选择申请人" style="width: 100%;" filterable remote remote-show-suffix :remote-method="remoteMethod" :loading="applyPersonLoading" > <el-option v-for="item in usePersonOptions" :key="item.id" :label="item.name" :value="item.id" /> </el-select> --> <el-input v-model="form.applyPersonName" :class="{ 'detail-input': typeValue === 'detail' }" disabled /> </el-form-item> </el-col> <el-col :span="6"> <el-form-item label="借用时间" prop="time"> <el-date-picker v-model="form.time" type="datetime" placeholder="请选择借用时间" format="YYYY-MM-DD hh:mm" value-format="YYYY-MM-DD hh:mm" :disabled="typeValue === 'detail'" /> </el-form-item> </el-col> <el-col :span="12"> <el-form-item label="申请说明" prop="applyDesc"> <el-input v-model="form.applyDesc" type="textarea" autosize clearable :disabled="typeValue === 'detail'" /> </el-form-item> </el-col> </el-row> <el-row v-if="approvalStatusName === '未通过-驳回'" :gutter="20"> <el-col :span="12"> <el-form-item label="历次驳回原因:"> <el-input v-model.trim="form.rejectRemark" :placeholder="typeValue === 'detail' ? '' : '历次驳回原因'" class="full-width-input" clearable type="textarea" autosize disabled /> </el-form-item> </el-col> </el-row> </el-form> </div> </div> <!-- 表格 --> <detail-block title="设备借用列表"> <template #btns> <el-button v-if="typeValue !== 'detail'" type="primary" @click="multiAdd"> 批量添加 </el-button> <el-button v-if="typeValue !== 'detail'" type="primary" @click="addRow"> 增加行 </el-button> <el-button v-if="typeValue !== 'detail'" type="info" @click="delRow"> 删除行 </el-button> </template> <el-table :data="list" border style="width: 100%;" max-height="600" @selection-change="handleSelectionChange" > <el-table-column v-if="typeValue !== 'detail'" type="selection" width="38" /> <el-table-column align="center" label="序号" width="80" type="index" /> <el-table-column v-for="item in columns" :key="item.value" :prop="item.value" :label="item.text" :width="item.width" show-overflow-tooltip align="center" > <template v-if="item.value === 'equipmentNo' && (typeValue === 'add' || typeValue === 'edit')" #default="scope"> <el-input v-model="scope.row.equipmentNo" disabled placeholder="请选择设备" class="input"> <template #append> <el-button size="small" @click="handleSelect(scope.$index, scope.row)"> 选择 </el-button> </template> </el-input> </template> </el-table-column> </el-table> </detail-block> <detail-block v-if="approvalStatusName !== '草稿箱' && typeValue !== 'add'" title="审批流程"> <!-- 审批流程 --> <approval-record ref="approvalRecord" :approval-record-data="approvalRecordData" @give-reject-remark="giveRejectRemark" /> </detail-block> </div> <select-device-dialog :dialog-select-divice-visible="dialogSelectDiviceVisible" :is-multi="isMulti" @close-dialog="closeDialog" @update-device-confirm="updateDeviceConfirm" /> <!-- 同意、驳回、拒绝对话框显示 --> <approval-dialog ref="approvalDialog" @on-success="approvalSuccess" /> </app-container> </template> <style lang="scss" scoped> // 样式 .create-check { margin-top: 10px; .top-info { display: flex; flex-direction: column; width: 100%; padding-right: 10px; border-radius: 10px; background-color: #fff; // padding: 10px; .title-button { display: flex; align-items: center; &::before { content: ""; flex: 1; } .button-group { flex: 1; display: flex; justify-content: flex-end; } } .form-area { margin-top: 40px; } } } </style>