index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714
  1. <template>
  2. <view class="uni-column" style="height: 100%;padding: 8px;position: fixed;left: 0;right: 0;">
  3. <view v-if="allData.length>0" style="margin-bottom: 20rpx;">
  4. <view>
  5. <view class="item-info uni-row" style="height: 80rpx;">
  6. <view style="flex: 2;">
  7. <button :class="[ checkAll ? 'active' : 'select' ]" @click="handleAll"
  8. style="margin-left: 0px;display: flex; align-items: center; justify-content: center;">全选</button>
  9. </view>
  10. <button @click="handleSearch" style="margin-right: 20rpx ;">搜索</button>
  11. <uni-data-select v-model="workshopId" :localdata="workshopList" @change="handleChangeWorkshop"
  12. :clear="false" class="label right"
  13. style=" margin-right: 20rpx; outline: 2rpx solid #999999;border-radius: 10rpx;flex: 1;"></uni-data-select>
  14. </view>
  15. </view>
  16. </view>
  17. <view v-if="allData.length>0" style="overflow: auto; margin-bottom: 200rpx;height: calc(90% - 100rpx);">
  18. <view v-for="(item, index) in listData" :key="index" :class="{'list-item':true,'selected':isSelected(item)}"
  19. @click="handleSelection(item)">
  20. <view class="title-container uni-row">
  21. <view class="title uni-row"><text class="label">{{item.lotCode}}</text></view>
  22. <view><button class="start-batch-btn uni-row"
  23. style="height: 70rpx; display: flex; align-items: center; justify-content: center;"
  24. type=primary @click.stop='handleChangeCarrier(item)'>换箱</button>
  25. </view>
  26. </view>
  27. <view class="item-info uni-row">
  28. <text class="label">产品描述</text>
  29. <text class="label right">{{item['productDescription']}}</text>
  30. </view>
  31. <view class="item-info uni-row">
  32. <text class="label">关联箱号</text>
  33. <text class="label right">{{item['carrierName']}}</text>
  34. </view>
  35. <view class="item-info uni-row">
  36. <view class="label">设备</view>
  37. <text class="label right">{{item['equipmentDetailCode']}}</text>
  38. </view>
  39. <!-- <view class="item-info uni-row">
  40. <text class="label">下序</text>
  41. <text class="label right">{{item['process']}}</text>
  42. </view> -->
  43. <view class="item-info uni-row">
  44. <text class="label">当前序</text>
  45. <text class="label right">{{item['process'].processAlias}}</text>
  46. </view>
  47. <view class="item-info uni-row">
  48. <text class="label">下序</text>
  49. <text class="label right">{{item['nextProcess'].processAlias}}</text>
  50. </view>
  51. <view class="item-info uni-row">
  52. <text class="label">下序工段</text>
  53. <text class="label right">{{item.quickInfo.deptName}}</text>
  54. </view>
  55. </view>
  56. </view>
  57. <view v-if="allData.length==0" style="color: #999;">
  58. <image style="width: 420rpx; height: 420rpx; padding-top: 30% ; margin: auto;"
  59. src="../../static/images/fastProductionPlan.png" />
  60. </view>
  61. <view v-if="allData.length==0" class='bottom-btn-container'>
  62. <text style="margin: auto; padding-bottom: 10%;">扫箱码开始快速报工</text>
  63. <button class="start-batch-btn uni-row" type=primary @click='handleAdd'>扫码开始报工</button>
  64. </view>
  65. <view v-if="allData.length>0" class='btn uni-row'>
  66. <button class='bottom-btn left-btn' type="warn" @click="handleEnd">结束报工</button>
  67. <button class='bottom-btn right-btn' type="primary" @click="handleContinue">继续扫码</button>
  68. </view>
  69. <dialog-lotReporting ref="lotReporting" :getList="init" @scan="handleAdd"></dialog-lotReporting>
  70. <dialog-Search ref="searchRef" @search="refreshSearch"></dialog-Search>
  71. <QrScanner v-if="showQrCodeReader" @decode="onDecodeHandler" @close="qrReaderClose" />
  72. </view>
  73. <view
  74. style="background-color: #99999999; z-index: 5; position: absolute; left: 0px; right: 0px; top: 0px; bottom: 0px;"
  75. v-if="loading">
  76. </view>
  77. </template>
  78. <script setup>
  79. import {
  80. getPlanDetailsList
  81. } from '@/api/business/planDetails.js'
  82. import {
  83. store
  84. } from '@/store/index.js'
  85. import {
  86. onShow
  87. } from '@dcloudio/uni-app'
  88. import {
  89. getDayWorkList,
  90. showDaywork,
  91. showDayworkSave,
  92. turnoverDelete
  93. } from '@/api/business/dayWork.js'
  94. import QrScanner from '../vueQrCode/index.vue'
  95. import {
  96. getQuickDayworkList,
  97. finishQuick,
  98. getDayworkByCarrierId,
  99. getDayworkByCarrierCode,
  100. reportDaywork
  101. } from '@/api/business/quickDaywork'
  102. import {
  103. isTakeStock
  104. } from '@/api/business/taksStackLot.js'
  105. import {
  106. ref
  107. } from 'vue'
  108. import path from '@/api/base/path.js'
  109. const lotReporting = ref(null)
  110. const workshopId = ref(null);
  111. const searchRef = ref(null);
  112. const keyword = ref('')
  113. const loading = ref(false)
  114. const showQrCodeReader = ref(false);
  115. const form = ref([]); //表单数据true
  116. const checkAll = ref(false); //是否全选
  117. // 创建一个引用来存储最后一次请求的时间戳
  118. const lastRequestTimestamp = ref(0);
  119. const listData = ref([]);
  120. const allData = ref([])
  121. const selection = ref([]); //选中数据
  122. const workshopList = ref([]); //车间数据
  123. onShow(() => {
  124. init()
  125. })
  126. //初始化
  127. function init() {
  128. // console.log(store.curDeptDetails)
  129. uni.showLoading({
  130. title: '加载中'
  131. });
  132. checkAll.value = false
  133. getQuickDayworkList({
  134. deptId: store.curDeptDetails.deptId,
  135. }).then(res => {
  136. // console.log(res)
  137. if (res.code == 200) {
  138. allData.value = res.rows
  139. if (allData.value.length == 0) {
  140. listData.value = []
  141. }
  142. uni.hideLoading();
  143. }
  144. if (res.other.workShops != null) {
  145. workshopList.value = res.other.workShops.map(v => ({
  146. value: v.id,
  147. text: v.name,
  148. depts: v.depts
  149. }))
  150. if ((workshopId.value == null || !workshopList.value.some(e => e.value === workshopId.value)) &&
  151. workshopList.value.length > 0) {
  152. workshopId.value = workshopList.value[0].value
  153. handleChangeWorkshop(workshopId.value)
  154. } else {
  155. handleChangeWorkshop(workshopId.value)
  156. }
  157. } else {
  158. workshopList.value = []
  159. }
  160. uni.hideLoading();
  161. loading.value = false
  162. })
  163. }
  164. // 搜索按钮操作
  165. function handleSearch() {
  166. searchRef.value.open();
  167. }
  168. function refreshSearch(input) {
  169. // console.log(input)
  170. keyword.value = input
  171. handleChangeWorkshop(workshopId.value)
  172. }
  173. /* 【原有代码】
  174. function handleAdd() {
  175. const mpaasScanModule = uni.requireNativePlugin("Mpaas-Scan-Module");
  176. if (mpaasScanModule) {
  177. // 调用插件的 mpaasScan 方法
  178. mpaasScanModule.mpaasScan({
  179. // 扫码识别类型,参数可多选,qrCode、barCode,
  180. // 如不设置,默认识别所有扫码类型,可能有些许影响识别效率
  181. scanType: ["qrCode", "barCode"],
  182. // 是否隐藏相册,默认false不隐藏
  183. hideAlbum: false,
  184. },
  185. (ret) => {
  186. let vehicleObj = JSON.parse(ret.resp_result);
  187. if (!vehicleObj.carrierId || vehicleObj.carrierId == "") {
  188. uni.showToast({
  189. icon: "none",
  190. title: "请扫载具码",
  191. duration: 1000
  192. })
  193. return;
  194. }
  195. getDayworkByCarrierId({
  196. carrierId: vehicleObj.carrierId,
  197. deptId: store.curDeptDetails.deptId,
  198. status: 7
  199. }).then(response => {
  200. if (response.code == 200) {
  201. // console.log(response.data.items.length)
  202. // console.log(response.data)
  203. // if (response.data.items[0].deptId !== store.curDeptDetails.deptId) {
  204. // uni.showToast({
  205. // icon: 'none',
  206. // title: '该批次不在当前工段',
  207. // duration: 2000
  208. // })
  209. // return
  210. // }
  211. if (response.data.items.length > 0) {
  212. lotReporting.value.open(response.data);
  213. } else {
  214. uni.showToast({
  215. icon: 'none',
  216. title: '该批次不在此计划单内, 或不在当前工段',
  217. duration: 2000
  218. })
  219. }
  220. } else {
  221. uni.showToast({
  222. icon: 'none',
  223. title: response.msg,
  224. duration: 2000
  225. })
  226. }
  227. })
  228. }
  229. );
  230. } else {
  231. // 测试时用
  232. getDayworkByCarrierId({
  233. carrierId: '1747500987688890381',
  234. status: 7,
  235. deptId: store.curDeptDetails.deptId,
  236. }).then(response => {
  237. console.log(response)
  238. if (response.code == 200) {
  239. //
  240. // if (response.data.items[0].deptId !== store.curDeptDetails.deptId) {
  241. // uni.showToast({
  242. // icon: 'none',
  243. // title: '该批次不在当前工段',
  244. // duration: 2000
  245. // })
  246. // return
  247. // }
  248. if (response.data.items.length > 0) {
  249. // console.log(response.data)
  250. lotReporting.value.open(response.data);
  251. } else {
  252. uni.showToast({
  253. icon: 'none',
  254. title: '该批次不在此计划单内, 或不在当前工段',
  255. duration: 2000
  256. })
  257. }
  258. } else {
  259. uni.showToast({
  260. icon: 'none',
  261. title: response.msg,
  262. duration: 2000
  263. })
  264. }
  265. })
  266. }
  267. // lotReporting.value.open(data);
  268. }
  269. */
  270. //H5扫码器回调
  271. function onDecodeHandler(data) {
  272. showQrCodeReader.value = false;
  273. let vehicleObj = {
  274. carrierCode: data
  275. };
  276. if (!vehicleObj.carrierCode || vehicleObj.carrierCode == "") {
  277. uni.showToast({
  278. icon: "none",
  279. title: "请扫载具码",
  280. duration: 1000
  281. })
  282. return;
  283. }
  284. getDayworkByCarrierCode({
  285. carrierCode: vehicleObj.carrierCode,
  286. deptId: store.curDeptDetails.deptId,
  287. status: 7
  288. }).then(response => {
  289. if (response.code == 200) {
  290. if (response.data.items.length > 0) {
  291. lotReporting.value.open(response.data);
  292. } else {
  293. uni.showToast({
  294. icon: 'none',
  295. title: '该批次不在此计划单内, 或不在当前工段',
  296. duration: 2000
  297. })
  298. }
  299. } else {
  300. uni.showToast({
  301. icon: 'none',
  302. title: response.msg,
  303. duration: 2000
  304. })
  305. }
  306. })
  307. }
  308. //H5扫码器关闭
  309. function qrReaderClose() {
  310. showQrCodeReader.value = false;
  311. }
  312. function handleAdd() {
  313. showQrCodeReader.value = true;
  314. // const mpaasScanModule = uni.requireNativePlugin("Mpaas-Scan-Module");
  315. // if (mpaasScanModule) {
  316. // // 调用插件的 mpaasScan 方法
  317. // mpaasScanModule.mpaasScan({
  318. // // 扫码识别类型,参数可多选,qrCode、barCode,
  319. // // 如不设置,默认识别所有扫码类型,可能有些许影响识别效率
  320. // scanType: ["qrCode", "barCode"],
  321. // // 是否隐藏相册,默认false不隐藏
  322. // hideAlbum: false,
  323. // },
  324. // (ret) => {
  325. // let vehicleObj = {
  326. // carrierCode: ret.resp_result
  327. // };
  328. // if (!vehicleObj.carrierCode || vehicleObj.carrierCode == "") {
  329. // uni.showToast({
  330. // icon: "none",
  331. // title: "请扫载具码",
  332. // duration: 1000
  333. // })
  334. // return;
  335. // }
  336. // getDayworkByCarrierCode({
  337. // carrierCode: vehicleObj.carrierCode,
  338. // deptId: store.curDeptDetails.deptId,
  339. // status: 7
  340. // }).then(response => {
  341. // if (response.code == 200) {
  342. // if (response.data.items.length > 0) {
  343. // lotReporting.value.open(response.data);
  344. // } else {
  345. // uni.showToast({
  346. // icon: 'none',
  347. // title: '该批次不在此计划单内, 或不在当前工段',
  348. // duration: 2000
  349. // })
  350. // }
  351. // } else {
  352. // uni.showToast({
  353. // icon: 'none',
  354. // title: response.msg,
  355. // duration: 2000
  356. // })
  357. // }
  358. // })
  359. // }
  360. // );
  361. // } else {
  362. // // 测试时用
  363. // getDayworkByCarrierCode({
  364. // carrierCode: '900005',
  365. // status: 7,
  366. // deptId: store.curDeptDetails.deptId,
  367. // }).then(response => {
  368. // console.log(response)
  369. // if (response.code == 200) {
  370. // //
  371. // // if (response.data.items[0].deptId !== store.curDeptDetails.deptId) {
  372. // // uni.showToast({
  373. // // icon: 'none',
  374. // // title: '该批次不在当前工段',
  375. // // duration: 2000
  376. // // })
  377. // // return
  378. // // }
  379. // if (response.data.items.length > 0) {
  380. // // console.log(response.data)
  381. // lotReporting.value.open(response.data);
  382. // } else {
  383. // uni.showToast({
  384. // icon: 'none',
  385. // title: '该批次不在此计划单内, 或不在当前工段',
  386. // duration: 2000
  387. // })
  388. // }
  389. // } else {
  390. // uni.showToast({
  391. // icon: 'none',
  392. // title: response.msg,
  393. // duration: 2000
  394. // })
  395. // }
  396. // })
  397. // }
  398. // lotReporting.value.open(data);
  399. }
  400. function handleContinue() {
  401. // lotReporting.value.open('test')
  402. handleAdd()
  403. }
  404. // 全选按钮操作
  405. function handleAll() {
  406. //清空选中数据
  407. selection.value.length = 0;
  408. if (checkAll.value) {
  409. //变更选中状态
  410. checkAll.value = false;
  411. } else {
  412. checkAll.value = true;
  413. listData.value.findIndex(item => handleSelection(item))
  414. }
  415. }
  416. function handleChangeWorkshop(arg) {
  417. const workshop = workshopList.value.find(v => v.value === arg)
  418. // console.log(allData.value)
  419. // console.log(workshop)
  420. // console.log()
  421. listData.value = allData.value.filter(v => workshop.depts.some(e => e.deptId === v.quickInfo.deptId) && (v.lotCode
  422. .includes(keyword.value) || v.productDescription.includes(keyword.value) || v.carrierName.includes(
  423. keyword.value)))
  424. selection.value = []
  425. }
  426. function isSelected(item) {
  427. return selection.value.includes(item);
  428. }
  429. //
  430. function handleSelection(item) {
  431. const buttonIndex = selection.value.findIndex(selectedItem => selectedItem === item);
  432. if (buttonIndex > -1) {
  433. selection.value.splice(buttonIndex, 1); // 取消选中
  434. } else {
  435. selection.value.push(item); // 选中
  436. }
  437. if (selection.value.length == listData.value.length) {
  438. checkAll.value = true;
  439. } else {
  440. checkAll.value = false;
  441. }
  442. }
  443. function handleChangeCarrier(item) {
  444. uni.$once('refreshQuickReport', () => {
  445. init()
  446. })
  447. store.dayworkInfo = null
  448. uni.navigateTo({
  449. url: "/pages/changeBox/index",
  450. success: function(res) {
  451. // 通过eventChannel向被打开页面传送数据
  452. res.eventChannel.emit('acceptDataFromOpenerPage', {
  453. data: item
  454. })
  455. }
  456. })
  457. }
  458. function handleEnd() {
  459. if (selection.value.length === 0) {
  460. uni.showToast({
  461. icon: 'none',
  462. title: '请选择完成报工批次'
  463. })
  464. return
  465. }
  466. const currentTime = Date.now();
  467. // 检查是否已经过去了 2 秒
  468. if (currentTime - lastRequestTimestamp.value < 2000) {
  469. // 如果在 2 秒 内已经有请求发出,那么不执行
  470. uni.showToast({
  471. icon: 'none',
  472. title: `请勿重复点击`,
  473. duration: 2000
  474. })
  475. return;
  476. }
  477. lastRequestTimestamp.value = currentTime;
  478. // 更新请求时间戳
  479. isTakeStock().then(response => {
  480. if (response.data) {
  481. uni.showToast({
  482. icon: 'none',
  483. title: '正在盘点,不能结束报工',
  484. duration: 2000
  485. })
  486. } else {
  487. loading.value = true
  488. uni.showLoading({
  489. title: '加载中'
  490. });
  491. lastRequestTimestamp.value = currentTime;
  492. selection.value.forEach(item => {
  493. item.tenantId = !store.tenantId ? store.userInfo.tenantId : store.tenantId
  494. })
  495. finishQuick(selection.value).then(res => {
  496. // console.log(res)
  497. if (res.code === 200) {
  498. init()
  499. } else {
  500. // loading.value = false
  501. // uni.hideLoading()
  502. uni.showToast({
  503. icon: 'none',
  504. title: res.msg,
  505. duration: 2000
  506. });
  507. setTimeout(() => {
  508. init()
  509. }, 1500);
  510. }
  511. })
  512. }
  513. })
  514. }
  515. // init();
  516. </script>
  517. <style lang="scss">
  518. $nav-height: 60rpx;
  519. .bottom-btn-container {
  520. position: fixed;
  521. top: 80%;
  522. right: 20rpx;
  523. left: 20rpx;
  524. .start-batch-btn {
  525. margin-bottom: 24rpx;
  526. border-radius: 8rpx;
  527. background-color: #00e2a6;
  528. width: 80%;
  529. }
  530. }
  531. .active {
  532. flex: 1;
  533. height: 40rpx;
  534. background-color: #5e6eff;
  535. border: 1px solid #5e6eff;
  536. color: #000000;
  537. }
  538. .select {
  539. flex: 1;
  540. height: 40rpx;
  541. // font-size: 20rpx;
  542. background-color: #5e6eff;
  543. border: 1px solid #5e6eff;
  544. color: #ffffff;
  545. }
  546. .btn {
  547. position: fixed;
  548. right: 0;
  549. bottom: 0;
  550. left: 0;
  551. height: 100rpx;
  552. padding: 16rpx 24rpx;
  553. align-items: center;
  554. background-color: #FFFFFF;
  555. justify-content: space-between;
  556. .bottom-btn {
  557. flex: 1;
  558. font-size: 28rpx;
  559. color: #FFFFFF;
  560. &.left-btn {
  561. // background-color: #a4adb3;
  562. }
  563. &.right-btn {
  564. background-color: #1684fc;
  565. margin-left: 24rpx;
  566. }
  567. }
  568. }
  569. .box-bg {
  570. width: 100%;
  571. background-color: #F5F5F5;
  572. padding: 5rpx 0;
  573. justify-content: space-around;
  574. align-items: center;
  575. .input-view {
  576. width: 100%;
  577. flex: 4;
  578. background-color: #f8f8f8;
  579. height: $nav-height;
  580. border: 1rpx solid #999;
  581. border-radius: 15rpx;
  582. padding: 0 15rpx;
  583. flex-wrap: nowrap;
  584. margin: 0 10rpx 20rpx;
  585. line-height: $nav-height;
  586. .input-uni-icon {
  587. line-height: $nav-height;
  588. }
  589. .nav-bar-input {
  590. width: 80%;
  591. height: $nav-height;
  592. line-height: $nav-height;
  593. padding: 0 5rpx;
  594. background-color: #f8f8f8;
  595. }
  596. }
  597. .search {
  598. width: 20%;
  599. text-align: center;
  600. color: #808080;
  601. margin-top: -20rpx;
  602. }
  603. }
  604. .list-item {
  605. background-color: #fff;
  606. position: relative;
  607. padding: 16rpx;
  608. padding-bottom: 24rpx;
  609. border-radius: 24rpx;
  610. margin-bottom: 24rpx;
  611. .title-container {
  612. justify-content: space-between;
  613. margin-top: 8rpx;
  614. margin-bottom: 16rpx;
  615. .title {
  616. height: 48rpx;
  617. align-items: center;
  618. .label {
  619. font-size: 32rpx;
  620. font-weight: bold;
  621. &.code {
  622. margin-left: 8rpx;
  623. }
  624. }
  625. }
  626. .tag {
  627. border: 1px solid #1ce5b0;
  628. background-color: #f6fffd;
  629. padding: 8rpx;
  630. border-radius: 8rpx;
  631. .label {
  632. color: #1ce5b0;
  633. font-size: 24rpx;
  634. }
  635. &.not-start {
  636. border: 1px solid #bbbbbb;
  637. background-color: #f5f5f5;
  638. .label {
  639. color: #bbbbbb;
  640. }
  641. }
  642. }
  643. }
  644. .item-info {
  645. margin-bottom: 8rpx;
  646. .label {
  647. font-size: 28rpx;
  648. width: 150rpx;
  649. color: #808080;
  650. &.right {
  651. flex: 1;
  652. color: #000000;
  653. }
  654. }
  655. }
  656. }
  657. .selected {
  658. border: 1rpx solid #c0c4fc;
  659. background-color: #c0c4fc;
  660. /* 选中之后样式 */
  661. }
  662. </style>