1162 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			1162 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | ||
|   <div class="app_detail detail-content details-page">
 | ||
|     <ai-detail>
 | ||
|       <ai-title slot="title" title="审批详情" isShowBack isShowBottomBorder @onBackClick="approval.goBack()">
 | ||
|         <template #rightBtn>
 | ||
|           <template v-if="listType==0&&$permissions('zwsp_oaapprovalapplyinfo_approve')">
 | ||
|             <el-button size="small" class="iconfont iconClean del-btn-list" @click="agreeRefulse(0)">拒绝</el-button>
 | ||
|             <el-button size="small" type="primary" class="iconfont iconCorrect" @click="agreeRefulse(1)">同意</el-button>
 | ||
|           </template>
 | ||
|           <el-button v-if="listType==2&&detail.approvalStatus==0&&$permissions('app_oaapprovalapplyinfo_del')"
 | ||
|                      size="small" class="iconfont iconRevoke del-btn-list" style="width: 76px;" @click="recall">撤回
 | ||
|           </el-button>
 | ||
|         </template>
 | ||
|       </ai-title>
 | ||
| 
 | ||
|       <template #content>
 | ||
|         <ai-sidebar :tabTitle="menuList" @change="change"></ai-sidebar>
 | ||
|         <el-scrollbar>
 | ||
|           <template v-if="currentMenu==0">
 | ||
|             <ai-card title="基本信息">
 | ||
|               <template #content>
 | ||
|                 <ul class="detail_ul">
 | ||
|                   <li style="width: 60%">
 | ||
|                     <span>审批编号:</span>
 | ||
|                     <p>{{ detail.serialNumber }}</p>
 | ||
|                   </li>
 | ||
|                   <li style="width: 60%">
 | ||
|                     <span>发起人:</span>
 | ||
|                     <p>{{ detail.createUserName }}</p>
 | ||
|                   </li>
 | ||
|                   <li>
 | ||
|                     <span>所属部门:</span>
 | ||
|                     <p> {{ dict.getLabel('hbDepartment', detail.department) || '-' }}</p>
 | ||
|                   </li>
 | ||
|                   <li>
 | ||
|                     <span>所属分类:</span>
 | ||
|                     <p>{{ detail.classificationName }}</p>
 | ||
|                   </li>
 | ||
|                   <li>
 | ||
|                     <span>申请时间:</span>
 | ||
|                     <p>{{ detail.createTime |format }}</p>
 | ||
|                   </li>
 | ||
|                 </ul>
 | ||
|               </template>
 | ||
|             </ai-card>
 | ||
|           </template>
 | ||
| 
 | ||
|           <template v-if="currentMenu==1">
 | ||
|             <ai-card title="申请表单">
 | ||
|               <template #content>
 | ||
|                 <el-form label-suffix=":" label-width="180px" size="small">
 | ||
|                   <div class="border-wrap">
 | ||
|                     <div v-for="(item, index) in applyForm" :key="index">
 | ||
|                       <ai-title :title="index"></ai-title>
 | ||
|                       <el-form-item v-for="e in item" :key="e.id" :label="[e.fieldName,e.fieldNameSuffix].join('')">
 | ||
|                         <el-input :value="getFieldValue(e)" readonly style="width: 100%;" v-if="e.fieldDataType!=5"/>
 | ||
|                         <el-checkbox-group v-model="!e.fieldValue ? '' : e.fieldValue.split(',')">
 | ||
|                           <el-checkbox :label="val.dictValue" disabled
 | ||
|                                        v-for="(val,idx) in dict.getDict(e.dictionaryCode)" :key="idx">{{val.dictName}}</el-checkbox>
 | ||
|                         </el-checkbox-group>
 | ||
|                       </el-form-item>
 | ||
|                     </div>
 | ||
|                     <template v-if="applyForm=={}">
 | ||
|                       <div class="no-data"></div>
 | ||
|                     </template>
 | ||
|                   </div>
 | ||
|                 </el-form>
 | ||
|               </template>
 | ||
|             </ai-card>
 | ||
|           </template>
 | ||
| 
 | ||
| 
 | ||
|           <template v-if="currentMenu==2">
 | ||
|             <ai-card title="附件材料">
 | ||
|               <template #content>
 | ||
|                 <ai-table :tableData="detailObj.annexs" :colConfigs="colConfigs" :isShowPagination="false"
 | ||
|                           :header-cell-style="{fontWeight:'bold',color:'#333'}">
 | ||
|                   <el-table-column slot="annex" label="材料附件">
 | ||
|                     <template v-slot="{row}">
 | ||
|                       <img class="tableImage" :src="row.annexFile.url" alt="" v-viewer>
 | ||
|                     </template>
 | ||
|                   </el-table-column>
 | ||
|                   <el-table-column slot="options" label="操作" align="center">
 | ||
|                     <template v-slot="{row}">
 | ||
|                       <el-button v-if="row.exampleFile" @click="downFile(row.exampleFile.accessUrl)" type="text">查看样例
 | ||
|                       </el-button>
 | ||
|                       <el-button v-if="row.emptyFile" @click="downFile(row.emptyFile.accessUrl)" type="text">下载空表
 | ||
|                       </el-button>
 | ||
|                     </template>
 | ||
|                   </el-table-column>
 | ||
|                 </ai-table>
 | ||
|               </template>
 | ||
|             </ai-card>
 | ||
|           </template>
 | ||
| 
 | ||
|           <template v-if="currentMenu==3">
 | ||
|             <ai-card title="审批记录">
 | ||
|               <template #content>
 | ||
|                 <div class="add_record">
 | ||
|                   <el-steps direction="vertical">
 | ||
|                     <el-step v-for="(item,index) in processList" :key="index"
 | ||
|                              :class="item.isCancelItem ? 'bg-999' : ''">
 | ||
|                       <div slot="icon" class="record_icon">
 | ||
|                         <span class="icon_img iconfont iconAll_Profile"
 | ||
|                               v-if="!item.stepAvatar && !item.userName"></span>
 | ||
|                         <img v-if="item.stepAvatar" :src="item.stepAvatar" alt="" width="40px" height="40px"
 | ||
|                              style="border-radius: 50%;margin-top: 3px;" :style="{right:item.stepAvatar?'-12px':''}">
 | ||
|                         <span class="icon_img"
 | ||
|                               v-if="!item.stepAvatar && item.userName">{{ item.userName.slice(-2) }}</span>
 | ||
| 
 | ||
|                         <svg class="svgProgress" aria-hidden="true" v-if="['0','1','6'].includes(item.stepType)">
 | ||
|                           <use xlink:href="#iconsptg"></use>
 | ||
|                         </svg>
 | ||
| 
 | ||
|                         <svg class="svgProgress" aria-hidden="true" v-if="['3','4'].includes(item.stepType)"
 | ||
|                              :style="{right:!item.stepAvatar?'-8px':''}">
 | ||
|                           <use xlink:href="#icondsp"></use>
 | ||
|                         </svg>
 | ||
| 
 | ||
|                         <svg class="svgProgress" aria-hidden="true" v-if="item.stepType==8">
 | ||
|                           <use xlink:href="#iconRecalled"></use>
 | ||
|                         </svg>
 | ||
| 
 | ||
|                         <svg class="svgProgress" aria-hidden="true" v-if="item.stepType==2">
 | ||
|                           <use xlink:href="#iconNo_Effect"></use>
 | ||
|                         </svg>
 | ||
| 
 | ||
|                       </div>
 | ||
|                       <div slot="title" class="record_title">
 | ||
|                         <p>{{ item.title }}</p>
 | ||
|                         <span>{{ item.approvalTime && moment(item.approvalTime).format("YYYY-MM-DD HH:mm") }}</span>
 | ||
|                       </div>
 | ||
|                       <div slot="description" class="record_desc">
 | ||
|                         <p class="desc_name">
 | ||
|                           {{ item.title2 }}
 | ||
|                           <span :style="{color:color(item.stepType)}">{{ item.title2Desc }}</span>
 | ||
|                         </p>
 | ||
|                         <!--                    <p class="desc_name">{{item.userName}}</p>-->
 | ||
| 
 | ||
|                         <span class="desc_name" v-if="item.opinion"
 | ||
|                               style="line-height: 26px;">审批意见:{{ item.opinion }}</span>
 | ||
|                         <ul class="desc_ul">
 | ||
|                           <li class="desc_li" v-if="item.candidateFieldInfos && item.candidateFieldInfos.length"
 | ||
|                               style="display: flex;flex-direction: column;">
 | ||
|                             <div v-for="(m,i) in item.candidateFieldInfos" :key="i" style="margin-left: 10px;">
 | ||
|                               <div class="desc_div">{{ m.fieldName }}<span
 | ||
|                                   v-if="m.fieldNameSuffix">{{ m.fieldNameSuffix }}</span>:{{
 | ||
|                                   m.dictionaryCode
 | ||
|                                       ? dict.getLabel(m.dictionaryCode, m.fieldValue) : m.fieldValue
 | ||
|                                 }}
 | ||
|                               </div>
 | ||
|                             </div>
 | ||
|                           </li>
 | ||
|                           <li class="desc_li">
 | ||
|                             <span class="li_opinion" v-if="item.annexFiles && item.annexFiles.length>0">审批附件:</span>
 | ||
|                             <div style="flex: 1;">
 | ||
|                               <div class="desc_div">
 | ||
|                                 <img @click="openImg(value.accessUrl)" v-for="(value,_v) in item.pictureFiles" :key="_v"
 | ||
|                                      :src="value.accessUrl" alt="图片" width="80px" height="80px"
 | ||
|                                      style="border: 1px solid #ddd;cursor: pointer;">
 | ||
|                               </div>
 | ||
|                               <ul class="file_ul">
 | ||
|                                 <li v-for="(v,_i) in item.annexFiles" :key="_i" @click="downFile(v.accessUrl)">
 | ||
|                                   <p>{{ v.name }}</p>
 | ||
|                                   <span>{{ Math.round(v.size / 1024) }}KB</span>
 | ||
|                                 </li>
 | ||
|                               </ul>
 | ||
|                             </div>
 | ||
|                           </li>
 | ||
|                         </ul>
 | ||
|                         <ul class="desc_ul dia_ul">
 | ||
|                           <li v-for="(value,index) in item.candidates" :key="index">
 | ||
|                             <p class="right_name" v-if="value.name">
 | ||
|                               <span v-if="!value.avatar">{{ value.name.slice(-2) }}</span>
 | ||
|                               <img v-else :src="value.avatar" alt="" width="40px" height="40px"
 | ||
|                                    style="border-radius: 50%;">
 | ||
|                             </p>
 | ||
|                             <p style="text-align: center;margin-top: 4px;">{{ value.name }}</p>
 | ||
|                           </li>
 | ||
|                         </ul>
 | ||
|                       </div>
 | ||
|                     </el-step>
 | ||
|                   </el-steps>
 | ||
|                 </div>
 | ||
|               </template>
 | ||
|             </ai-card>
 | ||
|           </template>
 | ||
| 
 | ||
|           <template v-if="currentMenu==4">
 | ||
|             <ai-card title="签署文件">
 | ||
|               <template #right>
 | ||
|                 <el-button type="primary" @click="handleDownload">下载文件</el-button>
 | ||
|               </template>
 | ||
|               <template #content>
 | ||
|                 <div class="sealFile">
 | ||
|                   <el-image :src="sealFileURL" :preview-src-list="[sealFileURL]">
 | ||
|                     <ai-empty slot="error"/>
 | ||
|                   </el-image>
 | ||
|                 </div>
 | ||
|               </template>
 | ||
|             </ai-card>
 | ||
|           </template>
 | ||
|         </el-scrollbar>
 | ||
|       </template>
 | ||
|     </ai-detail>
 | ||
| 
 | ||
|     <el-dialog :visible.sync="isOpen" width="600px">
 | ||
|       <img :src="imgUrl" alt="" width="100%" height="500px">
 | ||
|     </el-dialog>
 | ||
| 
 | ||
|     <!--审批同意、拒绝-->
 | ||
|     <el-dialog :title="titleType" center :visible.sync="isAgree" width="720px" v-loading="loading"
 | ||
|                :close-on-click-modal="false" @close="form.fieldInfos = []">
 | ||
|       <div style="height: 400px;overflow-y: auto;">
 | ||
|         <el-form size="small" :model="form" label-width="90px" ref="ruleForm" label-position="right"
 | ||
|                  class="dialog-form">
 | ||
|           <el-form-item v-for="(op,i) in form.fieldInfos" :key="i"
 | ||
|                         :label="op.fieldName + (op.fieldNameSuffix ? op.fieldNameSuffix : '')" class="dynamicFormItem"
 | ||
|                         :prop="`fieldInfos.${i}.fieldValue`"
 | ||
|                         :rules="{required:op.mustFill==1,message:`请输入${op.fieldName}`}">
 | ||
|             <el-input placeholder="请输入..." v-model.trim="op.fieldValue"
 | ||
|                       clearable v-if="op.fieldDataType=='0'" oninput="value=value.replace(/[^\d]/g,'')" show-word-limit
 | ||
|                       :maxlength="op.fieldLength"/>
 | ||
| 
 | ||
|             <el-input type="textarea" :rows="3" placeholder="请输入..." v-model.trim="op.fieldValue"
 | ||
|                       maxlength='500' clearable v-if="op.fieldDataType=='1'" show-word-limit
 | ||
|                       :maxlength="op.fieldLength"/>
 | ||
| 
 | ||
|             <el-radio-group style="width: 100%;" v-if="op.fieldDataType==4" v-model="op.fieldValue">
 | ||
|               <el-radio :label="k.dictValue" v-for="(k,m) in dict.getDict(op.dictionaryCode)" :key="m">
 | ||
|                 {{ k.dictName }}
 | ||
|               </el-radio>
 | ||
|             </el-radio-group>
 | ||
| 
 | ||
|             <el-date-picker
 | ||
|                 v-if="op.fieldDataType=='8'"
 | ||
|                 v-model.trim="op.fieldValue"
 | ||
|                 format="yyyy年MM月dd日"
 | ||
|                 value-format="yyyy年MM月dd日"
 | ||
|                 type="date"
 | ||
|                 placeholder="请选择">
 | ||
|             </el-date-picker>
 | ||
| 
 | ||
|             <el-select
 | ||
|                 v-if="op.fieldDataType=='9'"
 | ||
|                 size="small"
 | ||
|                 v-model="op.fieldValue"
 | ||
|                 placeholder="请选择"
 | ||
|                 clearable>
 | ||
|               <el-option
 | ||
|                   v-for="(k,m) in dict.getDict(op.dictionaryCode)"
 | ||
|                   :key="m"
 | ||
|                   :label="k.dictName"
 | ||
|                   :value="k.dictValue"
 | ||
|               />
 | ||
|             </el-select>
 | ||
| 
 | ||
|           </el-form-item>
 | ||
|           <el-form-item label="审批意见" prop="opinion" :rules="[{ required: true, message: '请输入审批意见', trigger: 'blur' }]"
 | ||
|                         v-if="titleType=='审批拒绝'">
 | ||
|             <el-input type="textarea" :rows='5' v-model.trim="form.opinion" placeholder="请输入" show-word-limit
 | ||
|                       :maxlength="500"></el-input>
 | ||
|           </el-form-item>
 | ||
|           <el-form-item label="图片" prop="imgList" style="position: relative;">
 | ||
|             <span style="position: absolute;left: -78px;top: 18px;font-size: 12px;color: #999;">(最多9张)</span>
 | ||
|             <el-upload
 | ||
|                 action
 | ||
|                 class="upload-demo"
 | ||
|                 multiple
 | ||
|                 list-type="picture-card"
 | ||
|                 :http-request="uploadImg"
 | ||
|                 :on-remove="handleRemoveImg"
 | ||
|                 :on-change="handleChangeImg"
 | ||
|                 :file-list="imgList"
 | ||
|                 :limit="9"
 | ||
|                 accept=".jpg,.png,.jpeg"
 | ||
|                 :on-exceed="()=>$message.error('最多只能上传9张图片!')">
 | ||
|               <div style="position: relative;">
 | ||
|                 <span class="iconfont iconPhoto" style="font-size: 35px;"></span>
 | ||
|                 <p style="position: absolute;top: 30px;left: 46px;">上传图片</p>
 | ||
|               </div>
 | ||
|             </el-upload>
 | ||
|           </el-form-item>
 | ||
|           <el-form-item label="附件" prop="fileList">
 | ||
|             <el-upload
 | ||
|                 class="upload-demo"
 | ||
|                 action
 | ||
|                 multiple
 | ||
|                 accept=".zip,.rar,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.txt,.jpg,.png"
 | ||
|                 :http-request="uploadFile"
 | ||
|                 :on-exceed="()=>$message.error('最多只能上传9个附件!')"
 | ||
|                 :on-remove="handleRemove"
 | ||
|                 :on-change="handleChange"
 | ||
|                 :limit="9"
 | ||
|                 :file-list="fileList">
 | ||
|               <el-button size="mini"> 添加附件</el-button>
 | ||
|               <div slot="tip" class="el-upload__tip">
 | ||
|                 <p style="line-height: 0;">最多上传9个附件,单个文件最大10MB </p>
 | ||
|                 <p style="line-height: 40px;">
 | ||
|                   支持.zip、.rar、.doc、.docx、.xls、.xlsx、.ppt、.pptx、.pdf、.txt、.jpg、.png格式</p>
 | ||
|               </div>
 | ||
|             </el-upload>
 | ||
|           </el-form-item>
 | ||
|         </el-form>
 | ||
|       </div>
 | ||
|       <div slot="footer" style="text-align: center;">
 | ||
|         <el-button style="width: 92px;" size="small" @click="cancel()">取消</el-button>
 | ||
|         <el-button style="width: 92px;" size="small" type="primary" @click="saveAgree">确认
 | ||
|         </el-button>
 | ||
|       </div>
 | ||
|     </el-dialog>
 | ||
|     <svg class="svgStatus" aria-hidden="true" v-if="currentMenu==0">
 | ||
|       <use xlink:href="#iconsp_ing" v-if="detail.approvalStatus==0"></use>
 | ||
|       <use xlink:href="#iconsp-pass" v-if="detail.approvalStatus==1"></use>
 | ||
|       <use xlink:href="#iconsp_refused" v-if="detail.approvalStatus==2"></use>
 | ||
|       <use xlink:href="#iconcancel" v-if="detail.approvalStatus==3"></use>
 | ||
|     </svg>
 | ||
|   </div>
 | ||
| </template>
 | ||
| 
 | ||
| <script>
 | ||
| import moment from 'dayjs'
 | ||
| import {mapState} from "vuex";
 | ||
| import Viewer from 'v-viewer'
 | ||
| import Vue from 'vue'
 | ||
| 
 | ||
| Vue.use(Viewer)
 | ||
| 
 | ||
| export default {
 | ||
|   name: "approvalDetail",
 | ||
|   inject: ['approval'],
 | ||
|   props: {
 | ||
|     instance: Function,
 | ||
|     dict: Object,
 | ||
|     permissions: Function,
 | ||
|     detail: Object,
 | ||
|     listType: String
 | ||
|   },
 | ||
|   data() {
 | ||
|     return {
 | ||
|       moment,
 | ||
|       currentMenu: 0,
 | ||
|       detailObj: {},
 | ||
|       dataList: [],
 | ||
|       processList: [],
 | ||
|       titleType: '',
 | ||
|       isAgree: false,
 | ||
|       form: {
 | ||
|         id: '',
 | ||
|         pass: true,
 | ||
|         annex: '',
 | ||
|         picture: '',
 | ||
|         option: "",
 | ||
|         transfers: [],
 | ||
|         fieldInfos: []
 | ||
|       },
 | ||
|       form1: {
 | ||
|         transfers: [],
 | ||
|         type: 1
 | ||
|       },
 | ||
|       allPerson: [],
 | ||
|       imgList: [],
 | ||
|       fileList: [],
 | ||
|       alreadyList: [],//已审批的
 | ||
|       imgUrl: '',
 | ||
|       isOpen: false,
 | ||
|       url: "/admin/sysunit/getAll2",
 | ||
|       applyForm: {},
 | ||
|       menuList: ["基本信息", '申请表单', '附件材料', "审批记录"],
 | ||
|       loading: false,
 | ||
|       areaId: "",
 | ||
|     }
 | ||
|   },
 | ||
|   computed: {
 | ||
|     rules() {
 | ||
|       return {
 | ||
|         transfers: [
 | ||
|           {required: true, message: '请选择转办人', trigger: 'change'}
 | ||
|         ]
 | ||
|       }
 | ||
|     },
 | ||
|     ...mapState(['user']),
 | ||
|     sealFileURL() {
 | ||
|       return this.detailObj?.pdfPicFile?.accessUrl || ""
 | ||
|     },
 | ||
|     colConfigs() {
 | ||
|       return [
 | ||
|         {label: "材料名称", prop: "annexName"},
 | ||
|         {slot: "annex"},
 | ||
|         {slot: "options"}
 | ||
|       ]
 | ||
|     }
 | ||
|   },
 | ||
|   methods: {
 | ||
|     handleDownload() {
 | ||
|       const aLink = document.createElement('a')
 | ||
|       aLink.download = this.detailObj.pdfFile.fileName || "签署文件"
 | ||
|       aLink.href = this.detailObj.pdfFile.url
 | ||
|       aLink.dispatchEvent(new MouseEvent('click', {}))
 | ||
|     },
 | ||
|     change(index) {
 | ||
|       this.currentMenu = index
 | ||
|       this.searchLog(index)
 | ||
|     },
 | ||
|     getValue(e, val) {
 | ||
|       return e.dictionaryCode && this.dict.getLabel(e.dictionaryCode, val)
 | ||
|     },
 | ||
|     getFieldValue(e) {
 | ||
|       return e.dictionaryCode ? this.dict.getLabel(e.dictionaryCode, e.fieldValue) : e.fieldValue
 | ||
|     },
 | ||
|     color(status) {
 | ||
|       return ['#2EA222', '#2EA222', '#FF4466', '#2EA222', '#FF8822', '#2EA222', '#2EA222', '#FF4466', '#FF8822', '#FF8822'][+status]
 | ||
|     },
 | ||
|     /**
 | ||
|      * 转办
 | ||
|      */
 | ||
|     onConfirm() {
 | ||
|       this.$refs["ruleForm1"].validate(valid => {
 | ||
|         if (valid) {
 | ||
|           this.form1.id = this.detail.id;
 | ||
|           this.instance.post('/oa/approv-alapply-info/approval', this.form1).then(res => {
 | ||
|             if (res && res.code == 0) {
 | ||
|               this.$message.success("转办成功");
 | ||
|               this.approval.goBack()
 | ||
|             }
 | ||
|           })
 | ||
|         }
 | ||
|       })
 | ||
|     },
 | ||
|     cancel() {
 | ||
|       this.form = {id: '', pass: true, annex: '', picture: '', fieldInfos: []}
 | ||
|       this.imgList = []
 | ||
|       this.fileList = []
 | ||
|       this.isAgree = false
 | ||
|     },
 | ||
|     openImg(url) {
 | ||
|       this.isOpen = true;
 | ||
|       this.imgUrl = url;
 | ||
|     },
 | ||
|     // 下载
 | ||
|     downFile(url) {
 | ||
|       window.open(url);
 | ||
|     },
 | ||
|     searchLog(index) {
 | ||
|       if (index == 3) {
 | ||
|         this.instance.post('/app/approv-alapply-info/processinfo-id2', null, {
 | ||
|           params: {id: this.detail.id}
 | ||
|         }).then(res => {
 | ||
|           if (res && res.data) {
 | ||
|             let cancelIndex = ''
 | ||
|             let isCancel = false
 | ||
|             let dictionaryArr = []
 | ||
|             res.data.map((item, index) => {
 | ||
|               item.isCancelItem = false
 | ||
|               if (item.stepType == 8) {
 | ||
|                 cancelIndex = index
 | ||
|                 isCancel = true
 | ||
|               }
 | ||
| 
 | ||
|               if (item.candidateFieldInfos) {
 | ||
|                 item.candidateFieldInfos.map(e => {
 | ||
|                   if (e.dictionaryCode && dictionaryArr.indexOf(e.dictionaryCode) == -1) {
 | ||
|                     dictionaryArr.push(e.dictionaryCode)
 | ||
|                   }
 | ||
|                 })
 | ||
|               }
 | ||
|             })
 | ||
|             if (isCancel) {
 | ||
|               res.data.map((item, index) => {
 | ||
|                 if (index > cancelIndex) {
 | ||
|                   item.isCancelItem = true
 | ||
|                 }
 | ||
|               })
 | ||
|             }
 | ||
|             if (dictionaryArr.length) {
 | ||
|               this.dict.load(dictionaryArr)
 | ||
|             }
 | ||
|             this.processList = res.data;
 | ||
|           }
 | ||
|         })
 | ||
|       }
 | ||
|     },
 | ||
|     // 节点记录
 | ||
|     searchDetail(id) {
 | ||
|       this.instance.post('/app/approv-alapply-info/info-id-table', null, {
 | ||
|         params: {id}
 | ||
|       }).then(res => {
 | ||
|         if (res && res.data) {
 | ||
|           this.detailObj = res.data
 | ||
|           let dicts = []
 | ||
|           res.data.tableInfo.tableFieldInfos.map(item => {
 | ||
|             item.dictionaryCode && dicts.push(item.dictionaryCode)
 | ||
|             if (item.fieldType == 0) {
 | ||
|               let {groupName} = item
 | ||
|               this.applyForm[groupName]?.push(item) || (this.applyForm[groupName] = [item])
 | ||
|             }
 | ||
|           })
 | ||
|           this.dict.load(dicts)
 | ||
|           if (res.data.approvalStatus == 1) {
 | ||
|             this.menuList.push('签署文件')
 | ||
|           }
 | ||
|         }
 | ||
|       })
 | ||
|     },
 | ||
|     // 上传图片
 | ||
|     uploadImg(file) {
 | ||
|       const isLt10M = file.file.size / 1024 / 1024 < 10;
 | ||
|       if (!isLt10M) {
 | ||
|         this.$message.error("附件大小不超过10mb!");
 | ||
|         for (let i = 0; i < this.imgList.length; i++) {
 | ||
|           if (this.imgList[i].uid == file.file.uid) {
 | ||
|             this.imgList.splice(i, 1);
 | ||
|           }
 | ||
|         }
 | ||
|         return;
 | ||
|       }
 | ||
|       let formData = new FormData();
 | ||
|       formData.append("file", file.file);
 | ||
|       this.instance.post(`/admin/file/add`, formData).then(res => {
 | ||
|         if (res && res.code == 0) {
 | ||
|           let img = res.data[0].split(';');
 | ||
|           this.imgList.forEach((item, index) => {
 | ||
|             if (item.uid == file.file.uid) {
 | ||
|               this.imgList[index].id = img[1];
 | ||
|             }
 | ||
|           })
 | ||
|         }
 | ||
|       });
 | ||
|     },
 | ||
|     handleRemoveImg(file, fileList) {
 | ||
|       this.imgList = fileList;
 | ||
|     },
 | ||
|     handleChangeImg(file, fileList) {
 | ||
|       this.imgList = fileList;
 | ||
|     },
 | ||
|     // 上传附件
 | ||
|     uploadFile: function (file) {
 | ||
|       const isLt10M = file.file.size / 1024 / 1024 < 10;
 | ||
|       if (!isLt10M) {
 | ||
|         this.$message.error("附件大小不超过10mb!");
 | ||
|         for (let i = 0; i < this.fileList.length; i++) {
 | ||
|           if (this.fileList[i].uid == file.file.uid) {
 | ||
|             this.fileList.splice(i, 1);
 | ||
|           }
 | ||
|         }
 | ||
|         return;
 | ||
|       }
 | ||
|       let formData = new FormData();
 | ||
|       formData.append("file", file.file);
 | ||
|       this.instance.post(`/admin/file/add`, formData, {withCredentials: false}).then(res => {
 | ||
|         if (res && res.code == 0) {
 | ||
|           let img = res.data[0].split(';');
 | ||
|           this.fileList.forEach((item, index) => {
 | ||
|             if (item.uid == file.file.uid) {
 | ||
|               this.fileList[index].id = img[1];
 | ||
|             }
 | ||
|           })
 | ||
|         }
 | ||
|       });
 | ||
|     },
 | ||
|     handleRemove(file, fileList) {
 | ||
|       this.fileList = fileList;
 | ||
|     },
 | ||
|     handleChange(file, fileList) {
 | ||
|       this.fileList = fileList;
 | ||
|     },
 | ||
| 
 | ||
|     /**
 | ||
|      * 同意和拒绝
 | ||
|      * @param index
 | ||
|      */
 | ||
|     agreeRefulse(index) {
 | ||
|       let dictionaryArr = []
 | ||
|       this.instance.post(`/app/approv-alapply-info/approval-popup?id=${this.detail.id}&type=${index}`).then(res => {
 | ||
|         if (res && res.data) {
 | ||
|           if (index == 1) {
 | ||
|             res.data.fieldInfos.map(e => {
 | ||
|               if (e.fieldType == 3 && e.dictionaryCode && dictionaryArr.indexOf(e.dictionaryCode) == -1) {
 | ||
|                 dictionaryArr.push(e.dictionaryCode)
 | ||
|               }
 | ||
|             })
 | ||
|             if (dictionaryArr.length) {
 | ||
|               this.dict.load(dictionaryArr).then(() => {
 | ||
|                 this.form.fieldInfos = res.data.fieldInfos.filter(e => e.fieldType == 3)
 | ||
|               })
 | ||
|             } else {
 | ||
|               this.form.fieldInfos = res.data.fieldInfos.filter(e => e.fieldType == 3)
 | ||
|             }
 | ||
|           }
 | ||
| 
 | ||
|           this.isAgree = true;
 | ||
|           if (index == 0) {
 | ||
|             this.form.pass = false;
 | ||
|             this.titleType = '审批拒绝';
 | ||
|           } else {
 | ||
|             this.form.pass = true;
 | ||
|             this.titleType = '审批同意';
 | ||
|           }
 | ||
|         }
 | ||
|       }).catch(err => {
 | ||
|         console.log(err);
 | ||
|       })
 | ||
|     },
 | ||
|     saveAgree() {
 | ||
|       this.form.id = this.detail.id;
 | ||
|       let arr = [];
 | ||
|       let brr = [];
 | ||
|       this.imgList.map(v => {
 | ||
|         arr.push(v.id)
 | ||
|       });
 | ||
|       this.form.picture = arr.join(',');
 | ||
|       this.fileList.map(_v => {
 | ||
|         brr.push(_v.id)
 | ||
|       });
 | ||
|       this.form.transfers = this.allPerson.candidateList;
 | ||
|       this.form.annex = brr.join(',');
 | ||
|       this.$refs["ruleForm"].validate((valid) => {
 | ||
|         if (valid) {
 | ||
|           this.loading = true
 | ||
|           this.instance.post('/app/approv-alapply-info/approval', this.form).then((res) => {
 | ||
|             if (res?.code == 0) {
 | ||
|               this.$message.success('审批已提交!');
 | ||
|               this.isAgree = false
 | ||
|               this.loading = false
 | ||
|               this.approval.goBack()
 | ||
|             }
 | ||
|           }).catch((err) => {
 | ||
|             this.$message.error(err.response.data.msg || "服务器异常")
 | ||
|             this.loading = false
 | ||
|           })
 | ||
|         }
 | ||
|       });
 | ||
|     },
 | ||
|     // 撤回
 | ||
|     recall() {
 | ||
|       this.$confirm("确定撤回该审批吗?").then(() => {
 | ||
|         this.instance.post('/app/approv-alapply-info/cancel', null, {
 | ||
|           params: {id: this.detail.id}
 | ||
|         }).then((res) => {
 | ||
|           if (res && res.code == 0) {
 | ||
|             this.approval.goBack()
 | ||
|           }
 | ||
|         }).catch(() => {
 | ||
|         })
 | ||
|       })
 | ||
|     },
 | ||
|   },
 | ||
|   created() {
 | ||
|     this.dict.load(['nodeType', 'approvalStatus', 'hbDepartment', 'sex', 'nation', 'marital', 'education', 'yesOrNo'])
 | ||
|     this.areaId = this.user.info.areaId.substring(0, 6) + '000000'
 | ||
|     this.searchDetail(this.detail.id);
 | ||
|     this.searchLog(this.currentMenu)
 | ||
|   },
 | ||
|   filters: {
 | ||
|     format(time) {
 | ||
|       return time ? moment(time).format("YYYY-MM-DD HH:mm") : '-'
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| </script>
 | ||
| 
 | ||
| <style scoped lang="scss">
 | ||
| .app_detail {
 | ||
|   height: 100%;
 | ||
|   display: flex;
 | ||
|   flex-direction: column;
 | ||
| 
 | ||
|   ::v-deep .el-scrollbar {
 | ||
|     min-height: 0;
 | ||
|     flex: 1;
 | ||
|     margin-bottom: 16px;
 | ||
| 
 | ||
|     .is-horizontal {
 | ||
|       display: none;
 | ||
|     }
 | ||
| 
 | ||
|     .el-scrollbar__wrap {
 | ||
|       overflow-x: hidden;
 | ||
|     }
 | ||
| 
 | ||
|     .right-content {
 | ||
|       position: relative;
 | ||
|       height: 100%;
 | ||
|       padding: 0 !important;
 | ||
|       width: 760px;
 | ||
|       display: flex;
 | ||
|       flex-direction: column;
 | ||
|       gap: 16px;
 | ||
|       overflow: visible !important;
 | ||
| 
 | ||
|       .applyForm {
 | ||
|         min-height: 0;
 | ||
|         flex: 1;
 | ||
|       }
 | ||
| 
 | ||
|       .sealFile {
 | ||
|         min-height: 0;
 | ||
|         flex: 1;
 | ||
|         background: #F7F7F7;
 | ||
|         border: 1px solid #DDDDDD;
 | ||
|         padding: 20px;
 | ||
| 
 | ||
|         .el-image {
 | ||
|           width: 100%;
 | ||
|           height: 100%;
 | ||
|           background: #fff;
 | ||
|           border: 1px solid #EEEEEE;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   ::v-deep .dynamicFormItem {
 | ||
|     .el-form-item__label {
 | ||
|       line-height: normal;
 | ||
|       display: flex;
 | ||
|       align-items: center;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .tableImage {
 | ||
|     width: 64px;
 | ||
|     height: 64px;
 | ||
|   }
 | ||
| 
 | ||
|   .com_nav {
 | ||
|     height: 48px;
 | ||
|     line-height: 48px;
 | ||
|     background-color: #fff;
 | ||
|     padding: 0 16px;
 | ||
|     font-weight: bold;
 | ||
|     border-bottom: 1px solid #D8DCE3;
 | ||
|     display: flex;
 | ||
|     justify-content: space-between;
 | ||
|   }
 | ||
| 
 | ||
|   .add_title {
 | ||
|     height: 56px;
 | ||
|     line-height: 56px;
 | ||
|     border-bottom: 1px solid #eee;
 | ||
|     color: #333;
 | ||
|     font-weight: bold;
 | ||
|     margin-bottom: 16px;
 | ||
|     display: flex;
 | ||
|     justify-content: space-between;
 | ||
|   }
 | ||
| 
 | ||
|   .border-wrap {
 | ||
|     box-sizing: border-box;
 | ||
|     padding: 20px;
 | ||
|     width: 100%;
 | ||
|     min-height: 100px;
 | ||
|     border: 1px solid #6FAFFF;
 | ||
| 
 | ||
|     .no-data {
 | ||
|       background-size: 120px 120px;
 | ||
|       height: 160px;
 | ||
|       margin: 48px auto 10px;
 | ||
|     }
 | ||
| 
 | ||
|     .small-input {
 | ||
|       width: 48px;
 | ||
|       margin: 0 8px;
 | ||
|     }
 | ||
| 
 | ||
|     ::v-deep .family-info {
 | ||
|       margin-left: 24px;
 | ||
| 
 | ||
|       ::v-deep .el-form-item__content {
 | ||
|         margin-left: 24px !important;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .svgStatus {
 | ||
|     position: absolute;
 | ||
|     top: 80px;
 | ||
|     right: 380px;
 | ||
|     width: 90px;
 | ||
|   }
 | ||
| 
 | ||
|   .detail_ul {
 | ||
|     display: flex;
 | ||
|     justify-content: space-between;
 | ||
|     flex-wrap: wrap;
 | ||
|     font-size: 14px;
 | ||
|     margin-bottom: 20px;
 | ||
| 
 | ||
|     li {
 | ||
|       width: 33%;
 | ||
|       display: flex;
 | ||
|       margin-bottom: 8px;
 | ||
| 
 | ||
|       span {
 | ||
|         width: 70px;
 | ||
|         color: #999;
 | ||
|       }
 | ||
| 
 | ||
|       p {
 | ||
|         flex: 1;
 | ||
|         color: #333;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     img {
 | ||
|       margin-right: 16px;
 | ||
|       margin-bottom: 16px;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .file_ul {
 | ||
|     li {
 | ||
|       height: 40px;
 | ||
|       line-height: 40px;
 | ||
|       border: 1px solid #D0D4DC;
 | ||
|       border-radius: 4px;
 | ||
|       margin-bottom: 16px;
 | ||
|       padding: 0 8px;
 | ||
|       font-size: 14px;
 | ||
|       color: #333;
 | ||
|       display: flex;
 | ||
|       justify-content: space-between;
 | ||
|       cursor: pointer;
 | ||
| 
 | ||
|       span {
 | ||
|         color: #999;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     li:hover {
 | ||
|       color: #2266FF;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .add_record {
 | ||
|     .record_icon {
 | ||
|       position: relative;
 | ||
| 
 | ||
|       .icon_img {
 | ||
|         width: 40px;
 | ||
|         height: 40px;
 | ||
|         border-radius: 50%;
 | ||
|         // background-color: #2266FF;
 | ||
|         color: #fff;
 | ||
|         line-height: 44px;
 | ||
|         font-size: 14px;
 | ||
|       }
 | ||
| 
 | ||
|       .svgProgress {
 | ||
|         height: 14px;
 | ||
|         width: 14px;
 | ||
|         position: absolute;
 | ||
|         bottom: -2px;
 | ||
|         right: -2px;
 | ||
|       }
 | ||
| 
 | ||
|       .pro {
 | ||
|         height: 14px;
 | ||
|         width: 14px;
 | ||
|         position: absolute;
 | ||
|         bottom: 2px;
 | ||
|         right: -6px;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .record_title {
 | ||
|       display: flex;
 | ||
|       justify-content: space-between;
 | ||
| 
 | ||
|       p {
 | ||
|         font-size: 16px;
 | ||
|         color: #333;
 | ||
|       }
 | ||
| 
 | ||
|       span {
 | ||
|         font-size: 14px;
 | ||
|         color: #999;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .record_desc {
 | ||
|       .desc_name {
 | ||
|         font-size: 14px;
 | ||
|         color: #666;
 | ||
|       }
 | ||
| 
 | ||
|       .desc_ul {
 | ||
|         font-size: 14px;
 | ||
|         color: #666;
 | ||
| 
 | ||
|         .desc_li {
 | ||
|           display: flex;
 | ||
|           margin-top: 8px;
 | ||
| 
 | ||
|           .li_opinion {
 | ||
|             width: 80px;
 | ||
|           }
 | ||
| 
 | ||
|           .desc_div {
 | ||
|             flex: 1;
 | ||
|             display: flex;
 | ||
|             flex-wrap: wrap;
 | ||
| 
 | ||
|             img {
 | ||
|               margin-right: 8px;
 | ||
|               margin-bottom: 8px;
 | ||
|             }
 | ||
|           }
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       .dia_ul {
 | ||
|         display: flex;
 | ||
|         flex-wrap: wrap;
 | ||
|         margin-top: 10px;
 | ||
| 
 | ||
|         li {
 | ||
|           margin-right: 16px;
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       .desc_status {
 | ||
|         color: #2EA222;
 | ||
|       }
 | ||
| 
 | ||
|       .desc_status2 {
 | ||
|         color: #FF4466;
 | ||
|       }
 | ||
| 
 | ||
|       .desc_status1 {
 | ||
|         color: #FF8822;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .right_name {
 | ||
|     border: 1px solid #fff;
 | ||
|     width: 40px;
 | ||
|     height: 40px;
 | ||
|     border-radius: 50%;
 | ||
|     line-height: 40px;
 | ||
|     text-align: center;
 | ||
|     font-size: 14px;
 | ||
|     background-color: #2266FF;
 | ||
|     color: #fff;
 | ||
|     position: relative;
 | ||
|   }
 | ||
| 
 | ||
|   ::v-deep .ailist-title__right {
 | ||
|     font-size: 14px;
 | ||
|     color: #5088FF;
 | ||
|     user-select: none;
 | ||
|     cursor: pointer;
 | ||
|   }
 | ||
| }
 | ||
| </style>
 | ||
| <style lang="scss">
 | ||
| .app_detail {
 | ||
|   height: 100%;
 | ||
|   overflow: auto;
 | ||
| 
 | ||
|   .el-step.is-vertical .el-step__line {
 | ||
|     width: 1px;
 | ||
|     left: 20px;
 | ||
|   }
 | ||
| 
 | ||
|   .el-step__icon {
 | ||
|     width: 40px;
 | ||
|     height: 40px;
 | ||
|     background-color: #2266FF;
 | ||
|     border: 1px solid #fff;
 | ||
|   }
 | ||
| 
 | ||
|   .bg-999 {
 | ||
|     color: #999;
 | ||
| 
 | ||
|     .el-step__icon {
 | ||
|       background-color: #D0D4DC !important;
 | ||
|     }
 | ||
| 
 | ||
|     .el-step__line {
 | ||
|       background-color: #fff;
 | ||
|     }
 | ||
| 
 | ||
|     .record_title {
 | ||
|       p {
 | ||
|         color: #999 !important;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .desc_name, .desc_ul {
 | ||
|       color: #999 !important;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .step-hide {
 | ||
|     .el-step__line {
 | ||
|       background-color: #fff;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
| 
 | ||
|   .el-step__main {
 | ||
|     padding-left: 36px !important;
 | ||
|     margin-bottom: 30px;
 | ||
|   }
 | ||
| 
 | ||
|   .line-left {
 | ||
|     flex: 1;
 | ||
|     display: flex;
 | ||
|     justify-content: flex-end;
 | ||
|   }
 | ||
| 
 | ||
|   .dia_ul {
 | ||
|     justify-content: left;
 | ||
|     flex-wrap: wrap;
 | ||
| 
 | ||
|     li {
 | ||
|       margin-bottom: 10px;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .line-right {
 | ||
|     width: 90px;
 | ||
|   }
 | ||
| 
 | ||
|   .right_p {
 | ||
|     border: 1px dashed #2266FF;
 | ||
|     width: 40px;
 | ||
|     height: 40px;
 | ||
|     border-radius: 50%;
 | ||
|     line-height: 40px;
 | ||
|     text-align: center;
 | ||
|     color: #2266FF;
 | ||
|     margin: 0 22px;
 | ||
|     cursor: pointer;
 | ||
|     box-sizing: border-box;
 | ||
| 
 | ||
|     .el-icon-plus {
 | ||
|       font-size: 20px;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .right_name {
 | ||
|     border: 1px solid #fff;
 | ||
|     width: 40px;
 | ||
|     height: 40px;
 | ||
|     border-radius: 50%;
 | ||
|     line-height: 40px;
 | ||
|     text-align: center;
 | ||
|     font-size: 14px;
 | ||
|     background-color: #2266FF;
 | ||
|     color: #fff;
 | ||
|     margin: 0 20px;
 | ||
|     position: relative;
 | ||
| 
 | ||
|     .el-icon-arrow-right, .el-icon-circle-plus {
 | ||
|       position: absolute;
 | ||
|       top: 15px;
 | ||
|       right: -30px;
 | ||
|       color: #999;
 | ||
|     }
 | ||
| 
 | ||
|     .el-icon-error {
 | ||
|       position: absolute;
 | ||
|       top: 0;
 | ||
|       color: #333;
 | ||
|       right: -6px;
 | ||
|       cursor: pointer;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .material {
 | ||
|     box-sizing: border-box;
 | ||
|     padding: 30px 40px;
 | ||
| 
 | ||
|     .mat-title {
 | ||
|       width: 100%;
 | ||
|       display: flex;
 | ||
|       align-items: center;
 | ||
|       justify-content: space-between;
 | ||
| 
 | ||
|       & > p:nth-child(1) {
 | ||
|         width: 120px;
 | ||
|         text-align: center;
 | ||
|       }
 | ||
| 
 | ||
|       & > p:nth-child(2) {
 | ||
|         width: 350px;
 | ||
|         text-align: center;
 | ||
|       }
 | ||
| 
 | ||
|       & > p:nth-child(3) {
 | ||
|         width: 145px;
 | ||
|         text-align: center;
 | ||
|       }
 | ||
| 
 | ||
|       & > p {
 | ||
|         color: #333333;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .mat-item {
 | ||
|       width: 100%;
 | ||
|       display: flex;
 | ||
|       align-items: center;
 | ||
|       justify-content: space-between;
 | ||
|       margin-top: 13px;
 | ||
| 
 | ||
|       & > p:nth-child(1) {
 | ||
|         width: 120px;
 | ||
|         text-align: center;
 | ||
|       }
 | ||
| 
 | ||
|       & > p:nth-child(2) {
 | ||
|         width: 350px;
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         justify-content: center;
 | ||
|         flex-wrap: wrap;
 | ||
| 
 | ||
|         & > img {
 | ||
|           margin-right: 8px;
 | ||
|           margin-bottom: 8px;
 | ||
|           width: 64px;
 | ||
|           height: 64px;
 | ||
|         }
 | ||
|       }
 | ||
| 
 | ||
|       & > p:nth-child(3) {
 | ||
|         width: 145px;
 | ||
|         color: #5088FF;
 | ||
|         user-select: none;
 | ||
|         cursor: pointer;
 | ||
|         text-align: center;
 | ||
| 
 | ||
|         & > span:nth-child(2) {
 | ||
|           margin-left: 16px;
 | ||
|         }
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   .upload-demo {
 | ||
|     ::v-deep .el-icon-close {
 | ||
|       transform: translateX(-50px);
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
|   ::v-deep .el-radio {
 | ||
|     margin-bottom: 10px;
 | ||
|   }
 | ||
| 
 | ||
|   .dialog-form {
 | ||
|     ::v-deep .el-form-item__label {
 | ||
|       justify-content: flex-end;
 | ||
|     }
 | ||
|   }
 | ||
| 
 | ||
| }
 | ||
| </style>
 |