index.vue 16 KB

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