audit.vue 19 KB

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