plan_group.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. <template>
  2. <view class="nvue-page-root">
  3. <view class="head">
  4. <view class="header-wrap">
  5. <view class="index-header">
  6. <uni-icons class="fanhui" custom-prefix="iconfont" type="icon-fanhui"
  7. @click="leftClick"></uni-icons>
  8. <view class="input-wrap">
  9. <text class="iconfont">组盘</text>
  10. </view>
  11. <view class="map-wrap" @click="rightClick">
  12. <!-- <uni-icons class="lanya" custom-prefix="iconfont" type="icon-lanya"></uni-icons> -->
  13. </view>
  14. </view>
  15. </view>
  16. <view class="blank"></view>
  17. </view>
  18. <view class="uni-common-mt" style="padding: 5px;">
  19. <view class="uni-form-item uni-column">
  20. <view class="uni-input-wrapper" style="margin: 5px auto;">
  21. <text class="uni-form-item__title" style="width: 20%;">容&nbsp;&nbsp;器&nbsp;&nbsp;码</text>
  22. <input class="uni-input" auto-focus="true" :focus="firstFocus" placeholder="请扫描容器码"
  23. :value="container_code" @input="hideKeyboard" />
  24. <!-- <button class="mini-btn" type="primary" size="mini" @click="containerAdd('new')">创建新容器码并打印</button> -->
  25. </view>
  26. <view class="uni-input-wrapper" style="margin: 5px auto;">
  27. <text class="uni-form-item__title" style="width: 20%;">储位地址</text>
  28. <picker @change="bindPickerChange" :value="index" :range="addrList" range-key="name"
  29. style="width: 80%;">
  30. <view class="uni-input">{{addrList[index].name}}</view>
  31. </picker>
  32. </view>
  33. <view class="uni-padding-wrap uni-common-mt">
  34. <button type="primary" @click="SelectInventoryPlan()">选择计划</button>
  35. </view>
  36. <view class="uni-input-wrapper table-title">
  37. <view class="tab-tr" style="width: 30%;">单号</view>
  38. <view class="tab-tr" style="width: 30%;">编码</view>
  39. <view class="tab-tr" style="width: 53%;">名称</view>
  40. <view class="tab-tr-end" style="width: 12%;">数量</view>
  41. </view>
  42. <view style="min-height:245px;overflow-y:auto;max-height:245px">
  43. <view class="uni-input-wrapper table-data" v-for="(item,index) in tableData" :key="index">
  44. <view class="tab-tr" style="text-align: left;width: 30%;;color:cadetblue" @click="Delete(item)">
  45. {{item.receipt_num}}
  46. </view>
  47. <view class="tab-tr" style="text-align: left;width: 30%;;color:cadetblue" @click="Delete(item)">
  48. {{item.product_code}}
  49. </view>
  50. <view class="tab-tr"
  51. style="text-align: left;width: 53%;word-break: break-all;word-wrap: break-word;line-height: initial;">
  52. {{item.product_name}}
  53. </view>
  54. <view class="tab-tr-end" style="width: 12%">{{item.num}}</view>
  55. <!-- @click="Update(item)" -->
  56. </view>
  57. </view>
  58. <!--
  59. <view class="uni-input-wrapper table-title">
  60. <text style="text-align: center;line-height: 40px;">当前容器码:</text>
  61. <text style="text-align: center;line-height: 40px;">{{container_code}}</text>
  62. </view>
  63. -->
  64. <view class="uni-input-wrapper button-sp-area">
  65. <button type="primary" plain="true" @click="groupDisk()">组盘并入库</button>
  66. <button type="primary" plain="true" @click="in_stock()">待入库</button>
  67. </view>
  68. </view>
  69. </view>
  70. <!-- 输入框示例 -->
  71. <uni-popup ref="inputDialog" type="dialog">
  72. <uni-popup-dialog ref="inputClose" mode="input" :title="product_name" value="" placeholder="请填写数量"
  73. @confirm="UpdateNum"></uni-popup-dialog>
  74. </uni-popup>
  75. <!-- 提示窗示例 -->
  76. <uni-popup ref="deleteDialog" type="dialog">
  77. <uni-popup-dialog type="info" cancelText="取消" confirmText="确定" title="提示" :content="del_tips"
  78. @confirm="dialogConfirm" @close="dialogClose"></uni-popup-dialog>
  79. </uni-popup>
  80. </view>
  81. </template>
  82. <script>
  83. // import printConnect from "@/common/print.js"; //引入打印机模板文件
  84. let _this = null;
  85. import {
  86. mapGetters,
  87. mapActions
  88. } from 'vuex';
  89. import {
  90. GET_INFODATA,
  91. GET_CONNECTBLEDATA
  92. } from "@/store/gettersType.js";
  93. import {
  94. SET_CONNECTBLEDATA
  95. } from '@/store/actionsType.js';
  96. // #ifdef APP-PLUS
  97. const modal = uni.requireNativePlugin('modal');
  98. // const HPRT = uni.requireNativePlugin('DCloud-RichAlert');
  99. const printModule = uni.requireNativePlugin('PrintModuleCPCL');
  100. // #endif
  101. let print;
  102. var reqRootUrl = plus.storage.getItem("reqRootUrl");
  103. let rData = [];
  104. const SpeechTTS = uni.requireNativePlugin('MT-TTS-Speech');
  105. export default {
  106. data() {
  107. return {
  108. addrList: [{
  109. name: '请选择'
  110. }],
  111. addr: "",
  112. addr_sn: "",
  113. index: 0,
  114. product_name: "",
  115. product_code: "",
  116. del_tips: "",
  117. sn: "",
  118. isStart: true,
  119. bArray: [], //用于搜索蓝牙去重用的
  120. no_match_list: [], //没有配对的蓝牙列表
  121. match_list: "", //已连接蓝牙打印机
  122. val: "",
  123. localtion: '',
  124. dateTimer: "",
  125. valArr: [],
  126. url: '',
  127. item: {
  128. name: "HM",
  129. mac: "E0:6E:41:34:E0:93",
  130. },
  131. result: -1,
  132. title: 'input',
  133. firstFocus: false,
  134. src: '../../../static/eye-1.png',
  135. platform: '',
  136. container_code: "",
  137. tableData: [{
  138. name: '张三',
  139. age: 20
  140. },
  141. {
  142. name: '李四',
  143. age: 22
  144. },
  145. {
  146. name: '王五',
  147. age: 23
  148. },
  149. // 其他数据...
  150. ],
  151. }
  152. },
  153. computed: {
  154. ...mapGetters([GET_INFODATA, GET_CONNECTBLEDATA])
  155. },
  156. methods: {
  157. onUnload() {
  158. SpeechTTS.destroy();
  159. },
  160. bindPickerChange: function(e) {
  161. console.log("e.detail ", this.addrList[e.detail.value])
  162. console.log('picker发送选择改变,携带值为:' + e.detail.value)
  163. this.addr = this.addrList[e.detail.value].addr;
  164. this.addr_sn = this.addrList[e.detail.value].sn
  165. this.index = e.detail.value
  166. },
  167. speak_init() {
  168. console.log('>> TTS:init...')
  169. SpeechTTS.init((callback) => {
  170. // SpeechTTS.setEngine("com.iflytek.speechcloud"); // 设置引擎
  171. SpeechTTS.setEngine("com.google.android.tts"); // 设置引擎
  172. console.log('>> tts: init success');
  173. SpeechTTS.setPitch(50); // 设置语调 setPitch(num) 0-100, 默认 50
  174. SpeechTTS.setSpeed(65); // 设置语速 setSpeed(num) 0-100, 默认 50
  175. });
  176. SpeechTTS.onDone((res) => {
  177. console.log(">> tts: play end " + res)
  178. });
  179. },
  180. leftClick: function() {
  181. setTimeout(() => {
  182. uni.navigateBack();
  183. // uni.redirectTo({
  184. // url: '/pages/sample/main',
  185. // })
  186. }, 30);
  187. // this.$emit('change', this.value)
  188. },
  189. rightClick: function() {
  190. setTimeout(() => {
  191. uni.navigateTo({
  192. url: '/pages/sample/richAlert',
  193. })
  194. }, 30);
  195. // this.$emit("rightClick")
  196. },
  197. onLoad() {
  198. this.platform = uni.getSystemInfoSync().platform
  199. // #ifdef APP-PLUS-NVUE
  200. // #endif
  201. _this = this;
  202. _this.firstFocus = true;
  203. },
  204. onShow() {
  205. uni.hideKeyboard();
  206. setTimeout(() => {
  207. _this.firstFocus = true;
  208. this.getList();
  209. this.speak_init();
  210. }, 500);
  211. },
  212. SelectInventoryPlan() {
  213. setTimeout(() => {
  214. _this.firstFocus = false;
  215. uni.navigateTo({
  216. url: '/pages/sample/select_inventory_plan',
  217. })
  218. }, 30);
  219. },
  220. hideKeyboard: function(event) {
  221. uni.hideKeyboard();
  222. let Value = event.detail.value
  223. Value.trim()
  224. if (Value !== "" && Value !== null && Value !== undefined) {
  225. this.container_code = Value
  226. }
  227. },
  228. containerAdd(types) {
  229. let container_code = uni.getStorageSync("container_code")
  230. if (types === "new" || container_code === "" || container_code === undefined || container_code === null) {
  231. uni.request({
  232. url: reqRootUrl + '/wms/api',
  233. method: 'POST',
  234. headers: {
  235. 'Content-Type': 'application/json'
  236. },
  237. data: JSON.stringify({
  238. "method": "ContainerAdd",
  239. "param": {
  240. "num": "1"
  241. }
  242. }),
  243. success: (ret) => {
  244. if (ret.data.ret === "ok") {
  245. this.container_code = ret.data.data.code;
  246. _this.printCode(this.container_code)
  247. uni.setStorageSync("container_code", ret.data.data.code)
  248. }
  249. },
  250. fail: (err) => {
  251. // console.log('request fail', err);
  252. },
  253. complete: () => {
  254. // console.log('complete');
  255. }
  256. })
  257. } else {
  258. console.log("container_code ", container_code)
  259. this.container_code = container_code
  260. }
  261. // uni.setStorageSync(key, value)
  262. // uni.getStorageSync("key")
  263. // uni.removeStorageSync(key)
  264. },
  265. Delete(item) {
  266. this.sn = item["sn"]
  267. this.del_tips = "确定删除货物" + item["product_name"] + "?";
  268. this.$refs.deleteDialog.open()
  269. },
  270. dialogConfirm() {
  271. setTimeout(() => {
  272. uni.hideLoading()
  273. if (parseFloat() <= 0) {
  274. modal.toast({
  275. message: msg,
  276. duration: 6
  277. });
  278. return
  279. } else {
  280. uni.request({
  281. url: reqRootUrl + '/wms/api',
  282. method: 'POST',
  283. headers: {
  284. 'Content-Type': 'application/json'
  285. },
  286. data: JSON.stringify({
  287. "method": "GroupDiskDelete",
  288. "param": {
  289. [_this.sn]: {}
  290. }
  291. }),
  292. success: (ret) => {
  293. SpeechTTS.speak({
  294. text: "删除成功!"
  295. });
  296. _this.getList()
  297. //处理成功逻辑
  298. },
  299. fail: (err) => {
  300. // console.log('request fail', err);
  301. },
  302. complete: () => {
  303. // console.log('complete');
  304. }
  305. })
  306. }
  307. // 关闭窗口后,恢复默认内容
  308. this.$refs.deleteDialog.close()
  309. }, 30)
  310. },
  311. dialogClose() {
  312. _this.getList();
  313. },
  314. Update(item) {
  315. this.sn = item["sn"]
  316. this.product_name = item["product_name"] + "当前数量为:" + item["num"]
  317. this.$refs.inputDialog.open()
  318. },
  319. UpdateNum(val) {
  320. setTimeout(() => {
  321. uni.hideLoading()
  322. if (parseFloat(val) <= 0) {
  323. modal.toast({
  324. message: msg,
  325. duration: 6
  326. });
  327. return
  328. } else {
  329. uni.request({
  330. url: reqRootUrl + '/wms/api',
  331. method: 'POST',
  332. headers: {
  333. 'Content-Type': 'application/json'
  334. },
  335. data: JSON.stringify({
  336. "method": "GroupDiskUpdate",
  337. "param": {
  338. [_this.sn]: {
  339. "num": parseFloat(val)
  340. }
  341. }
  342. }),
  343. success: (ret) => {
  344. SpeechTTS.speak({
  345. text: "更新成功!"
  346. });
  347. _this.getList()
  348. //处理成功逻辑
  349. },
  350. fail: (err) => {
  351. // console.log('request fail', err);
  352. },
  353. complete: () => {
  354. // console.log('complete');
  355. }
  356. })
  357. }
  358. // 关闭窗口后,恢复默认内容
  359. this.$refs.inputDialog.close()
  360. }, 30)
  361. },
  362. getList() {
  363. uni.request({
  364. url: reqRootUrl + '/wms/api',
  365. method: 'POST',
  366. headers: {
  367. 'Content-Type': 'application/json'
  368. },
  369. data: JSON.stringify({
  370. "method": "SpaceGet",
  371. "param": {
  372. "status": "0",
  373. "types": "货位",
  374. }
  375. }),
  376. success: (ret) => {
  377. //处理成功逻辑
  378. let rows = ret.data.data;
  379. for (var i = 0; i < rows.length; i++) {
  380. let addrName = rows[i].addr.f + "层" + rows[i].addr.c + "列" + rows[i].addr.r + "排";
  381. this.addrList.push({
  382. name: addrName,
  383. addr: rows[i].addr,
  384. sn: rows[i].sn
  385. })
  386. }
  387. },
  388. fail: (err) => {
  389. // console.log('request fail', err);
  390. },
  391. complete: () => {
  392. // console.log('complete');
  393. }
  394. })
  395. console.log("获取列表");
  396. uni.request({
  397. url: reqRootUrl + '/wms/api',
  398. method: 'POST',
  399. headers: {
  400. 'Content-Type': 'application/json'
  401. },
  402. data: JSON.stringify({
  403. "method": "GroupDiskGet",
  404. "param": {
  405. "status": "status_wait",
  406. "types": "plan",
  407. }
  408. }),
  409. success: (ret) => {
  410. //处理成功逻辑
  411. // console.log("ret.data ", ret.data.data)
  412. let rows = ret.data.data;
  413. // alert(rows)
  414. rData = rows;
  415. this.tableData = rows;
  416. },
  417. fail: (err) => {
  418. // console.log('request fail', err);
  419. },
  420. complete: () => {
  421. // console.log('complete');
  422. }
  423. })
  424. },
  425. groupDisk: function() {
  426. _this.firstFocus = false;
  427. uni.showModal({
  428. title: "提示",
  429. content: "确定组盘?",
  430. success: function(res) {
  431. if (res.confirm) {
  432. let sns = [];
  433. for (var i = 0; i < rData.length; i++) {
  434. if (rData[i]["status"] !== "status_wait") {
  435. continue
  436. }
  437. sns.push(rData[i].sn)
  438. }
  439. uni.request({
  440. url: reqRootUrl + '/wms/api',
  441. method: 'POST',
  442. headers: {
  443. 'Content-Type': 'application/json'
  444. },
  445. data: JSON.stringify({
  446. "method": "ReceiptAdd",
  447. "param": {
  448. "group_disk_sn_list": sns,
  449. "container_code": _this.container_code,
  450. "addr": _this.addr,
  451. "types": "plan",
  452. }
  453. }),
  454. success: (ret) => {
  455. if (ret.data.ret === "ok") {
  456. SpeechTTS.speak({
  457. text: "组盘成功!"
  458. });
  459. modal.toast({
  460. message: "组盘成功!",
  461. duration: 6
  462. });
  463. _this.firstFocus = true;
  464. _this.AddOrder()
  465. _this.addrList = [{
  466. name: '请选择'
  467. }];
  468. _this.index = 0;
  469. _this.getList()
  470. uni.removeStorageSync("container_code")
  471. // _this.containerAdd()
  472. } else {
  473. SpeechTTS.speak({
  474. text: "组盘失败!" + ret.data.msg,
  475. });
  476. modal.toast({
  477. message: "组盘失败!" + ret.data.msg,
  478. duration: 6
  479. });
  480. console.log('request fail', ret.data.msg);
  481. }
  482. },
  483. fail: (err) => {
  484. // console.log('request fail', err);
  485. },
  486. complete: () => {
  487. // console.log('complete');
  488. }
  489. })
  490. } else {
  491. }
  492. }
  493. })
  494. },
  495. AddOrder: function() {
  496. uni.request({
  497. url: reqRootUrl + '/wms/api',
  498. method: 'POST',
  499. headers: {
  500. 'Content-Type': 'application/json'
  501. },
  502. data: JSON.stringify({
  503. "method": "AddOrder",
  504. "param": {
  505. "container_code": _this.container_code,
  506. "addr": _this.addr,
  507. "addr_sn": _this.addr_sn,
  508. }
  509. }),
  510. success: (ret) => {
  511. },
  512. fail: (err) => {
  513. // console.log('request fail', err);
  514. },
  515. complete: () => {
  516. // console.log('complete');
  517. }
  518. })
  519. },
  520. in_stock: function(code) {
  521. setTimeout(() => {
  522. uni.navigateTo({
  523. url: '/pages/sample/in_stock',
  524. })
  525. }, 500);
  526. },
  527. printCode: function(code) {
  528. this.handlePrint(code)
  529. },
  530. isEmpty: function(obj) {
  531. return typeof obj === undefined || obj == null || obj === "" || obj === "000000000000000000000000" ||
  532. obj.length === 0;
  533. },
  534. onNavigationBarButtonTap: function(e) {
  535. setTimeout(() => {
  536. uni.navigateTo({
  537. url: '/pages/sample/richAlert',
  538. })
  539. }, 500);
  540. },
  541. // 打印机相关
  542. ...mapActions([SET_CONNECTBLEDATA]),
  543. // 连接打印机
  544. confirm_bluetooth(item) {
  545. // let {
  546. // name,
  547. // mac
  548. // } = item;
  549. uni.showLoading({
  550. title: "连接中...",
  551. mask: true
  552. })
  553. let mac = item.mac;
  554. try {
  555. printModule.connectionBT({
  556. 'address': mac
  557. }, result => {
  558. const msg = JSON.stringify(result);
  559. this.result = JSON.parse(msg).result;
  560. modal.toast({
  561. message: msg,
  562. duration: 6
  563. });
  564. uni.hideLoading()
  565. printModule.setDisConnectBTListener((ret) => {
  566. modal.toast({
  567. message: '蓝牙断开',
  568. duration: 6
  569. });
  570. })
  571. })
  572. } catch (e) {
  573. console.log(e)
  574. }
  575. },
  576. //搜索没匹配的蓝牙设备
  577. search_bluetooth(address) {
  578. let _this = this;
  579. //检查蓝牙是否开启
  580. this.$check_bluetooth_open().then(ores => {
  581. if (ores) {
  582. console.log(ores);
  583. //搜索蓝牙
  584. _this.$search_bluetooth().then(bres => {
  585. console.log(bres);
  586. if (bres.code) {
  587. _this.$search_pipei().then(pres => {
  588. console.log(pres);
  589. })
  590. }
  591. })
  592. }
  593. })
  594. },
  595. handlePrint(code) {
  596. printModule.printAreaSize({
  597. 'height': '500',
  598. 'number': '1'
  599. }, result => {})
  600. printModule.printBarCode({
  601. 'x_pos': '0',
  602. 'y_pos': '20',
  603. 'code_type': '128',
  604. 'ratio': '1',
  605. 'height': '250',
  606. 'width': '4',
  607. 'rotation': 'BARCODE',
  608. 'undertext': true,
  609. 'number': '4',
  610. 'offset': '5',
  611. "textAlign": "right",
  612. 'code_data': code
  613. });
  614. printModule.printForm()
  615. printModule.print()
  616. },
  617. closeBT() {
  618. printModule.closeBT();
  619. },
  620. },
  621. }
  622. </script>
  623. <style scoped>
  624. .nvue-page-root {
  625. background-color: #F8F8F8;
  626. padding-bottom: 0px;
  627. }
  628. .uni-form-item__title {
  629. margin: 5px auto;
  630. }
  631. .uni-input-wrapper {
  632. /* #ifndef APP-NVUE */
  633. display: flex;
  634. /* #endif */
  635. flex-direction: row;
  636. flex-wrap: nowrap;
  637. background-color: #FFFFFF;
  638. }
  639. .uni-input {
  640. height: 28px;
  641. line-height: 28px;
  642. font-size: 15px;
  643. padding: 1px;
  644. flex: 1;
  645. border-radius: 5px;
  646. border: 1px solid #cfdadd;
  647. background-color: #FFFFFF;
  648. }
  649. .mini-btn {
  650. height: 30px;
  651. padding-left: 1px;
  652. padding-right: 1px;
  653. }
  654. .uni-eye-active {
  655. color: #007AFF;
  656. }
  657. .table-title {
  658. background-color: aliceblue;
  659. font-weight: 700;
  660. margin-top: 10px;
  661. height: 40px;
  662. }
  663. .table-data {
  664. background-color: aliceblue;
  665. font-weight: 700;
  666. margin-top: 1px;
  667. height: 40px;
  668. }
  669. .tab-tr {
  670. width: 25%;
  671. line-height: 50px;
  672. border-right: 1px solid #ccc;
  673. margin: auto;
  674. text-align: center;
  675. }
  676. .tab-tr-end {
  677. width: 25%;
  678. line-height: 50px;
  679. border-right: 0px solid #ccc;
  680. margin: auto;
  681. text-align: center;
  682. }
  683. </style>
  684. <style lang="scss">
  685. $color-base: #0039a6;
  686. $words-color-base: #333333;
  687. $words-color-light: #999999;
  688. .header-wrap {
  689. width: 100%;
  690. position: fixed;
  691. top: 0;
  692. z-index: 999;
  693. .index-header {
  694. height: 88upx;
  695. line-height: 88upx;
  696. padding: 0 30upx;
  697. padding-top: 40upx;
  698. background-color: $color-base;
  699. font-Size: 28upx;
  700. color: #fff;
  701. display: flex;
  702. align-items: center;
  703. justify-content: space-between;
  704. .fanhui {
  705. color: #fff !important;
  706. font-size: 28px;
  707. padding-top: 5px;
  708. font-weight: 700;
  709. }
  710. .lanya {
  711. color: #fff !important;
  712. font-size: 28px;
  713. padding-top: 5px;
  714. }
  715. .map-wrap {
  716. padding-top: 5px;
  717. }
  718. }
  719. }
  720. .blank {
  721. height: 126upx;
  722. }
  723. </style>