index.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699
  1. <template>
  2. <div class="index_box">
  3. <div class="content_box">
  4. <!-- @tab-click="handleClick" -->
  5. <!-- 工序名称 -->
  6. <!-- <Search></Search> -->
  7. <div class="content_box_tab">
  8. <el-input style="width: 180px" clearable v-model="name" placeholder="请输入筛选项" @input="seekInput" />
  9. <el-tabs v-model="activeName" type="card" stretch @tab-click="tabClickValue">
  10. <el-tab-pane label="工序" name="0">
  11. <el-tree :data="produceTaskList" :props="defaultProps" node-key="id" :highlight-current="true"
  12. @node-click="handleNodeClick">
  13. </el-tree>
  14. <!--
  15. v-loading="treeLoading"
  16. :node-key="nodeKey"
  17. ref="tree"
  18. :highlight-current="true"
  19. :expand-on-click-node="false"
  20. @node-click="handleNodeClick"
  21. v-bind="$attrs"
  22. :default-expand-all="defaultExpandAll" -->
  23. </el-tab-pane>
  24. <el-tab-pane label="工位" name="second">
  25. <!-- <AssetTree @handleNodeClick="handleNodeClickNew" @setRootId="setRootId" id="0" :paramsType="'type'"
  26. ref="treeList" eqDevice="sb" /> -->
  27. <el-tree :data="factoryworkstationList" :props="defaultPropsTow" node-key="id" :highlight-current="true"
  28. @node-click="handleNodeClick">
  29. </el-tree>
  30. </el-tab-pane>
  31. </el-tabs>
  32. </div>
  33. <div style="width: calc(100% - 220px);">
  34. <div class="seek-list" style="background-color: #157A2C;">
  35. <div>
  36. <el-input style="width: 180px;margin-right: 5px;" clearable v-model="keyWord" placeholder="请输入关键字" />
  37. <!-- <el-input style="width: 180px" clearable v-model="taskName" placeholder="请输入工序进度" /> -->
  38. <!-- -->
  39. <el-button size="mini" type="primary" style="margin: 0 5px" @click="handleSearch">查询</el-button>
  40. </div>
  41. <div style="width: 55%;color: #fff; display: flex;justify-content: space-between;">
  42. <div>
  43. <b style="margin-right:50px;">当前工序:{{ title }}</b>
  44. <b>下道工序:{{ title1 }}</b>
  45. </div>
  46. <div>
  47. 操作员:{{ info.name }}
  48. </div>
  49. </div>
  50. </div>
  51. <ele-split-layout space="0px" width="45%" :resizable="true" :min-size="200" :max-size="-200" :left-style="{
  52. overflow: 'hidden',
  53. width: '100%'
  54. }" :right-style="{ overflow: 'hidden' }" :responsive="false" style="height: calc(100vh - 70px - 50px - 90px)">
  55. <!-- 左侧 工单列表 -->
  56. <div class="left_main">
  57. <div class="top">
  58. <!-- /工单列表 -->
  59. <produceOrder @workSelect="workSelect" @rowClick="rowClick" ref="produceOrder" @getTaskName="getTaskName">
  60. </produceOrder>
  61. </div>
  62. <!-- <div class="bottom">
  63. <productionResource :BomObj="BomObj"></productionResource>
  64. </div> -->
  65. </div>
  66. <!-- 右侧 详情 -->
  67. <template v-slot:content>
  68. <div class="right_main">
  69. <!-- 领料 -->
  70. <div v-if="operationType == 'pick'">
  71. <pickDetails ref="pickListRef" @pickAdd="pickAdd"></pickDetails>
  72. </div>
  73. <div v-if="operationType == 'feed'">
  74. <!-- 投料 -->
  75. <feeding :workListIds="workListIds" :feedNeedEquipment="feedNeedEquipment"></feeding>
  76. </div>
  77. <div v-if="operationType == 'job'">
  78. <!-- // 报工列表 入库 -->
  79. <warehousing v-if="taskObj.id == -1" :workListIds="workListIds" ref="wareRef"></warehousing>
  80. <!-- // 设备 入库 -->
  81. <!-- 普通报工 -->
  82. <jobBooking v-else :workListIds="workListIds" ref="jobRef" :reportNeedFeed="reportNeedFeed"></jobBooking>
  83. </div>
  84. <!-- 质检工序 -->
  85. <div v-if="operationType == 'inspection'">
  86. <inspection :workListIds="workListIds" ref="inspectionRef"></inspection>
  87. </div>
  88. <!-- 委外 -->
  89. <div v-if="operationType == 'Outsourcing' && isType == '3'" class="right_main_box">
  90. <outsourcing :outsourceFormVal="outsourceForm" @changePlugIn="changePlugIn" v-if="isStep"></outsourcing>
  91. <!-- -->
  92. <outsourceList :outsourceFormVal="outObj" @closeForm="closeForm" @outScucc="outScucc" v-else></outsourceList>
  93. </div>
  94. </div>
  95. </template>
  96. </ele-split-layout>
  97. <footBtn @footBtn="footBtn" :type="type" :singleReportInspection="singleReportInspection" style="background: rgba(223, 250, 222,0.6);padding: 10px;"></footBtn>
  98. </div>
  99. <!-- <footBtn @footBtn="footBtn"></footBtn> -->
  100. </div>
  101. <!--领料弹框 -->
  102. <picking v-if="pickingShow" @close="pickingClose" :workListIds="workListIds"></picking>
  103. <!-- 工艺文件 -->
  104. <wokePopup ref="wokePopupRef"></wokePopup>
  105. <!-- :workListIds="workListIds" :taskId="taskObj.id" -->
  106. </div>
  107. </template>
  108. <script>
  109. import Search from './components/search.vue';
  110. import footBtn from './components/footBtn.vue';
  111. import produceOrder from './components/produceOrder.vue';
  112. import productionResource from './components/productionResource/index.vue';
  113. import outsourcing from './components/outsourcing/index.vue';
  114. import picking from './components/picking/index.vue';
  115. import wokePopup from './components/picking/wokePopup.vue';
  116. import inspection from './components/inspection/index.vue';
  117. import pickDetails from './components/picking/details.vue';
  118. import AssetTree from '@/components/AssetTree/joobIndex.vue';
  119. import feeding from './components/feeding/index.vue';
  120. import jobBooking from './components/jobBooking/index.vue';
  121. import warehousing from './components/warehousing/index.vue';
  122. import outsourceList from './components/outsourcing/outsourceList.vue';
  123. import { getByTaskId, pcCheckOutsource, getTaskInstanceById, checkOutsourceMaterial, listTask, factoryworkstationPage, nextTask } from '@/api/produce/index';
  124. export default {
  125. components: {
  126. Search,
  127. footBtn,
  128. wokePopup,
  129. produceOrder,
  130. productionResource,
  131. outsourcing,
  132. picking,
  133. pickDetails,
  134. outsourceList,
  135. feeding,
  136. AssetTree,
  137. jobBooking,
  138. inspection,
  139. warehousing
  140. },
  141. data() {
  142. return {
  143. name: '',
  144. activeName: '0',
  145. taskName: '',
  146. keyWord: '',//搜索
  147. title: '',
  148. type: '',
  149. loading: false,
  150. operationType: null,
  151. workListIds: [],
  152. factoryworkstationList: [],
  153. title1: '',
  154. arr: [],
  155. arrTow:[],
  156. produceTaskList: [],
  157. isType: '',
  158. isStep: true,
  159. outsourceForm: {},
  160. outObj: {},
  161. pickingShow: false,
  162. wokePopup: false,
  163. BomObj: {},
  164. defaultProps: {
  165. children: 'children',
  166. label: 'newName'
  167. },
  168. defaultPropsTow: {
  169. children: 'children',
  170. label: 'name',
  171. value: 'code'
  172. },
  173. feedNeedEquipment:0,//投料是否要添加生产设备1是0否
  174. reportNeedFeed:0,//生产质检是否需要处置再报工1是0否
  175. singleReportInspection:null,//获取选中的工单是单个还是批量
  176. };
  177. },
  178. computed: {
  179. taskObj() {
  180. return this.$store.state.user.taskObj;
  181. },
  182. info() {
  183. return this.$store.state.user.info;
  184. }
  185. },
  186. created() {
  187. this.init()
  188. this.getTaskList();
  189. this.getFactoryworkstationPageList();
  190. this.operationType = null;
  191. this.workListIds = [];
  192. },
  193. methods: {
  194. tabClickValue(){
  195. this.name ='';
  196. this.seekInput()
  197. },
  198. // 前端筛选
  199. seekInput() {
  200. // console.log(activeName);
  201. if (this.activeName == '0') {
  202. if (!this.name) return (this.produceTaskList = this.arr);
  203. this.produceTaskList = this.produceTaskList.filter(item => {
  204. return item.name.indexOf(this.name) > -1
  205. })
  206. } else {
  207. if (!this.name) return (this.factoryworkstationList = this.arrTow);
  208. this.factoryworkstationList = this.factoryworkstationList.filter(item => {
  209. return item.name.indexOf(this.name) > -1
  210. })
  211. }
  212. },
  213. // 折叠悬浮中样式调整
  214. init() {
  215. this.$store.dispatch('theme/setCollapse', true);
  216. },
  217. async getTaskName(value) {
  218. if (value.length > 0) {
  219. let res = await nextTask({
  220. taskId: this.taskObj.id,
  221. workOrderIds: value.map(item => item.id)
  222. })
  223. this.title1 = res.data.map(item => item.taskTypeName).toString()
  224. } else {
  225. this.title1 = ''
  226. }
  227. },
  228. handleSearch() {
  229. let obj = {
  230. keyWord: this.keyWord,
  231. taskName: this.taskName
  232. }
  233. this.$refs.produceOrder.handleSearch(obj);
  234. //handleSearch(this.code);
  235. },
  236. handleNodeClickNew(info) {
  237. console.log(info, '999');
  238. // this.current = info;
  239. let current = { id: info.id };
  240. this.$store.commit('user/currentObj', current);
  241. },
  242. setRootId(id) {
  243. this.rootId = id;
  244. },
  245. // 点击工序
  246. handleNodeClick(data) {
  247. console.log(data,'11111sassasgasg');
  248. this.feedNeedEquipment=data.feedNeedEquipment
  249. this.reportNeedFeed=data.reportNeedFeed
  250. let obj = {
  251. '1': `${data.workCenterName}-${data.name}(普通工序)`,
  252. '3': `${data.workCenterName}-${data.name}(质检工序)`,
  253. '4': `${data.workCenterName}-${data.name}(包装工序)`,
  254. '5': `${data.workCenterName}-${data.name}(入库工序)`,
  255. '6': `${data.workCenterName}-${data.name}(质检工序)`
  256. }
  257. this.title = obj[data.type] || '';
  258. this.type = data.type;
  259. let taskObj = {};
  260. taskObj = this.produceTaskList.find((item) => item.id === data.id);
  261. this.$store.commit('user/setTaskObj', taskObj);
  262. },
  263. // 获取工序列表
  264. getTaskList() {
  265. listTask().then((res) => {
  266. res.map(v => {
  267. v.newName = `${v.workCenterName}-${v.name}`
  268. })
  269. this.produceTaskList = res;
  270. this.arr = JSON.parse(JSON.stringify(this.produceTaskList));
  271. // newName
  272. });
  273. },
  274. // 获取工位
  275. getFactoryworkstationPageList() {
  276. factoryworkstationPage({ pageNum: 1, size: 99999999 }).then((res) => {
  277. console.log(res, 'res');
  278. this.factoryworkstationList = res.list;
  279. this.arrTow = JSON.parse(JSON.stringify(this.factoryworkstationList));
  280. // newName
  281. });
  282. },
  283. closeForm() {
  284. this.isStep = true;
  285. },
  286. outScucc(){
  287. this.operationType=null
  288. },
  289. // 切换组件
  290. async changePlugIn(e) {
  291. this.outObj = e;
  292. let req = {
  293. taskId: e.taskId,
  294. taskIds: e.taskIds,
  295. workOrderId: e.workOrderId,
  296. quantity:e.formedNumLast
  297. }
  298. const res = await checkOutsourceMaterial(req);
  299. this.outObj = { ...res.data, ...this.outsourceForm ,...this.outObj};
  300. this.isStep = false;
  301. },
  302. workSelect(data) {
  303. this.singleReportInspection=data.list.length>0?data.list[0].singleReport:null;//获取选中的工单是单个还是批量
  304. this.isStep = true;
  305. this.operationType = null;
  306. this.workListIds = data.ids;
  307. },
  308. pickingWokeClose() {
  309. this.wokePopup = false;
  310. },
  311. footBtn(t) {
  312. this.operationType = t;
  313. if (
  314. Object.keys(this.$store.state.user.taskObj).length === 0 &&
  315. this.$store.state.user.taskObj.constructor === Object
  316. ) {
  317. this.$message.warning('请选择工序');
  318. return false;
  319. }
  320. if (['pick', 'feed', 'job'].includes(t)) {
  321. if (this.workListIds.length == 0) {
  322. this.$message.warning('请选择工单列表');
  323. return false;
  324. }
  325. }
  326. if (t == 'pick') {
  327. this.$nextTick(() => {
  328. this.$refs.pickListRef.getList(this.workListIds);
  329. });
  330. }
  331. // 工艺路线
  332. if (t === 'work') {
  333. let req = {
  334. taskId: this.taskObj.id,
  335. workOrderId: this.workListIds[0]
  336. }
  337. this.$refs.wokePopupRef.open(req);
  338. }
  339. if (t == 'feed') {
  340. }
  341. // 委外
  342. if (t == 'Outsourcing') {
  343. if (this.workListIds.length > 1) {
  344. return this.$message.warning('委外工序只能选择一个工单!');
  345. } else if (this.workListIds.length < 1)
  346. return this.$message.warning('请选择工单!');
  347. else {
  348. // /
  349. this.handOutsource(this.workListIds[0]);
  350. }
  351. }
  352. },
  353. handOutsource(workOrderId) {
  354. console.log(this.taskObj, workOrderId);
  355. // return
  356. let param = {
  357. taskId: this.taskObj.id,
  358. workOrderId: workOrderId,
  359. }
  360. pcCheckOutsource(param).then(res => {
  361. this.outsourceForm = {
  362. ...res.data,
  363. }
  364. this.outsourceForm.name = this.taskObj.name + '委外'
  365. console.log(res, 'res');
  366. if (res.data.outsource) {
  367. this.isType = '3';
  368. this.getTaskInstanceByIdFn(workOrderId)
  369. } else {
  370. return this.$message.warning('此工序不能委外');
  371. }
  372. })
  373. },
  374. //获取工单列表
  375. getTaskInstanceByIdFn(workOrderId) {
  376. getTaskInstanceById(workOrderId).then((res) => {
  377. console.log(res, 'res');
  378. let { data } = res;
  379. if (data.length) {
  380. data = data.filter(item => item.type == 1);
  381. let arr = data.findIndex(item => item.sourceTaskId == this.taskObj.id)
  382. console.log(arr);
  383. if (arr != -1) {
  384. data.splice(0, arr + 1)
  385. }
  386. this.$set(this.outsourceForm, 'newStepsList', data)
  387. }
  388. })
  389. },
  390. pickAdd() {
  391. this.pickingShow = true;
  392. },
  393. // 关闭领料弹窗
  394. pickingClose(val) {
  395. if (val) {
  396. this.$nextTick(() => {
  397. this.$refs.pickListRef.getList(this.workListIds);
  398. });
  399. }
  400. this.pickingShow = false;
  401. },
  402. rowClick(row, taskId) {
  403. if (taskId) {
  404. let params = {
  405. categoryId: row.categoryId,
  406. taskId: taskId
  407. };
  408. getByTaskId(params).then((res) => {
  409. this.BomObj = res.data;
  410. this.$forceUpdate();
  411. });
  412. }
  413. }
  414. },
  415. mounted() {
  416. this.$nextTick(() => {
  417. const targetElements =
  418. document.getElementsByClassName('ele-admin-tabs');
  419. if (targetElements.length > 0) {
  420. // 遍历所有具有 'ele-admin-tabs' 类的元素
  421. Array.from(targetElements).forEach((element) => {
  422. // 对每个元素添加 'new-ele-admin-tabs' 类
  423. element.classList.add('new-ele-admin-tabs');
  424. });
  425. }
  426. });
  427. },
  428. destroyed() {
  429. this.$nextTick(() => {
  430. const targetElements =
  431. document.getElementsByClassName('ele-admin-tabs');
  432. if (targetElements.length > 0) {
  433. Array.from(targetElements).forEach((element) => {
  434. element.classList.remove('new-ele-admin-tabs');
  435. });
  436. }
  437. });
  438. }
  439. };
  440. </script>
  441. <style>
  442. .content_box {
  443. display: flex;
  444. }
  445. .content_box_tab {
  446. width: 220px;
  447. padding: 5px;
  448. height: calc(100vh - 73px);
  449. background-color: #fff;
  450. overflow-y: auto;
  451. }
  452. .footBtn {
  453. position: absolute;
  454. bottom: 20px;
  455. left: 0;
  456. }
  457. .new-ele-admin-tabs {
  458. display: none !important;
  459. }
  460. .c_title {
  461. color: #157a2c;
  462. font-size: 16px;
  463. font-weight: bold;
  464. }
  465. .tableZ_box {
  466. border: 1px solid #e3e5e5;
  467. margin: 6px 0;
  468. &:last-child {
  469. border-bottom: none;
  470. }
  471. .row {
  472. width: 100%;
  473. display: flex;
  474. }
  475. .col {
  476. width: calc(100% / 5);
  477. display: flex;
  478. align-items: center;
  479. min-width: 200px;
  480. min-height: 32px;
  481. border-bottom: 1px solid #e3e5e5;
  482. border-right: 1px solid #e3e5e5;
  483. &:last-child {
  484. border-right: none;
  485. }
  486. .name {
  487. display: flex;
  488. align-items: center;
  489. padding: 4px;
  490. width: 80px;
  491. height: 100%;
  492. background-color: #d0e4d5;
  493. color: #000;
  494. }
  495. .content {
  496. padding: 4px 6px;
  497. color: #000;
  498. }
  499. }
  500. .pd6 {
  501. padding: 0 6px;
  502. }
  503. }
  504. </style>
  505. <style lang="scss" scoped>
  506. .seek-list {
  507. display: flex;
  508. justify-content: space-between;
  509. align-items: center;
  510. padding: 10px 10px;
  511. }
  512. .right_main_box {
  513. background-color: #fff;
  514. height: 100%;
  515. box-sizing: border-box;
  516. }
  517. .index_box {
  518. padding: 10px;
  519. padding-bottom: 0;
  520. width: 100%;
  521. box-sizing: border-box;
  522. min-width: 1280px !important;
  523. height: calc(100vh - 60px);
  524. // overflow-x: auto;
  525. /* 当内容超出宽度时,允许水平滚动 */
  526. white-space: nowrap;
  527. /* 防止内部文本换行,确保所有内容都在一行显示 */
  528. scrollbar-width: thin;
  529. /* 设置滚动条宽度(浏览器兼容性可能有所不同) */
  530. scrollbar-color: #40a9ff transparent;
  531. /* 设置滚动条颜色和轨道颜色(同样,浏览器兼容性) */
  532. }
  533. .main {
  534. width: 100%;
  535. min-width: 1280px;
  536. height: calc(100vh - 70px - 50px - 80px);
  537. display: flex;
  538. justify-content: space-between;
  539. }
  540. .left_main {
  541. width: 100%;
  542. height: 100%;
  543. display: flex;
  544. flex-direction: column;
  545. justify-content: space-around;
  546. min-width: 640px;
  547. .top {
  548. width: 100%;
  549. height: 100%;
  550. overflow: hidden;
  551. }
  552. // .bottom {
  553. // width: 100%;
  554. // min-height: calc((100vh - 70px - 50px - 80px - 20px) / 2);
  555. // overflow: hidden;
  556. // }
  557. }
  558. ::v-deep .el-tabs__item.is-active {
  559. background-color: #DFFADE;
  560. /* 蓝色背景 */
  561. color: #333;
  562. }
  563. ::v-deep .is-active {
  564. color: #DFFADE;
  565. }
  566. .right_main {
  567. min-width: 640px;
  568. padding-bottom: 12px;
  569. height: calc((100vh - 70px - 50px - 80px - 12px));
  570. background: #f0f3f3;
  571. }
  572. </style>