index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453
  1. <!-- 保养工单 -->
  2. <template>
  3. <div>
  4. <div class="ele-body">
  5. <el-card shadow="never">
  6. <div class="filter-container">
  7. <seekPage
  8. :seekList="seekList"
  9. :formLength="3"
  10. @search="search"
  11. ></seekPage>
  12. </div>
  13. <ele-pro-table
  14. ref="table"
  15. :columns="columns"
  16. :datasource="datasource"
  17. maxHeight="580"
  18. :pageSize="20"
  19. >
  20. <!-- 操作列 -->
  21. <template v-slot:action="{ row }">
  22. <el-link
  23. v-if="row.orderStatus !== 3 && row.orderStatus !== 4"
  24. type="primary"
  25. :underline="false"
  26. icon="el-icon-edit"
  27. @click="toSigningUpWork(row)"
  28. >
  29. 报工
  30. </el-link>
  31. <el-link
  32. v-if="row.orderStatus !== 3 && row.orderStatus !== 4"
  33. type="primary"
  34. :underline="false"
  35. icon="el-icon-edit"
  36. @click="toRedeploy(row)"
  37. >
  38. 转派
  39. </el-link>
  40. </template>
  41. </ele-pro-table>
  42. </el-card>
  43. </div>
  44. <!-- 验收 -->
  45. <RepairDetailsDialog ref="detailsDialogRef" @refesh="getData" />
  46. <!-- 转派弹窗 -->
  47. <redeployOther ref="redeployOtherRef" @refresh="getData" />
  48. <!-- 报工弹框 -->
  49. <signingUpWork ref="signingUpWorkRef" @refresh="getData" />
  50. </div>
  51. </template>
  52. <script>
  53. import RepairDetailsDialog from '../components/RepairDetailsDialog.vue';
  54. import redeployOther from '../components/redeployOther.vue';
  55. import signingUpWork from '../components/signingUpWork.vue';
  56. import { ticketStatus, resultStatus } from '@/utils/dict/tickets';
  57. import { getWorkOrderPage, getRule } from '@/api/tickets';
  58. import pagenation from '@/components/Pagination';
  59. // 修改
  60. import {
  61. notifyMessagePageAPI,
  62. updateNotifyMessageReadByIdAPI
  63. } from '@/api/bpm/task';
  64. import { mapGetters } from 'vuex';
  65. export default {
  66. components: {
  67. pagenation,
  68. redeployOther,
  69. signingUpWork,
  70. RepairDetailsDialog
  71. },
  72. data() {
  73. return {
  74. ruleNameList: [],
  75. tableData: [],
  76. statusOptions: [],
  77. ticketStatus: [],
  78. searchForm: {
  79. code: '',
  80. orderStatus: '',
  81. ruleId: '',
  82. date: '',
  83. startTime: '',
  84. endTime: '',
  85. type: 2,
  86. isQueryTodo: 1,
  87. executeUserId: ''
  88. },
  89. pages: {
  90. page: 1,
  91. size: 15
  92. },
  93. total: 0,
  94. //
  95. addOrEditDialogFlag: false,
  96. columns: [
  97. {
  98. columnKey: 'index',
  99. label: '序号',
  100. type: 'index',
  101. width: 60,
  102. align: 'center',
  103. showOverflowTooltip: true,
  104. fixed: 'left'
  105. },
  106. {
  107. prop: 'code',
  108. label: '工单编号',
  109. minWidth: '200',
  110. align: 'center'
  111. },
  112. {
  113. prop: 'planCode',
  114. label: '计划单号',
  115. width: '200',
  116. align: 'center'
  117. },
  118. {
  119. prop: 'planName',
  120. label: '保养名称',
  121. align: 'center',
  122. minWidth: '180',
  123. showOverflowTooltip: true
  124. },
  125. {
  126. prop: 'ruleName',
  127. label: '规则名称',
  128. align: 'center',
  129. minWidth: '180',
  130. showOverflowTooltip: true
  131. },
  132. {
  133. prop: 'createUserName',
  134. label: '创建人',
  135. align: 'center',
  136. minWidth: '180',
  137. showOverflowTooltip: true
  138. },
  139. {
  140. prop: 'createTime',
  141. label: '创建时间',
  142. align: 'center',
  143. minWidth: '180',
  144. showOverflowTooltip: true
  145. },
  146. {
  147. prop: 'acceptTime',
  148. label: '开始时间',
  149. align: 'center',
  150. minWidth: '180',
  151. showOverflowTooltip: true
  152. },
  153. {
  154. prop: 'finishTime',
  155. label: '结束时间',
  156. align: 'center',
  157. minWidth: '180',
  158. showOverflowTooltip: true
  159. },
  160. {
  161. prop: 'planFinishTime',
  162. label: '计划完成时间',
  163. align: 'center',
  164. minWidth: '180',
  165. showOverflowTooltip: true
  166. },
  167. {
  168. prop: 'isAbnormal',
  169. label: '执行结果',
  170. align: 'center',
  171. showOverflowTooltip: true,
  172. formatter: (_row, _column, cellValue) => {
  173. return { 0: '缺陷', 1: '正常' }[_row.isAbnormal];
  174. }
  175. },
  176. {
  177. prop: 'orderStatus',
  178. label: '状态',
  179. align: 'center',
  180. showOverflowTooltip: true,
  181. formatter: (_row, _column, cellValue) => {
  182. return ticketStatus.filter(
  183. (item) => item.id == _row.orderStatus
  184. )[0]?.label;
  185. }
  186. },
  187. {
  188. prop: 'practicalTime',
  189. label: '实际工时',
  190. align: 'center',
  191. showOverflowTooltip: true,
  192. formatter: (_row, _column, cellValue) => {
  193. let _this = this;
  194. return _this.time_interval(_row.acceptTime, _row.finishTime);
  195. }
  196. },
  197. {
  198. columnKey: 'action',
  199. label: '操作',
  200. minWidth: 200,
  201. align: 'center',
  202. slot: 'action',
  203. fixed: 'right'
  204. }
  205. ],
  206. tableData: [],
  207. size: 10,
  208. page: 1
  209. };
  210. },
  211. computed: {
  212. ...mapGetters(['user']),
  213. // 是否开启响应式布局
  214. styleResponsive() {
  215. return this.$store.state.theme.styleResponsive;
  216. },
  217. seekList() {
  218. return [
  219. {
  220. label: '工单编号',
  221. value: 'code',
  222. type: 'input',
  223. placeholder: ' '
  224. },
  225. {
  226. label: '规则名称:',
  227. value: 'ruleId',
  228. type: 'select',
  229. placeholder: ' ',
  230. planList: this.ruleNameList.map((item) => {
  231. return { label: item.name, value: item.id };
  232. })
  233. },
  234. {
  235. label: '状态',
  236. value: 'orderStatus',
  237. type: 'select',
  238. planList: ticketStatus.map((item) => {
  239. return { label: item.label, value: item.id };
  240. }),
  241. placeholder: ' '
  242. },
  243. // {
  244. // label: '开始结束时间:',
  245. // value: 'createTime',
  246. // type: 'date',
  247. // dateType: 'datetimerange',
  248. // placeholder: '',
  249. // width: 380,
  250. // labelWidth: '130px',
  251. // valueAr: ['startTime', 'endTime']
  252. // }
  253. ];
  254. }
  255. },
  256. methods: {
  257. //新增或修改模板
  258. async handleAddOrEdit(row) {
  259. await updateNotifyMessageReadByIdAPI([row.id]);
  260. this.$refs.table.reload();
  261. },
  262. search(e) {
  263. this.searchForm = e;
  264. this.$refs.table.reload({ page: 1, where: e });
  265. },
  266. // 获取table数据
  267. async datasource({ page, where, limit, ...row }) {
  268. const res = await getWorkOrderPage({
  269. ...where,
  270. pageNum: page,
  271. size: limit,
  272. userId: this.user.info.userId,
  273. executeUserId: this.userId,
  274. type: 2,
  275. isQueryTodo: 1
  276. });
  277. this.total = res.total;
  278. this.$emit('recount');
  279. return res;
  280. },
  281. // 获取规则名列表(设备保养)
  282. async getRuleNameList() {
  283. const res = await getRule({
  284. status: 1,
  285. type: 2,
  286. pageNum: 1,
  287. size: -1
  288. });
  289. if (res.list) {
  290. this.ruleNameList = res.list || [];
  291. }
  292. },
  293. // 转派
  294. toRedeploy(row) {
  295. this.$refs.redeployOtherRef.open(row);
  296. },
  297. // 报工
  298. toSigningUpWork(row) {
  299. this.$refs.signingUpWorkRef.open(row);
  300. },
  301. openDetail({ id }) {
  302. this.$router.push({
  303. path: '/tickets/maintenance/detail',
  304. query: {
  305. id
  306. }
  307. });
  308. },
  309. getData() {
  310. this.search(this.searchForm);
  311. },
  312. // 计算实际工时
  313. time_interval(dt1, dt2) {
  314. if (!dt1 || !dt2) {
  315. return '';
  316. }
  317. if (typeof dt1 == 'string') {
  318. dt1 = new Date(dt1.replace(/-/, '/'));
  319. dt2 = new Date(dt2.replace(/-/, '/'));
  320. }
  321. var res = dt2 - dt1;
  322. if (isNaN(res)) throw Error('invalid dates arguments');
  323. let re = res / (1000 * 60 * 60);
  324. var h = parseInt(re);
  325. var m = parseInt((re - h) * 60);
  326. let result = '';
  327. if (h) {
  328. result += `${h} 小时`;
  329. }
  330. if (m) {
  331. result += `${m} 分钟`;
  332. }
  333. return result;
  334. },
  335. changeDate(val) {
  336. if (val === null) {
  337. this.searchForm.startTime = '';
  338. this.searchForm.endTime = '';
  339. return;
  340. }
  341. this.searchForm.startTime = val[0];
  342. this.searchForm.endTime = val[1];
  343. }
  344. },
  345. created() {
  346. this.userId = localStorage.getItem('userId');
  347. this.getRuleNameList();
  348. this.ticketStatus = ticketStatus.filter((item) => {
  349. return [0, 2, 3].includes(item.id);
  350. });
  351. }
  352. };
  353. </script>
  354. <style lang="scss" scoped>
  355. // 步骤条边线显示
  356. // ::v-deep .el-step__head.is-process .el-step__icon.is-text {
  357. // border: none !important;
  358. // background: none !important;
  359. // }
  360. // ::v-deep .el-step:last-of-type .el-step__line {
  361. // display: block !important;
  362. // width: 3px !important;
  363. // }
  364. // ::v-deep .el-steps:last-child .el-step__line {
  365. // display: none !important;
  366. // }
  367. // .patrolInspection {
  368. // height: 100%;
  369. // width: 100%;
  370. // display: flex;
  371. // flex-direction: column;
  372. // .search {
  373. // flex: 0 0 50px;
  374. // }
  375. // .table {
  376. // flex: 1;
  377. // .el-table {
  378. // width: 100%;
  379. // display: flex;
  380. // flex-direction: column;
  381. // }
  382. // }
  383. // .table-footer {
  384. // flex: 0 0 30px;
  385. // display: flex;
  386. // justify-content: flex-end;
  387. // }
  388. // }
  389. // 修改
  390. ::v-deep .el-card__body {
  391. padding: 0;
  392. }
  393. .app-container {
  394. background: #f0f3f3;
  395. min-height: calc(100vh - 84px);
  396. }
  397. .zw-page-table {
  398. background: #ffffff;
  399. padding-top: 20px;
  400. }
  401. .pagination-wrap {
  402. display: flex;
  403. justify-content: flex-end;
  404. padding: 10px 0;
  405. }
  406. .table {
  407. width: 100%;
  408. margin-top: 10px;
  409. }
  410. // 修改
  411. ::v-deep .el-card__body {
  412. padding: 0;
  413. }
  414. .app-container {
  415. background: #f0f3f3;
  416. min-height: calc(100vh - 84px);
  417. }
  418. .zw-page-table {
  419. background: #ffffff;
  420. padding-top: 20px;
  421. }
  422. .pagination-wrap {
  423. display: flex;
  424. justify-content: flex-end;
  425. padding: 10px 0;
  426. }
  427. .table {
  428. width: 100%;
  429. margin-top: 10px;
  430. }
  431. </style>