index.vue 16 KB

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