put-storage.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. <template>
  2. <view class="deliver-page">
  3. <u-navbar
  4. height="40px"
  5. title="采购入库"
  6. bgColor="#0256FF"
  7. :titleStyle="{ color: '#fff' }"
  8. leftIconColor="#fff"
  9. autoBack
  10. placeholder
  11. >
  12. </u-navbar>
  13. <view class="container_main">
  14. <view class="info-box" :class="isUnfold ? '' : 'min-height'">
  15. <view class="info-line">
  16. <view class="info-line-label">
  17. <text>收入仓库</text>
  18. </view>
  19. <view class="info-line-value">
  20. {{ depotInfo ? cangName.depotName : "" }}
  21. </view>
  22. </view>
  23. <view class="info-line">
  24. <view class="info-line-label">
  25. <text>供应商</text>
  26. </view>
  27. <view class="info-line-value">
  28. {{ orderInfo.supplierName }}
  29. </view>
  30. </view>
  31. <view class="info-line">
  32. <view class="info-line-label">
  33. <text>入库类型</text>
  34. </view>
  35. <view class="info-line-value">
  36. {{ orderInfo.subType }}
  37. </view>
  38. </view>
  39. <view class="info-line">
  40. <view class="info-line-label">
  41. <text>入库日期</text>
  42. </view>
  43. <view class="info-line-value">
  44. {{ orderInfo.operTime }}
  45. </view>
  46. </view>
  47. <view class="info-line">
  48. <view class="info-line-label">
  49. <text>上传凭证</text>
  50. </view>
  51. <view class="info-line-value ss-p-y-24">
  52. <upload-image
  53. v-model="voucherPicture"
  54. width="196rpx"
  55. height="196rpx"
  56. ></upload-image>
  57. </view>
  58. </view>
  59. <view class="info-line">
  60. <view class="info-line-label">
  61. <text>备注信息</text>
  62. </view>
  63. <view class="info-line-value">
  64. <u-input
  65. v-model="orderInfo.mark"
  66. placeholder="请输入备注信息"
  67. border="none"
  68. ></u-input>
  69. </view>
  70. </view>
  71. </view>
  72. <view class="btn-box">
  73. <view class="btn-cont" @click="isUnfold = !isUnfold">
  74. <text>{{ isUnfold ? "收起" : "展开" }}</text>
  75. <u-icon :name="isUnfold ? 'arrow-up' : 'arrow-down'"></u-icon>
  76. </view>
  77. </view>
  78. <view class="scan-box">
  79. <view class="scan-box-l" @click="scanCode">
  80. <u-image
  81. width="120rpx"
  82. height="120rpx"
  83. src="@/static/image/zidong-saoma-img.png"
  84. ></u-image>
  85. <view class="tips-text">扫描快速识别货物</view>
  86. <view class="tips-text2">
  87. <u-icon name="checkmark-circle-fill" color="#0256FF"></u-icon>
  88. <text>连续扫描</text>
  89. </view>
  90. </view>
  91. <!-- <view class="scan-box-r" @click="manualClick">
  92. <u-image width="120rpx" height="120rpx" src="@/static/image/shoudong-saoma-img.png"></u-image>
  93. <view class="tips-text">手动选择</view>
  94. </view> -->
  95. </view>
  96. <!-- 货物清单 -->
  97. <view class="cargo-list">
  98. <view class="cargo-list-title">
  99. <view>入库货物清单</view>
  100. <view class="cargo-list-title-tips">(轻触货物查看详情)</view>
  101. </view>
  102. <block v-for="(item, i) in goodsList" :key="i">
  103. <good-item
  104. :item="item"
  105. @toDetail="toDetail"
  106. @calendarClick="calendarClick"
  107. :show-print="true"
  108. @print="(e) => handlePrint(e.id, '1', status)"
  109. >
  110. <view class="num-box">
  111. <view class="num-box-text">已确认入库数量</view>
  112. <u-number-box
  113. v-model="item.materialNumber"
  114. min="0"
  115. :inputWidth="56"
  116. >
  117. <!-- <view slot="minus" class="minus">
  118. <u-icon name="minus" color="#0256FF" size="12"></u-icon>
  119. </view>
  120. <text slot="input" class="input">{{item.materialNumber}}</text>
  121. <view slot="plus" class="plus">
  122. <u-icon name="plus" color="#FFFFFF" size="12"></u-icon>
  123. </view> -->
  124. </u-number-box>
  125. </view>
  126. </good-item>
  127. </block>
  128. </view>
  129. </view>
  130. <view class="footer-box">
  131. <view class="footer-box-l">
  132. <view>货物种类:{{ speciesNum }}种</view>
  133. <view>货物总数:{{ orderGoodsNum }}件</view>
  134. </view>
  135. <button class="submitBtn" @tap="submitClick">提交</button>
  136. </view>
  137. <error-pop
  138. v-model="errorShow"
  139. @close="errorShow = false"
  140. @confirm="confirm"
  141. :content="popText.errorText"
  142. ></error-pop>
  143. <success-pop
  144. v-model="successShow"
  145. @close="successShow = false"
  146. @backClick="backClick"
  147. :content="popText.successText"
  148. ></success-pop>
  149. <!-- 扫码之后弹窗 -->
  150. <scaned-pop
  151. v-if="scanedShow"
  152. v-model="scanedShow"
  153. :scanNum="scanNum"
  154. @close="scanedShow = false"
  155. @confirm="scanConfirm"
  156. ></scaned-pop>
  157. <goods-pop
  158. v-model="goodsShow"
  159. @close="goodsShow = false"
  160. type="caigou"
  161. ></goods-pop>
  162. <u-datetime-picker
  163. :show="calendarShow"
  164. v-model="value1"
  165. :maxDate="maxDate"
  166. mode="date"
  167. :closeOnClickOverlay="true"
  168. @confirm="calendarConfirm"
  169. @cancel="calendarShow = false"
  170. ></u-datetime-picker>
  171. <!-- 打印条码弹框 -->
  172. <print-pop
  173. :show.sync="blePrintPop.show"
  174. :info="blePrintPop.data"
  175. @confirm="startPrint"
  176. ></print-pop>
  177. <!-- 选择蓝牙设备弹框 -->
  178. <ble-pop
  179. :show.sync="bleSelectPop.show"
  180. :list="discoveredDevices"
  181. @close="closeBleSelectPop"
  182. @refresh="refreshBleDevice"
  183. @selectItem="handleSelectBle"
  184. ></ble-pop>
  185. <ble-tip-pop
  186. v-model="bleErrorTipPop.show"
  187. :is-center="true"
  188. @confirm="bleErrorTipConfirm"
  189. :content="bleErrorTipPop.content"
  190. :extraText="bleErrorTipPop.extraText"
  191. >
  192. </ble-tip-pop>
  193. </view>
  194. </template>
  195. <script>
  196. import goodItem from "@/components/good-item/good-item.vue";
  197. import errorPop from "@/components/error-pop/error-pop.vue";
  198. import successPop from "@/components/success-pop/success-pop.vue";
  199. import scanedPop from "@/components/scaned-pop/scaned-pop.vue";
  200. import goodsPop from "@/components/goods-pop/goods-pop.vue";
  201. import {
  202. orderDetail,
  203. orderInfo,
  204. orderSubmit,
  205. } from "@/common/request/apis/purchase";
  206. import { mapGetters } from "vuex";
  207. import blePrintMixin from "@/common/mixins/blePrintMixin.js";
  208. export default {
  209. mixins: [blePrintMixin],
  210. components: {
  211. goodItem,
  212. errorPop,
  213. successPop,
  214. scanedPop,
  215. goodsPop,
  216. },
  217. data() {
  218. return {
  219. popText: {
  220. errorText: "实际入库数量与应入库数量有差异,是否确认提交?",
  221. successText: "入库成功!",
  222. },
  223. goodsShow: false,
  224. scanedShow: false,
  225. errorShow: false,
  226. successShow: false,
  227. value: 0,
  228. isUnfold: true, //是否展开
  229. info: {
  230. mark: "",
  231. url: "",
  232. },
  233. goodsList: [],
  234. orderInfo: {},
  235. id: "",
  236. calendarShow: false,
  237. value1: "",
  238. maxDate: Number(new Date()),
  239. chooseGoodsInfo: {},
  240. voucherPicture: "",
  241. scanIndex: -1,
  242. scanNum: 1,
  243. status: null,
  244. };
  245. },
  246. onLoad(e) {
  247. this.id = e.id;
  248. this.status = e.status;
  249. this.getOrderDetail(e.id);
  250. this.getOrderInfo(e.id);
  251. },
  252. onShow() {
  253. uni.$on("scanFinish", (data) => {
  254. if (this.goodsList.length == 0) return uni.$u.toast("该货物不属于该任务");
  255. let index = this.goodsList.findIndex((item) => item.barCode == data);
  256. if (index == -1) return uni.$u.toast("该货物不属于该任务");
  257. this.scanIndex = index;
  258. this.scanNum = this.goodsList[index].materialNumber;
  259. this.scanedShow = true;
  260. });
  261. },
  262. onHide() {
  263. uni.$off("scanFinish");
  264. },
  265. onUnload() {
  266. uni.$off("scanFinish");
  267. },
  268. computed: {
  269. ...mapGetters(["depotInfo"]),
  270. speciesNum() {
  271. let num = 0;
  272. if (this.goodsList.length == 0 || !this.goodsList) {
  273. num = 0;
  274. } else {
  275. num = this.goodsList.length;
  276. }
  277. return num;
  278. },
  279. // 手动输入的数量
  280. goodsNum() {
  281. let num = 0;
  282. if (this.goodsList.length == 0 || !this.goodsList) {
  283. num = 0;
  284. } else {
  285. this.goodsList.forEach((item) => {
  286. num += item.materialNumber;
  287. });
  288. }
  289. return num;
  290. },
  291. // 订单返回的数量
  292. orderGoodsNum() {
  293. let num = 0;
  294. if (this.goodsList.length == 0 || !this.goodsList) {
  295. num = 0;
  296. } else {
  297. this.goodsList.forEach((item) => {
  298. num += item.operNumber;
  299. });
  300. }
  301. return num;
  302. },
  303. },
  304. methods: {
  305. scanCode() {
  306. this.$scan.scanCode();
  307. },
  308. calendarConfirm(val) {
  309. this.goodsList.forEach((item) => {
  310. if (item.id == this.chooseGoodsInfo.id) {
  311. item.productionDate = this.$u.timeFormat(val.value, "yyyy-mm-dd");
  312. }
  313. });
  314. this.calendarShow = false;
  315. },
  316. calendarCole() {
  317. this.calendarShow = false;
  318. },
  319. calendarClick(item) {
  320. this.chooseGoodsInfo = item;
  321. if (item.productionDate) {
  322. this.value1 = Number(new Date(item.productionDate));
  323. } else {
  324. this.value1 = Number(new Date());
  325. }
  326. this.calendarShow = true;
  327. },
  328. getOrderInfo(id) {
  329. orderInfo(id).then((res) => {
  330. if (res.code == 200) {
  331. this.orderInfo = res.data;
  332. }
  333. });
  334. },
  335. getOrderDetail(id) {
  336. orderDetail(id).then((res) => {
  337. if (res.code == 200) {
  338. res.data.rows.forEach((item) => {
  339. item.materialNumber = 0;
  340. if (item.imgName && item.imgName.length > 0) {
  341. item.imgNameArr = item.imgName.split(",");
  342. } else {
  343. item.imgNameArr = [];
  344. }
  345. });
  346. this.goodsList = res.data.rows;
  347. }
  348. });
  349. },
  350. submitClick() {
  351. let num = 0;
  352. this.goodsList.forEach((item) => {
  353. if (item.materialNumber * 1 != item.operNumber) {
  354. num++;
  355. }
  356. });
  357. if (num > 0) {
  358. return (this.errorShow = true);
  359. }
  360. this.toOrderSubmit();
  361. },
  362. toOrderSubmit() {
  363. let materials = this.goodsList.map((item) => {
  364. return {
  365. barCode: item.barCode,
  366. materialNumber: item.materialNumber,
  367. productionDate: item.productionDate
  368. ? this.$u.timeFormat(item.productionDate, "yyyy-mm-dd")
  369. : "",
  370. };
  371. });
  372. let params = {
  373. id: this.id,
  374. materials: materials,
  375. voucherPicture: this.voucherPicture || "",
  376. remark: this.orderInfo.mark || "",
  377. };
  378. orderSubmit(params).then((res) => {
  379. if (res.code == 200) {
  380. if (this.errorShow) {
  381. this.errorShow = false;
  382. }
  383. this.successShow = true;
  384. }
  385. });
  386. },
  387. confirm() {
  388. this.toOrderSubmit();
  389. this.errorShow = false;
  390. },
  391. backClick() {
  392. uni.setStorageSync("orderRefresh", true);
  393. uni.navigateBack();
  394. },
  395. // 扫码确认
  396. scanConfirm(val) {
  397. this.goodsList[this.scanIndex].materialNumber = Number(val);
  398. this.scanedShow = false;
  399. },
  400. manualClick() {
  401. // this.goodsShow = true
  402. },
  403. toDetail(val) {
  404. uni.navigateTo({
  405. url: `/pages/goods/detail?id=${val.id}&name=${val.materialName}`,
  406. });
  407. },
  408. },
  409. };
  410. </script>
  411. <style lang="scss" scoped>
  412. .deliver-page {
  413. min-height: 100vh;
  414. background-color: #f0f6fb;
  415. padding-bottom: 130rpx;
  416. .container_main {
  417. padding: 24rpx;
  418. .info-box {
  419. background-color: #fff;
  420. border-radius: 16rpx 16rpx 0 0;
  421. padding: 24rpx 24rpx 0 24rpx;
  422. .info-line {
  423. border-bottom: 1px solid #f4f4f4;
  424. min-height: 92rpx;
  425. color: #333;
  426. font-family: "PingFang SC";
  427. font-size: 28rpx;
  428. font-weight: 400;
  429. display: flex;
  430. align-items: center;
  431. &-label {
  432. width: 162rpx;
  433. }
  434. .must-box {
  435. color: #ff3b1d;
  436. }
  437. }
  438. }
  439. .min-height {
  440. height: 300rpx;
  441. overflow: hidden;
  442. }
  443. .btn-box {
  444. height: 112rpx;
  445. display: flex;
  446. align-items: center;
  447. justify-content: center;
  448. background-color: #fff;
  449. border-radius: 0 0 16rpx 16rpx;
  450. .btn-cont {
  451. display: flex;
  452. align-items: center;
  453. justify-content: center;
  454. width: 154rpx;
  455. height: 56rpx;
  456. border-radius: 120rpx;
  457. border: 1px solid #d9d9d9;
  458. color: #666;
  459. font-family: "PingFang SC";
  460. font-size: 28rpx;
  461. font-weight: 400;
  462. }
  463. }
  464. .scan-box {
  465. margin-top: 24rpx;
  466. padding: 24rpx 0;
  467. border-radius: 16rpx;
  468. background: #fff;
  469. display: flex;
  470. .tips-text {
  471. color: #333;
  472. font-size: 28rpx;
  473. font-weight: 400;
  474. line-height: 48rpx;
  475. }
  476. .tips-text2 {
  477. color: #0256ff;
  478. font-size: 24rpx;
  479. font-weight: 400;
  480. display: flex;
  481. align-items: center;
  482. .radio-box {
  483. width: 32rpx;
  484. height: 32rpx;
  485. border-radius: 50%;
  486. border: 1px solid #d9d9d9;
  487. margin-right: 16rpx;
  488. }
  489. }
  490. .scan-box-l {
  491. width: 100%;
  492. display: flex;
  493. flex-direction: column;
  494. align-items: center;
  495. position: relative;
  496. &::after {
  497. content: "";
  498. display: block;
  499. width: 1px;
  500. height: 138rpx;
  501. background-color: #f4f4f4;
  502. position: absolute;
  503. top: 50%;
  504. right: 0;
  505. transform: translateY(-50%);
  506. }
  507. }
  508. .scan-box-r {
  509. width: 50%;
  510. display: flex;
  511. flex-direction: column;
  512. align-items: center;
  513. }
  514. }
  515. .cargo-list {
  516. padding: 24rpx 0;
  517. background-color: #fff;
  518. margin-top: 24rpx;
  519. border-radius: 16rpx;
  520. .cargo-list-title {
  521. font-family: "PingFang SC";
  522. font-size: 32rpx;
  523. font-style: normal;
  524. font-weight: bold;
  525. display: flex;
  526. align-items: center;
  527. position: relative;
  528. padding-left: 50rpx;
  529. &::after {
  530. content: "";
  531. display: block;
  532. width: 6rpx;
  533. height: 30rpx;
  534. border-radius: 100px;
  535. background: #0256ff;
  536. position: absolute;
  537. top: 50%;
  538. left: 24rpx;
  539. transform: translateY(-50%);
  540. }
  541. .cargo-list-title-tips {
  542. color: #0256ff;
  543. font-size: 24rpx;
  544. font-weight: 400;
  545. }
  546. }
  547. .num-box {
  548. display: flex;
  549. align-items: center;
  550. justify-content: space-between;
  551. padding: 0 48rpx 0 26rpx;
  552. .num-box-text {
  553. color: #666;
  554. font-family: "PingFang SC";
  555. font-size: 28rpx;
  556. font-weight: 400;
  557. }
  558. .input {
  559. width: 112rpx;
  560. text-align: center;
  561. border-bottom: 1px solid #0256ff;
  562. margin: 0 8rpx;
  563. }
  564. .minus {
  565. width: 40rpx;
  566. height: 40rpx;
  567. border-radius: 8rpx;
  568. border: 1px solid #0256ff;
  569. display: flex;
  570. align-items: center;
  571. justify-content: center;
  572. }
  573. .plus {
  574. width: 40rpx;
  575. height: 40rpx;
  576. border-radius: 8rpx;
  577. background-color: #0256ff;
  578. display: flex;
  579. align-items: center;
  580. justify-content: center;
  581. }
  582. }
  583. }
  584. }
  585. .footer-box {
  586. background-color: #fff;
  587. height: 126rpx;
  588. position: fixed;
  589. bottom: 0;
  590. left: 0;
  591. right: 0;
  592. display: flex;
  593. align-items: center;
  594. justify-content: space-between;
  595. padding: 0 40rpx 0 60rpx;
  596. .footer-box-l {
  597. color: #666;
  598. font-family: "PingFang SC";
  599. font-size: 28rpx;
  600. font-weight: 400;
  601. }
  602. .submitBtn {
  603. width: 362rpx;
  604. height: 76rpx;
  605. border-radius: 16rpx;
  606. background: #0256ff;
  607. color: #fff;
  608. font-size: 28rpx;
  609. font-weight: 500;
  610. margin: 0;
  611. }
  612. }
  613. }
  614. </style>