index.vue 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. <template>
  2. <div class="ele-body">
  3. <el-card shadow="never" v-loading="loading">
  4. <order-search @search="reload" ref="searchRef"> </order-search>
  5. <!-- <el-tabs v-model="activeName" type="card">
  6. <el-tab-pane label="未完成工单" name="first"></el-tab-pane>
  7. <el-tab-pane label="已完成工单" name="second"></el-tab-pane>
  8. </el-tabs> -->
  9. <!-- 数据表格 -->
  10. <!-- <plan-statistics></plan-statistics> -->
  11. <!-- <ele-pro-table
  12. ref="table"
  13. :columns="newColumns"
  14. :datasource="datasource"
  15. cache-key="workOrderTable"
  16. row-key="code"
  17. @sort-change="onSortChange"
  18. height="calc(100vh - 380px)"
  19. autoAmendPage
  20. :parse-data="parseData"
  21. > -->
  22. <ele-pro-table
  23. ref="table"
  24. :columns="newColumns"
  25. :datasource="datasource"
  26. cache-key="workOrderTable"
  27. row-key="id"
  28. @sort-change="onSortChange"
  29. autoAmendPage
  30. :parse-data="parseData"
  31. :cache-key="cacheKeyUrl"
  32. @columns-change="handleColumnChange"
  33. >
  34. <!-- :key="activeName" -->
  35. <!-- :selection.sync="selection" -->
  36. <!-- @update:selection="handleSelectionChange" -->
  37. <template v-slot:code="{ row }">
  38. {{ row.code }}
  39. </template>
  40. <template v-slot:formingWeight="{ row }">
  41. {{ row.formingWeight }} {{ row.newWeightUnit }}
  42. </template>
  43. <template v-slot:priority="{ row }">
  44. <div style="display: flex">
  45. <el-input
  46. v-model="row.priority"
  47. type="number"
  48. size="mini"
  49. :min="0"
  50. :max="10"
  51. @change="priorityChange(row)"
  52. style="width: 80px"
  53. ></el-input>
  54. <el-popover
  55. placement="right"
  56. width="200"
  57. trigger="hover"
  58. content="数值越大优先级越高(0-3普通, 4-6优先, 7-10紧急)"
  59. >
  60. <div class="sort-wrap" slot="reference">
  61. <i class="el-icon-caret-top" @click="sortTop(row)"></i>
  62. <i class="el-icon-caret-bottom" @click="sortBottom(row)"></i>
  63. </div>
  64. </el-popover>
  65. </div>
  66. </template>
  67. <template v-slot:status="{ row }">
  68. <span :class="{ 'ele-text-danger': row.status == 3 }">
  69. {{ statusFormatter(row.status) }}
  70. </span>
  71. </template>
  72. <!-- 操作列 -->
  73. <template v-slot:action="{ row }">
  74. <el-link
  75. type="primary"
  76. :underline="false"
  77. @click="toUnpack(row)"
  78. v-if="
  79. (clientEnvironmentId != '4' && row.status == 8) ||
  80. (clientEnvironmentId == '4' &&
  81. !row.productName.includes('板材') &&
  82. row.status == 8)
  83. "
  84. >
  85. 拆单
  86. </el-link>
  87. <!-- <el-link
  88. type="primary"
  89. :underline="false"
  90. icon="el-icon-truck"
  91. @click="toRelease(row)"
  92. v-if="
  93. (row.isSplit != 1 &&
  94. clientEnvironmentId != '4' &&
  95. row.status == 8) ||
  96. (clientEnvironmentId == '4' &&
  97. !row.productName.includes('板材') &&
  98. row.status == 8)
  99. "
  100. >
  101. 派单
  102. </el-link> -->
  103. <!-- <el-link
  104. type="primary"
  105. :underline="false"
  106. icon="el-icon-truck"
  107. @click="toRelease(row)"
  108. v-if="
  109. (row.isSplit != 1 &&
  110. clientEnvironmentId != '4' &&
  111. row.status == 8) ||
  112. (clientEnvironmentId == '4' &&
  113. !row.productName.includes('板材') &&
  114. row.status == 8)
  115. "
  116. >
  117. 派单12
  118. </el-link> -->
  119. <el-link
  120. type="primary"
  121. :underline="false"
  122. icon="el-icon-truck"
  123. @click="toReleaseOpen(row)"
  124. v-if="dispatchPermission(row)"
  125. >
  126. 派单
  127. </el-link>
  128. </template>
  129. </ele-pro-table>
  130. </el-card>
  131. <el-dialog :visible.sync="visible" title="派单" width="500px">
  132. <el-form
  133. ref="form"
  134. :model="form"
  135. :rules="rules"
  136. label-position="left"
  137. label-width="100px"
  138. >
  139. <el-form-item label="报工类型:" prop="singleReport">
  140. <el-radio-group v-model="form.singleReport">
  141. <el-radio :label="1" v-if="clientEnvironmentId != 2"
  142. >单件报工</el-radio
  143. >
  144. <el-radio :label="0">批量报工</el-radio>
  145. </el-radio-group>
  146. </el-form-item>
  147. <el-form-item label="指定:" prop="assignType">
  148. <el-radio-group
  149. v-model="form.assignType"
  150. size="mini"
  151. @change="assignTypeFn"
  152. >
  153. <el-radio-button :label="1">工位</el-radio-button>
  154. <el-radio-button :label="2">人员</el-radio-button>
  155. </el-radio-group>
  156. </el-form-item>
  157. <el-form-item label="班组:" prop="teamId">
  158. <el-select
  159. class="ele-block"
  160. v-model="form.teamId"
  161. placeholder="请选择班组"
  162. size="mini"
  163. filterable
  164. @change="stationChange"
  165. >
  166. <el-option
  167. v-for="item in teamsList"
  168. :key="item.id"
  169. :label="item.name + '(' + item.code + ')'"
  170. :value="item.id"
  171. >
  172. </el-option>
  173. </el-select>
  174. </el-form-item>
  175. <el-form-item
  176. label="工位:"
  177. prop="workstationIds"
  178. v-if="form.assignType == 1"
  179. >
  180. <el-select
  181. class="ele-block"
  182. v-model="form.workstationIds"
  183. placeholder="请选择工位"
  184. size="mini"
  185. multiple
  186. filterable
  187. >
  188. <el-option
  189. v-for="item in stationList"
  190. :key="item.id"
  191. :label="item.name + '(' + item.code + ')'"
  192. :value="item.id"
  193. >
  194. </el-option>
  195. </el-select>
  196. </el-form-item>
  197. <el-form-item label="人员:" prop="crewIds" v-if="form.assignType == 2">
  198. <el-select
  199. class="ele-block"
  200. v-model="form.crewIds"
  201. placeholder="请选择人员"
  202. size="mini"
  203. filterable
  204. multiple
  205. >
  206. <el-option
  207. v-for="item in crewList"
  208. :key="item.id"
  209. :label="item.name"
  210. :value="item.id"
  211. >
  212. </el-option>
  213. </el-select>
  214. </el-form-item>
  215. </el-form>
  216. <div class="footer" slot="footer">
  217. <el-button @click="close">取消</el-button>
  218. <el-button type="primary" v-click-once @click="confirm">确定</el-button>
  219. </div>
  220. </el-dialog>
  221. <unpackDialog ref="unpackRef" @success="createSuccess" />
  222. <releaseDialog
  223. ref="releaseRef"
  224. :current="dispatchRow"
  225. :dispatchVisible.sync="dispatchVisible"
  226. @createSuccess="createSuccess"
  227. v-if="dispatchVisible"
  228. />
  229. </div>
  230. </template>
  231. <script>
  232. import {
  233. getList,
  234. releaseWorkOrder,
  235. updatePriority
  236. } from '@/api/workOrder/index.js';
  237. import {
  238. teamPage,
  239. listByFirstTaskId,
  240. listByWorkCenterId,
  241. listUserByIds,
  242. getTaskIdByInstanceId
  243. } from '@/api/mainData/index.js';
  244. import OrderSearch from './components/order-search.vue';
  245. import unpackDialog from './components/unpackDialog.vue';
  246. import releaseDialog from './components/releaseDialog.vue';
  247. import { fieldModel } from '@/api/saleOrder';
  248. import { debounce } from 'lodash';
  249. import PlanStatistics from '@/components/statistics/PlanStatistics.vue';
  250. import tabMixins from '@/mixins/tableColumnsMixin';
  251. export default {
  252. mixins: [tabMixins],
  253. components: {
  254. PlanStatistics,
  255. OrderSearch,
  256. unpackDialog,
  257. releaseDialog
  258. },
  259. data() {
  260. return {
  261. visible: false,
  262. loading: false,
  263. form: {
  264. assignType: 1,
  265. crewIds: '',
  266. workstationIds: '',
  267. teamId: '',
  268. singleReport: ''
  269. },
  270. rules: {
  271. singleReport: [
  272. {
  273. required: true,
  274. message: '请选择报工类型',
  275. trigger: ['blur', 'change']
  276. }
  277. ],
  278. workstationIds: [
  279. {
  280. required: true,
  281. message: '请选择工位',
  282. trigger: ['blur']
  283. }
  284. ],
  285. teamId: [
  286. {
  287. required: true,
  288. message: '请选择班组',
  289. trigger: ['blur']
  290. }
  291. ]
  292. },
  293. teamList: [],
  294. statusOpt: [
  295. { label: '待生产', value: 4 },
  296. { label: '生产中', value: 5 },
  297. { label: '待下达', value: 8 }
  298. ],
  299. newColumns: [],
  300. stationList: [],
  301. teamsList: [],
  302. crewList: [],
  303. current: null,
  304. cacheKeyUrl: '3cbbdff9-aps-workOrder',
  305. columnsVersion: 1,
  306. dispatchRow: {},
  307. dispatchVisible: false
  308. };
  309. },
  310. computed: {
  311. dispatchPermission() {
  312. return (row) => {
  313. if (!row.firstTaskId) {
  314. return false;
  315. }
  316. return (
  317. (row.isSplit != 1 &&
  318. this.clientEnvironmentId != '4' &&
  319. row.status == 8) ||
  320. (this.clientEnvironmentId == '4' &&
  321. !row.productName.includes('板材') &&
  322. row.status == 8)
  323. );
  324. };
  325. },
  326. teamId() {
  327. return this.$store.state.user.info.teamId;
  328. },
  329. clientEnvironmentId() {
  330. return this.$store.state.user.info.clientEnvironmentId;
  331. },
  332. // 表格列配置
  333. columns() {
  334. const num = this.columnsVersion;
  335. return [
  336. {
  337. columnKey: 'index',
  338. slot: 'index',
  339. label: '序号',
  340. type: 'index',
  341. width: 55,
  342. align: 'center',
  343. showOverflowTooltip: true,
  344. fixed: 'left'
  345. },
  346. {
  347. slot: 'code',
  348. label: '生产订单号',
  349. align: 'center',
  350. minWidth: 210,
  351. sortable: true
  352. },
  353. {
  354. prop: 'productionPlanCode',
  355. label: '计划编号',
  356. align: 'center',
  357. minWidth: 150
  358. },
  359. {
  360. prop: 'produceRoutingName',
  361. label: '工艺路线',
  362. align: 'center',
  363. minWidth: 170
  364. },
  365. {
  366. prop: 'productCode',
  367. label: '编码',
  368. align: 'center',
  369. minWidth: 110
  370. },
  371. {
  372. prop: 'productName',
  373. label: '名称',
  374. align: 'center',
  375. minWidth: 170
  376. },
  377. {
  378. prop: 'productionCodes',
  379. label: '生产编号',
  380. align: 'center',
  381. minWidth: 150,
  382. showOverflowTooltip: true
  383. },
  384. {
  385. prop: 'brandNo',
  386. label: '牌号',
  387. align: 'center'
  388. },
  389. {
  390. prop: 'batchNo',
  391. label: '批次号',
  392. align: 'center',
  393. minWidth: 100,
  394. showOverflowTooltip: true
  395. },
  396. {
  397. prop: 'model',
  398. label: '型号',
  399. align: 'center',
  400. showOverflowTooltip: true
  401. },
  402. {
  403. prop: 'priority',
  404. label: '优先级',
  405. align: 'center',
  406. minWidth: 120,
  407. slot: 'priority',
  408. sortable: 'custom'
  409. },
  410. {
  411. prop: 'formingNum',
  412. label: '要求生产数量',
  413. align: 'center',
  414. showOverflowTooltip: true,
  415. minWidth: 110
  416. },
  417. {
  418. prop: 'formingWeight',
  419. label: '要求生产重量',
  420. align: 'center',
  421. showOverflowTooltip: true,
  422. minWidth: 110,
  423. slot: 'formingWeight'
  424. },
  425. {
  426. prop: 'planStartTime',
  427. label: '计划开始时间',
  428. align: 'center',
  429. showOverflowTooltip: true,
  430. minWidth: 110
  431. },
  432. {
  433. prop: 'planCompleteTime',
  434. label: '计划结束时间',
  435. align: 'center',
  436. showOverflowTooltip: true,
  437. minWidth: 110
  438. },
  439. {
  440. prop: 'workCenterName',
  441. label: '工作中心',
  442. align: 'center',
  443. minWidth: 110,
  444. showOverflowTooltip: true
  445. },
  446. {
  447. prop: 'firstTaskName',
  448. label: '首工序',
  449. align: 'center',
  450. minWidth: 110,
  451. showOverflowTooltip: true
  452. },
  453. {
  454. prop: 'createTime',
  455. label: '创建时间',
  456. align: 'center',
  457. showOverflowTooltip: true,
  458. minWidth: 110,
  459. sortable: 'custom'
  460. },
  461. {
  462. slot: 'status',
  463. label: '状态',
  464. align: 'center',
  465. formatter: (row) => {
  466. const obj = this.statusOpt.find((i) => i.value == row.status);
  467. return obj && obj.label;
  468. }
  469. },
  470. {
  471. prop: 'customerName',
  472. label: '客户名称',
  473. align: 'center',
  474. showOverflowTooltip: true
  475. },
  476. {
  477. prop: 'serialNo',
  478. label: '客户代号',
  479. align: 'center',
  480. showOverflowTooltip: true
  481. },
  482. {
  483. prop: 'simpleName',
  484. label: '客户简称',
  485. align: 'center',
  486. showOverflowTooltip: true
  487. }
  488. ];
  489. }
  490. },
  491. created() {
  492. this.getFieldModel();
  493. },
  494. methods: {
  495. assignTypeFn(e) {},
  496. statusFormatter(status) {
  497. const obj = this.statusOpt.find((i) => i.value == status);
  498. return obj && obj.label;
  499. },
  500. /* 表格数据源 */
  501. datasource({ page, limit, where }) {
  502. if (where.status) {
  503. where.statusList = [];
  504. where.statusList.push(where.status);
  505. }
  506. return getList({
  507. pageNum: page,
  508. size: limit,
  509. ...where,
  510. ...this.sort
  511. });
  512. },
  513. /* 数据转为树形结构 */
  514. parseData(data) {
  515. return {
  516. ...data,
  517. list: this.$util.toTreeData({
  518. data: data.list,
  519. count: data.total,
  520. idField: 'code',
  521. parentIdField: 'originalCode'
  522. })
  523. };
  524. },
  525. getFieldModel() {
  526. fieldModel({ fieldModel: 't_main_category' }).then((res) => {
  527. const privateColumn = [
  528. {
  529. columnKey: 'action',
  530. label: '操作',
  531. width: 120,
  532. align: 'center',
  533. resizable: false,
  534. fixed: 'right',
  535. slot: 'action'
  536. }
  537. ];
  538. let newRes = res.map((m) => {
  539. return {
  540. prop: 'extField.' + m.prop,
  541. label: m.label,
  542. align: 'center',
  543. showOverflowTooltip: true
  544. };
  545. });
  546. this.newColumns = [...this.columns, ...newRes, ...privateColumn];
  547. this.$forceUpdate();
  548. });
  549. },
  550. // 下达
  551. toRelease(row) {
  552. this.current = row;
  553. this.visible = true;
  554. this.FirstTaskIdFn();
  555. this.WorkCenterIdFn();
  556. this.form.singleReport = this.clientEnvironmentId == 2 ? 0 : 1;
  557. },
  558. // 下达
  559. confirm() {
  560. this.$refs.form.validate((valid) => {
  561. if (valid) {
  562. const loading = this.$loading({ text: '加载中...' });
  563. if (this.form.assignType * 1 == 2) {
  564. this.form.workstationIds = [];
  565. } else {
  566. this.form.crewIds = [];
  567. }
  568. releaseWorkOrder({
  569. id: this.current.id,
  570. ...this.form
  571. })
  572. .then((res) => {
  573. if (res) {
  574. this.$message.success('成功');
  575. this.reData();
  576. this.reload();
  577. this.visible = false;
  578. }
  579. })
  580. .finally(() => {
  581. loading.close();
  582. });
  583. }
  584. });
  585. },
  586. close() {
  587. this.visible = false;
  588. this.reData();
  589. },
  590. reData() {
  591. this.form = {
  592. assignType: 1,
  593. crewIds: '',
  594. workstationIds: '',
  595. teamId: '',
  596. singleReport: this.clientEnvironmentId == 2 ? 0 : 1
  597. };
  598. },
  599. /* 刷新表格 */
  600. reload(where) {
  601. this.$nextTick(() => {
  602. this.$refs.table.reload({ page: 1, where });
  603. });
  604. },
  605. onSortChange(e) {
  606. let sort = {
  607. orderBy: e.order,
  608. sortName: e.prop
  609. };
  610. this.sort = sort;
  611. this.reload();
  612. },
  613. sortTop(row) {
  614. row.priority = Number(row.priority) + 1;
  615. this.priorityChange(row);
  616. },
  617. sortBottom(row) {
  618. if (row.priority <= 1) {
  619. return;
  620. }
  621. row.priority = Number(row.priority) - 1;
  622. this.priorityChange(row);
  623. },
  624. FirstTaskIdFn() {
  625. listByFirstTaskId(this.current.firstTaskId).then((res) => {
  626. this.stationList = res;
  627. });
  628. },
  629. WorkCenterIdFn() {
  630. listByWorkCenterId(this.current.workCenterId).then((res) => {
  631. this.teamsList = res;
  632. this.$nextTick(() => {
  633. if (this.teamId) {
  634. this.$set(this.form, 'teamId', this.teamId);
  635. this.stationChange();
  636. }
  637. // this.$refs.form.clearValidate();
  638. });
  639. });
  640. },
  641. // 拆分
  642. toUnpack(row) {
  643. this.$refs.unpackRef.open(row);
  644. },
  645. //派单
  646. toReleaseOpen(row) {
  647. this.dispatchRow = { ...row };
  648. console.log(row,'row ----')
  649. this.dispatchRow.initialWeight = row.formingWeight
  650. ? row.formingWeight + row.newWeightUnit
  651. : '';
  652. this.dispatchVisible = true;
  653. // getTaskIdByInstanceId(row.firstTaskId)
  654. // .then((res) => {
  655. // if (res) {
  656. // }
  657. // })
  658. // .catch((err) => {
  659. // this.$message.error(err.message);
  660. // });
  661. },
  662. createSuccess() {
  663. this.reload();
  664. },
  665. stationChange() {
  666. this.crewList = [];
  667. this.crewIds = [];
  668. listUserByIds([this.form.teamId]).then((res) => {
  669. this.crewList = res;
  670. });
  671. },
  672. priorityChange(row) {
  673. if (row.priority > 10) {
  674. row.priority = 10; // 如果大于 10,则设置为 10
  675. } else if (row.priority < 0) {
  676. row.priority = 0; // 如果小于 0,则设置为 0
  677. }
  678. this.priorityFn(row);
  679. },
  680. priorityFn: debounce(function (row) {
  681. let params = {
  682. id: row.id,
  683. priority: row.priority
  684. };
  685. updatePriority(params).then((res) => {});
  686. }, 800)
  687. }
  688. };
  689. </script>
  690. <style lang="scss" scoped>
  691. // ::v-deep .el-table__row {
  692. // height: 51px !important;
  693. // }
  694. </style>