Browse Source

用印审批列表

jwyu 1 year ago
parent
commit
eaf5027b30

+ 20 - 20
src/router/modules/approvalRoutes.js

@@ -17,17 +17,17 @@ export default [
 					keepAlive: false
 				}
 			},
-			// {
-			// 	path: 'contractdetailapr',
-			// 	component: () => import('@/views/contract_manage/contractDetail.vue'),
-			// 	name: "合同详情",
-			// 	hidden: false,
-			// 	meta: {
-			// 		pathFrom: 'contractapprovallist',
-			// 		pathName: '合同审批',
-			// 		keepAlive: false
-			// 	}
-			// },
+			{
+				path: 'contractdetailapr',
+				component: () => import('@/views/contract_manage/contractDetail.vue'),
+				name: "合同详情",
+				hidden: false,
+				meta: {
+					pathFrom: 'contractapprovallist',
+					pathName: '合同审批',
+					keepAlive: false
+				}
+			},
 			// {
 			// 	path: 'contractdetaildcapr',
 			// 	component: () => import('@/views/contract_manage/contractDetailDC.vue'),
@@ -48,15 +48,15 @@ export default [
 					keepAlive: false
 				}
 			},
-			// {
-			// 	path: "sealApprovalList",
-			// 	component: () => import('@/views/seal_manage/approvalList.vue'),
-			// 	name: '用印审批',
-			// 	hidden: false,
-			// 	meta: {
-			// 		keepAlive: false
-			// 	}
-			// },
+			{
+				path: "sealApprovalList",
+				component: () => import('@/views/seal_manage/approvalList.vue'),
+				name: '用印审批',
+				hidden: false,
+				meta: {
+					keepAlive: false
+				}
+			},
 			// {
 			// 	path: "addSeal",
 			// 	component: () => import('@/views/seal_manage/updateSeal.vue'),

+ 9 - 0
src/views/contract_manage/contractDetail.vue

@@ -0,0 +1,9 @@
+<script setup>
+
+</script>
+
+<template>
+    <div>
+        
+    </div>
+</template>

+ 26 - 3
src/views/contract_manage/preViewContract.vue

@@ -1,10 +1,33 @@
 <script setup>
-
 import { ref } from 'vue'
+import { contractInterface } from "@/api/api.js";
+import { useRoute } from 'vue-router';
+
+const route = useRoute()
+
+const content = ref('')
+
+function getContent() {
+  const id = route.query.contractid || ''
+  if (!id) {
+    content.value = sessionStorage.getItem('contractdtl')
+    return
+  }
+  contractInterface.previewContractById({ ContractId: id }).then(res => {
+    if (res.Ret === 200) {
+      content.value = res.Data.Html
+    }
+  })
+}
+
+getContent()
+
 </script>
+
+
 <template>
-  <div></div>
+  <div v-html="content"></div>
 </template>
-<style scoped lang="scss">
 
+<style scoped lang="scss">
 </style>

+ 1186 - 0
src/views/seal_manage/approvalList.vue

@@ -0,0 +1,1186 @@
+<script setup>
+import { formatTime } from '@/utils/date'
+import { reactive, watch, ref } from 'vue'
+import { contractInterface, sealInterence } from "@/api/api.js";
+import $ from "jquery"
+import { ElMessage, ElMessageBox } from 'element-plus';
+
+const pageState = reactive({
+  RoleType: localStorage.getItem('Role') || '',
+  userId: localStorage.getItem('AdminId'),
+  contractTypeList: ['新签合同', '续约合同', '补充协议', '代付合同'],
+  contractTypeVal: '',
+  sealStatusList: ['待审批', '待提交', '已撤回', '处理中', '已审批', '已驳回', '已签回', '已作废'],
+  sealStatusVal: '',
+  time: ['', ''],
+  searchVal: '',
+  tableList: [],
+  page: 1,
+  pageSize: 10,
+  total: 0,
+
+  sellerList: [], //申请销售列表
+  seller: "", //选择的申请销售
+  defaultSalesProps: {
+    multiple: true,
+    label: 'RealName',
+    children: 'ChildrenList',
+    value: 'AdminId'
+  },//销售级联配置
+
+  detail: null,
+  showDetail: false,
+  optList: [],
+  stepArr: [],//审批流程数据
+  approvalEditData: {
+    Use: '',//用印用途
+    Type: '',//加盖印章 类型
+    FileNum: '',//文件份数
+    Remark: '',//备注
+  },
+
+  form: {
+    status: "通过",
+    reason: "",
+  },
+  formRule: {
+    status: [{ required: true, message: "请选择状态", trigger: "change" }],
+    reason: [{ required: true, message: "请填写驳回理由", trigger: "blur" }],
+  },
+
+  showUploadAttachment: false,//显示上传(更新附件)
+  fileData: {
+    type: 0,//1 上传附件 2 更新附件
+    title: "",
+    name: "",
+    file: null,
+    sealId: 0,
+  },//上传/更新附件文件数据
+  showAttachment: false,// 是否显示预览附件弹窗
+  attachmentUrls: [],// 附件列表
+})
+
+// 弹窗关闭清除弹窗的值
+watch(
+  () => pageState.showDetail,
+  (nval) => {
+    if (!nval) {
+      pageState.detail = null
+      pageState.optList = []
+      pageState.stepArr = []
+      pageState.approvalEditData = {
+        Use: '',//用印用途
+        Type: '',//加盖印章 类型
+        FileNum: '',//文件份数
+        Remark: '',//备注
+      }
+      pageState.form = {
+        status: "通过",
+        reason: "",
+      }
+
+    }
+  }
+)
+
+//上传附件弹窗关闭清除值
+watch(
+  () => pageState.showUploadAttachment,
+  (nval) => {
+    if (!nval) {
+      pageState.fileData = {
+        type: 0,//1 上传附件 2 更新附件
+        title: "",
+        name: "",
+        file: null,
+        sealId: 0,
+      }
+    }
+  }
+)
+
+function initPage() {
+  getSellerList();
+  getSealApprovalList()
+  if (['ficc_seller', 'rai_seller'].includes(pageState.RoleType)) {
+    pageState.sealStatusList = ['待审批', '已撤回', '处理中', '已审批', '已驳回', '已签回', '已作废']
+  } else {
+    pageState.sealStatusList = ['待审批', '处理中', '已审批', '已驳回', '已签回', '已作废']
+  }
+}
+initPage()
+
+function getSellerList() {//获取所属销售列表
+  contractInterface.getSellerList().then((res) => {
+    if (res.Ret === 200) {
+      pageState.sellerList = res.Data.List;
+    }
+  });
+}
+
+async function getSealApprovalList() {
+  let salesArr = []
+  if (pageState.seller.length) {
+    salesArr = pageState.seller.map(item => {
+      return item[item.length - 1]
+    })
+  }
+  const res = await sealInterence.getSealApprovalList({
+    PageSize: pageState.pageSize,
+    CurrentIndex: pageState.page,
+    ContractType: pageState.contractTypeVal,
+    Status: pageState.sealStatusVal,
+    SellerId: salesArr.join(','),
+    StartTime: pageState.time && pageState.time[0] || '',
+    EndTime: pageState.time && pageState.time[1] || '',
+    Keyword: pageState.searchVal
+  })
+  if (res.Ret === 200) {
+    pageState.tableList = res.Data.List
+    pageState.total = res.Data.Paging.Totals
+  }
+}
+
+function handleSelectChange() {
+  pageState.searchVal = ''
+  getSealApprovalList()
+}
+
+function handleSearch() {
+  pageState.contractTypeVal = ''
+  pageState.sealStatusVal = ''
+  pageState.time = ['', '']
+  pageState.seller = ''
+  getSealApprovalList()
+}
+
+function handlePageChange(e) {
+  pageState.page = e
+  getSealApprovalList()
+}
+
+async function handleDetail(e) {
+  getSealOprationList(e.SealId)
+  const res = await sealInterence.getSealDetail({ SealId: e.SealId })
+  if (res.Ret == 200) {
+    pageState.showDetail = true
+    pageState.detail = res.Data
+    pageState.approvalEditData.Use = res.Data.SealDetail.Use
+    pageState.approvalEditData.Type = res.Data.SealDetail.SealType.split(',')
+    pageState.approvalEditData.FileNum = res.Data.SealDetail.FileNum
+    pageState.approvalEditData.Remark = res.Data.SealDetail.Remark
+    handleStepArr()
+  }
+}
+
+// 处理审批流程节点
+function handleStepArr() {
+  let arr = []
+  let count = 0
+  arr = pageState.detail.FlowNodeList && pageState.detail.FlowNodeList.map(item => {
+    item[0].NodeType === 'check' && count++
+    let stepCon = {
+      name: item[0].NodeType === 'check' ? '审批人' : '抄送人',//审批节点标题
+      intro: '',//描述
+      user: item.slice(0, 2),//审批节点人列表
+      allUser: item,
+      approve: [],//审批人信息{name:'',time:""}
+      auditType: 1,
+      stepName: ''
+    }
+    if (item[0].NodeType === 'check') {
+      if (item[0].AuditType === 1) {
+        stepCon.intro = item.length > 1 ? item.length + '人或签' : ''
+        stepCon.auditType = 1
+      } else if (item[0].AuditType === 2) {
+        stepCon.intro = item.length > 1 ? item.length + '人会签' : ''
+        stepCon.auditType = 2
+      }
+      item.forEach(item2 => {
+        if (item2.Status !== '待审批' && item2.Status !== '已撤回') {
+          let time = ''
+          if (item2.Status === '已驳回') {
+            time = `驳回时间:${item2.ApproveTime}`
+          } else {
+            time = `审批时间:${item2.ApproveTime}`
+          }
+          let obj = { name: item2.ApproveUserName, time: time }
+          stepCon.approve.push(obj)
+        }
+      })
+    }
+
+    if (item[0].NodeType === 'cc') {
+      stepCon.intro = '抄送' + item.length + '人'
+    }
+
+    return stepCon
+  })
+
+
+  // 处理审批节点标题描述  若有多级审批 则 为 一级审批 二级审批 若只有一级 则 不变
+  // if(count>1){
+  let tag = 0
+  arr.forEach(item => {
+    if (item.name === '审批人') {
+      tag++
+      switch (tag) {
+        case 1:
+          item.stepName = '一级审批'
+          break;
+        case 2:
+          item.stepName = '二级审批'
+          break;
+        case 3:
+          item.stepName = '三级审批'
+          break;
+      }
+    }
+  })
+  // }
+
+  pageState.stepArr = arr
+}
+
+// 获取操作记录
+async function getSealOprationList(id) {
+  const res = await sealInterence.getSealOperationList({ SealId: id })
+  if (res.Ret === 200) {
+    pageState.optList = res.Data.List
+  }
+}
+
+// 预览合同
+function handlePreContractFile(urls) {
+  if (urls.length == 0) return
+  if (urls.length == 1) {
+    viewAttachment(urls[0])
+  } else {
+    pageState.attachmentUrls = urls
+    pageState.showAttachment = true
+  }
+
+}
+
+// 根据文件返回文件图标
+function fileTypeIcon(url) {
+  if (!url) return "";
+  const fileType = fileType(url);
+  return fileType === "word"
+    ? require("@/assets/img/constract/word-icon.png")
+    : require("@/assets/img/constract/pdf.png");
+}
+
+// 根据fileUrl判断文件类型
+function fileType(fileUrl) {
+  if (/^.+(\.pdf)$/i.test(fileUrl)) {
+    return "pdf";
+  } else if (/^.+(\.doc|\.docx)$/i.test(fileUrl)) {
+    return "word";
+  } else {
+    return "other";
+  }
+}
+
+
+// 预览合同附件
+function viewAttachment(url) {
+  const reg = /\.(pdf)$/;
+  // pdf
+  if (reg.test(url)) {
+    window.open(url, '_blank');
+  } else {
+    window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url, '_blank');
+  }
+}
+
+// 审批弹窗审批状态切换
+function approvalFromStatusChange() {
+  if (pageState.form.status === '驳回') {
+    let top = $('.detail-wrap')[0].offsetTop
+    $('.detail-wrap').animate({
+      "scrollTop": top + 1000
+    })
+  }
+}
+
+const form = ref(null)
+function handleConfirmApproval() {
+  form.value.validate((valid) => {
+    if (valid) {
+      if (pageState.form.status == '通过') {
+        //判断是否有内容修改
+        const flag1 = pageState.approvalEditData.Use === pageState.detail.SealDetail.Use
+        const flag2 = Number(pageState.approvalEditData.FileNum) === Number(pageState.detail.SealDetail.FileNum)
+        const flag3 = pageState.approvalEditData.Type.join(',') === pageState.detail.SealDetail.SealType
+        const flag4 = pageState.approvalEditData.Remark === pageState.detail.SealDetail.Remark
+        if (flag1 && flag2 && flag3 && flag4) {
+          handleApprovalPass()
+        } else {
+          handleApprovePassModify()
+        }
+      } else {
+        handleApprvoalReject()
+      }
+    }
+  })
+
+
+}
+
+// 通过审批
+async function handleApprovalPass() {
+  const res = await sealInterence.sealApprovalPass({
+    SealId: pageState.detail.SealDetail.SealId
+  })
+  if (res.Ret == 200) {
+    ElMessage.success('审批成功')
+    pageState.showDetail = false
+    setTimeout(() => {
+      getSealApprovalList()
+    }, 300);
+
+  }
+}
+
+// 审批人修改后通过审批
+async function handleApprovePassModify() {
+  const res = await sealInterence.sealApprovalPassModify({
+    CompanyName: pageState.detail.SealDetail.CompanyName,
+    ContractId: pageState.detail.SealDetail.ContractId,
+    CreditCode: pageState.detail.SealDetail.CreditCode,
+    FileUrls: pageState.detail.SealDetail.FileUrls,
+    SealId: pageState.detail.SealDetail.SealId,
+    ServiceType: pageState.detail.SealDetail.ServiceType,
+    UseCompanyName: pageState.detail.SealDetail.UseCompanyName,
+
+    FileNum: Number(pageState.approvalEditData.FileNum),
+    Remark: pageState.approvalEditData.Remark,
+    SealType: pageState.approvalEditData.Type.join(','),
+    Use: pageState.approvalEditData.Use,
+  })
+  if (res.Ret == 200) {
+    ElMessage.success('审批成功')
+    pageState.showDetail = false
+    setTimeout(() => {
+      getSealApprovalList()
+    }, 300);
+  }
+}
+
+// 申请驳回
+async function handleApprvoalReject() {
+  const res = await sealInterence.sealApprovalReject({
+    SealId: pageState.detail.SealDetail.SealId,
+    Remark: pageState.form.reason
+  })
+  if (res.Ret == 200) {
+    ElMessage.success('操作成功')
+    pageState.showDetail = false
+    setTimeout(() => {
+      getSealApprovalList()
+    }, 300);
+  }
+}
+
+// 操作
+// 删除-delete 撤回-back 作废-invalid
+function handleOpt(e, data) {
+  if (e == 'delete') {
+    ElMessageBox.confirm("确定删除该用印申请吗?", "提示", {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }).then(() => {
+      sealInterence.sealDelete({ SealId: data.SealId }).then((res) => {
+        if (res.Ret === 200) {
+          ElMessage.success("删除成功");
+          getSealApprovalList()
+        }
+      });
+    });
+  }
+
+  if (e == 'back') {
+    ElMessageBox.confirm("确定撤回该用印申请吗?", "提示", {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }).then(() => {
+      sealInterence.sealApprovalBack({ SealId: data.SealId }).then((res) => {
+        if (res.Ret === 200) {
+          ElMessage.success("撤回成功");
+          getSealApprovalList()
+        }
+      });
+    });
+  }
+
+  if (e == 'invalid') {
+    ElMessageBox.confirm("确定作废该用印申请吗?", "提示", {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }).then(() => {
+      sealInterence.sealInvalid({ SealId: data.SealId }).then((res) => {
+        if (res.Ret === 200) {
+          ElMessage.success("撤回成功");
+          getSealApprovalList()
+        }
+      });
+    });
+  }
+}
+
+// 显示驳回理由
+function handleShowRejectReason(e) {
+  ElMessageBox.confirm(e.ApprovalRemark, '驳回理由', {
+    confirmButtonText: '知道了',
+    showCancelButton: false,
+    type: 'info '
+  })
+}
+
+//选择文件
+function checkFileBeforeUpload(file) {
+  let hostfile = file;
+  let size = Math.floor(hostfile.size / 1024 / 1024);
+  if (size > 200) {
+    ElMessage.warning("上传文件大小不能大于200M!");
+    hostfile = {};
+    return false;
+  }
+  if (hostfile.name.toLowerCase().includes(".pdf") || hostfile.name.toLowerCase().includes(".doc") || hostfile.name.toLowerCase().includes(".docx")) {
+    pageState.fileData.file = hostfile
+    pageState.fileData.name = hostfile.name.toLowerCase()
+  } else {
+    ElMessage.warning("请上传PDF/word文件!");
+  }
+  return false
+}
+
+// 显示上传签回弹窗
+function handleShowUploadAttachment(e){
+  pageState.fileData.sealId = e.SealId
+  if (e.CheckBackFileUrl) {
+    pageState.fileData.type = 2
+    pageState.fileData.title = `更新签回附件(${e.CompanyName})`
+    pageState.fileData.name = e.CheckBackFileUrl.substring(e.CheckBackFileUrl.lastIndexOf('/') + 1)
+  } else {
+    pageState.fileData.type = 1
+    pageState.fileData.title = `上传签回附件(${e.CompanyName})`
+  }
+  pageState.showUploadAttachment = true
+}
+
+// 提交上传/更新签回附件
+async function handleConfirmAttachment() {
+  if (!pageState.fileData.file) {
+    ElMessage.warning('请选择文件')
+    return
+  }
+  let form = new FormData();
+  form.append("file", pageState.fileData.file)
+  form.append('SealId', pageState.fileData.sealId)
+  const res = await sealInterence.sealCheckFileUpload(form)
+  if (res.Ret == 200) {
+    ElMessage.success('操作成功')
+    getSealApprovalList()
+    pageState.showUploadAttachment = false
+  }
+}
+
+function handlePreFile(e) {
+  let url = e.CheckBackFileUrl
+  const reg = /\.(pdf)$/;
+  // pdf
+  if (reg.test(url)) {
+    window.open(url, '_blank');
+  } else {
+    window.open('https://view.officeapps.live.com/op/view.aspx?src=' + url, '_blank');
+  }
+}
+
+</script>
+
+<template>
+  <div class="seal-approval-wrap">
+    <div class="content">
+      <div class="select-wrap" style="margin-bottom: 30px">
+        <el-select
+          v-model="pageState.contractTypeVal"
+          placeholder="合同类型"
+          @change="handleSelectChange"
+          clearable
+          style="margin-right: 20px"
+        >
+          <el-option
+            v-for="item in pageState.contractTypeList"
+            :key="item"
+            :label="item"
+            :value="item"
+          >
+          </el-option>
+        </el-select>
+        <el-select
+          v-model="pageState.sealStatusVal"
+          placeholder="用印状态"
+          @change="handleSelectChange"
+          clearable
+          style="margin-right: 20px"
+        >
+          <el-option
+            v-for="item in pageState.sealStatusList"
+            :key="item"
+            :label="item"
+            :value="item"
+          >
+          </el-option>
+        </el-select>
+        <el-cascader
+          v-if="pageState.RoleType != 'ficc_seller' && pageState.RoleType != 'rai_seller'"
+          v-model="pageState.seller"
+          placeholder="申请销售"
+          style="min-width: 250px; margin-bottom: 20px; margin-right: 20px"
+          :options="pageState.sellerList"
+          :props="pageState.defaultSalesProps"
+          :show-all-levels="false"
+          collapse-tags
+          clearable
+          filterable
+          @change="handleSelectChange"
+        >
+        </el-cascader>
+        <el-date-picker
+          v-model="pageState.time"
+          type="daterange"
+          range-separator="至"
+          value-format="yyyy-MM-dd"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          @change="handleSelectChange"
+          style="margin-right: 20px"
+        >
+        </el-date-picker>
+        <el-input
+          placeholder="客户名称/社会信用码"
+          prefix-icon="el-icon-search"
+          v-model="pageState.searchVal"
+          style="display: inline-block; width: 300px"
+          clearable
+          @input="handleSearch"
+        >
+        </el-input>
+        <el-button
+          type="primary"
+          style="float: right"
+          @click="$router.push('/addSeal')"
+          v-if="['ficc_seller', 'rai_seller', 'compliance'].includes(pageState.RoleType)"
+          >添加用印</el-button
+        >
+      </div>
+      <div class="list-wrap">
+        <el-table :data="pageState.tableList" border>
+          <el-table-column align="center" prop="CompanyName" label="客户名称">
+            <template #default="scope">
+              <span>{{ scope.row.CompanyName }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="CreditCode"
+            label="社会信用码"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="Use"
+            label="用印用途"
+            width="120px"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="ContractCode"
+            label="合同编号"
+            width="180px"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="ContractType"
+            label="合同类型"
+            width="100px"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="SealType"
+            label="加盖印章"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="ApplyUserName"
+            label="所属销售"
+            width="100px"
+          ></el-table-column>
+          <el-table-column
+            align="center"
+            prop="CreateTimeStr"
+            label="提交时间"
+            width="150px"
+          >
+            <template #default="scope">
+              <span>{{ formatTime(scope.row.CreateTimeStr) }}</span>
+            </template>
+          </el-table-column>
+          <el-table-column
+            align="center"
+            prop="Status"
+            label="用印状态"
+            width="100px"
+          ></el-table-column>
+          <el-table-column align="center" label="操作">
+            <template #default="scope">
+              <span
+                class="btn"
+                @click="handleDetail(scope.row)"
+                v-if="
+                  scope.row.Status != '已撤回' && !scope.row.OpButton.Approval
+                "
+                >审批详情</span
+              >
+              <span
+                class="btn"
+                v-if="scope.row.OpButton.Cancel"
+                @click="handleOpt('back', scope.row)"
+                >撤回</span
+              >
+              <span
+                class="btn"
+                v-if="scope.row.OpButton.Edit"
+                @click="$router.push('/editSeal?id=' + scope.row.SealId)"
+                >编辑重提</span
+              >
+              <span
+                class="btn"
+                style="color: #ff4040"
+                v-if="
+                  scope.row.Status == '已撤回' &&
+                  scope.row.ApplyUserId == pageState.userId
+                "
+                @click="handleOpt('delete', scope.row)"
+                >删除</span
+              >
+              <span
+                class="btn"
+                v-if="scope.row.OpButton.Invalid"
+                @click="handleOpt('invalid', scope.row)"
+                >用印作废</span
+              >
+              <span
+                class="btn"
+                v-if="scope.row.CheckBackFileUrl"
+                @click="handlePreFile(scope.row)"
+                >查看附件</span
+              >
+              <span
+                class="btn"
+                v-if="
+                  scope.row.OpButton.Approval && scope.row.Status == '待审批'
+                "
+                @click="handleDetail(scope.row)"
+                >审批</span
+              >
+              <span
+                class="btn"
+                v-if="scope.row.OpButton.UploadFile"
+                @click="handleShowUploadAttachment(scope.row)"
+                >{{
+                  scope.row.CheckBackFileUrl ? "更新附件" : "签回附件"
+                }}</span
+              >
+            </template>
+          </el-table-column>
+
+          <template #empty>
+            <div style="padding: 100px 0">暂无数据</div>
+          </template>
+        </el-table>
+
+        <el-pagination
+          layout="total,prev,pager,next,jumper"
+          background
+          :current-page="pageState.page"
+          @current-change="handlePageChange"
+          :page-size="pageState.pageSize"
+          :total="pageState.total"
+          class="pagination-wrap"
+        >
+        </el-pagination>
+      </div>
+      <!-- 审批弹窗 -->
+      <el-dialog
+        width="58%"
+        top="5vh"
+        draggable
+        :model-value="pageState.showDetail"
+        :modal-append-to-body="false"
+        :append-to-body="true"
+        @close="pageState.showDetail = false"
+      >
+        <template #header>
+          <div v-if="pageState.detail">
+            <span>{{ pageState.detail.OpButton.Approval ? "审批" : "审批详情" }}</span>
+          </div>
+        </template>
+
+        <div class="detail-wrap" v-if="pageState.detail">
+          <div class="main" v-if="pageState.detail.OpButton">
+            <table class="table-wrap">
+              <tbody>
+                <tr>
+                  <td class="table-item width-50">
+                    <p v-if="pageState.detail.OpButton.CheckEdit">
+                      <span>用印用途:</span>
+                      <el-select
+                        v-model="pageState.approvalEditData.Use"
+                        placeholder="请选择"
+                      >
+                        <el-option
+                          label="销售合同"
+                          value="销售合同"
+                        ></el-option>
+                        <el-option
+                          label="代付合同"
+                          value="代付合同"
+                        ></el-option>
+                        <el-option
+                          label="总对总协议"
+                          value="总对总协议"
+                        ></el-option>
+                        <el-option
+                          label="渠道合同"
+                          value="渠道合同"
+                        ></el-option>
+                        <el-option
+                          label="付款通知函"
+                          value="付款通知函"
+                        ></el-option>
+                        <el-option label="招投标" value="招投标"></el-option>
+                        <el-option
+                          label="战略合作协议"
+                          value="战略合作协议"
+                        ></el-option>
+                      </el-select>
+                    </p>
+                    <p v-else>用印用途:{{ pageState.detail.SealDetail.Use }}</p>
+                  </td>
+                  <td class="table-item width-50">
+                    所属销售:{{ pageState.detail.SealDetail.UserName }}
+                  </td>
+                </tr>
+                <tr>
+                  <td class="table-item width-50">
+                    客户名称:{{ pageState.detail.SealDetail.CompanyName }}
+                  </td>
+                  <td class="table-item width-50">
+                    社会信用码:{{ pageState.detail.SealDetail.CreditCode }}
+                  </td>
+                </tr>
+                <tr>
+                  <td class="table-item width-50">
+                    合同类型:{{ pageState.detail.SealDetail.ServiceType }}
+                  </td>
+                  <td class="table-item width-50">
+                    <p v-if="pageState.detail.OpButton.CheckEdit">
+                      <span>文件份数:</span>
+                      <!-- <el-input type="number" v-model="approvalEditData.FileNum"></el-input> -->
+                      <el-input-number
+                        :min="1"
+                        v-model="pageState.approvalEditData.FileNum"
+                      ></el-input-number>
+                    </p>
+                    <p v-else>文件份数:{{ pageState.detail.SealDetail.FileNum }}</p>
+                  </td>
+                </tr>
+                <tr>
+                  <td class="table-item">
+                    <p v-if="pageState.detail.OpButton.CheckEdit">
+                      <span>加盖印章:</span>
+                      <el-select
+                        v-model="pageState.approvalEditData.Type"
+                        collapse-tags
+                        multiple
+                        placeholder="请选择"
+                      >
+                        <el-option label="合同章" value="合同章"></el-option>
+                        <el-option label="公章" value="公章"></el-option>
+                        <el-option label="法人章" value="法人章"></el-option>
+                      </el-select>
+                    </p>
+                    <p v-else>加盖印章:{{ pageState.detail.SealDetail.SealType }}</p>
+                  </td>
+                  <td class="table-item">
+                    实际使用方:{{
+                      pageState.detail.SealDetail.UseCompanyName ||
+                      pageState.detail.SealDetail.CompanyName
+                    }}
+                  </td>
+                </tr>
+                <tr>
+                  <td class="table-item" colspan="2" style="text-align: left">
+                    <p v-if="pageState.detail.OpButton.CheckEdit" style="display: flex">
+                      <span>审批备注:</span>
+                      <el-input
+                        type="textarea"
+                        placeholder="请填写备注"
+                        v-model="pageState.approvalEditData.Remark"
+                        style="flex: 1"
+                      ></el-input>
+                    </p>
+                    <p v-else>审批备注:{{ pageState.detail.SealDetail.Remark }}</p>
+                  </td>
+                </tr>
+              </tbody>
+            </table>
+            <!-- 审批流程 -->
+            <div class="process-box" style="margin-top: 30px">
+              <h2>审批流程:</h2>
+              <div class="approval-step-wrap">
+                <div
+                  v-for="(step, index) in pageState.stepArr"
+                  :key="index"
+                  class="step-item"
+                >
+                  <span class="title" v-if="step.stepName"
+                    >{{ step.stepName }}:</span
+                  >
+                  <div v-if="step.stepName" class="user-box">
+                    <span>审批人:</span>
+                    <span
+                      v-for="user in step.allUser"
+                      :key="user.ApproveUserName"
+                      >{{ user.ApproveUserName }}</span
+                    >
+                    <p></p>
+                  </div>
+                  <div v-else class="user-box">
+                    <span>抄送人:</span>
+                    <span
+                      v-for="user in step.allUser"
+                      :key="user.ApproveUserName"
+                      >{{ user.ApproveUserName }}</span
+                    >
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="dashed-line" v-if="pageState.detail.OpButton.Approval"></div>
+            <el-form
+              ref="form"
+              :model="pageState.form"
+              :rules="pageState.formRule"
+              label-width="100px"
+              label-position="left"
+              v-if="pageState.detail.OpButton.Approval"
+            >
+              <el-form-item prop="status" label="审批状态">
+                <el-radio-group
+                  v-model="pageState.form.status"
+                  @change="approvalFromStatusChange"
+                >
+                  <el-radio label="通过"></el-radio>
+                  <el-radio label="驳回"></el-radio>
+                </el-radio-group>
+              </el-form-item>
+              <el-form-item
+                prop="reason"
+                label="驳回理由"
+                v-if="pageState.form.status === '驳回'"
+              >
+                <el-input
+                  v-model="pageState.form.reason"
+                  placeholder="请输入理由"
+                  type="textarea"
+                ></el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+          <div class="right">
+            <el-button
+              type="primary"
+              style="width: 100%"
+              @click="handlePreContractFile(pageState.detail.SealDetail.FileUrls)"
+              >预览合同</el-button
+            >
+            <div class="contract-origin">
+              合同来源:{{
+                pageState.detail.SealDetail.ContractId == 0 ? "上传附件" : "系统合同"
+              }}
+            </div>
+            <div class="timeline-wrap">
+              <el-timeline>
+                <el-timeline-item
+                  color="#409EFF"
+                  v-for="item in pageState.optList"
+                  :key="item.Id"
+                  placement="top"
+                  :timestamp="item.CreateTimeStr"
+                >
+                  {{ item.OpUserName }}{{ item.Remark }}
+                  <span
+                    style="
+                      color: #409eff;
+                      cursor: pointer;
+                      display: inline-block;
+                    "
+                    v-if="item.Operation == 'reject'"
+                    @click="handleShowRejectReason(item)"
+                    >驳回理由</span
+                  >
+                </el-timeline-item>
+              </el-timeline>
+            </div>
+          </div>
+        </div>
+        <div
+          style="text-align: center; margin-bottom: 40px; margin-top: 40px"
+          v-if="pageState.detail"
+        >
+          <block v-if="pageState.detail.OpButton.Approval">
+            <el-button
+              type="primary"
+              style="margin-right: 24px"
+              plain
+              @click="pageState.showDetail = false"
+              >取消</el-button
+            >
+            <el-button type="primary" @click="handleConfirmApproval"
+              >确定</el-button
+            >
+          </block>
+          <block v-else
+            ><el-button type="primary" @click="pageState.showDetail = false"
+              >知道了</el-button
+            ></block
+          >
+        </div>
+        <!-- 预览合同附件弹窗 当附件大于1个时显示 -->
+        <el-dialog
+          title="请选择附件"
+          :model-value="pageState.showAttachment"
+          @close="pageState.showAttachment = false"
+          :close-on-click-modal="false"
+          :append-to-body="true"
+        >
+          <div class="attachment-contain" style="min-height: 240px">
+            <el-image
+              v-for="item in pageState.attachmentUrls"
+              :key="item"
+              :src="fileTypeIcon(item)"
+              @click="viewAttachment(item)"
+              class="attachment-image"
+            ></el-image>
+          </div>
+        </el-dialog>
+      </el-dialog>
+      <!-- 上传\更新 附件 -->
+      <el-dialog
+        top="30vh"
+        draggable
+        width="570px"
+        :model-value="pageState.showUploadAttachment"
+        :modal-append-to-body="false"
+        @close="pageState.showUploadAttachment = false"
+      >
+        <template #header>
+          <div>
+            <img
+              width="15"
+              src="../../assets/img/icons/edit1.png"
+              alt=""
+              v-if="pageState.fileData.type == 2"
+            />
+            <img width="15" src="../../assets/img/icons/up.png" alt="" v-else />
+            <span
+              style="
+                display: inline-block;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                max-width: 450px;
+              "
+              >{{ pageState.fileData.title }}</span
+            >
+          </div>
+        </template>
+
+        <div class="upload-attachment-wrap">
+          <div style="display: flex; align-items: center">
+            <div class="box">
+              <span :style="{ color: pageState.fileData.name ? '' : '#999' }">{{
+                !pageState.fileData.name ? "请选择文件" : pageState.fileData.name
+              }}</span>
+            </div>
+            <el-upload :before-upload="checkFileBeforeUpload">
+              <el-button type="primary">选择文件</el-button>
+            </el-upload>
+          </div>
+          <div style="text-align: center; margin: 60px 0 30px 0">
+            <el-button type="primary" @click="handleConfirmAttachment"
+              >确定</el-button
+            >
+            <el-button
+              type="primary"
+              plain
+              @click="pageState.showUploadAttachment = false"
+              >取消</el-button
+            >
+          </div>
+        </div>
+      </el-dialog>
+    </div>
+  </div>
+</template>
+
+
+<style>
+.el-message-box__header .el-message-box__title {
+  color: #333 !important;
+}
+.detail-wrap .el-input {
+  width: 100% !important;
+}
+.detail-wrap .el-input-number .el-input__inner {
+  pointer-events: none;
+}
+</style>
+<style lang="scss" scoped>
+.upload-attachment-wrap {
+  .box {
+    width: 380px;
+    display: inline-block;
+    box-sizing: border-box;
+    height: 40px;
+    line-height: 40px;
+    padding: 0 17px;
+    font-size: 14px;
+    border: 1px solid #dcdfe6;
+    border-radius: 4px;
+    margin-right: 20px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+.seal-approval-wrap {
+  .content {
+    background: #ffffff;
+    border: 1px solid #ececec;
+    box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
+    border-radius: 4px;
+    padding: 30px;
+    min-height: 80vh;
+  }
+  .btn {
+    display: inline-block;
+    color: #409eff;
+    cursor: pointer;
+    margin: 0 5px;
+  }
+}
+
+.pagination-wrap {
+  margin-top: 30px;
+  display: flex;
+  justify-content: flex-end;
+}
+.detail-wrap {
+  max-height: 70vh;
+  overflow-y: scroll;
+  display: flex;
+  justify-content: space-between;
+  .main {
+    width: 75%;
+    .table-wrap {
+      width: 100%;
+      // text-align: center;
+      border-top: 1px solid #dcdfe6;
+      border-left: 1px solid #dcdfe6;
+      .table-item {
+        padding: 14px 10px;
+        border-right: 1px solid #dcdfe6;
+        border-bottom: 1px solid #dcdfe6;
+        position: relative;
+      }
+      .width-50 {
+        width: 50%;
+      }
+    }
+    .service-wrap {
+      margin-top: 42px;
+      font-size: 14px;
+      display: flex;
+      color: #333;
+    }
+    .dashed-line {
+      margin: 40px 0;
+      border-top: 1px dashed #aab4cc;
+    }
+  }
+  .right {
+    width: 22%;
+    .contract-origin {
+      margin: 15px 0;
+    }
+    .timeline-wrap {
+      max-height: 500px;
+      overflow-y: auto;
+      // margin-top: 20px;
+      background-color: #fff;
+      border: 1px solid #aab4cc;
+      padding: 20px;
+      border-radius: 4px;
+      text-align: left;
+      height: calc(100% - 120px);
+    }
+  }
+}
+
+.approval-step-wrap {
+  .step-item {
+    margin: 15px 0;
+    .title {
+      font-size: 16px;
+      font-weight: bold;
+      color: #333;
+      float: left;
+      margin-top: 4px;
+    }
+    .user-box {
+      padding-left: 100px;
+      span {
+        display: inline-block;
+        background-color: #409eff;
+        color: #fff;
+        padding: 3px 5px;
+        border-radius: 3px;
+        margin-right: 10px;
+      }
+      span:first-child {
+        background-color: #fff;
+        color: #333;
+        padding: 0;
+      }
+    }
+  }
+}
+.attachment-contain {
+  display: flex;
+  flex-wrap: wrap;
+  padding: 20px 0;
+  .attachment-image {
+    height: 100px;
+    width: 100px;
+    cursor: pointer;
+    margin: 0 10px 20px 10px;
+  }
+}
+</style>