list.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818
  1. <template>
  2. <view class="mainBox">
  3. <uni-nav-bar
  4. fixed="true"
  5. statusBar="true"
  6. left-icon="back"
  7. :title="getTitle"
  8. @clickLeft="back"
  9. >
  10. </uni-nav-bar>
  11. <view class="top-wrapper">
  12. <view class="tab-bar">
  13. <view
  14. class="tab-item"
  15. :class="{ active: activeTab === 'mine' }"
  16. @click="switchTab('mine')"
  17. >我的工单</view
  18. >
  19. <view
  20. class="tab-item"
  21. :class="{ active: activeTab === 'all' }"
  22. @click="switchTab('all')"
  23. >全部工单</view
  24. >
  25. <view
  26. class="tab-item"
  27. :class="{ active: activeTab === 'plan' }"
  28. @click="switchTab('plan')"
  29. >计划</view
  30. >
  31. </view>
  32. <uni-section>
  33. <uni-easyinput
  34. prefixIcon="search"
  35. style="width: 460rpx"
  36. v-model="keyWord"
  37. :placeholder="
  38. activeTab === 'plan'
  39. ? '计划单号,计划名称,记录规则名称'
  40. : '工单单号,计划单号,记录规则名称'
  41. "
  42. >
  43. </uni-easyinput>
  44. </uni-section>
  45. <button class="search_btn" @click="doSearch">搜索</button>
  46. </view>
  47. <div style="height: 180rpx; width: 475rpx"></div>
  48. <view class="wrapper">
  49. <u-list @scrolltolower="scrolltolower" class="listContent">
  50. <view
  51. v-for="(item, index) in tableList"
  52. :key="index"
  53. style="position: relative"
  54. >
  55. <myCard
  56. :item="item"
  57. :index="index + 1"
  58. :btnList="
  59. activeTab === 'all'
  60. ? []
  61. : activeTab === 'plan'
  62. ? planBtnList
  63. : btnList
  64. "
  65. :columns="activeTab === 'plan' ? planColumns : columns"
  66. :title="item.code || item.planCode"
  67. :status="
  68. activeTab === 'plan'
  69. ? planStatusMap[item.status]
  70. : statusMap[item.status]
  71. "
  72. :showDetail="activeTab !== 'plan'"
  73. @goDetail="goDetail(item, 'view')"
  74. @openRedeployOther="openRedeployOther(item)"
  75. @edit="goDetail(item, 'edit')"
  76. @dispatch="handleDispatch(item)"
  77. @dispatchAll="handleDispatchAll(item)"
  78. @revoke="handleRevoke(item)"
  79. >
  80. </myCard>
  81. </view>
  82. <view style="width: 100%; height: 40rpx"></view>
  83. <view style="margin-top: 20vh" v-if="tableList.length == 0">
  84. <u-empty iconSize="150" textSize="32" text="暂无数据"> </u-empty>
  85. </view>
  86. </u-list>
  87. </view>
  88. <u-toast ref="uToast"></u-toast>
  89. <workOrderReport
  90. ref="workOrderReportRef"
  91. :pageName="pageName"
  92. @refresh="successInit"
  93. ></workOrderReport>
  94. <Assign ref="Assign" @refresh="successInit"></Assign>
  95. <batchRevokeDialog
  96. ref="batchRevokeDialogRef"
  97. @refresh="successInit"
  98. :pageName="pageName"
  99. ></batchRevokeDialog>
  100. <u-popup
  101. :show="dispatchAllShow"
  102. mode="bottom"
  103. :round="20"
  104. @close="dispatchAllShow = false"
  105. >
  106. <view class="popup-content">
  107. <view class="popup-header">
  108. <text class="popup-title">批量派单</text>
  109. <view class="close-btn" @click="dispatchAllShow = false">×</view>
  110. </view>
  111. <view class="popup-body">
  112. <view class="form-item">
  113. <text class="form-label"
  114. >派单次数 <text class="required">*</text></text
  115. >
  116. <uni-easyinput
  117. v-model="dispatchQuantity"
  118. type="number"
  119. placeholder="请输入派单次数"
  120. />
  121. </view>
  122. </view>
  123. <view class="popup-footer">
  124. <u-button type="default" @click="dispatchAllShow = false"
  125. >取消</u-button
  126. >
  127. <u-button type="primary" @click="submitDispatchAll">确定</u-button>
  128. </view>
  129. </view>
  130. </u-popup>
  131. </view>
  132. </template>
  133. <script>
  134. import dictMixns from "@/mixins/dictMixins";
  135. import myCard from "@/components/myCard.vue";
  136. import Assign from "./components/Assign.vue";
  137. import workOrderReport from "./components/workOrderReport.vue";
  138. import batchRevokeDialog from "./components/batchRevokeDialog.vue";
  139. import {
  140. producetaskrulerecordQueryRecordWorkOrderPage,
  141. recordrulesplanPage,
  142. recordrulesplanRevoke,
  143. dispatchRepeatedly,
  144. recordrulesplanManualDispatchOrder,
  145. getRecordRulesPlanDetail,
  146. } from "@/api/recordRules/index";
  147. export default {
  148. components: {
  149. myCard,
  150. workOrderReport,
  151. batchRevokeDialog,
  152. Assign,
  153. },
  154. mixins: [dictMixns],
  155. props: {
  156. pageName: {
  157. default: "",
  158. },
  159. },
  160. data() {
  161. return {
  162. dispatchAllData: null,
  163. dispatchAllShow: false,
  164. dispatchQuantity: "",
  165. statusMap: {
  166. 0: "未报工",
  167. 1: "执行中",
  168. 2: "已执行",
  169. },
  170. planStatusMap: {
  171. 0: "未派单",
  172. 2: "执行中",
  173. 3: "已完成",
  174. 4: "已撤回",
  175. },
  176. planTypeList: {
  177. productionRecords: 2,
  178. steamInjectionInspectionRecord: 3,
  179. solidWasteRecord: 4,
  180. qualityTestRecords: 5,
  181. boilerOperationRecord: 6,
  182. QualityInspection: 7,
  183. HaulSlag: 8,
  184. TransportAsh: 9,
  185. },
  186. btnList: [
  187. {
  188. name: "报工",
  189. apiName: "edit",
  190. btnType: "primary",
  191. judge: [
  192. {
  193. key: "status",
  194. value: [1],
  195. },
  196. ],
  197. },
  198. {
  199. name: "转派",
  200. apiName: "openRedeployOther",
  201. btnType: "primary",
  202. judge: [
  203. {
  204. key: "status",
  205. value: [1],
  206. },
  207. ],
  208. },
  209. ],
  210. planBtnList: [
  211. {
  212. name: "派单",
  213. apiName: "dispatch",
  214. btnType: "primary",
  215. judge: [
  216. {
  217. fn: (row) =>
  218. row.dispatchType == 1 || (row.status != 2 && row.status != 3),
  219. },
  220. ],
  221. },
  222. {
  223. name: "批量派单",
  224. apiName: "dispatchAll",
  225. btnType: "primary",
  226. judge: [
  227. {
  228. fn: (row) => row.dispatchType == 1,
  229. },
  230. ],
  231. },
  232. {
  233. name: "撤回",
  234. apiName: "revoke",
  235. btnType: "warning",
  236. judge: [
  237. {
  238. fn: (row) => row.status == 2,
  239. },
  240. ],
  241. },
  242. ],
  243. columns: [
  244. [
  245. {
  246. label: "计划单号:",
  247. prop: "planCode",
  248. className: "perce100",
  249. },
  250. ],
  251. [
  252. {
  253. label: "记录规则名称:",
  254. prop: "ruleName",
  255. className: "perce100",
  256. },
  257. ],
  258. [
  259. {
  260. label: "场站名称:",
  261. className: "perce100",
  262. prop: "productLineName",
  263. },
  264. ],
  265. [
  266. {
  267. className: "perce100",
  268. label: "班组:",
  269. prop: "teamName",
  270. },
  271. ],
  272. [
  273. {
  274. label: "工单生成时间:",
  275. className: "perce100",
  276. prop: "createTime",
  277. },
  278. ],
  279. [
  280. {
  281. label: "检查时间:",
  282. className: "perce100",
  283. prop: "checkStartTime",
  284. },
  285. ],
  286. [
  287. {
  288. label: "报工时间:",
  289. className: "perce100",
  290. prop: "checkFinishTime",
  291. },
  292. ],
  293. [
  294. {
  295. label: "执行人:",
  296. className: "perce100",
  297. prop: "executeUsers",
  298. formatter: (row) => {
  299. if ((row.type == 1 && row.status == 2) || row.type != 1) {
  300. return (
  301. row.executeUsers &&
  302. row.executeUsers.map((i) => i.userName).join(",")
  303. );
  304. }
  305. },
  306. },
  307. ],
  308. [
  309. {
  310. label: "客户:",
  311. prop: "contactName",
  312. className: "perce100",
  313. isNone:
  314. !["productionRecords", "qualityTestRecords"].includes(
  315. this.pageName,
  316. ) || this.pageName == "boilerOperationRecord",
  317. },
  318. {
  319. label: "供应商:",
  320. prop: "supplierName",
  321. className: "perce100",
  322. isNone: [
  323. "productionRecords",
  324. "qualityTestRecords",
  325. "boilerOperationRecord",
  326. ].includes(this.pageName),
  327. },
  328. ],
  329. [
  330. {
  331. label: "操作:",
  332. prop: "action",
  333. type: "action",
  334. className: "perce100",
  335. },
  336. ],
  337. ].filter((item) => !item.isNone),
  338. planColumns: [
  339. [
  340. {
  341. label: "计划名称:",
  342. prop: "name",
  343. className: "perce100",
  344. },
  345. ],
  346. [
  347. {
  348. label: "记录规则名称:",
  349. prop: "ruleName",
  350. className: "perce100",
  351. },
  352. ],
  353. [
  354. {
  355. label: "场站名称:",
  356. prop: "productLineName",
  357. className: "perce100",
  358. },
  359. ],
  360. [
  361. {
  362. label: "班组:",
  363. prop: "teamName",
  364. className: "perce100",
  365. },
  366. ],
  367. [
  368. {
  369. label: "部门:",
  370. prop: "groupNames",
  371. className: "perce100",
  372. formatter: (row) =>
  373. [
  374. ...new Set(
  375. (row.executeUsers || [])
  376. .map((i) => i.groupName)
  377. .filter((i) => i),
  378. ),
  379. ].join(","),
  380. },
  381. ],
  382. [
  383. {
  384. label: "负责人:",
  385. prop: "userNames",
  386. className: "perce100",
  387. formatter: (row) =>
  388. (row.executeUsers || []).map((i) => i.userName).join(","),
  389. },
  390. ],
  391. [
  392. {
  393. label: "记录对象:",
  394. prop: "recordObject",
  395. className: "perce100",
  396. formatter: (row) =>
  397. row.associatedObject == 1 ? row.workshopName : row.deviceName,
  398. },
  399. ],
  400. [
  401. {
  402. label: "派单类型:",
  403. prop: "dispatchTypeText",
  404. className: "perce100",
  405. formatter: (row) => (row.dispatchType ? "多次" : "单次"),
  406. },
  407. ],
  408. [
  409. {
  410. label: "状态:",
  411. prop: "statusText",
  412. className: "perce100",
  413. formatter: (row) => this.planStatusMap[row.status] || "",
  414. },
  415. ],
  416. [
  417. {
  418. label: "创建人:",
  419. prop: "createUserName",
  420. className: "perce100",
  421. },
  422. ],
  423. [
  424. {
  425. label: "创建时间:",
  426. prop: "createTime",
  427. className: "perce100",
  428. },
  429. ],
  430. [
  431. {
  432. label: "操作:",
  433. prop: "action",
  434. type: "action",
  435. className: "perce100",
  436. },
  437. ],
  438. ],
  439. tableList: [],
  440. page: 1,
  441. size: 10,
  442. isEnd: false,
  443. keyWord: "",
  444. userInfo: {},
  445. activeTab: "mine",
  446. };
  447. },
  448. computed: {
  449. getTitle() {
  450. return this.pageName == "productionRecords"
  451. ? "生产记录"
  452. : this.pageName == "steamInjectionInspectionRecord"
  453. ? "注汽检查记录"
  454. : this.pageName == "solidWasteRecord"
  455. ? "固废记录"
  456. : this.pageName == "qualityTestRecords"
  457. ? "质量检查检测记录"
  458. : this.pageName == "HaulSlag"
  459. ? "拉渣记录表"
  460. : this.pageName == "TransportAsh"
  461. ? "拉灰记录表"
  462. : this.pageName == "QualityInspection"
  463. ? "来煤质检记录"
  464. : "锅炉运行记录";
  465. },
  466. },
  467. created() {
  468. this.requestDict("记录规则类型");
  469. },
  470. onLoad() {},
  471. methods: {
  472. goDetail(item, type) {
  473. console.log(item, "item");
  474. this.$refs.workOrderReportRef.open(item, type);
  475. },
  476. openRedeployOther(row) {
  477. this.$refs.Assign.open(row);
  478. },
  479. switchTab(tab) {
  480. if (this.activeTab === tab) return;
  481. this.activeTab = tab;
  482. this.isEnd = false;
  483. this.page = 1;
  484. this.tableList = [];
  485. this.getList();
  486. },
  487. successInit() {
  488. uni.showLoading({
  489. title: "加载中",
  490. });
  491. if (this.activeTab === "plan") {
  492. let data = {
  493. pageNum: 1,
  494. size: this.tableList.length,
  495. keyword: this.keyWord,
  496. planType: this.planTypeList[this.pageName],
  497. };
  498. recordrulesplanPage(data)
  499. .then((res) => {
  500. this.tableList = res.list;
  501. })
  502. .then(() => {
  503. uni.hideLoading();
  504. });
  505. return;
  506. }
  507. let data = {
  508. pageNum: 1,
  509. size: this.tableList.length,
  510. keyword: this.keyWord,
  511. planType: this.planTypeList[this.pageName],
  512. };
  513. if (this.activeTab === "mine") {
  514. data.currentLoginUserId = this.userInfo.userId;
  515. }
  516. producetaskrulerecordQueryRecordWorkOrderPage(data)
  517. .then((res) => {
  518. this.tableList = res.list;
  519. })
  520. .then(() => {
  521. uni.hideLoading();
  522. });
  523. },
  524. doSearch() {
  525. this.isEnd = false;
  526. this.page = 1;
  527. this.getList();
  528. },
  529. //获取列表信息
  530. getList() {
  531. this.userInfo = uni.getStorageSync("userInfo");
  532. if (this.isEnd || !this.userInfo.userId) {
  533. return;
  534. }
  535. uni.showLoading({
  536. title: "加载中",
  537. });
  538. if (this.activeTab === "plan") {
  539. let data = {
  540. pageNum: this.page,
  541. size: this.size,
  542. keyword: this.keyWord,
  543. planType: this.planTypeList[this.pageName],
  544. };
  545. recordrulesplanPage(data)
  546. .then((res) => {
  547. if (this.page === 1) {
  548. this.tableList = res.list;
  549. } else {
  550. this.tableList.push(...res.list);
  551. }
  552. this.page += 1;
  553. this.isEnd = this.tableList.length >= res.count;
  554. })
  555. .then(() => {
  556. uni.hideLoading();
  557. });
  558. return;
  559. }
  560. let data = {
  561. pageNum: this.page,
  562. size: this.size,
  563. keyword: this.keyWord,
  564. planType: this.planTypeList[this.pageName],
  565. };
  566. if (this.activeTab === "mine") {
  567. data.currentLoginUserId = this.userInfo.userId;
  568. }
  569. producetaskrulerecordQueryRecordWorkOrderPage(data)
  570. .then((res) => {
  571. if (this.page === 1) {
  572. this.tableList = res.list;
  573. } else {
  574. this.tableList.push(...res.list);
  575. }
  576. this.page += 1;
  577. this.isEnd = this.tableList.length >= res.count;
  578. })
  579. .then(() => {
  580. uni.hideLoading();
  581. });
  582. },
  583. scrolltolower() {
  584. if (this.isEnd) {
  585. return;
  586. }
  587. this.getList();
  588. },
  589. async handleDispatch(item) {
  590. try {
  591. const data = await getRecordRulesPlanDetail(item.id);
  592. await recordrulesplanManualDispatchOrder(data);
  593. this.$refs.uToast.show({
  594. type: "success",
  595. icon: false,
  596. message: `派单成功`,
  597. });
  598. this.successInit();
  599. } catch (error) {
  600. this.$refs.uToast.show({
  601. type: "error",
  602. icon: false,
  603. message: `派单失败`,
  604. });
  605. }
  606. },
  607. async handleDispatchAll(item) {
  608. this.dispatchAllData = await getRecordRulesPlanDetail(item.id);
  609. this.dispatchQuantity = "";
  610. this.dispatchAllShow = true;
  611. },
  612. async submitDispatchAll() {
  613. if (!this.dispatchQuantity || Number(this.dispatchQuantity) <= 0) {
  614. this.$refs.uToast.show({
  615. type: "error",
  616. icon: false,
  617. message: `请输入派单次数`,
  618. });
  619. return;
  620. }
  621. try {
  622. const body = {
  623. ...this.dispatchAllData,
  624. dispatchQuantity: Number(this.dispatchQuantity),
  625. };
  626. await dispatchRepeatedly(body);
  627. this.$refs.uToast.show({
  628. type: "success",
  629. icon: false,
  630. message: `批量派单成功`,
  631. });
  632. this.dispatchAllShow = false;
  633. this.successInit();
  634. } catch (error) {
  635. this.$refs.uToast.show({
  636. type: "error",
  637. icon: false,
  638. message: `批量派单失败`,
  639. });
  640. }
  641. },
  642. async revoke(id) {
  643. await recordrulesplanRevoke({
  644. id,
  645. });
  646. this.successInit();
  647. },
  648. handleRevoke(item) {
  649. if (item.dispatchType == 1) {
  650. // 多次派单,打开批量撤回弹窗
  651. this.$refs.batchRevokeDialogRef.open(item.code);
  652. } else {
  653. this.revoke(item.id);
  654. }
  655. },
  656. },
  657. };
  658. </script>
  659. <style lang="scss" scoped>
  660. .mainBox {
  661. background-color: #f3f8fb;
  662. }
  663. .wrapper {
  664. padding: 20rpx 24rpx;
  665. }
  666. .top-wrapper {
  667. background-color: #fff;
  668. display: flex;
  669. flex-wrap: wrap;
  670. width: 750rpx;
  671. padding: 16rpx 32rpx;
  672. align-items: center;
  673. position: absolute;
  674. z-index: 999;
  675. .tab-bar {
  676. display: flex;
  677. width: 100%;
  678. margin-bottom: 16rpx;
  679. border-bottom: 2rpx solid #eee;
  680. }
  681. .tab-item {
  682. flex: 1;
  683. text-align: center;
  684. padding: 16rpx 0;
  685. font-size: 30rpx;
  686. color: #666;
  687. position: relative;
  688. &.active {
  689. color: $theme-color;
  690. font-weight: bold;
  691. &::after {
  692. content: "";
  693. position: absolute;
  694. bottom: 0;
  695. left: 50%;
  696. transform: translateX(-50%);
  697. width: 60rpx;
  698. height: 4rpx;
  699. background: $theme-color;
  700. border-radius: 4rpx;
  701. }
  702. }
  703. }
  704. /deep/.uni-section {
  705. margin-top: 0px;
  706. }
  707. /deep/.uni-section-header {
  708. padding: 0px;
  709. }
  710. .search_btn {
  711. width: 120rpx;
  712. height: 70rpx;
  713. line-height: 70rpx;
  714. padding: 0 24rpx;
  715. background: $theme-color;
  716. font-size: 32rpx;
  717. color: #fff;
  718. margin: 0;
  719. margin-left: 26rpx;
  720. }
  721. .menu_icon {
  722. width: 44rpx;
  723. height: 44rpx;
  724. margin-left: 14rpx;
  725. }
  726. }
  727. .popup-content {
  728. width: 100vw;
  729. height: 60vh;
  730. background: #fff;
  731. border-radius: 20rpx 20rpx 0 0;
  732. display: flex;
  733. flex-direction: column;
  734. }
  735. .popup-header {
  736. display: flex;
  737. justify-content: space-between;
  738. align-items: center;
  739. padding: 30rpx;
  740. border-bottom: 1rpx solid #e5e5e5;
  741. .popup-title {
  742. font-size: 36rpx;
  743. font-weight: bold;
  744. color: #333;
  745. }
  746. .close-btn {
  747. width: 60rpx;
  748. height: 60rpx;
  749. display: flex;
  750. align-items: center;
  751. justify-content: center;
  752. font-size: 60rpx;
  753. color: #999;
  754. line-height: 1;
  755. }
  756. }
  757. .popup-body {
  758. flex: 1;
  759. padding: 28rpx;
  760. }
  761. .form-item {
  762. margin-bottom: 24rpx;
  763. .form-label {
  764. font-size: 28rpx;
  765. color: #333;
  766. margin-bottom: 16rpx;
  767. display: block;
  768. .required {
  769. color: #ff4d4f;
  770. }
  771. }
  772. }
  773. .popup-footer {
  774. display: flex;
  775. padding: 20rpx 30rpx;
  776. border-top: 1rpx solid #e5e5e5;
  777. gap: 20rpx;
  778. /deep/ .u-button {
  779. flex: 1;
  780. }
  781. }
  782. </style>