index.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. `
  2. <template>
  3. <div style="position: relative">
  4. <div class="headerInfo">
  5. <!-- <div
  6. class="titleText"
  7. style="
  8. width: 300px;
  9. white-space: nowrap;
  10. overflow: hidden;
  11. text-overflow: ellipsis;
  12. "
  13. >
  14. {{ store.processInfo.materialName }} -
  15. {{ store.processInfo.materialModel }}
  16. </div>
  17. <div class="info">
  18. <div class="item">
  19. 当前工序:
  20. {{
  21. store.scanInfo.operationName ? store.scanInfo.operationName : "-"
  22. }}
  23. </div>
  24. <div class="item">
  25. 下一工位:{{
  26. store.scanInfo.nextStation ? store.scanInfo.nextStation : "-"
  27. }}
  28. </div>
  29. <div class="item">
  30. 卡号:{{ store.scanInfo.seqNo ? store.scanInfo.seqNo : "-" }}
  31. </div>
  32. <div class="item">
  33. 编码:{{
  34. store.scanInfo.materialCode ? store.scanInfo.materialCode : "-"
  35. }}
  36. </div>
  37. </div> -->
  38. </div>
  39. <div class="mainContentBox">
  40. <el-row :gutter="20">
  41. <el-col :span="4" class="boxStyle">
  42. <div class="productInfo" @click="openPop">
  43. <template v-if="taskIndex != null">
  44. <div
  45. class="productitleText"
  46. style="font-size: 500; font-size: 24px"
  47. >
  48. {{ taskArray[taskIndex].materialName }}
  49. </div>
  50. <div
  51. class="productitleText"
  52. style="
  53. color: #ffffff60;
  54. white-space: nowrap;
  55. overflow: hidden;
  56. text-overflow: ellipsis;
  57. "
  58. >
  59. {{ taskArray[taskIndex].materialModel }}
  60. </div>
  61. <div style="display: flex">
  62. <div class="productitleText" style="color: #ffffff60">S/N</div>
  63. <div class="productitleText">
  64. &nbsp;{{ snVal ? snVal : "-" }}
  65. </div>
  66. </div>
  67. </template>
  68. <template v-else>
  69. <div
  70. class="productitleText"
  71. style="
  72. font-size: 500;
  73. font-size: 24px;
  74. display: flex;
  75. justify-content: center;
  76. align-items: center;
  77. height: 100%;
  78. "
  79. >
  80. 请选择产品
  81. </div>
  82. </template>
  83. </div>
  84. <!-- 侧边栏盒子 -->
  85. <div class="commonTitle">工序</div>
  86. <el-scrollbar
  87. style="height: calc(100vh - 220px); padding-bottom: 60px"
  88. >
  89. <Steps
  90. v-if="opsArray.length > 0"
  91. :opsArray="opsArray"
  92. @init="init"
  93. />
  94. <template v-else>
  95. <div
  96. class="productitleText"
  97. style="
  98. font-size: 500;
  99. font-size: 24px;
  100. display: flex;
  101. height: calc(100vh - 280px);
  102. justify-content: center;
  103. align-items: center;
  104. background-color: var(--ohos-area-bg);
  105. border-radius: 16px;
  106. color: white;
  107. "
  108. >
  109. 暂无工序
  110. </div>
  111. </template>
  112. </el-scrollbar>
  113. </el-col>
  114. <el-col :span="20">
  115. <div class="typeContainer">
  116. <el-scrollbar>
  117. <div style="display: flex">
  118. <div
  119. v-for="(item, index) in stepComponents"
  120. :key="index"
  121. class="scrollbar-demo-item"
  122. >
  123. <router-link :to="{ name: item.name }" replace>
  124. <div
  125. :class="getNameClass(index)"
  126. class="typeBox"
  127. @click="setSelectIndex(index)"
  128. >
  129. <div class="svgIcon">
  130. <svg-icon :icon-class="item.iconName" size="30" />
  131. </div>
  132. <div class="name">{{ item.compentName }}</div>
  133. </div>
  134. </router-link>
  135. </div>
  136. <div
  137. v-if="snVal == null && taskIndex == null"
  138. style="
  139. font-size: 40px;
  140. font-weight: 500;
  141. color: white;
  142. width: 100%;
  143. height: 80px;
  144. text-align: center;
  145. line-height: 80px;
  146. "
  147. >
  148. 请先选择工序
  149. </div>
  150. <div
  151. v-else-if="snVal == null"
  152. style="
  153. font-size: 40px;
  154. font-weight: 500;
  155. color: white;
  156. width: 100%;
  157. height: 80px;
  158. text-align: center;
  159. line-height: 80px;
  160. "
  161. >
  162. 请选择其他工序
  163. </div>
  164. </div>
  165. </el-scrollbar>
  166. </div>
  167. <div :key="key" class="routerView" v-if="snVal != null">
  168. <el-scrollbar style="width: 100%">
  169. <router-view v-slot="{ Component, route }">
  170. <keep-alive
  171. include="Dianjian,Jiluxiang,Duomeiticaiji,Esop,Jingu,Mingpaibangding,Shebeijilu,Tiaoshipipei,Wuliaocaiji,Screwdriver"
  172. >
  173. <component :is="Component" :key="route.fullPath" />
  174. </keep-alive>
  175. </router-view>
  176. </el-scrollbar>
  177. </div>
  178. </el-col>
  179. </el-row>
  180. </div>
  181. <div class="midPopUp" v-if="popStatus" @click.stop="popStatus = false">
  182. <div class="popView">
  183. <div class="hang">
  184. 请扫码:
  185. <ScanCodeInput
  186. style="width: 400px"
  187. v-model="seqVal"
  188. @keyup.enter="console.log(111)"
  189. />
  190. </div>
  191. <el-divider class="dark" content-position="center"
  192. ><div
  193. style="
  194. background-color: var(--ohos-area-bg);
  195. width: 100%;
  196. height: 100%;
  197. display: flex;
  198. font-size: 20px;
  199. padding: 0 20px;
  200. color: white;
  201. font-weight: 500;
  202. "
  203. >
  204. 选择近期产品
  205. </div></el-divider
  206. >
  207. <el-scrollbar style="height: calc(100vh - 220px)">
  208. <div class="taskBox">
  209. <div
  210. class="productInfo"
  211. :key="item + index"
  212. style="background-color: var(--ohos-area-active-bg)"
  213. v-for="(item, index) in taskArray"
  214. @click="selectProduct(index)"
  215. >
  216. <div
  217. class="productitleText"
  218. style="font-size: 500; font-size: 24px; color: #000000"
  219. >
  220. {{ item.materialName }}
  221. </div>
  222. <div
  223. class="productitleText"
  224. style="
  225. color: #00000060;
  226. white-space: nowrap;
  227. overflow: hidden;
  228. text-overflow: ellipsis;
  229. width: 20vw;
  230. "
  231. >
  232. {{ item.materialModel }}
  233. </div>
  234. <div style="display: flex">
  235. <div class="productitleText" style="color: #00000060">Code</div>
  236. <div class="productitleText" style="color: #000000">
  237. &nbsp;{{ item.materialCode }}
  238. </div>
  239. </div>
  240. </div>
  241. </div>
  242. </el-scrollbar>
  243. </div>
  244. </div>
  245. </div>
  246. </template>
  247. <script setup>
  248. import OperationBar from "@/views/pro-steps/operationBar.vue";
  249. import ScanCodeInput from "@/components/ScanCodeInput/index.vue";
  250. import Steps from "@/views/process/components/steps.vue";
  251. import { useProcessStore } from "@/store";
  252. import { getOpCompent } from "@/api/prosteps";
  253. import { getOrders } from "@/api/process";
  254. import { getScan } from "@/api/process";
  255. defineOptions({
  256. name: "ProSteps",
  257. });
  258. const popStatus = ref(null);
  259. const openPop = async () => {
  260. await getTaskArray();
  261. popStatus.value = true;
  262. };
  263. const seqVal = ref("");
  264. const snVal = ref(null);
  265. const selectProduct = async (index) => {
  266. taskIndex.value = index;
  267. selectIndex.value = 0;
  268. //设置数据
  269. store.odersData.workOrderCode =
  270. taskArray.value[taskIndex.value].workOrderCode;
  271. store.processInfo.materialName =
  272. taskArray.value[taskIndex.value].materialName;
  273. store.processInfo.materialModel =
  274. taskArray.value[taskIndex.value].materialModel;
  275. if (taskArray.value[taskIndex.value].ops.length > 0) {
  276. opsArray.value = taskArray.value[taskIndex.value].ops;
  277. selectStepIndex.value = 0;
  278. snVal.value =
  279. taskArray.value[taskIndex.value].ops[selectStepIndex.value].seqs.length >
  280. 0
  281. ? taskArray.value[taskIndex.value].ops[selectStepIndex.value].seqs[0]
  282. .seqNo
  283. : null;
  284. } else {
  285. selectStepIndex.value = null;
  286. ElMessage.warning("暂无操作步骤");
  287. }
  288. if (snVal.value != null) {
  289. await init(0);
  290. } else {
  291. ElMessage.warning("当前工序暂不可操作");
  292. }
  293. popStatus.value = false;
  294. };
  295. const store = useProcessStore();
  296. store.odersData.productLineId = 10;
  297. const taskArray = ref([]);
  298. const taskIndex = ref(null);
  299. const getScanData = async () => {
  300. const value = snVal.value;
  301. const res = await getScan({
  302. operationId: Number(
  303. taskArray.value[taskIndex.value].ops[selectStepIndex.value].operationId
  304. ),
  305. qrCode: value,
  306. workOrderCode: taskArray.value[taskIndex.value].workOrderCode,
  307. //stationId暂时随便传一个
  308. stationId: 1,
  309. });
  310. if (res) {
  311. const { code, data, msg } = res;
  312. if (code == "200") {
  313. store.scanInfo = data;
  314. store.useSeqNo = data.seqNo;
  315. }
  316. return true;
  317. } else {
  318. snVal.value = null;
  319. stepComponents.value = [];
  320. router.replace({ name: "ProSteps" });
  321. return false;
  322. }
  323. };
  324. const getTaskArray = async () => {
  325. const { data } = await getOrders({
  326. pageNo: 1,
  327. pageSize: 999999999,
  328. queryComplete: 0,
  329. });
  330. taskArray.value = data.records;
  331. };
  332. const opsArray = ref([]);
  333. const selectStepIndex = ref(null);
  334. provide("selectStepIndex", selectStepIndex);
  335. const key = ref(false);
  336. const route = useRoute();
  337. const router = useRouter();
  338. const instance = getCurrentInstance();
  339. const loading = ref(false);
  340. const recondOPId = ref(null);
  341. const qrCode = ref(null);
  342. //配置标签信息Data
  343. const stepComponents = ref([]);
  344. const defaultComponents = [
  345. {
  346. compentName: "物料采集",
  347. iconName: "wuliaocaiji",
  348. path: "wuliaocaiji",
  349. name: "Wuliaocaiji",
  350. },
  351. {
  352. compentName: "记录项",
  353. iconName: "jiluxiang",
  354. path: "jiluxiang",
  355. name: "Jiluxiang",
  356. },
  357. {
  358. compentName: "多媒体采集",
  359. iconName: "duomeiticaiji",
  360. path: "duomeiticaiji",
  361. name: "Duomeiticaiji",
  362. },
  363. {
  364. compentName: "ESOP",
  365. iconName: "ESOP",
  366. path: "esop",
  367. name: "Esop",
  368. },
  369. {
  370. compentName: "点检",
  371. iconName: "dianjian",
  372. path: "dianjian",
  373. name: "Dianjian",
  374. },
  375. {
  376. compentName: "设备记录",
  377. iconName: "shebeijilu",
  378. path: "shebeijilu",
  379. name: "Shebeijilu",
  380. },
  381. {
  382. compentName: "紧固",
  383. iconName: "jingu",
  384. path: "jingu",
  385. name: "Jingu",
  386. },
  387. {
  388. compentName: "调试配对",
  389. iconName: "tiaoshipipei",
  390. path: "tiaoshipipei",
  391. name: "Tiaoshipipei",
  392. },
  393. {
  394. compentName: "铭牌绑定",
  395. iconName: "mingpai",
  396. path: "mingpaibangding",
  397. name: "Mingpaibangding",
  398. },
  399. {
  400. compentName: "测试记录",
  401. iconName: "mingpai",
  402. path: "ceshijilu",
  403. name: "Ceshijilu",
  404. },
  405. {
  406. compentName: "工序表单",
  407. iconName: "mingpai",
  408. path: "execl",
  409. name: "Excel",
  410. },
  411. {
  412. compentName: "数据采集",
  413. iconName: "mingpai",
  414. path: "screwdriver",
  415. name: "Screwdriver",
  416. },
  417. ];
  418. //当前路由在setpComponents中的index
  419. const selectIndex = ref(0);
  420. //配置data固定路由参数等
  421. const setStepComponents = (data) => {
  422. let resData = [];
  423. data.forEach((item) => {
  424. defaultComponents.forEach((obj) => {
  425. if (item.compentName === obj.compentName) {
  426. resData.push({ ...item, ...obj });
  427. }
  428. });
  429. });
  430. return resData;
  431. };
  432. const getNameClass = (index) => {
  433. return index === selectIndex.value ? "typeBoxSelected" : "typeBoxNormal";
  434. };
  435. //获取当前tags列表
  436. const getOpCompentArray = async () => {
  437. const { data } = await getOpCompent(
  438. "/" +
  439. `${Number(
  440. taskArray.value[taskIndex.value].ops[selectStepIndex.value].operationId
  441. )}` +
  442. "/" +
  443. `${store.scanInfo.id}`
  444. );
  445. stepComponents.value = setStepComponents(data);
  446. router.replace({ name: stepComponents.value[selectIndex.value].name });
  447. };
  448. //设置标签是否被选中
  449. const setSelectIndex = (index) => {
  450. selectIndex.value = index;
  451. };
  452. const init = async (index) => {
  453. if (taskIndex.value == null) {
  454. return;
  455. }
  456. selectStepIndex.value = index != null ? index : 0;
  457. //数据设置
  458. store.odersData.operationId =
  459. taskArray.value[taskIndex.value].ops[selectStepIndex.value].operationId;
  460. store.processInfo.operationCode =
  461. taskArray.value[taskIndex.value].ops[selectStepIndex.value].operationCode;
  462. store.processInfo.operationName =
  463. taskArray.value[taskIndex.value].ops[selectStepIndex.value].operationName;
  464. snVal.value =
  465. taskArray.value[taskIndex.value].ops[selectStepIndex.value].seqs.length > 0
  466. ? taskArray.value[taskIndex.value].ops[selectStepIndex.value].seqs[0]
  467. .seqNo
  468. : null;
  469. if (snVal.value != null) {
  470. const res = await getScanData();
  471. if (res == true) {
  472. await getOpCompentArray();
  473. }
  474. } else {
  475. stepComponents.value = [];
  476. ElMessage.warning("当前工序暂不可操作");
  477. }
  478. };
  479. onActivated(async () => {
  480. //缓存组件数据逻辑
  481. init(selectStepIndex.value);
  482. });
  483. </script>
  484. <style lang="scss" scoped>
  485. :deep(.el-input__wrapper) {
  486. background-color: #000;
  487. }
  488. .boxStyle {
  489. height: calc(100vh - 80px);
  490. .commonTitle {
  491. color: var(--ohos-text);
  492. font-size: 28px;
  493. }
  494. }
  495. .productInfo {
  496. width: 100%;
  497. height: 100px;
  498. margin-bottom: 10px;
  499. border-radius: 16px;
  500. background-color: var(--ohos-area-bg);
  501. padding: 10px 20px;
  502. cursor: pointer;
  503. .productitleText {
  504. color: white;
  505. }
  506. }
  507. .optionBox {
  508. height: calc(100vh - 150px);
  509. background-color: var(--ohos-area-bg);
  510. border-radius: 16px;
  511. }
  512. .headerInfo {
  513. height: 20px;
  514. width: calc(100vw - 40px);
  515. // padding: 10px;
  516. // margin: 0 20px;
  517. // display: flex;
  518. // justify-content: space-between;
  519. // align-items: center;
  520. // border-radius: 16px;
  521. // border-right: 0px;
  522. // border-left: 0px;
  523. // box-sizing: border-box;
  524. // margin-bottom: 10px;
  525. // background-color: white;
  526. .info {
  527. display: flex;
  528. flex-shrink: 0;
  529. .item {
  530. margin: 0 5px;
  531. font-size: 14px;
  532. font-weight: 300;
  533. }
  534. }
  535. }
  536. .scrollbar-demo-item {
  537. flex-shrink: 0;
  538. display: flex;
  539. align-items: center;
  540. justify-content: center;
  541. height: 80px;
  542. width: 135px;
  543. border-radius: 16px;
  544. text-align: center;
  545. background-color: var(--ohos-box-bg);
  546. margin-right: 10px;
  547. }
  548. .typeContainer {
  549. width: 100%;
  550. height: 80px;
  551. overflow-x: auto;
  552. .svgIcon {
  553. @include flex;
  554. }
  555. }
  556. .mainContentBox {
  557. height: calc(100vh - 110px);
  558. }
  559. .routerView {
  560. display: flex;
  561. flex: 1;
  562. overflow-y: auto;
  563. width: 100%;
  564. height: calc(100vh - 214px);
  565. margin-top: 20px;
  566. background-color: #ffffff20 !important;
  567. padding: 0 20px;
  568. border-radius: 16px;
  569. }
  570. .typeBox {
  571. height: 80px;
  572. width: 135px;
  573. border-radius: 16px;
  574. display: flex;
  575. flex-direction: column;
  576. justify-content: center;
  577. align-items: center;
  578. .name {
  579. height: 16px;
  580. font-weight: 500;
  581. font-size: $f20;
  582. line-height: 20px;
  583. text-align: center;
  584. font-style: normal;
  585. text-transform: none;
  586. margin-top: $p10;
  587. }
  588. }
  589. .typeBoxNormal {
  590. background: transparent;
  591. color: var(--ohos-text);
  592. }
  593. .typeBoxSelected {
  594. background-color: var(--ohos-area-active-bg);
  595. color: black !important;
  596. }
  597. :deep(.el-divider__text) {
  598. padding: 0px;
  599. }
  600. .popView {
  601. width: 80%;
  602. display: flex;
  603. flex-direction: column;
  604. height: 80%;
  605. background-color: var(--ohos-area-bg);
  606. border-radius: 16px;
  607. padding: 20px;
  608. .hang {
  609. display: flex;
  610. align-items: center;
  611. color: white;
  612. font-size: 20px;
  613. }
  614. .taskBox {
  615. display: grid;
  616. grid-template-columns: repeat(3, 1fr); /* 每行 3 列 */
  617. gap: 20px; /* 设置间距为 20px */
  618. }
  619. }
  620. </style>