audit.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. //通用审核
  2. <template>
  3. <div class="container">
  4. <div class="center">
  5. <el-row style='margin-bottom:10px;'>
  6. <el-col :span="12">
  7. <div style='margin-left:10px;' class="datascreen">
  8. <el-date-picker value-format='yyyy-MM-dd' v-model="value" type="daterange" unlink-panels range-separator="至"
  9. start-placeholder="开始日期" end-placeholder="结束日期" :picker-options="pickerOptions" class="data_css" @change="changeDate" >
  10. </el-date-picker>
  11. <el-input placeholder="可按发起人姓名或业务编号查找" class="input_css" v-model="searchKeyWord"></el-input>
  12. <el-button class="find" type="primary" @click="find()"><img width="16" height="16" style="left: -8px;"
  13. src="../../../public/img/sousuo.png" alt="" /></el-button>
  14. </div>
  15. </el-col>
  16. <el-col style="text-align:right;" :span="12">
  17. <el-button style="margin-right:10px" @click="addlist" type="primary">添加</el-button>
  18. </el-col>
  19. </el-row>
  20. <el-row style='margin-bottom:10px;'>
  21. <el-col :span="18">
  22. <el-button style="margin-left:10px" @click="typeChange1('')" :type="searchType == ''?'primary':''">全部</el-button>
  23. <el-button @click="typeChange1(1)" :type="searchType == 1?'primary':''">待审核</el-button>
  24. <el-button @click="typeChange1(2)" :type="searchType == 2?'primary':''">已驳回</el-button>
  25. <el-button @click="typeChange1(3)" :type="searchType == 3?'primary':''">已通过</el-button>
  26. <el-select v-model="businessType" filterable clearable placeholder="选择类型" @change="typeChange" >
  27. <el-option key="type0" label="全部类型" value=""
  28. style="color: #8890b1" />
  29. <el-option v-for="item in xialaList" :key="item.id" :label="item.constValue" :value="item.constValue"
  30. style="color: #8890b1" />
  31. </el-select>
  32. <i @click="aduitflow" class="el-icon-question"></i>
  33. </el-col>
  34. <el-col :span="6">
  35. </el-col>
  36. </el-row>
  37. <div class="fromdata">
  38. <el-table :data="tableData" stripe style="width: 100%" @selection-change="handleSelectionChange">
  39. <el-table-column
  40. type="selection"
  41. width="55">
  42. </el-table-column>
  43. <el-table-column type="index" label="序号">
  44. <template scope="scope">
  45. <span v-if="scope.$index < 9">0{{ scope.$index + 1 }}</span>
  46. <span v-else>{{ scope.$index + 1 }}</span>
  47. </template>
  48. </el-table-column>
  49. <el-table-column prop="auditBusinessNo" label="审核业务编号">
  50. </el-table-column>
  51. <el-table-column prop="sponsor" label="发起人">
  52. </el-table-column>
  53. <el-table-column prop="businessType" label="类型">
  54. </el-table-column>
  55. <el-table-column prop="buyer" label="备注">
  56. <template slot-scope="scope">
  57. <el-popover
  58. placement="bottom"
  59. title="备注详情"
  60. width="400"
  61. trigger="click"
  62. >
  63. <div>
  64. <div>{{scope.row.sponsor+'('+scope.row.auditBusinessNo+')'}}</div>
  65. <div>{{scope.row.remark}}</div>
  66. </div>
  67. <el-button slot="reference">查看</el-button>
  68. </el-popover>
  69. </template>
  70. </el-table-column>
  71. <el-table-column prop="addressUrl" label="附件">
  72. <template slot-scope="scope">
  73. <img width="18" height="20" style="vertical-align: text-top; position: relative; top: -1px"
  74. src="../../../public/img/fujian.png" @click="fujian(scope.row)" alt="" />
  75. <span v-if="scope.row.addressUrlArray != null">
  76. {{
  77. scope.row.addressUrlArray.length == 0
  78. ? ''
  79. : scope.row.addressUrlArray.length
  80. }}
  81. </span>
  82. </template>
  83. </el-table-column>
  84. <el-table-column prop="createDate" label="时间"></el-table-column>
  85. <el-table-column prop="status" label="状态">
  86. <template slot-scope="scope">{{scope.row.approveStatus?scope.row.approveStatus:scope.row.status}}<i @click="handlerecord(scope.row)" class="el-icon-s-claim"></i></template>
  87. </el-table-column>
  88. <el-table-column prop="address" label="操作" width="300">
  89. <template slot-scope="scope">
  90. <el-button v-if="scope.row.approveStatus&&scope.row.taskId" @click="pass(scope.row)" type="primary">通过</el-button>
  91. <el-button v-if="scope.row.approveStatus&&scope.row.taskId" @click="reject(scope.row)" type="primary">驳回</el-button>
  92. <!-- <div style="display:inline-block;"> -->
  93. <el-button v-if="scope.row.status=='已驳回'" @click="del(scope.row)" type="danger">删除</el-button>
  94. <!-- </div> -->
  95. </template>
  96. </el-table-column>
  97. </el-table>
  98. </div>
  99. <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage"
  100. style="text-align:center" :page-size="pageSize"
  101. layout="total, sizes, prev, pager, next, jumper" :total="deptBudgetTotal">
  102. </el-pagination>
  103. </div>
  104. <el-dialog
  105. title="提示"
  106. :visible.sync="addshow"
  107. width="70%"
  108. :before-close="handleClose">
  109. <el-form ref="form" :model="form" label-width="80px">
  110. <el-form-item label="类型">
  111. <el-select v-model="form.businessType" filterable clearable placeholder="选择类型">
  112. <el-option v-for="item in xialaList" :key="item.id" :label="item.constValue" :value="item.constValue" style="color: #8890b1" />
  113. </el-select>
  114. </el-form-item>
  115. <el-form-item label="附件">
  116. <ws-upload ref="upload" limit="20" accept=".jpg, .jpeg, .png, .pdf, .doc, .docx, .xls, .xlsx" :comp-id="compId" :appendix-ids="form.addressUrl" :size-limit="size"
  117. @onChange="onChange"
  118. />
  119. </el-form-item>
  120. <el-form-item label="备注">
  121. <el-input maxlength="2000" rows="5" type="textarea" show-word-limit v-model="form.remark"></el-input>
  122. </el-form-item>
  123. <el-form-item>
  124. <el-button @click="addshow=false">取消</el-button>
  125. <el-button type="primary" @click="onSubmit">提交</el-button>
  126. </el-form-item>
  127. </el-form>
  128. </el-dialog>
  129. <el-dialog
  130. title="审核流详情"
  131. :visible.sync="show"
  132. width="30%"
  133. :before-close="handleClose1">
  134. <div v-for="item in blocks">
  135. <div style="margin:10px 0;">{{item.title}}</div>
  136. <div style="display:inline-block;" v-for="(item1,index) in item.subBlocks"><span v-if="item1.desc!='_PLACEHOLDER_'">{{item1.desc}}</span> <span v-if="item1.desc!='_PLACEHOLDER_'&&index!=item.subBlocks.length-1">----></span> </div>
  137. </div>
  138. </el-dialog>
  139. <el-dialog
  140. :title="title"
  141. :visible.sync="rejectshow"
  142. width="30%"
  143. :before-close="handleClose">
  144. <span>{{title=='驳回'?'确定驳回审核?':'确定通过审核?'}}</span>
  145. <div><el-input
  146. type="textarea"
  147. :rows="2"
  148. placeholder="请输入审核意见"
  149. v-model="textarea">
  150. </el-input>
  151. </div>
  152. <span slot="footer" class="dialog-footer">
  153. <el-button @click="rejectshow = false">取 消</el-button>
  154. <el-button type="primary" @click="rejectclick">确 定</el-button>
  155. </span>
  156. </el-dialog>
  157. <WinseaContentModal v-model="accessoryTFs" :title="$t('system.noticeCircular.information')"
  158. @on-cancel="handleClose">
  159. <ws-upload ref="upload" :comp-id="compId" :appendix-ids="appendixIdss" :editable="false"
  160. accept=".jpg, .jpeg, .png, .pdf, .doc, .zip, .rar" />
  161. </WinseaContentModal>
  162. <el-dialog width="50%" :visible.sync="dialogVisible1" title="审核记录">
  163. <div style="padding: 20px" v-for="(item, index) in recordList" :style="{
  164. 'border-bottom':
  165. index != recordList.length - 1 ? '1px solid #ccc' : 'none',
  166. }">
  167. <div style="width: 100%; text-align: left">
  168. {{ item.operateUser }}({{item.approveResult==1?'已通过':'已驳回'}})
  169. </div>
  170. <div style="width: 100%; text-align: left">
  171. {{ item.verifyRemark }}
  172. </div>
  173. </div>
  174. </el-dialog>
  175. </div>
  176. </template>
  177. <script>
  178. import {
  179. xiala,
  180. aduitinfoList,
  181. addaduitinfo,
  182. deladuitinfo,
  183. workflow,
  184. gethis
  185. } from '@/model/universalityAudit/index'
  186. import { getUuid } from '../../utils'
  187. import WsUpload from '@/components/WsUpload'
  188. import {
  189. woekflowhandle
  190. } from '@/model/tasksport/index'
  191. import {
  192. getAuditRecord,
  193. } from '@/model/profitable/index'
  194. export default {
  195. components: {
  196. WsUpload
  197. },
  198. data() {
  199. return {
  200. value: "",
  201. tableData: [],
  202. show:false,
  203. title:'',
  204. textarea:'',
  205. rejectshow:false,
  206. addshow:false,
  207. correlationshow:false,
  208. deptBudgetTotal: 0,
  209. currentPage: 1,
  210. pageSize: 10,
  211. businessType:'',
  212. searchType:"",
  213. searchKeyWord:"",
  214. startDate:"",
  215. endDate:"",
  216. outtotal:0,
  217. xialaList:[],
  218. intotal:0,
  219. form:{},
  220. dialogVisible:false,
  221. contractList:[],
  222. datalist:{},
  223. size:100,
  224. accessoryTFs:false,
  225. appendixIdss:'',
  226. blocks:[],
  227. compId:localStorage.getItem('ws-pf_compId'),
  228. currectdata:{},
  229. dialogVisible1:false,
  230. recordList:[]
  231. }
  232. },
  233. activated() {
  234. xiala({constId:'EXA1'}).toPromise()
  235. .then(response => {
  236. this.xialaList=response
  237. })
  238. this.getList()
  239. },
  240. methods: {
  241. rejectclick(){
  242. if(this.title=='驳回'){
  243. woekflowhandle({
  244. taskId: this.currectdata.taskId,
  245. approved:false,
  246. auditMind: this.textarea,
  247. needReapply: true,
  248. }).toPromise()
  249. .then((response) => {
  250. this.$message({
  251. message: '驳回成功!',
  252. type: 'success',
  253. })
  254. this.rejectshow=false
  255. this.getList()
  256. }).catch((response) => {
  257. this.$message({
  258. message: '驳回失败!',
  259. type: 'error',
  260. })
  261. })
  262. }else{
  263. woekflowhandle({
  264. taskId: this.currectdata.taskId,
  265. approved:true,
  266. auditMind: this.textarea,
  267. needReapply: true,
  268. }).toPromise()
  269. .then((response) => {
  270. this.$message({
  271. message: '通过成功!',
  272. type: 'success',
  273. })
  274. this.rejectshow=false
  275. this.getList()
  276. }).catch((response) => {
  277. this.$message({
  278. message: '通过失败!',
  279. type: 'error',
  280. })
  281. })
  282. }
  283. },
  284. handlerecord(row) {
  285. getAuditRecord({ id: row.id, workflowId: row.workflowId })
  286. .toPromise()
  287. .then((response) => {
  288. this.recordList = response
  289. this.dialogVisible1 = true
  290. })
  291. .catch((response) => { })
  292. },
  293. pass(row){
  294. this.currectdata=row
  295. this.title='通过'
  296. this.rejectshow=true
  297. },
  298. reject(row){
  299. this.currectdata=row
  300. this.title='驳回'
  301. this.rejectshow=true
  302. },
  303. aduitflow(){
  304. workflow({businessCode: 'GENERAL-AUDIT-APPROVE'}).toPromise().then(response => {
  305. for (let i = 0; i < response.length; i++) {
  306. if(response[i].latest==1){
  307. gethis({workflowId:response[i].id}).toPromise().then(response => {
  308. const branchSameNodeIds = [];
  309. this.convertStepsToBlocks(response.steps ? response.steps : [], this.blocks, branchSameNodeIds, 0, false, false);
  310. console.log(this.blocks,branchSameNodeIds)
  311. })
  312. }
  313. }
  314. })
  315. },
  316. convertStepsToBlocks (steps, blocks, branchSameNodeIds, fromIndex, onBranch, shouldAddEndPoint) {
  317. let index = fromIndex;
  318. let index1 = 0;
  319. let arr=[]
  320. while (index < steps.length) {
  321. const item = steps[index];
  322. switch (item.stepType) {
  323. case 'NORMAL':
  324. if (item.branchNodeLocation !== 'END') { // 普通节点直接加上
  325. arr[index1].subBlocks.push({
  326. ...item,
  327. })
  328. } else { // END节点,需要在合适时机给加到主分支节点下面
  329. arr[index1].subBlocks.push({
  330. ...item,
  331. })
  332. index1++
  333. }
  334. break;
  335. case 'COUNTERSIGN':
  336. arr[index1].subBlocks.push({
  337. ...item,
  338. })
  339. break;
  340. case 'CONDITION':
  341. if (item.branchSameNodeId==0&&item.branchConditions) { // 新的条件主节点
  342. arr[index1]={subBlocks:[],title:item.branchConditions[0].varValue}
  343. arr[index1].subBlocks.push({
  344. ...item,
  345. })
  346. }
  347. break;
  348. default:
  349. break;
  350. }
  351. index++;
  352. }
  353. this.blocks=arr
  354. this.show=true
  355. // console.log(arr)
  356. },
  357. // convertStepsToBlocks (steps, fromIndex) {
  358. // let index = fromIndex;
  359. // while (index < steps.length) {
  360. // const item = steps[index];
  361. // switch (item.stepType) {
  362. // case 'NORMAL':
  363. // if(item.branchNodeLocation !== 'END'){
  364. // this. blocks.push({
  365. // ...item,
  366. // type: 0,
  367. // })
  368. // }else{
  369. // }
  370. // break;
  371. // case 'COUNTERSIGN':
  372. // break;
  373. // case 'CONDITION':
  374. // break;
  375. // default:
  376. // break;
  377. // }
  378. // index++
  379. // }
  380. // },
  381. fujian(row) {
  382. this.id = row.id
  383. this.accessoryTFs = true
  384. this.appendixIdss = row.addressUrl
  385. console.log(this.appendixIdss)
  386. },
  387. del(row){
  388. this.$confirm('确定删除审核信息?', '提示', {
  389. confirmButtonText: '确定',
  390. cancelButtonText: '取消',
  391. type: 'warning'
  392. })
  393. .then(() => {
  394. deladuitinfo({id:row.id}).toPromise().then(response => {
  395. this.$message({
  396. message: '删除成功!',
  397. type: 'success',
  398. })
  399. this.getList()
  400. })
  401. })
  402. },
  403. onChange() {
  404. this.$refs.upload
  405. .handleSaveBill()
  406. .then(async (response) => {
  407. this.form.addressUrl = response
  408. })
  409. .catch((res) => {
  410. EventBus.$emit('error', (JSON.parse(res) || {}).message)
  411. this.$refs.upload.clearFiles()
  412. })
  413. },
  414. onSubmit(){
  415. if(!this.form.businessType){
  416. this.$message({
  417. message: '审核类型不能为空!',
  418. type: 'warning',
  419. })
  420. }
  421. if(this.form.remark&&this.form.remark.length<2||this.form.remark&&this.form.remark.length>1000){
  422. this.$message({
  423. message: '备注信息10-2000个字!',
  424. type: 'warning',
  425. })
  426. }
  427. this.$confirm('确定发起审核?', '提示', {
  428. confirmButtonText: '确定',
  429. cancelButtonText: '取消',
  430. type: 'warning'
  431. })
  432. .then(() => {
  433. this.form.compId=localStorage.getItem('ws-pf_compId')
  434. this.form.sponsor=localStorage.getItem('ws-pf_staffName')
  435. addaduitinfo(this.form).toPromise().then(response => {
  436. this.$message({
  437. message: '提交成功!',
  438. type: 'success',
  439. })
  440. this.form={}
  441. this.$refs.upload.clearFiles()
  442. this.addshow=false
  443. this.getList()
  444. })
  445. })
  446. },
  447. addlist(){
  448. this.addshow=true
  449. },
  450. handleClose(){
  451. this.addshow=false
  452. },
  453. handleClose1(){
  454. this.show=false
  455. },
  456. typeChange(num){
  457. this.businessType= num
  458. this.getList()
  459. },
  460. typeChange1(num){
  461. this.searchType= num
  462. this.getList()
  463. },
  464. returnsales(){
  465. this.$router.go(-1)
  466. },
  467. handleSelectionChange(val) {
  468. this.multipleSelection = val;
  469. },
  470. async getList() {
  471. aduitinfoList({
  472. startDate:this.startDate,
  473. endDate:this.endDate,
  474. searchKeyWord:this.searchKeyWord,
  475. currentPage: this.currentPage,
  476. pageSize:this.pageSize ,
  477. searchType:this.searchType,
  478. businessType:this.businessType,
  479. flag:0
  480. })
  481. .toPromise()
  482. .then(response => {
  483. if(response.records.length>0){
  484. for (let i = 0; i < response.records.length; i++) {
  485. if(response.records[i].addressUrl){
  486. response.records[i].addressUrlArray=[]
  487. var arr=response.records[i].addressUrl.split(',')
  488. for (let q = 0; q < arr.length; q++) {
  489. if(arr[q]!=''){
  490. response.records[i].addressUrlArray.push(arr[q])
  491. }
  492. }
  493. }
  494. }
  495. }
  496. this.tableData=response.records
  497. this.deptBudgetTotal=response.total
  498. })
  499. },
  500. changeDate(){
  501. if(this.value){
  502. this.startDate = this.value[0]
  503. this.endDate = this.value[1]
  504. }
  505. this.getList()
  506. },
  507. pickerOptions() {},
  508. find() {
  509. this.getList()
  510. },
  511. handleSizeChange(val) {
  512. console.log(`每页 ${val} 条`)
  513. this.pageSize = val
  514. this.getList()
  515. },
  516. handleCurrentChange(val) {
  517. this.currentPage = val
  518. console.log(`当前页: ${val}`)
  519. this.getList()
  520. },
  521. },
  522. }
  523. </script>
  524. <style lang="scss" scoped>
  525. table,
  526. table tr th,
  527. table tr td {
  528. border: 2px solid #333333;
  529. padding: 5px 0;
  530. height: 55px;
  531. }
  532. .content {
  533. width: 1000px;
  534. padding: 70px 20px 20px 20px;
  535. font-size: 22px;
  536. position: absolute;
  537. top: 0;
  538. bottom: 0;
  539. left: 0;
  540. right: 0;
  541. }
  542. table {
  543. width: 100%;
  544. text-align: center;
  545. border-collapse: collapse;
  546. border: 3px solid #333333;
  547. }
  548. .col-bgc {
  549. background: #f6f7fb;
  550. }
  551. .container {
  552. background: #E8ECF6;
  553. }
  554. .center {
  555. margin: 0 auto;
  556. background: #ffffff;
  557. height: calc(100vh - 13vh);
  558. border-radius: 4px;
  559. padding: 20px 0;
  560. /deep/.el-table td,
  561. /deep/.el-table th {
  562. text-align: center;
  563. }
  564. }
  565. .row_top {
  566. background: #F6F7FC;
  567. border-radius: 4px;
  568. margin-bottom: 10px;
  569. .bg-left {
  570. padding-left: 30px;
  571. }
  572. .bg-right {
  573. padding-right: 10px;
  574. text-align: right;
  575. }
  576. .title {
  577. position: relative;
  578. }
  579. .title::before {
  580. content: '';
  581. display: inline-block;
  582. width: 5px;
  583. height: 30px;
  584. background: #5473e8;
  585. position: absolute;
  586. left: 0;
  587. }
  588. }
  589. .datascreen {
  590. display: flex;
  591. .data_css {
  592. width: 40%;
  593. }
  594. .input_css {
  595. width: 50%;
  596. margin: 0 10px;
  597. }
  598. .find {
  599. margin-right: 10px;
  600. }
  601. }
  602. .fromdata {
  603. margin: 20px 0;
  604. overflow-y: scroll;
  605. height: 546px;
  606. }
  607. .top_info{
  608. margin: 10px 0 0 10px;
  609. min-width: 712px;
  610. .info_css{
  611. margin-right: 20px;
  612. }
  613. }
  614. .bg-right{
  615. padding-top:15px;
  616. }
  617. </style>