approvalList.vue 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984
  1. <template>
  2. <div class="seal-approval-wrap">
  3. <div class="content">
  4. <div class="select-wrap" style="margin-bottom:30px">
  5. <el-select v-model="belongCompany" placeholder="请选择归属公司" @change="handleSelectChange" clearable style="margin-right:20px">
  6. <el-option
  7. v-for="item in belongCompanyOption"
  8. :key="item"
  9. :label="item"
  10. :value="item">
  11. </el-option>
  12. </el-select>
  13. <el-select v-model="contractTypeVal" placeholder="合同类型" @change="handleSelectChange" clearable style="margin-right:20px">
  14. <el-option
  15. v-for="item in contractTypeList"
  16. :key="item"
  17. :label="item"
  18. :value="item">
  19. </el-option>
  20. </el-select>
  21. <el-select v-model="sealStatusVal" placeholder="用印状态" @change="handleSelectChange" clearable style="margin-right:20px">
  22. <el-option
  23. v-for="item in sealStatusList"
  24. :key="item"
  25. :label="item"
  26. :value="item">
  27. </el-option>
  28. </el-select>
  29. <el-cascader
  30. v-if="RoleType!='ficc_seller'&&RoleType!='rai_seller'"
  31. v-model="seller"
  32. placeholder="申请销售"
  33. style="min-width:250px;margin-bottom: 20px;margin-right:20px"
  34. :options="sellerList"
  35. :props="defaultSalesProps"
  36. :show-all-levels="false"
  37. collapse-tags
  38. clearable
  39. filterable
  40. @change="handleSelectChange">
  41. </el-cascader>
  42. <el-date-picker
  43. v-model="time"
  44. type="daterange"
  45. range-separator="至"
  46. value-format="yyyy-MM-dd"
  47. start-placeholder="开始日期"
  48. end-placeholder="结束日期"
  49. @change="handleSelectChange"
  50. style="margin-right:20px">
  51. </el-date-picker>
  52. <el-input
  53. placeholder="客户名称/社会信用码"
  54. prefix-icon="el-icon-search"
  55. v-model="searchVal"
  56. style="display:inline-block;width:300px"
  57. clearable
  58. @input="handleSearch">
  59. </el-input>
  60. <div style="float:right" >
  61. <el-button
  62. type="primary"
  63. @click="$router.push('/addSeal')"
  64. v-if="['ficc_seller','rai_seller','compliance'].includes(RoleType)"
  65. >添加用印</el-button>
  66. <a :href="exportUrl" download v-if="['admin','ficc_admin','compliance'].includes(RoleType)">
  67. <el-button type="primary">导出</el-button>
  68. </a>
  69. </div>
  70. </div>
  71. <div class="list-wrap">
  72. <el-table :data="tableList" border>
  73. <el-table-column align="center" prop="CompanyName" label="归属公司">
  74. <template slot-scope="scope">
  75. <span>{{scope.row.AffiliatedCompany}}</span>
  76. </template>
  77. </el-table-column>
  78. <el-table-column align="center" prop="CompanyName" label="客户名称">
  79. <template slot-scope="scope">
  80. <span>{{scope.row.CompanyName}}</span>
  81. </template>
  82. </el-table-column>
  83. <el-table-column align="center" prop="CreditCode" label="社会信用码"></el-table-column>
  84. <el-table-column align="center" prop="Use" label="用印用途" width="120px"></el-table-column>
  85. <el-table-column align="center" prop="ContractCode" label="合同编号" width="180px"></el-table-column>
  86. <el-table-column align="center" prop="ContractType" label="合同类型" width="100px"></el-table-column>
  87. <el-table-column align="center" prop="SealType" label="加盖印章"></el-table-column>
  88. <el-table-column align="center" prop="ApplyUserName" label="所属销售" width="100px"></el-table-column>
  89. <el-table-column align="center" prop="CreateTimeStr" label="提交时间" width="150px">
  90. <template slot-scope="scope">
  91. <span>{{scope.row.CreateTimeStr|formatTime}}</span>
  92. </template>
  93. </el-table-column>
  94. <el-table-column align="center" prop="Status" label="用印状态" width="100px"></el-table-column>
  95. <el-table-column align="center" label="操作">
  96. <template slot-scope="scope">
  97. <span class="btn" @click="handleDetail(scope.row)" v-if="scope.row.Status!='已撤回'&&!scope.row.OpButton.Approval">审批详情</span>
  98. <span class="btn" v-if="scope.row.OpButton.Cancel" @click="handleOpt('back',scope.row)">撤回</span>
  99. <span class="btn" v-if="scope.row.OpButton.Edit" @click="$router.push('/editSeal?id='+scope.row.SealId)">编辑重提</span>
  100. <span class="btn" style="color:#FF4040" v-if="scope.row.Status=='已撤回'&&scope.row.ApplyUserId==userId" @click="handleOpt('delete',scope.row)">删除</span>
  101. <span class="btn" v-if="scope.row.OpButton.Invalid" @click="handleOpt('invalid',scope.row)">用印作废</span>
  102. <span class="btn" v-if="scope.row.CheckBackFileUrl" @click="handlePreFile(scope.row)">查看附件</span>
  103. <span class="btn" v-if="scope.row.OpButton.Approval&&scope.row.Status=='待审批'" @click="handleDetail(scope.row)">审批</span>
  104. <span class="btn" v-if="scope.row.OpButton.UploadFile" @click="handleShowUploadAttachment(scope.row)">{{scope.row.CheckBackFileUrl?'更新附件':'签回附件'}}</span>
  105. </template>
  106. </el-table-column>
  107. <div slot="empty" style="padding:100px 0">暂无数据</div>
  108. </el-table>
  109. <el-pagination
  110. layout="total,prev,pager,next,jumper"
  111. background
  112. :current-page="page"
  113. @current-change="handlePageChange"
  114. :page-size="pageSize"
  115. :total="total"
  116. class="pagination-wrap">
  117. </el-pagination>
  118. </div>
  119. <!-- 审批弹窗 -->
  120. <el-dialog
  121. width="58%"
  122. top="5vh"
  123. v-dialogDrag
  124. :visible.sync="showDetail"
  125. :modal-append-to-body="false"
  126. :append-to-body="true"
  127. @close="showDetail=false">
  128. <div slot="title" v-if="detail">
  129. <span>{{detail.OpButton.Approval?'审批':'审批详情'}}</span>
  130. </div>
  131. <div class="detail-wrap" v-if="detail">
  132. <div class="main" v-if="detail.OpButton">
  133. <table class="table-wrap" >
  134. <tbody>
  135. <tr>
  136. <td class="table-item width-50">
  137. <p v-if="detail.OpButton.CheckEdit">
  138. <span>所属公司:</span>
  139. <el-select v-model="approvalEditData.AffiliatedCompany" placeholder="请选择">
  140. <el-option
  141. v-for="item in belongCompanyOption"
  142. :key="item"
  143. :label="item"
  144. :value="item">
  145. </el-option>
  146. </el-select>
  147. </p>
  148. <p v-else>所属公司:{{detail.SealDetail.AffiliatedCompany}}</p>
  149. </td>
  150. <td class="table-item width-50">
  151. <p v-if="detail.OpButton.CheckEdit">
  152. <span>用印用途:</span>
  153. <el-select v-model="approvalEditData.Use" placeholder="请选择">
  154. <el-option label="销售合同" value="销售合同"></el-option>
  155. <el-option label="代付合同" value="代付合同"></el-option>
  156. <el-option label="总对总协议" value="总对总协议"></el-option>
  157. <el-option label="渠道合同" value="渠道合同"></el-option>
  158. <el-option label="付款通知函" value="付款通知函"></el-option>
  159. <el-option label="招投标" value="招投标"></el-option>
  160. <el-option label="战略合作协议" value="战略合作协议"></el-option>
  161. </el-select>
  162. </p>
  163. <p v-else>用印用途:{{detail.SealDetail.Use}}</p>
  164. </td>
  165. </tr>
  166. <tr>
  167. <td class="table-item width-50">所属销售:{{detail.SealDetail.UserName}}</td>
  168. <td class="table-item width-50">客户名称:{{detail.SealDetail.CompanyName}}</td>
  169. </tr>
  170. <tr>
  171. <td class="table-item width-50">社会信用码:{{detail.SealDetail.CreditCode}}</td>
  172. <td class="table-item width-50">合同类型:{{detail.SealDetail.ServiceType}}</td>
  173. </tr>
  174. <tr>
  175. <td class="table-item width-50">
  176. <p v-if="detail.OpButton.CheckEdit">
  177. <span>文件份数:</span>
  178. <!-- <el-input type="number" v-model="approvalEditData.FileNum"></el-input> -->
  179. <el-input-number :min="1" v-model="approvalEditData.FileNum"></el-input-number>
  180. </p>
  181. <p v-else>文件份数:{{detail.SealDetail.FileNum}}</p>
  182. </td>
  183. <td class="table-item">
  184. <p v-if="detail.OpButton.CheckEdit">
  185. <span>加盖印章:</span>
  186. <el-select v-model="approvalEditData.Type" collapse-tags multiple placeholder="请选择">
  187. <el-option label="合同章" value="合同章"></el-option>
  188. <el-option label="公章" value="公章"></el-option>
  189. <el-option label="法人章" value="法人章"></el-option>
  190. <el-option label="电子合同章" value="电子合同章"></el-option>
  191. </el-select>
  192. </p>
  193. <p v-else>加盖印章:{{detail.SealDetail.SealType}}</p>
  194. </td>
  195. </tr>
  196. <tr>
  197. <td class="table-item" colspan="2">实际使用方:{{detail.SealDetail.UseCompanyName||detail.SealDetail.CompanyName}}</td>
  198. </tr>
  199. <tr>
  200. <td class="table-item" colspan="2" style="text-align: left">
  201. <p v-if="detail.OpButton.CheckEdit" style="display:flex">
  202. <span>审批备注:</span>
  203. <el-input type="textarea" placeholder="请填写备注" v-model="approvalEditData.Remark" style="flex:1"></el-input>
  204. </p>
  205. <p v-else>审批备注:{{detail.SealDetail.Remark}}</p>
  206. </td>
  207. </tr>
  208. </tbody>
  209. </table>
  210. <!-- 审批流程 -->
  211. <div class="process-box" style="margin-top:30px">
  212. <h2>审批流程:</h2>
  213. <div class="approval-step-wrap">
  214. <div v-for="(step,index) in stepArr" :key="index" class="step-item">
  215. <span class="title" v-if="step.stepName">{{step.stepName}}:</span>
  216. <div v-if="step.stepName" class="user-box">
  217. <span>审批人:</span>
  218. <span v-for="user in step.allUser" :key="user.ApproveUserName">{{user.ApproveUserName}}</span>
  219. <p></p>
  220. </div>
  221. <div v-else class="user-box">
  222. <span>抄送人:</span>
  223. <span v-for="user in step.allUser" :key="user.ApproveUserName">{{user.ApproveUserName}}</span>
  224. </div>
  225. </div>
  226. </div>
  227. </div>
  228. <div class="dashed-line" v-if="detail.OpButton.Approval"></div>
  229. <el-form ref="form" :model="form" :rules="formRule" label-width="100px" label-position="left" v-if="detail.OpButton.Approval">
  230. <el-form-item prop="status" label="审批状态">
  231. <el-radio-group v-model="form.status" @change="approvalFromStatusChange">
  232. <el-radio label="通过"></el-radio>
  233. <el-radio label="驳回"></el-radio>
  234. </el-radio-group>
  235. </el-form-item>
  236. <el-form-item prop="reason" label="驳回理由" v-if="form.status === '驳回'">
  237. <el-input v-model="form.reason" placeholder="请输入理由" type="textarea"></el-input>
  238. </el-form-item>
  239. </el-form>
  240. </div>
  241. <div class="right">
  242. <el-button type="primary" style="width: 100%" @click="handlePreContractFile(detail.SealDetail.FileUrls)">预览合同</el-button>
  243. <div class="contract-origin">合同来源:{{detail.SealDetail.ContractId == 0?'上传附件':'系统合同'}}</div>
  244. <div class="timeline-wrap">
  245. <el-timeline>
  246. <el-timeline-item
  247. color="#409EFF"
  248. v-for="item in optList"
  249. :key="item.Id"
  250. placement="top"
  251. :timestamp="item.CreateTimeStr"
  252. >
  253. {{ item.OpUserName }}{{ item.Remark }}
  254. <span
  255. style="color:#409EFF;cursor: pointer;display:inline-block"
  256. v-if="item.Operation=='reject'"
  257. @click="handleShowRejectReason(item)"
  258. >驳回理由</span>
  259. </el-timeline-item>
  260. </el-timeline>
  261. </div>
  262. </div>
  263. </div>
  264. <div style="text-align: center; margin-bottom: 40px; margin-top: 40px" v-if="detail">
  265. <block v-if="detail.OpButton.Approval">
  266. <el-button type="primary" style="margin-right: 24px" plain @click="showDetail=false">取消</el-button>
  267. <el-button type="primary" @click="handleConfirmApproval">确定</el-button>
  268. </block>
  269. <block v-else><el-button type="primary" @click="showDetail=false">知道了</el-button></block>
  270. </div>
  271. <!-- 预览合同附件弹窗 当附件大于1个时显示 -->
  272. <el-dialog title="请选择附件" :visible.sync="showAttachment" @close = "showAttachment=false"
  273. :close-on-click-modal='false' :append-to-body="true" >
  274. <div class="attachment-contain" style="min-height: 240px;">
  275. <el-image v-for="item in attachmentUrls" :key="item"
  276. :src="fileTypeIcon(item)"
  277. @click="viewAttachment(item)"
  278. class="attachment-image"></el-image>
  279. </div>
  280. </el-dialog>
  281. </el-dialog>
  282. <!-- 上传\更新 附件 -->
  283. <el-dialog
  284. top="30vh"
  285. v-dialogDrag
  286. width="570px"
  287. :visible.sync="showUploadAttachment"
  288. :modal-append-to-body="false"
  289. @close="showUploadAttachment=false"
  290. >
  291. <div slot="title">
  292. <img width='15' src="../../assets/img/icons/edit1.png" alt="" v-if="fileData.type==2">
  293. <img width="15" src="../../assets/img/icons/up.png" alt="" v-else>
  294. <span style="display:inline-block;overflow: hidden;text-overflow: ellipsis;white-space: nowrap;max-width:450px">{{fileData.title}}</span>
  295. </div>
  296. <div class="upload-attachment-wrap">
  297. <div style="display:flex;align-items: center;">
  298. <div class="box">
  299. <span :style="{color:fileData.name?'':'#999'}">{{!fileData.name?'请选择文件':fileData.name}}</span>
  300. </div>
  301. <el-upload :before-upload="checkFileBeforeUpload">
  302. <el-button type="primary">选择文件</el-button>
  303. </el-upload>
  304. </div>
  305. <div style="text-align:center;margin:60px 0 30px 0">
  306. <el-button type="primary" @click="handleConfirmAttachment">确定</el-button>
  307. <el-button type="primary" plain @click="showUploadAttachment=false">取消</el-button>
  308. </div>
  309. </div>
  310. </el-dialog>
  311. </div>
  312. </div>
  313. </template>
  314. <script>
  315. import {contractInterface,sealInterence} from "@/api/api.js";
  316. export default {
  317. watch:{
  318. showDetail(nval){// 弹窗关闭清除弹窗的值
  319. if(!nval){
  320. this.detail=null
  321. this.optList=[]
  322. this.stepArr=[]
  323. this.approvalEditData={
  324. AffiliatedCompany:'',//所属公司
  325. Use:'',//用印用途
  326. Type:'',//加盖印章 类型
  327. FileNum:'',//文件份数
  328. Remark:'',//备注
  329. }
  330. this.form={
  331. status: "通过",
  332. reason: "",
  333. }
  334. }
  335. },
  336. showUploadAttachment(nval){//上传附件弹窗关闭清除值
  337. if(!nval){
  338. this.fileData={
  339. type:0,//1 上传附件 2 更新附件
  340. title:"",
  341. name:"",
  342. file:null,
  343. sealId:0,
  344. }
  345. }
  346. }
  347. },
  348. computed: {
  349. exportUrl() {
  350. let auth = localStorage.getItem("auth") || "";
  351. let salesArr=[]
  352. if(this.seller.length){
  353. salesArr=this.seller.map(item=>{
  354. return item[item.length-1]
  355. })
  356. }
  357. return `${process.env.API_ROOT}/seal/getApprovalPageList?IsExport=true&${auth}&PageSize=${this.pageSize}&CurrentIndex=${this.page}&ContractType=${this.contractTypeVal}&Status=${this.sealStatusVal}&SellerId=${salesArr.join(',')}&StartTime=${this.time&&this.time[0]||''}&EndTime=${this.time&&this.time[1]||''}&Keyword=${this.searchVal}&AffiliatedCompany=${this.belongCompany}`
  358. }
  359. },
  360. data () {
  361. return {
  362. RoleType:localStorage.getItem('Role')||'',
  363. userId:localStorage.getItem('AdminId'),
  364. contractTypeList:['新签合同','续约合同','补充协议','代付合同'],
  365. contractTypeVal:'',
  366. sealStatusList:['待审批','待提交','已撤回','处理中','已审批','已驳回','已签回','已作废'],
  367. sealStatusVal:'',
  368. time:['',''],
  369. searchVal:'',
  370. tableList:[],
  371. page:1,
  372. pageSize:10,
  373. total:0,
  374. sellerList: [], //申请销售列表
  375. seller: "", //选择的申请销售
  376. defaultSalesProps:{
  377. multiple: true,
  378. label:'RealName',
  379. children:'ChildrenList',
  380. value:'AdminId'
  381. },//销售级联配置
  382. detail:null,
  383. showDetail:false,
  384. optList:[],
  385. stepArr:[],//审批流程数据
  386. approvalEditData:{
  387. AffiliatedCompany:'',//所属公司
  388. Use:'',//用印用途
  389. Type:'',//加盖印章 类型
  390. FileNum:'',//文件份数
  391. Remark:'',//备注
  392. },
  393. form: {
  394. status: "通过",
  395. reason: "",
  396. },
  397. formRule: {
  398. status: [{ required: true, message: "请选择状态", trigger: "change" }],
  399. reason: [{ required: true, message: "请填写驳回理由", trigger: "blur" }],
  400. },
  401. showUploadAttachment:false,//显示上传(更新附件)
  402. fileData:{
  403. type:0,//1 上传附件 2 更新附件
  404. title:"",
  405. name:"",
  406. file:null,
  407. sealId:0,
  408. },//上传/更新附件文件数据
  409. showAttachment:false,// 是否显示预览附件弹窗
  410. attachmentUrls:[],// 附件列表
  411. belongCompany: '',//归属公司
  412. belongCompanyOption: []
  413. }
  414. },
  415. created () {
  416. this.getSellerList();
  417. this.getSealApprovalList()
  418. this.getBelongCompanyOptions()
  419. if(['ficc_seller','rai_seller'].includes(this.RoleType)){
  420. this.sealStatusList=['待审批','已撤回','处理中','已审批','已驳回','已签回','已作废']
  421. }else{
  422. this.sealStatusList=['待审批','处理中','已审批','已驳回','已签回','已作废']
  423. }
  424. },
  425. methods: {
  426. async getBelongCompanyOptions() {
  427. const res = await sealInterence.getBelongCompany()
  428. if(res.Ret !==200 ) return
  429. this.belongCompanyOption = res.Data || []
  430. },
  431. //获取所属销售列表
  432. getSellerList() {
  433. contractInterface.getSellerList().then((res) => {
  434. if (res.Ret === 200) {
  435. this.sellerList = res.Data.List;
  436. }
  437. });
  438. },
  439. async getSealApprovalList(){
  440. let salesArr=[]
  441. if(this.seller.length){
  442. salesArr=this.seller.map(item=>{
  443. return item[item.length-1]
  444. })
  445. }
  446. const res=await sealInterence.getSealApprovalList({
  447. PageSize:this.pageSize,
  448. CurrentIndex:this.page,
  449. ContractType:this.contractTypeVal,
  450. Status:this.sealStatusVal,
  451. SellerId:salesArr.join(','),
  452. StartTime:this.time&&this.time[0]||'',
  453. EndTime:this.time&&this.time[1]||'',
  454. Keyword:this.searchVal,
  455. AffiliatedCompany: this.belongCompany
  456. })
  457. if(res.Ret===200){
  458. this.tableList=res.Data.List
  459. this.total=res.Data.Paging.Totals
  460. }
  461. },
  462. handleSelectChange(){
  463. this.searchVal=''
  464. this.getSealApprovalList()
  465. },
  466. handleSearch(){
  467. this.contractTypeVal=''
  468. this.sealStatusVal=''
  469. this.time=['','']
  470. this.seller=''
  471. this.getSealApprovalList()
  472. },
  473. handlePageChange(e){
  474. this.page = e
  475. this.getSealApprovalList()
  476. },
  477. async handleDetail(e){
  478. this.getSealOprationList(e.SealId)
  479. const res=await sealInterence.getSealDetail({SealId:e.SealId})
  480. if(res.Ret==200){
  481. console.log(res.Data)
  482. this.showDetail=true
  483. this.detail=res.Data
  484. this.approvalEditData.AffiliatedCompany=res.Data.SealDetail.AffiliatedCompany
  485. this.approvalEditData.Use=res.Data.SealDetail.Use
  486. this.approvalEditData.Type=res.Data.SealDetail.SealType.split(',')
  487. this.approvalEditData.FileNum=res.Data.SealDetail.FileNum
  488. this.approvalEditData.Remark=res.Data.SealDetail.Remark
  489. this.handleStepArr()
  490. }
  491. },
  492. // 处理审批流程节点
  493. handleStepArr(){
  494. let arr=[]
  495. let count=0
  496. arr=this.detail.FlowNodeList&&this.detail.FlowNodeList.map(item=>{
  497. item[0].NodeType==='check'&&count++
  498. let stepCon={
  499. name:item[0].NodeType==='check'?'审批人':'抄送人',//审批节点标题
  500. intro:'',//描述
  501. user:item.slice(0,2),//审批节点人列表
  502. allUser:item,
  503. approve:[],//审批人信息{name:'',time:""}
  504. auditType:1,
  505. stepName:''
  506. }
  507. if(item[0].NodeType==='check'){
  508. if(item[0].AuditType===1){
  509. stepCon.intro=item.length>1?item.length+'人或签':''
  510. stepCon.auditType=1
  511. }else if(item[0].AuditType===2){
  512. stepCon.intro=item.length>1?item.length+'人会签':''
  513. stepCon.auditType=2
  514. }
  515. item.forEach(item2=>{
  516. if(item2.Status!=='待审批'&&item2.Status!=='已撤回'){
  517. let time=''
  518. if(item2.Status==='已驳回'){
  519. time=`驳回时间:${item2.ApproveTime}`
  520. }else {
  521. time=`审批时间:${item2.ApproveTime}`
  522. }
  523. let obj={name:item2.ApproveUserName,time:time}
  524. stepCon.approve.push(obj)
  525. }
  526. })
  527. }
  528. if(item[0].NodeType==='cc'){
  529. stepCon.intro='抄送'+item.length+'人'
  530. }
  531. return stepCon
  532. })
  533. // 处理审批节点标题描述 若有多级审批 则 为 一级审批 二级审批 若只有一级 则 不变
  534. // if(count>1){
  535. let tag=0
  536. arr.forEach(item=>{
  537. if(item.name==='审批人'){
  538. tag++
  539. switch (tag) {
  540. case 1:
  541. item.stepName='一级审批'
  542. break;
  543. case 2:
  544. item.stepName='二级审批'
  545. break;
  546. case 3:
  547. item.stepName='三级审批'
  548. break;
  549. }
  550. }
  551. })
  552. // }
  553. this.stepArr=arr
  554. },
  555. // 获取操作记录
  556. async getSealOprationList(id){
  557. const res=await sealInterence.getSealOperationList({SealId:id})
  558. if(res.Ret===200){
  559. this.optList=res.Data.List
  560. }
  561. },
  562. // 预览合同
  563. handlePreContractFile(urls){
  564. if(urls.length ==0) return
  565. if(urls.length==1){
  566. this.viewAttachment(urls[0])
  567. }else{
  568. this.attachmentUrls = urls
  569. this.showAttachment = true
  570. }
  571. },
  572. // 根据文件返回文件图标
  573. fileTypeIcon(url) {
  574. if (!url) return "";
  575. const fileType = this.fileType(url);
  576. return fileType === "word"
  577. ? require("@/assets/img/constract/word-icon.png")
  578. : require("@/assets/img/constract/pdf.png");
  579. },
  580. // 根据fileUrl判断文件类型
  581. fileType(fileUrl) {
  582. if (/^.+(\.pdf)$/i.test(fileUrl)) {
  583. return "pdf";
  584. } else if (/^.+(\.doc|\.docx)$/i.test(fileUrl)) {
  585. return "word";
  586. } else {
  587. return "other";
  588. }
  589. },
  590. // 预览合同附件
  591. viewAttachment(url){
  592. const reg = /\.(pdf)$/;
  593. // pdf
  594. if(reg.test(url)){
  595. window.open(url,'_blank');
  596. }else{
  597. window.open('https://view.officeapps.live.com/op/view.aspx?src='+url,'_blank');
  598. }
  599. },
  600. // 审批弹窗审批状态切换
  601. approvalFromStatusChange(){
  602. if(this.form.status==='驳回'){
  603. let top=$('.detail-wrap')[0].offsetTop
  604. $('.detail-wrap').animate({
  605. "scrollTop": top+1000
  606. })
  607. }
  608. },
  609. handleConfirmApproval(){
  610. this.$refs.form.validate((valid)=>{
  611. if (valid){
  612. if(this.form.status=='通过'){
  613. //判断是否有内容修改
  614. const flag1=this.approvalEditData.Use===this.detail.SealDetail.Use
  615. const flag2=Number(this.approvalEditData.FileNum)===Number(this.detail.SealDetail.FileNum)
  616. const flag3=this.approvalEditData.Type.join(',')===this.detail.SealDetail.SealType
  617. const flag4=this.approvalEditData.Remark===this.detail.SealDetail.Remark
  618. const flag5=this.approvalEditData.AffiliatedCompany===this.detail.SealDetail.AffiliatedCompany
  619. if(flag1&&flag2&&flag3&&flag4&&flag5){
  620. this.handleApprovalPass()
  621. }else{
  622. this.handleApprovePassModify()
  623. }
  624. }else{
  625. this.handleApprvoalReject()
  626. }
  627. }
  628. })
  629. },
  630. // 通过审批
  631. async handleApprovalPass(){
  632. const res=await sealInterence.sealApprovalPass({
  633. SealId:this.detail.SealDetail.SealId
  634. })
  635. if(res.Ret==200){
  636. this.$message.success('审批成功')
  637. this.showDetail=false
  638. setTimeout(() => {
  639. this.getSealApprovalList()
  640. }, 300);
  641. }
  642. },
  643. // 审批人修改后通过审批
  644. async handleApprovePassModify(){
  645. const res=await sealInterence.sealApprovalPassModify({
  646. CompanyName:this.detail.SealDetail.CompanyName,
  647. ContractId:this.detail.SealDetail.ContractId,
  648. CreditCode:this.detail.SealDetail.CreditCode,
  649. FileUrls:this.detail.SealDetail.FileUrls,
  650. SealId:this.detail.SealDetail.SealId,
  651. ServiceType:this.detail.SealDetail.ServiceType,
  652. UseCompanyName:this.detail.SealDetail.UseCompanyName,
  653. FileNum:Number(this.approvalEditData.FileNum),
  654. Remark:this.approvalEditData.Remark,
  655. SealType:this.approvalEditData.Type.join(','),
  656. Use:this.approvalEditData.Use,
  657. AffiliatedCompany:this.approvalEditData.AffiliatedCompany,
  658. })
  659. if(res.Ret==200){
  660. this.$message.success('审批成功')
  661. this.showDetail=false
  662. setTimeout(() => {
  663. this.getSealApprovalList()
  664. }, 300);
  665. }
  666. },
  667. // 申请驳回
  668. async handleApprvoalReject(){
  669. const res=await sealInterence.sealApprovalReject({
  670. SealId:this.detail.SealDetail.SealId,
  671. Remark:this.form.reason
  672. })
  673. if(res.Ret==200){
  674. this.$message.success('操作成功')
  675. this.showDetail=false
  676. setTimeout(() => {
  677. this.getSealApprovalList()
  678. }, 300);
  679. }
  680. },
  681. // 操作
  682. // 删除-delete 撤回-back 作废-invalid
  683. handleOpt(e,data){
  684. if(e=='delete'){
  685. this.$confirm("确定删除该用印申请吗?", "提示", {
  686. confirmButtonText: "确定",
  687. cancelButtonText: "取消",
  688. type: "warning",
  689. }).then(() => {
  690. sealInterence.sealDelete({ SealId: data.SealId }).then((res) => {
  691. if (res.Ret === 200) {
  692. this.$message.success("删除成功");
  693. this.getSealApprovalList()
  694. }
  695. });
  696. });
  697. }
  698. if(e=='back'){
  699. this.$confirm("确定撤回该用印申请吗?", "提示", {
  700. confirmButtonText: "确定",
  701. cancelButtonText: "取消",
  702. type: "warning",
  703. }).then(() => {
  704. sealInterence.sealApprovalBack({ SealId: data.SealId }).then((res) => {
  705. if (res.Ret === 200) {
  706. this.$message.success("撤回成功");
  707. this.getSealApprovalList()
  708. }
  709. });
  710. });
  711. }
  712. if(e=='invalid'){
  713. this.$confirm("确定作废该用印申请吗?", "提示", {
  714. confirmButtonText: "确定",
  715. cancelButtonText: "取消",
  716. type: "warning",
  717. }).then(() => {
  718. sealInterence.sealInvalid({ SealId: data.SealId }).then((res) => {
  719. if (res.Ret === 200) {
  720. this.$message.success("撤回成功");
  721. this.getSealApprovalList()
  722. }
  723. });
  724. });
  725. }
  726. },
  727. // 显示驳回理由
  728. handleShowRejectReason(e){
  729. this.$confirm(e.ApprovalRemark, '驳回理由', {
  730. confirmButtonText: '知道了',
  731. showCancelButton:false,
  732. type: 'info '
  733. })
  734. },
  735. //选择文件
  736. checkFileBeforeUpload(file){
  737. let hostfile = file;
  738. let size = Math.floor(hostfile.size / 1024 / 1024);
  739. if (size > 200) {
  740. this.$message.warning("上传文件大小不能大于200M!");
  741. hostfile = {};
  742. return false;
  743. }
  744. if (hostfile.name.toLowerCase().includes(".pdf")||hostfile.name.toLowerCase().includes(".doc")||hostfile.name.toLowerCase().includes(".docx")) {
  745. this.fileData.file=hostfile
  746. this.fileData.name=hostfile.name.toLowerCase()
  747. } else {
  748. this.$message.warning("请上传PDF/word文件!");
  749. }
  750. return false
  751. },
  752. // 显示上传签回弹窗
  753. handleShowUploadAttachment(e){
  754. this.fileData.sealId=e.SealId
  755. if(e.CheckBackFileUrl){
  756. this.fileData.type=2
  757. this.fileData.title=`更新签回附件(${e.CompanyName})`
  758. this.fileData.name=e.CheckBackFileUrl.substring(e.CheckBackFileUrl.lastIndexOf('/') + 1)
  759. }else{
  760. this.fileData.type=1
  761. this.fileData.title=`上传签回附件(${e.CompanyName})`
  762. }
  763. this.showUploadAttachment=true
  764. },
  765. // 提交上传/更新签回附件
  766. async handleConfirmAttachment(){
  767. if(!this.fileData.file){
  768. this.$message.warning('请选择文件')
  769. return
  770. }
  771. let form = new FormData();
  772. form.append("file", this.fileData.file)
  773. form.append('SealId',this.fileData.sealId)
  774. const res=await sealInterence.sealCheckFileUpload(form)
  775. if(res.Ret==200){
  776. this.$message.success('操作成功')
  777. this.getSealApprovalList()
  778. this.showUploadAttachment=false
  779. }
  780. },
  781. handlePreFile(e){
  782. let url=e.CheckBackFileUrl
  783. const reg = /\.(pdf)$/;
  784. // pdf
  785. if(reg.test(url)){
  786. window.open(url,'_blank');
  787. }else{
  788. window.open('https://view.officeapps.live.com/op/view.aspx?src='+url,'_blank');
  789. }
  790. }
  791. }
  792. }
  793. </script>
  794. <style>
  795. .el-message-box__header .el-message-box__title {
  796. color: #333 !important;
  797. }
  798. .detail-wrap .el-input{
  799. width: 100% !important;
  800. }
  801. .detail-wrap .el-input-number .el-input__inner{
  802. pointer-events: none;
  803. }
  804. </style>
  805. <style lang="scss" scoped>
  806. .upload-attachment-wrap{
  807. .box{
  808. width: 380px;
  809. display: inline-block;
  810. box-sizing: border-box;
  811. height: 40px;
  812. line-height: 40px;
  813. padding: 0 17px;
  814. font-size: 14px;
  815. border: 1px solid #DCDFE6;
  816. border-radius: 4px;
  817. margin-right: 20px;
  818. overflow: hidden;
  819. text-overflow: ellipsis;
  820. white-space: nowrap;
  821. }
  822. }
  823. .seal-approval-wrap{
  824. .content{
  825. background: #FFFFFF;
  826. border: 1px solid #ECECEC;
  827. box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.05);
  828. border-radius: 4px;
  829. padding: 30px;
  830. min-height: 80vh;
  831. }
  832. .btn{
  833. display: inline-block;
  834. color:#409EFF;
  835. cursor:pointer;
  836. margin: 0 5px;
  837. }
  838. }
  839. .pagination-wrap{
  840. margin-top: 30px;
  841. display: flex;
  842. justify-content: flex-end;
  843. }
  844. .detail-wrap{
  845. max-height: 70vh;
  846. overflow-y: scroll;
  847. display: flex;
  848. justify-content: space-between;
  849. .main {
  850. width: 75%;
  851. .table-wrap {
  852. width: 100%;
  853. // text-align: center;
  854. border-top: 1px solid #dcdfe6;
  855. border-left: 1px solid #dcdfe6;
  856. .table-item {
  857. padding: 14px 10px;
  858. border-right: 1px solid #dcdfe6;
  859. border-bottom: 1px solid #dcdfe6;
  860. position: relative;
  861. }
  862. .width-50 {
  863. width: 50%;
  864. }
  865. }
  866. .service-wrap {
  867. margin-top: 42px;
  868. font-size: 14px;
  869. display: flex;
  870. color: #333;
  871. }
  872. .dashed-line {
  873. margin: 40px 0;
  874. border-top: 1px dashed #aab4cc;
  875. }
  876. }
  877. .right {
  878. width: 22%;
  879. .contract-origin{
  880. margin: 15px 0;
  881. }
  882. .timeline-wrap {
  883. max-height: 500px;
  884. overflow-y: auto;
  885. // margin-top: 20px;
  886. background-color: #fff;
  887. border: 1px solid #aab4cc;
  888. padding: 20px;
  889. border-radius: 4px;
  890. text-align: left;
  891. height: calc(100% - 120px);
  892. }
  893. }
  894. }
  895. .approval-step-wrap{
  896. .step-item{
  897. margin: 15px 0;
  898. .title{
  899. font-size: 16px;
  900. font-weight: bold;
  901. color: #333;
  902. float: left;
  903. }
  904. .user-box{
  905. padding-left: 100px;
  906. span{
  907. display: inline-block;
  908. background-color: #409eff;
  909. color: #fff;
  910. padding: 3px 5px;
  911. border-radius: 3px;
  912. margin-right: 10px;
  913. }
  914. span:first-child{
  915. background-color: #fff;
  916. color: #333;
  917. padding: 0;
  918. }
  919. }
  920. }
  921. }
  922. .attachment-contain{
  923. display: flex;
  924. flex-wrap: wrap;
  925. padding: 20px 0;
  926. .attachment-image{
  927. height: 100px;
  928. width: 100px;
  929. cursor: pointer;
  930. margin:0 10px 20px 10px ;
  931. }
  932. }
  933. </style>