From a886764374c7ee326bd632110fc6f518c5343e52 Mon Sep 17 00:00:00 2001 From: zhouwx <1175765986@qq.com> Date: 星期一, 18 十一月 2024 09:00:57 +0800 Subject: [PATCH] 项目管理 --- src/views/safetyReview/projectManage/components/chooseExpert.vue | 157 +++++++++ src/views/safetyReview/projectManage/components/projectArchive.vue | 142 ++++++++ src/views/safetyReview/projectManage/process.vue | 23 + src/views/safetyReview/projectManage/components/expertsList.vue | 277 +++++++++++++++++ src/router/index.js | 16 src/views/safetyReview/projectManage/index.vue | 4 src/views/safetyReview/projectManage/components/projectApproval.vue | 309 ++++++++++++++++++ 7 files changed, 906 insertions(+), 22 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index 33af930..ebac8ec 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -102,7 +102,21 @@ meta: { title: '个人中心', icon: 'user' } } ] - } + }, + { + path: '', + component: Layout, + redirect: '/process', + hidden: true, + children: [ + { + path: '/process', + component: () => import('@/views/safetyReview/projectManage/process.vue'), + name: 'Process', + meta: { title: '项目管理', icon: 'dashboard', affix: true } + } + ] + }, ] // 动态路由,基于用户权限动态去加载 diff --git a/src/views/safetyReview/projectManage/components/chooseExpert.vue b/src/views/safetyReview/projectManage/components/chooseExpert.vue index ada0125..59ffcd2 100644 --- a/src/views/safetyReview/projectManage/components/chooseExpert.vue +++ b/src/views/safetyReview/projectManage/components/chooseExpert.vue @@ -1,12 +1,128 @@ - <template> - <div>专家选用</div> + <div class="expertChoose"> + <div style="margin-bottom: 50px"> + <div class="fTop"> + <span style="font-weight: 600">固定选用部分</span> + <el-button type="primary" style="width: 100px" @click="chooseExpert('选取专家')">选取专家</el-button> + </div> + <el-table v-loading="fLoading" :data="fixedDataList" :border="true" ref="fTableRef" style="width: 100%;"> + <el-table-column label="姓名" prop="name" align="center" /> + <el-table-column label="性别" prop="sex" align="center" > + <template #default="scope"> + {{scope.row.sex === 0 ? '男' : '女' }} + </template> + </el-table-column> + <el-table-column label="身份证号" prop="idCard" align="center" /> + <el-table-column label="等级" prop="level" align="center" /> + <el-table-column label="专业领域" prop="domain" align="center" /> + <el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="180"> + <template #default="scope"> + <el-button link type="primary" @click="delF(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + </div> + <div style="display: flex;flex-direction: column"> + <span style="font-weight: 600">随机选用部分</span> + <el-form :model="queryParams" ref="queryForm" :inline="true" style="margin-top: 10px" label-width="90px"> + <el-row :gutter="24"> + <el-col :span="8"> + <el-form-item label="专业领域:"> + <el-cascader + style="width: 100%" + v-model="expertType" + :options="domainList" + :props="{ expandTrigger: 'hover',value: 'id',label: 'classifyName',multiple: true }" + @change="professionChange" + collapse-tags + collapse-tags-tooltip + clearable + > + </el-cascader> + </el-form-item> + </el-col> + <el-col :span="8"> + <el-form-item label="允许级别:"> + <el-checkbox-group v-model="checkList"> + <el-checkbox label="一级" value="一级" /> + <el-checkbox label="二级" value="二级" /> + <el-checkbox label="三级" value="三级" /> + </el-checkbox-group> + </el-form-item> + </el-col> + <el-col :span="8"> + <el-form-item style="float: right;"> + <el-button style="width: 100px;margin-right: -32px;" type="primary" @click="random">随机抽取</el-button> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="拟选用人数:"> + <el-input + v-model.trim="queryParams.num" + placeholder="请输入拟选用人数" + @input="queryParams.num = queryParams.num.replace(/[^0-9]/g,' ')" + > + </el-input> + </el-form-item> + </el-col> + </el-row> + </el-form> + <el-table v-loading="rLoading" :data="randomDataList" :border="true" ref="rTableRef" style="width: 100%;"> + <el-table-column label="姓名" prop="name" align="center" /> + <el-table-column label="性别" prop="sex" align="center" > + <template #default="scope"> + {{scope.row.sex === 0 ? '男' : '女' }} + </template> + </el-table-column> + <el-table-column label="身份证号" prop="idCard" align="center" /> + <el-table-column label="等级" prop="level" align="center" /> + <el-table-column label="专业领域" prop="domain" align="center" /> + <el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="180"> + <template #default="scope"> + <el-button link type="primary" @click="delF(scope.row)" >删除</el-button> + </template> + </el-table-column> + </el-table> + </div> + <experts-list ref="expertsListRef" @getName="getSelected"></experts-list> + </div> </template> <script setup> +import {onMounted, ref} from "vue"; +import expertsList from './expertsList.vue' +import {getExpertTypes} from "@/api/form"; +import {ElMessage} from "element-plus"; + const emit = defineEmits(["getNextStatus"]); +const fTableRef = ref(null); +const expertsListRef = ref(null) +const fLoading = ref(false); +const rLoading = ref(false); +const fixedDataList = ref([]); +const rTableRef = ref(null); +const randomDataList = ref([]); +const queryParams = ref({ + +}) +const expertType = ref([]) +const checkList = ref([]) +const domainList = ref([]) + +onMounted(() =>{ + getDomain() +}) const riskOpen = async (type,val) => { console.log("type",type,val) + if(type === 'add' || type === 'clickEdit'){ + if(fixedDataList.value.length === 0 && randomDataList.value.length === 0){ + ElMessage.warning('请选择专家') + return; + } + } + //保存按钮 if(type === 'add'){ //成功后自动到下一步 项目id @@ -20,6 +136,33 @@ } } +const chooseExpert = (type) => { + expertsListRef.value.openDialog(type,fixedDataList.value) +} +const getSelected = (type,data)=>{ + fixedDataList.value = JSON.parse(JSON.stringify(data)) +} +const delF = (val) => { + fixedDataList.value = fixedDataList.value.filter(item => item.id != val.id) +} + +const professionChange=(value)=> { + console.log(value,'val') +} +const getDomain = async () => { + // const res = await getExpertTypes() + // if(res.code == 200){ + // domainList.value = res.data + // }else{ + // ElMessage.warning(res.message) + // } +} + +const random = () => { + rLoading.value = true + rLoading.value = false +} + defineExpose({ riskOpen }); @@ -27,5 +170,15 @@ <style scoped lang="scss"> +.expertChoose{ + display: flex; + flex-direction: column; + .fTop{ + display: flex; + align-items: center; + justify-content: space-between; + margin-bottom: 15px; + } +} </style> diff --git a/src/views/safetyReview/projectManage/components/expertsList.vue b/src/views/safetyReview/projectManage/components/expertsList.vue new file mode 100644 index 0000000..fedffc6 --- /dev/null +++ b/src/views/safetyReview/projectManage/components/expertsList.vue @@ -0,0 +1,277 @@ +<template> + <div class="notice"> + <el-dialog + v-model="dialogVisible" + :title="title" + width="60%" + > + <el-form :model="queryParams" :inline="true" label-width="90px"> + <el-form-item label="姓名"> + <el-input + v-model.trim="queryParams.name" + placeholder="姓名" + style="width: 250px" + /> + </el-form-item> + <el-form-item label="手机号"> + <el-input + v-model.trim="queryParams.phone" + placeholder="手机号" + style="width: 250px" + /> + </el-form-item> + <el-form-item label="等级"> + <el-select v-model="queryParams.level" style="width: 250px" placeholder="等级" > + <el-option + v-for="item in levelList" + :key="item.id" + :label="item.name" + :value="item.name" + /> + </el-select> + </el-form-item> + <el-form-item label="专业领域"> + <el-cascader + style="width: 100%" + v-model="expertType" + :options="domainList" + :props="{ expandTrigger: 'hover',value: 'id',label: 'classifyName' }" + @change="professionChange" + > + </el-cascader> + </el-form-item> + <el-form-item> + <el-button type="primary" icon="Search" @click="search">搜索</el-button> + <el-button icon="Refresh" @click="research">重置</el-button> + </el-form-item> + </el-form> + <el-table v-loading="loading" ref="tableRef" :data="expertList" :border="true" row-key="id" @select="select" @selection-change="handleSelectionChange"> + <el-table-column type="selection" :reserve-selection="true" width="55" /> + <el-table-column label="姓名" align="center" prop="name" /> + <el-table-column label="身份证号" align="center" prop="idCard" /> + <el-table-column label="出生日期" align="center" prop="birthdayName" /> + <el-table-column label="性别" align="center" prop="sex" > + <template #default="scope"> + <span>{{scope.row.sex === 0 ? '男' : '女'}}</span> + </template> + </el-table-column> + <el-table-column label="学历" align="center" prop="degree" /> + <el-table-column label="所学专业" align="center" prop="speciality" /> + <el-table-column label="职称" align="center" prop="title"/> + <el-table-column label="在岗情况" align="center" prop="dutyStatus" > + <template #default="scope"> + <span>{{scope.row.dutyStatus === 0 ? '在岗' : '退休'}}</span> + </template> + </el-table-column> + <el-table-column label="单位全称" align="center" prop="companyName" width="180"/> + <el-table-column label="现从事专业及方向" align="center" prop="currentProfession"/> + <el-table-column label="联系方式" align="center" prop="phone"/> + <el-table-column label="支撑方向" align="center" prop="supportName" width="165"/> + <el-table-column label="专家领域" align="center" prop="domain"/> + <el-table-column label="入库分级" align="center" prop="level"/> + </el-table> + <pagination + v-show="total > 0" + :total="total" + v-model:page="queryParams.pageNum" + v-model:limit="queryParams.pageSize" + @pagination="getList" + /> + <template #footer> + <span class="dialog-footer"> + <el-button @click="dialogVisible = false" size="default">取 消</el-button> + <el-button type="primary" @click="onSubmit" size="default" v-preReClick>确认</el-button> + </span> + </template> + </el-dialog> + <project-dialog ref="projectRef" @getList="getList"></project-dialog> + </div> +</template> +<script setup> +import {getCurrentInstance, onMounted, reactive, ref, toRefs, defineEmits, nextTick} from "vue"; +import {getDictList} from "@/api/backManage/evaluate"; +import {ElMessage, ElMessageBox} from "element-plus"; +import projectDialog from "@/views/safetyReview/userManage/expertUsers/components/projectDialog.vue" +import Cookies from "js-cookie"; +import {delMonitor, getExpertList, getMonitorList} from "@/api/sysUsers"; +import {getExpertsList, getExpertTypes} from "@/api/form"; +const { proxy } = getCurrentInstance(); +const loading = ref(false); +const emit = defineEmits(['getName']) +const data = reactive({ + queryParams: { + pageNum: 1, + pageSize: 10, + name: '', + phone: '', + level: '', + domain: null, + post: '' + }, + total: 0, + choosed: [], + expertList: [], + domainList: [], + dialogVisible: false, + title: '', + selected: [], + expertType: [], + levelList: [ + { + id: 1, + name: '一级' + }, + { + id: 2, + name: '二级' + }, + { + id: 3, + name: '三级' + }, + ] +}) +const tableRef = ref() +const { queryParams, total, expertList, domainList, levelList , dialogVisible,title,selected, expertType } = toRefs(data); + +const openDialog = (type,choosedData) => { + getDomain() + research() + data.choosed = choosedData + data.choosed.forEach(item => { + tableRef.value.toggleRowSelection(item, true); + }) + data.selected = [] + data.title = type + data.dialogVisible = true +} + +const onSubmit = async () => { + if(data.selected.length>0){ + data.choosed = JSON.parse(JSON.stringify(data.selected)) + data.selected.length = 0 + data.queryParams.pageNum = 1 + data.queryParams.pageSize = 10 + emit('getName',data.title,data.choosed) + tableRef.value.clearSelection() + data.dialogVisible = false + } +} + +const getList = async () => { + loading.value = true; + const res = await getExpertsList(data.queryParams) + if(res.code == 200){ + data.expertList = res.data.list.map(item => { + return{ + ...item, + birthdayName: item.birthday ? item.birthday.slice(0,10) : '', + supportName: item.supportDirectionSafety.split(',') + } + }) + data.expertList.forEach(item => { + item.supportName.forEach((s,index) => { + switch (s){ + case '1': + item.supportName[index] = '现场检查' + break; + case '2': + item.supportName[index] = '调查评估' + break; + case '3': + item.supportName[index] = '咨询服务' + break; + case '4': + item.supportName[index] = '教育培训' + break; + case '5': + item.supportName[index] = '其他' + break; + } + }) + }) + data.total = res.data.total + }else{ + ElMessage.warning(res.msg) + } + loading.value = false; +} +const projectRef = ref(); +const openList = (val) => { + projectRef.value.openDialog(val); +} + +const getDomain = async () => { + const res = await getExpertTypes() + if(res.code == 200){ + data.domainList = res.data + }else{ + ElMessage.warning(res.message) + } +} + +const select = ((selection, row) => { + // data.expertList.forEach(item => { + // + // }) + // nextTick(() => { + // tableRef.value.toggleRowSelection(item, true) + // }) + + // tableRef.value.clearSelection() + // if(selection.length == 0) { + // return + // } + // tableRef.value.toggleRowSelection(row, true); +}) + +const handleSelectionChange = (val) => { + data.selected = val +} + +const search = ()=>{ + data.queryParams.pageNum = 1 + getList() +} + +const research = ()=>{ + data.expertType = [] + data.queryParams = { + pageNum: 1, + pageSize: 10, + name: '', + phone: '', + level: '', + domain: null, + post: '' + } + getList() +} + +const professionChange=(value)=> { + console.log(value,'val') +} + +defineExpose({ + openDialog +}); + +</script> + +<style scoped lang="scss"> +.notice{ + :deep(.el-form .el-form-item__label) { + font-size: 15px; + } + + ::v-deep(.el-table th.el-table__cell:nth-child(1) .cell) { + visibility: hidden; + } + + .file { + display: flex; + flex-direction: column; + align-items: flex-start; + } +} +</style> diff --git a/src/views/safetyReview/projectManage/components/projectApproval.vue b/src/views/safetyReview/projectManage/components/projectApproval.vue index ed2315e..6296004 100644 --- a/src/views/safetyReview/projectManage/components/projectApproval.vue +++ b/src/views/safetyReview/projectManage/components/projectApproval.vue @@ -1,24 +1,308 @@ - <template> - <div>项目审批</div> + <div class="approval"> + <el-form :model="state.dataForm" ref="dataForm" :inline="true" style="margin-top: 10px" label-width="130px" > + <el-row :gutter="24"> + <el-col :span="12"> + <el-form-item label="项目名称:"> + <span>{{state.dataForm.name}}</span> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="被检查/对接单位:"> + <span>{{state.dataForm.unit}}</span> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="12"> + <el-form-item label="计划实行时间:"> + <span>{{state.dataForm.time}}</span> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="项目地点:"> + <span>{{state.dataForm.address}}</span> + </el-form-item> + </el-col> + </el-row> + <el-row :gutter="24"> + <el-col :span="24"> + <el-form-item label="项目概况:"> + <span>{{state.dataForm.description}}</span> + </el-form-item> + </el-col> + </el-row> + </el-form> + <el-table v-loading="state.loading" :data="state.dataList" :border="true" ref="tableRef" style="width: 100%;"> + <el-table-column label="姓名" prop="name" align="center" /> + <el-table-column label="性别" prop="sex" align="center" > + <template #default="scope"> + {{scope.row.sex === 0 ? '男' : '女' }} + </template> + </el-table-column> + <el-table-column label="身份证号" prop="idCard" align="center" /> + <el-table-column label="等级" prop="level" align="center" /> + <el-table-column label="专业领域" prop="domain" align="center" /> + <el-table-column label="选用方式" prop="type" align="center" > + <template #default="scope"> + {{scope.row.type === 0 ? '固定' : '随机' }} + </template> + </el-table-column> + <el-table-column label="是否为组长" prop="isLeader" align="center" > + <template #default="scope"> + <span v-if="scope.row.isLeader === 0" style="color: red">是</span> + <span v-else>否</span> + </template> + </el-table-column> + <el-table-column fixed="right" label="操作" align="center" class-name="small-padding fixed-width" width="180"> + <template #default="scope"> + <el-button link type="primary" v-if="scope.row.isLeader === 0" @click="handleLeader(scope.row)">取消组长</el-button> + <el-button link type="primary" v-else @click="handleLeader(scope.row)">设为组长</el-button> + </template> + </el-table-column> + </el-table> +<!-- <div class="pag-container">--> +<!-- <el-pagination--> +<!-- v-model:current-page="state.queryParams.pageNum"--> +<!-- v-model:page-size="state.queryParams.pageSize"--> +<!-- :page-sizes="[10,15,20,25]"--> +<!-- layout="total, sizes, prev, pager, next, jumper"--> +<!-- :total="state.total"--> +<!-- @size-change="handleSizeChange"--> +<!-- @current-change="handleCurrentChange"--> +<!-- />--> +<!-- </div>--> + <el-dialog + v-model="dialogVisible" + width="600px" + > + <div> + <div style="display: flex;align-items: center"> + <span style="font-size: 18px;font-weight: 600">审批填报:</span> + <div style="display: flex;align-items: flex-end;margin-top: 15px"> + <img :src="wordSvg" style="width: 30px;height: 35px" /> + <el-button style="width: 110px;margin-left: 10px" type="primary" >下载审批单word</el-button> + </div> + </div> + </div> + <div style="margin-top: 30px"> + <div style="display: flex"> + <span style="font-size: 18px;font-weight: 600">审批记录附件:</span> + <el-upload :disabled="projectType==='view'" accept=".pdf" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,5)"> + <el-button type="primary">上传附件PDF</el-button> + <template #tip> + <div class="el-upload__tip">上传文件尺寸小于5M,最多可上传1份</div> + </template> + </el-upload> + </div> + </div> + <template #footer> + <div class="dialog-footer"> + <el-button type="success" @click="nextStatus">线下审批通过并进行下一步</el-button> + <el-button type="warning" style="margin-left: 40px;" @click="back">线下审批不通过返回上一步</el-button> + </div> + </template> + </el-dialog> + </div> </template> <script setup> +import {onMounted, reactive, ref} from "vue"; +import wordSvg from '@/assets/images/word.svg' +import {ElMessage, ElMessageBox} from "element-plus"; +import {getToken} from "@/utils/auth"; +import axios from "axios"; const emit = defineEmits(["getNextStatus"]); +const tableRef = ref() +const dialogVisible = ref(false); +const state = reactive({ + dataForm: { + name: 'xxx', + unit: 'xxx', + time: '2024年11月1日-2024年11月25日', + address: 'xxx', + description: 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' + + }, + queryParams: { + pageNum: 1, + pageSize: 20, + }, + loading: false, + dataList: [], + total: 0, + uploadUrl: import.meta.env.VITE_APP_BASE_API + '', + header: { + Authorization: getToken() + }, + fileList: [] +}); +const projectType = ref('') + +onMounted(async () => { + await getList() +}) + const riskOpen = async (type,val) => { console.log("type",type,val) - //保存按钮 - if(type === 'add'){ - //成功后自动到下一步 项目id - emit('getNextStatus', 3); + //生成审批按钮 + if(type === 'confirmApproval'){ + dialogVisible.value = true + + + // emit('getNextStatus', 3); }else if(type === 'clickEdit'){ //变更按钮 - }else if(type === 'detail'){ + }else if(type === 'detail' || type === 'view'){ + if(type === 'view'){ + projectType.value = type + } console.log("view333333",type,val) } } + +const nextStatus = () =>{ + dialogVisible.value = false + emit('getNextStatus', 3); +} +const back = () => { + dialogVisible.value = false +} + +const getList = async () => { + state.loading = true; + state.dataList = [ + { + id:1, + name: 'xxx', + idCard: 'xxx', + isLeader: 0, + level: '二级', + domain: 'xxx', + type: 0 + }, + { + id:2, + name: 'xxx', + idCard: 'xxx', + isLeader: 1, + level: '二级', + domain: 'xxx', + type: 1 + } + ] + // state.total = 1 + state.loading = false; +} + +// const handleSizeChange = (val) => { +// state.queryParams.pageNum = 1; +// state.queryParams.pageSize = val +// getList() +// } +// const handleCurrentChange = (val) => { +// state.queryParams.pageNum = val +// getList() +// } + +const handleLeader = (val) => { + state.dataList.forEach(item => { + if(val.id === item.id){ + if(val.isLeader === 0){ + item.isLeader = 1 + }else { + item.isLeader = 0 + } + } + }) + +} + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.fileList = res.data.map(i=>{ + return { + name: i.originName, + url: import.meta.env.VITE_APP_BASE_API + '/' + i.path, + id: i.id, + projectId: i.projectId, + } + }) + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: res.message + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} + +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; + +const handlePictureCardPreview = (uploadFile) => { + axios.get(uploadFile.url,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{ + if (res) { + const link = document.createElement('a') + let blob = new Blob([res.data],{type: res.data.type}) + link.style.display = "none"; + link.href = URL.createObjectURL(blob); // 创建URL + window.open(link.href) + } else { + ElMessage({ + type: 'warning', + message: '文件读取失败' + }); + } + }) +}; + +const handleRemove = async (file, uploadFile) => { + if(file && file.status == 'success') { + ElMessageBox.confirm( + '确定删除该附件?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then(async () => { + state.fileList = [] + // const res = await delFile(file.id) + // if (res.code == 200) { + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + // } else { + // ElMessage({ + // type: 'warning', + // message: res.message + // }) + // } + }) + .catch(() => { + }) + } +} + defineExpose({ riskOpen @@ -27,5 +311,14 @@ <style scoped lang="scss"> - +.approval{ + .pag-container{ + float: right; + margin-top: 10px; + } + :deep(.el-dialog__footer) { + display: flex; + justify-content: center; + } +} </style> diff --git a/src/views/safetyReview/projectManage/components/projectArchive.vue b/src/views/safetyReview/projectManage/components/projectArchive.vue index 5d5a3e6..04c1d1f 100644 --- a/src/views/safetyReview/projectManage/components/projectArchive.vue +++ b/src/views/safetyReview/projectManage/components/projectArchive.vue @@ -1,10 +1,55 @@ - <template> - <div>项目归档</div> + <div class="archive"> + <el-form style="display: flex;flex-direction: column" :model="state.dataForm" ref="dataForm" :inline="true" :rules="state.rules" label-width="130px" > + <el-form-item prop="deptName" label="结束日期:"> + <el-date-picker + v-model="state.dataForm.endTime" + type="date" + placeholder="请选择结束日期" + /> + </el-form-item> + <el-form-item prop="deptName" label="总结描述:"> + <el-input + type="textarea" + :rows="8" + v-model.trim="state.dataForm.summarize" + size="large" + placeholder="请输入总结描述" + > + </el-input> + </el-form-item> + <el-form-item label="附件上传:"> + <el-upload :disabled="projectType==='view'" accept=".pdf" :action="state.uploadUrl" :headers="state.header" method="post" :on-success="(res, uploadFile)=>handleAvatarSuccess(res, uploadFile)" :on-exceed="showTip" :on-preview="handlePictureCardPreview" :limit='1' v-model:file-list="state.fileList" :before-upload="picSize" :on-remove="(file, uploadFiles)=>handleRemove(file, uploadFiles,5)"> + <el-button type="primary">上传附件PDF</el-button> + <template #tip> + <div class="el-upload__tip">上传文件尺寸小于5M,最多可上传1份</div> + </template> + </el-upload> + </el-form-item> + </el-form> + </div> </template> <script setup> +import {reactive, ref} from "vue"; +import {getToken} from "@/utils/auth"; +import {ElMessage, ElMessageBox} from "element-plus"; +import axios from "axios"; + const emit = defineEmits(["getNextStatus"]); +const projectType = ref('') +const state = reactive({ + dataForm: { + endTime: '', + summarize:'' + }, + rules: {}, + uploadUrl: import.meta.env.VITE_APP_BASE_API + '', + header: { + Authorization: getToken() + }, + fileList: [] +}); const riskOpen = async (type,val) => { console.log("type",type,val) //完结按钮 @@ -12,10 +57,97 @@ //成功后自动到下一步 项目id emit('getNextStatus', 4); - }else if(type === 'detail'){ - console.log("view4444441",type,val) + }else if(type === 'detail' || type === 'view'){ + if(type === 'view'){ + projectType.value = type + } + console.log("view333333",type,val) } } + +const handleAvatarSuccess = (res, uploadFile) => { + if(res.code == 200){ + state.fileList = res.data.map(i=>{ + return { + name: i.originName, + url: import.meta.env.VITE_APP_BASE_API + '/' + i.path, + id: i.id, + projectId: i.projectId, + } + }) + }else{ + state.fileList = [] + ElMessage({ + type: 'warning', + message: res.message + }) + } +} + +const showTip =()=>{ + ElMessage({ + type: 'warning', + message: '超出文件上传数量' + }); +} + +const picSize = async (rawFile) => { + if(rawFile.size / 1024 / 1024 > 5){ + ElMessage({ + type: 'warning', + message: '文件大小不能超过5M' + }); + return false + } +}; + +const handlePictureCardPreview = (uploadFile) => { + axios.get(uploadFile.url,{headers:{'Content-Type': 'application/json','Authorization': `${getToken()}`,'uid':`${Cookies.get('uid')}`},responseType: 'blob'}).then(res=>{ + if (res) { + const link = document.createElement('a') + let blob = new Blob([res.data],{type: res.data.type}) + link.style.display = "none"; + link.href = URL.createObjectURL(blob); // 创建URL + window.open(link.href) + } else { + ElMessage({ + type: 'warning', + message: '文件读取失败' + }); + } + }) +}; + +const handleRemove = async (file, uploadFile) => { + if(file && file.status == 'success') { + ElMessageBox.confirm( + '确定删除该附件?', + '提示', + { + confirmButtonText: '确定', + cancelButtonText: '取消', + type: 'warning', + }) + .then(async () => { + state.fileList = [] + // const res = await delFile(file.id) + // if (res.code == 200) { + // ElMessage({ + // type: 'success', + // message: '文件已删除' + // }) + // } else { + // ElMessage({ + // type: 'warning', + // message: res.message + // }) + // } + }) + .catch(() => { + }) + } +} + defineExpose({ riskOpen @@ -24,5 +156,7 @@ <style scoped lang="scss"> +.archive{ +} </style> diff --git a/src/views/safetyReview/projectManage/index.vue b/src/views/safetyReview/projectManage/index.vue index b2c93e7..e5e37f2 100644 --- a/src/views/safetyReview/projectManage/index.vue +++ b/src/views/safetyReview/projectManage/index.vue @@ -210,8 +210,8 @@ window.onresize = () => { tableHeight.value = window.innerHeight - tableRef.value.$el.offsetTop - 170; }; - const userInfo = JSON.parse(Cookies.get('userInfo')) - isAgency.value = userInfo.identity === 1; + // const userInfo = JSON.parse(Cookies.get('userInfo')) + // isAgency.value = userInfo.identity === 1; }); const chooseType = ref(''); diff --git a/src/views/safetyReview/projectManage/process.vue b/src/views/safetyReview/projectManage/process.vue index 83c6b5c..cd85d77 100644 --- a/src/views/safetyReview/projectManage/process.vue +++ b/src/views/safetyReview/projectManage/process.vue @@ -33,8 +33,9 @@ </div> <div style="display: flex;align-items: center;justify-content: center;margin-bottom: -30px;margin-top: 10px"> <el-button type="primary" v-if="selectedObj.id !== 1" style="width: 80px" @click="back">上一步</el-button> - <el-button type="warning" style="width: 80px" v-if="(projectStatus === 'add' || projectStatus === 'edit') && selectedObj.status ===1 && selectedObj.id !==4 && newProgress !== 4" @click="save">保存</el-button> - <el-button type="warning" style="width: 80px" v-if="(projectStatus === 'add' || projectStatus === 'edit') && selectedObj.status !==1 && newProgress !== 4 " @click="clickEdit">变更</el-button> + <el-button type="warning" style="width: 80px" v-if="(projectStatus === 'add' || projectStatus === 'edit') && selectedObj.status ===1 && selectedObj.id !==4 && selectedObj.id !==3 && newProgress !== 4" @click="save">保存</el-button> + <el-button type="warning" style="width: 110px" v-if="(projectStatus === 'add' || projectStatus === 'edit') && selectedObj.id !==4 && selectedObj.id ===3 && newProgress !== 4" @click="confirmApproval">确认生成审批单</el-button> + <el-button type="warning" style="width: 80px" v-if="(projectStatus === 'add' || projectStatus === 'edit') && selectedObj.status !==1 && selectedObj.id !==3 && newProgress !== 4 " @click="clickEdit">变更</el-button> <el-button type="warning" style="width: 80px" v-if="selectedObj.id === 4 && selectedObj.status === 1 && newProgress !== 4" @click="confirm">确认完结</el-button> <el-button type="primary" style="width: 80px" v-if="selectedObj.id !== 4" @click="next">下一步</el-button> </div> @@ -125,6 +126,10 @@ const save = () => { goRouter(selectedObj.value.id,'add') } +const confirmApproval = () => { + goRouter(selectedObj.value.id,'confirmApproval') +} + const goRouter = (selectId,type) => { switch (selectId){ @@ -143,17 +148,25 @@ } break; case 3: - if(type === 'add' || type === 'clickEdit'){ + if(type === 'add' || type === 'clickEdit' || 'confirmApproval'){ approvalRef.value.riskOpen(type,projectId.value); }else if(projectStatus.value === 'view' || projectStatus.value === 'edit' || projectStatus.value === 'add'){ - approvalRef.value.riskOpen('detail',projectId.value); + if(projectStatus.value === 'view'){ + approvalRef.value.riskOpen('view',projectId.value); + }else{ + approvalRef.value.riskOpen('detail',projectId.value); + } } break; case 4: if(type === 'add' || type === 'clickEdit' || type === 'confirm'){ archiveRef.value.riskOpen(type,projectId.value); } else if(projectStatus.value === 'view' || projectStatus.value === 'edit' || projectStatus.value === 'add'){ - archiveRef.value.riskOpen('detail',projectId.value); + if(projectStatus.value === 'view'){ + archiveRef.value.riskOpen('view',projectId.value); + }else{ + archiveRef.value.riskOpen('detail',projectId.value); + } } break; } -- Gitblit v1.9.2