teskReportapprovalLook.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570
  1. <template>
  2. <basic-container>
  3. <Card class="cardTitle">
  4. <p>
  5. <el-button type="primary" @click="backPage" style="width: 80px; margin-left: 25px">返回</el-button>
  6. <el-tooltip class="item" effect="dark" content="请在批量审核前务必已查看各个服务详情,并确认服务完成情况符合服务要求。" placement="top" v-if="showBtn == 'approval'">
  7. <el-button type="primary" @click="moreApproval" style="width: 80px">批量审批</el-button>
  8. </el-tooltip>
  9. <el-button v-if="showBtn == 'approval'" type="primary" @click="exportWord" style="width: 100px; float: right; margin-left: 20px">导出</el-button>
  10. <!-- v-if="showBtn == 'approval'" -->
  11. <el-button v-if="showBtn == 'approval'" type="primary" @click="quickAuditClick" style="float: right">快捷审核模式</el-button>
  12. </p>
  13. </Card>
  14. <avue-crud
  15. :data="tableData"
  16. :option="option"
  17. :page.sync="page"
  18. :table-loading="tableLoading"
  19. @on-load="getList"
  20. @size-change="sizeChange"
  21. @current-change="currentChange"
  22. @selection-change="selectionChange"
  23. @search-change="searchVal"
  24. @search-reset="searchReset"
  25. style="width: 100%"
  26. >
  27. <template slot="menu" slot-scope="scope">
  28. <!-- :disabled="scope.row.reportApprovalOpinion != null" -->
  29. <el-button type="text" size="small" icon="el-icon-tickets" v-if="getShowBtn(scope.row)" @click="approvalBtn(scope.row.id, scope.row)">审批 </el-button>
  30. <el-button type="text" size="small" icon="el-icon-tickets" @click="showTaskInfo(scope.row, scope.index)">服务详情 </el-button>
  31. </template>
  32. <template slot="taskStatus" slot-scope="scope">
  33. <div style="line-height: 16px">
  34. <span>{{ getTaskStatusVal(scope.row.taskStatus) }}</span>
  35. <el-tooltip
  36. class="item"
  37. effect="dark"
  38. :content="'拒绝原因:' + (scope.row.reportApprovalInfo || (scope.row.checkState && scope.row.checkState.checkMsg) || '')"
  39. placement="top-start"
  40. >
  41. <i v-if="scope.row.taskStatus === '4'" class="el-icon-question f16 ml2"></i>
  42. </el-tooltip>
  43. </div>
  44. </template>
  45. <template slot="tip">
  46. <span class="ml20"
  47. >总服务积分:<span class="fwb f16">{{ totalScore }}</span></span
  48. >
  49. </template>
  50. <template slot="taskTypeIdSearch">
  51. <el-select v-model="taskTypeId" placeholder="服务类型">
  52. <el-option :label="item.taskTypeName" :value="item.id" v-for="item in taskList" :key="item.id"></el-option>
  53. </el-select>
  54. </template>
  55. <template slot="taskTypeId" slot-scope="scope">
  56. {{ getName && getName(scope.row) }}
  57. </template>
  58. </avue-crud>
  59. <el-dialog :title="showTitle" :visible.sync="showDig" top="12vh" width="40%" center :before-close="handleClose" class="review-dialog">
  60. <el-form :model="approvalLookform" :rules="rules" ref="approvalLookform" label-width="100px" class="demo-ruleForm">
  61. <div v-show="oneData">
  62. <p v-if="atypismData.length" class="teskDetailsty">不一致信息</p>
  63. <el-table v-if="atypismData.length" :data="atypismData" border style="width: 100%; margin-bottom: 20px">
  64. <el-table-column prop="name" label="信息项" width="180" align="center"> </el-table-column>
  65. <el-table-column prop="oldData" label="系统数据" width="180" align="center"> </el-table-column>
  66. <el-table-column prop="newData" label="调研数据" align="center"> </el-table-column>
  67. </el-table>
  68. <p class="missionSty">服务详情</p>
  69. <!-- <p class="missionContsty">-->
  70. <!-- <iframe class="iframe" :src="taskDetail" width="100%" height="100%" scrolling="auto" frameborder="0" />-->
  71. <!-- </p>-->
  72. <div v-if="oneData && showDig">
  73. <task-detail :id="singleVal" @getSurveyTaskInfoById="getSurveyTaskInfoById" />
  74. </div>
  75. </div>
  76. <p class="missionSty">审批意见</p>
  77. <el-form-item label="审批意见:" prop="resource">
  78. <el-radio-group v-model="approvalLookform.resource">
  79. <el-radio label="1">通过</el-radio>
  80. <el-radio label="2">拒绝</el-radio>
  81. </el-radio-group>
  82. </el-form-item>
  83. <el-form-item
  84. label="说明:"
  85. prop="explain"
  86. :rules="[
  87. {
  88. required: approvalLookform.resource == 1 ? false : true,
  89. message: '请输入审批说明',
  90. trigger: 'blur'
  91. }
  92. ]"
  93. >
  94. <el-input type="textarea" v-model="approvalLookform.explain"></el-input>
  95. </el-form-item>
  96. <refuseReason v-if="approvalLookform.resource === '2' && oneData" @selectRefuseReason="selectRefuseReason" />
  97. </el-form>
  98. <span slot="footer" class="dialog-footer">
  99. <el-button @click="handleClose">取 消</el-button>
  100. <el-button type="primary" @click="submitForm('approvalLookform')">确 定</el-button>
  101. </span>
  102. </el-dialog>
  103. <!-- 导出弹窗 -->
  104. <el-dialog title="导出" :visible.sync="exportDig" width="30%" :close-on-click-modal="false" center>
  105. <template>
  106. <div class="down-item">
  107. <span>word格式:</span>
  108. <template v-if="wordStatus && wordStatus.status === 'NOT_GENERATE'">
  109. <el-button class="first" @click="taskExport('word')" :loading="wordLoading">生成报告</el-button>
  110. </template>
  111. <template v-else-if="wordStatus && wordStatus.status === 'GENERATING'">
  112. <el-button class="first" :loading="true">报告生成中...</el-button>
  113. </template>
  114. <template v-else-if="wordStatus && (wordStatus.status === 'GENERATED' || wordStatus.status === 'ERROR')">
  115. <el-button @click="taskExport('word')">重新导出</el-button>
  116. <el-button @click="downloadTask('word')" v-if="wordStatus.status === 'GENERATED'">下载报告</el-button>
  117. <el-button disabled :title="wordStatus.errorMsg" v-else-if="wordStatus.status === 'ERROR'">导出失败</el-button>
  118. </template>
  119. <div class="title-msg">
  120. <p v-if="wordStatus && wordStatus.status === 'GENERATED'">下载截止日期:{{ wordStatus.ttl }}</p>
  121. <p v-if="wordStatus && wordStatus.status === 'ERROR'">本次导出失败:{{ wordStatus.errorMsg }}</p>
  122. </div>
  123. </div>
  124. <div class="down-item">
  125. <span>excel格式:</span>
  126. <template v-if="excelStatus && excelStatus.status === 'NOT_GENERATE'">
  127. <el-button class="first" @click="taskExport('excel')" :loading="excelLoading">生成报告</el-button>
  128. </template>
  129. <template v-if="excelStatus && excelStatus.status === 'GENERATING'">
  130. <el-button class="first" :loading="true">报告生成中...</el-button>
  131. </template>
  132. <template v-else-if="excelStatus && (excelStatus.status === 'GENERATED' || excelStatus.status === 'ERROR')">
  133. <el-button @click="taskExport('excel')">重新导出</el-button>
  134. <el-button @click="downloadTask('excel')" v-if="excelStatus.status === 'GENERATED'">下载报告</el-button>
  135. <el-button disabled :title="excelStatus.errorMsg" v-else-if="excelStatus.status === 'ERROR'">导出失败</el-button>
  136. </template>
  137. <div class="title-msg">
  138. <p v-if="excelStatus && excelStatus.status === 'GENERATED'">下载截止日期:{{ excelStatus.ttl }}</p>
  139. <p v-if="excelStatus && excelStatus.status === 'ERROR'">本次导出失败:{{ excelStatus.errorMsg }}</p>
  140. </div>
  141. </div>
  142. </template>
  143. <span slot="footer" class="dialog-footer">
  144. 注意: 1.报告将于24小时之内生成完毕,请注意下载。<br />
  145. <i style="margin-left: 62px"></i>2.报告汇总为封面+服务数据汇总+服务列表明细。
  146. <br />
  147. <i style="margin-left: 10px"></i>3.报告详情为每条服务的服务详情+图片。
  148. </span>
  149. </el-dialog>
  150. </basic-container>
  151. </template>
  152. <script>
  153. import { teskReportapprovalLookdata } from '@/const/crud/teskReportapproval';
  154. import { getTaskListPage, approvalReport, reviewTask, nodeHistoryCreateApi } from '@/api/taskManagement/teskReportapproval';
  155. import { approvalTask } from '@/api/assignPoints/currency/taskAudit';
  156. import Config from '@/settings';
  157. import taskDetail from '@/components/taskDetail';
  158. import taskApi from '@/api/taskDetail/task';
  159. import refuseReason from '@/components/refuseReason';
  160. import { getDictType } from '@/api/common';
  161. import { mapGetters } from 'vuex';
  162. export default {
  163. name: 'teskReportapprovalLook',
  164. components: {
  165. taskDetail,
  166. refuseReason
  167. },
  168. data() {
  169. return {
  170. form: {},
  171. taskList: [],
  172. taskTypeId: '',
  173. showBtn: '',
  174. isApprovalPage: 1, // 1审批 0查看
  175. showData: '',
  176. tableLoading: false,
  177. tableData: [],
  178. option: teskReportapprovalLookdata,
  179. page: {
  180. total: 0, // 总页数
  181. currentPage: 1, // 当前页数
  182. pageSize: 20 // 每页显示多少条
  183. },
  184. approvalLookform: {
  185. resource: '',
  186. explain: ''
  187. },
  188. rules: {
  189. resource: [{ required: true, message: '请选择审批意见', trigger: 'change' }]
  190. },
  191. showTitle: '',
  192. showDig: false,
  193. oneData: false,
  194. searchForm: {},
  195. singleVal: '',
  196. packageIds: '',
  197. taskDetail: '',
  198. moreDisabled: false,
  199. selectionVal: [],
  200. atypismData: [],
  201. selection: [],
  202. exportDig: false,
  203. wordStatus: {},
  204. excelStatus: {},
  205. wordLoading: false,
  206. excelLoading: false,
  207. task_status_dict: [],
  208. currentRow: {}
  209. };
  210. },
  211. computed: {
  212. ...mapGetters(['userInfo', 'roles']),
  213. totalScore() {
  214. return this.selection.reduce((pre, cur) => {
  215. return pre + (cur.score || 0);
  216. }, 0);
  217. },
  218. getTaskStatusVal() {
  219. return (taskStatusId) => {
  220. taskStatusId = String(taskStatusId).trim();
  221. const curr = this.task_status_dict.find((ele) => ele.value === taskStatusId);
  222. if (curr) return curr.label;
  223. };
  224. }
  225. },
  226. mounted() {
  227. console.log('userInfo', this.userInfo);
  228. },
  229. created() {
  230. this.showBtn = this.$route.query.type;
  231. this.isApprovalPage = this.$route.query.type === 'approval' ? 1 : 0;
  232. this.getTakList();
  233. this.getStatus();
  234. this.getTaskStatusDict();
  235. },
  236. methods: {
  237. getShowBtn(row) {
  238. let flag = false;
  239. // 当是审核的时候
  240. if (this.showBtn === 'approval') {
  241. // 当checkState的roleId是当前角色id说明可以审核
  242. if (this.userInfo.roles.includes(row.checkState.roleId)) {
  243. flag = true;
  244. }
  245. // 市场管理员与商务管理员并且roleId为-1的时候展示
  246. if ((this.userInfo.roles.includes(40) || this.userInfo.roles.includes(42)) && row.checkState.roleId == -1) {
  247. flag = true;
  248. }
  249. if (this.userInfo.roles.includes(39) && row.checkState.nextNodeId == -1) {
  250. flag = false;
  251. }
  252. }
  253. return flag;
  254. },
  255. getTaskStatusDict() {
  256. getDictType({ type: 'task_status' }).then((res) => {
  257. this.task_status_dict = res.data.data;
  258. });
  259. },
  260. selectRefuseReason(refuseReason) {
  261. this.$set(this.approvalLookform, 'explain', refuseReason);
  262. },
  263. getStatus() {
  264. taskApi.wordNBStatus(this.$route.query.id).then((res) => {
  265. this.wordStatus = res.data.data;
  266. });
  267. taskApi.excelNBStatus(this.$route.query.id).then((res) => {
  268. this.excelStatus = res.data.data;
  269. });
  270. },
  271. exportWord() {
  272. this.exportDig = true;
  273. },
  274. async taskExport(type) {
  275. if (type === 'word') {
  276. this.wordLoading = true;
  277. let res = await taskApi.wordNBReport(this.$route.query.id, this.$route.query.scoreId);
  278. if (res.data.code != 0) {
  279. this.$message.error('导出失败');
  280. return false;
  281. }
  282. this.$message.success(res.data.data);
  283. this.exportDig = false;
  284. this.getStatus();
  285. this.wordLoading = false;
  286. }
  287. if (type === 'excel') {
  288. this.excelLoading = true;
  289. let res = await taskApi.excelNBReport(this.$route.query.id, this.$route.query.scoreId);
  290. if (res.data.code != 0) {
  291. this.$message.error('导出失败');
  292. return false;
  293. }
  294. this.$message.success(res.data.data);
  295. this.exportDig = false;
  296. this.getStatus();
  297. this.excelLoading = false;
  298. }
  299. },
  300. downloadTask(type) {
  301. let latestUrl;
  302. if (type === 'word') {
  303. latestUrl = this.wordStatus.latestUrl;
  304. } else if (type === 'excel') {
  305. latestUrl = this.excelStatus.latestUrl;
  306. }
  307. let a = document.createElement('a');
  308. a.href = latestUrl;
  309. a.click();
  310. this.$message.success('导出汇总报告成功');
  311. this.exportDig = false;
  312. },
  313. quickAuditClick() {
  314. let id = this.$route.query.id;
  315. this.$router.push({
  316. path: '/admin/assignPoints/quota/quickAudit?id=' + id + '&type=2'
  317. });
  318. },
  319. async getTakList() {
  320. const res = await taskApi.getTaskList(this.$route.query.id, this.$route.query.type === 'approval' ? 1 : 0);
  321. this.taskList = res.data.data;
  322. console.log('res', this.taskList);
  323. },
  324. getName(row) {
  325. let id = row.taskTypeId;
  326. let curr = this.taskList.find((item) => item.id == id);
  327. if (curr) return curr.taskTypeName;
  328. },
  329. searchVal(form, done) {
  330. this.searchForm.taskTypeId = this.taskTypeId;
  331. this.page.currentPage = 1;
  332. this.getList(this.page, form);
  333. done();
  334. },
  335. searchReset() {
  336. this.taskTypeId = '';
  337. },
  338. // 初始化页面
  339. getList(page, params) {
  340. this.tableLoading = true;
  341. let obj = Object.assign(
  342. {
  343. isApprovalPage: this.isApprovalPage,
  344. id: this.$route.query.id,
  345. current: page.currentPage,
  346. size: page.pageSize
  347. },
  348. params,
  349. this.searchForm
  350. );
  351. console.log('obj', obj);
  352. getTaskListPage(obj)
  353. .then((response) => {
  354. this.tableData = response.data.data.records;
  355. this.page.total = response.data.data.total;
  356. this.tableLoading = false;
  357. })
  358. .catch(() => {
  359. this.tableLoading = false;
  360. });
  361. },
  362. // 单条审批
  363. approvalBtn(row, data) {
  364. this.currentRow = data;
  365. this.singleVal = row;
  366. this.showTitle = '审批';
  367. this.showDig = true;
  368. this.oneData = true;
  369. this.taskDetail = Config.outsideUrl + '/h5/#/pages/task/task-detail/index?id=' + row;
  370. },
  371. reviewBtn(row, index) {
  372. this.singleVal = row;
  373. this.showTitle = '审批';
  374. this.showDig = true;
  375. this.oneData = true;
  376. },
  377. // 批量审批按钮
  378. moreApproval() {
  379. if (this.selectionVal.length == 0) {
  380. this.$message.error('请选择需要审批的列');
  381. return false;
  382. } else {
  383. this.showTitle = '批量审批';
  384. this.showDig = true;
  385. this.oneData = false;
  386. }
  387. },
  388. // 返回按钮
  389. backPage() {
  390. this.$router.$avueRouter.closeTag();
  391. this.$router.push({ path: '/admin/taskManagement/teskReportapproval' });
  392. },
  393. // 分页查询
  394. sizeChange(pageSize) {
  395. this.page.pageSize = pageSize;
  396. },
  397. currentChange(current) {
  398. this.page.currentPage = current;
  399. },
  400. // 确定按钮
  401. submitForm(formName) {
  402. this.$refs[formName].validate(async (valid) => {
  403. if (valid) {
  404. if (this.showBtn == 'approval') {
  405. let id = '';
  406. if (this.showTitle === '审批') {
  407. id = this.singleVal;
  408. } else {
  409. (id = this.packageIds), (this.currentRow = this.tableData[0]);
  410. }
  411. let res;
  412. const obj = {
  413. id: this.$route.query.id,
  414. taskIds: id,
  415. approvalOpinion: this.approvalLookform.resource,
  416. approvalInfo: this.approvalLookform.explain,
  417. taskStatusInfo: this.approvalLookform.explain,
  418. nodeId: this.currentRow.checkState.nextNodeId
  419. };
  420. if (this.userInfo.roles.includes(42)) {
  421. obj.nodeId = 8;
  422. }
  423. // 40 商务组
  424. if (this.userInfo.roles.includes(40)) {
  425. obj.nodeId = 9;
  426. }
  427. res = await approvalReport(obj);
  428. if (res.data.code === 0) {
  429. this.getList(this.page);
  430. this.showDig = false;
  431. this.tableLoading = false;
  432. this.$message.success('审批成功');
  433. this.approvalLookform.resource = '';
  434. }
  435. this.handleClose();
  436. }
  437. return;
  438. // 当审核方式通过 并且不是当前审核id不是39 审核提交走 nodeHistoryCreateApi 接口
  439. if (this.approvalLookform.resource == 1 && !this.userInfo.roles.includes(39)) {
  440. const obj = {
  441. id: this.singleVal,
  442. approvalOpinion: this.approvalLookform.resource,
  443. taskStatusInfo: this.approvalLookform.explain,
  444. nodeId: this.currentRow.checkState.nextNodeId
  445. };
  446. // 针对市场组和商务组做特殊处理
  447. // 市场组
  448. res = await nodeHistoryCreateApi(obj);
  449. } else {
  450. // let args = {
  451. // id: this.$route.query.id,
  452. // taskIds: this.packageIds,
  453. // approvalOpinion: this.approvalLookform.resource,
  454. // approvalInfo: this.approvalLookform.explain
  455. // };
  456. // 拒绝接口 approvalReport
  457. }
  458. } else {
  459. console.log('error submit!!');
  460. return false;
  461. }
  462. });
  463. },
  464. // 多选
  465. selectionChange(selection, row) {
  466. this.selection = selection;
  467. this.selectionVal = selection;
  468. this.packageIds = '';
  469. if (undefined != selection) {
  470. for (var i = 0; i < selection.length; i++) {
  471. // if(selection[i].reportApprovalOpinion != null){
  472. // return false;
  473. // }else{
  474. // return true;
  475. // }
  476. this.packageIds += selection[i].id;
  477. if (i < selection.length - 1) {
  478. this.packageIds += ',';
  479. }
  480. }
  481. }
  482. },
  483. // 弹窗取消
  484. cancelBtn() {
  485. this.showDig = false;
  486. },
  487. handleClose() {
  488. this.$refs.approvalLookform.resetFields();
  489. this.showDig = false;
  490. this.atypismData = [];
  491. },
  492. // 服务详情
  493. showTaskInfo(row, index) {
  494. window.open(
  495. Config.outsideUrl + '/h5/#/pages/task/task-detail/index?id=' + row.id,
  496. 'newwindow',
  497. 'height=500, width=400, top=200, left=300, toolbar=no, menubar=no, scrollbars=no, resizable=no, location=no, status=no'
  498. );
  499. },
  500. // 获取不一致信息
  501. getSurveyTaskInfoById(id) {
  502. taskApi.getSurveyTaskInfoById(id).then((res) => {
  503. this.atypismData = res.data.data.compareList;
  504. });
  505. }
  506. }
  507. };
  508. </script>
  509. <style lang="scss" scoped>
  510. .review-dialog {
  511. ::v-deep .el-dialog__body {
  512. padding: 0 25px 0;
  513. }
  514. }
  515. .down-item {
  516. margin-left: 20px;
  517. margin-bottom: 15px;
  518. span {
  519. width: 80px;
  520. display: inline-block;
  521. text-align: right;
  522. }
  523. .first {
  524. width: 240px;
  525. }
  526. }
  527. </style>
  528. <style>
  529. .missionSty {
  530. height: 40px;
  531. line-height: 40px;
  532. font-size: 16px;
  533. font-weight: 600;
  534. border-bottom: 1px solid #d7d6d5;
  535. margin-bottom: 10px;
  536. }
  537. .missionContsty {
  538. height: 350px;
  539. margin-bottom: 10px;
  540. border: 1px solid red;
  541. }
  542. .cardTitle {
  543. margin-bottom: 15px;
  544. }
  545. </style>