billing.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. export default {
  2. data() {
  3. return {
  4. title: '收银台',
  5. type: 'goods',
  6. goodsData: {},
  7. orderData: {
  8. goods_num: 0,
  9. pay_money: 0,
  10. goods_list: [],
  11. remark: '',
  12. create_time: 0
  13. },
  14. remark: '',
  15. outTradeNo: '',
  16. orderId: 0,
  17. searchType: 'mobile',
  18. searchText: '',
  19. searchTypeList: [{
  20. 'label': '手机号',
  21. 'value': 'mobile',
  22. 'disabled': false
  23. },
  24. {
  25. label: '卡号',
  26. value: 'member_code',
  27. disabled: false
  28. },
  29. {
  30. 'label': '昵称',
  31. 'value': 'nickname',
  32. 'disabled': false
  33. }
  34. ],
  35. date: '',
  36. goodsIds: [],
  37. ordertime: '',
  38. scanCode: {
  39. code: '',
  40. lastTime: 0
  41. }
  42. }
  43. },
  44. onShow() {
  45. this.orderData.create_time = this.$util.timeFormat(parseInt(new Date().getTime() / 1000));
  46. this.addScancodeEvent();
  47. },
  48. onHide() {
  49. this.removeScancodeEvent();
  50. },
  51. onLoad() {},
  52. methods: {
  53. switchStoreAfter() {
  54. this.wholeOrderCancel(true);
  55. },
  56. showMember() {
  57. if (!this.memberInfo) {
  58. if (this.$refs.selectMember) this.$refs.selectMember.open();
  59. } else {
  60. this.type = 'member';
  61. }
  62. },
  63. showMemberCard() {
  64. if (!this.memberInfo) {
  65. if (this.$refs.selectMember) this.$refs.selectMember.open();
  66. } else {
  67. this.type = 'card';
  68. }
  69. },
  70. searchMember() {
  71. if (!this.searchText) {
  72. this.$util.showToast({
  73. title: '请输入会员信息',
  74. icon: 'error'
  75. });
  76. return false;
  77. }
  78. this.$refs.member.searchMemberByType(this.searchText, this.searchType);
  79. },
  80. switchType(index, item) {
  81. this.searchType = item.value;
  82. },
  83. addmember() {
  84. this.type = 'member';
  85. this.$refs.member.type = 'addmember';
  86. },
  87. /**
  88. * 切换会员
  89. */
  90. replaceMember() {
  91. if (this.$refs.member) this.$refs.member.memberId = 0;
  92. if (this.$refs.selectMember) this.$refs.selectMember.memberId = 0;
  93. this.$store.commit('setMemberInfo', null);
  94. let obj = {
  95. goods_num: 0,
  96. pay_money: 0,
  97. goods_list: [],
  98. remark: '',
  99. create_time: 0
  100. };
  101. Object.assign(this.orderData, obj);
  102. uni.setStorageSync('orderData', obj);
  103. this.type = !this.memberInfo ? 'goods' : 'member';
  104. },
  105. selectGoods(data) {
  106. let key = 'sku_' + data.sku_id;
  107. let num = 1;
  108. // 称重商品
  109. if (data.goods_class == 6) num = Number.parseFloat(data.weigh);
  110. if (this.goodsData[key]) {
  111. this.goodsData[key].num += num;
  112. } else {
  113. this.goodsData[key] = data;
  114. this.goodsData[key].num = num;
  115. }
  116. // 当编辑称重商品时,直接覆盖就可以不需要累加
  117. if (data.is_edit) this.goodsData[key].num = num;
  118. this.calculation();
  119. },
  120. selectMemberGoods(arr) {
  121. arr.forEach((data) => {
  122. let key = 'sku_' + data.sku_id + 'item_' + data.item_id;
  123. if (this.goodsData[key]) {
  124. this.goodsData[key].num += data.num;
  125. } else {
  126. this.goodsData[key] = data;
  127. this.goodsData[key].num = data.num;
  128. }
  129. })
  130. this.calculation();
  131. },
  132. deleteGoods(data) {
  133. if (data.card_item_id) {
  134. let _data = this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id];
  135. this.$refs.member.memberCardData.list[_data.card_index].total_use_num -= _data.num;
  136. this.$refs.member.memberCardData.list[_data.card_index].item_list[_data.index].use_num -= _data.num;
  137. if (this.$refs.member.memberCardData.index == _data.card_index) {
  138. if (_data.card_type != 'timecard') this.$refs.member.memberCardData.currData.item_list[_data.index]
  139. .use_num -= _data.num;
  140. this.$refs.member.memberCardData.currData.total_use_num -= _data.num;
  141. }
  142. delete this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id];
  143. } else {
  144. delete this.goodsData['sku_' + data.sku_id];
  145. }
  146. this.calculation();
  147. if (!Object.keys(this.goodsData).length) {
  148. this.orderData.goods_list = [];
  149. this.orderData.goods_num = 0;
  150. this.orderData.pay_money = 0;
  151. }
  152. },
  153. // 清空
  154. clearGoods() {
  155. this.goodsData = [];
  156. this.orderData.goods_list = [];
  157. this.orderData.goods_num = 0;
  158. this.orderData.pay_money = 0;
  159. this.goodsIds = [];
  160. uni.setStorageSync('orderData', "");
  161. },
  162. /**
  163. * 商品数量增加
  164. * @param {Object} data
  165. */
  166. inc(data) {
  167. if (data.card_item_id) {
  168. let _data = this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id],
  169. memberCardData = this.$refs.member.memberCardData;
  170. if (data.goods_type == '' && _data.num >= data.stock) {
  171. this.$util.showToast({
  172. title: '商品库存不足'
  173. });
  174. return;
  175. }
  176. // 如果会员卡项中正在变更的和该商品所使用的卡项一致
  177. if (memberCardData.index == _data.card_index && Object.keys(memberCardData.selected).length) return;
  178. if (_data.card_type == 'commoncard') {
  179. if (memberCardData.list[_data.card_index].total_num == memberCardData.list[_data.card_index]
  180. .total_use_num) return;
  181. } else if (_data.card_type != 'timecard') {
  182. if (memberCardData.list[_data.card_index].item_list[_data.index].num == memberCardData.list[_data
  183. .card_index].item_list[_data.index].use_num) return;
  184. }
  185. memberCardData.list[_data.card_index].total_use_num += 1;
  186. memberCardData.list[_data.card_index].item_list[_data.index].use_num += 1;
  187. if (memberCardData.index == _data.card_index) {
  188. memberCardData.currData.total_use_num += 1;
  189. if (_data.card_type != 'timecard') {
  190. memberCardData.currData.item_list[_data.index].use_num += 1;
  191. }
  192. }
  193. this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id].num += 1;
  194. } else {
  195. let _data = this.goodsData['sku_' + data.sku_id];
  196. if (data.goods_type == '' && _data.num >= data.stock) {
  197. this.$util.showToast({
  198. title: '商品库存不足'
  199. });
  200. return;
  201. }
  202. this.goodsData['sku_' + data.sku_id].num += 1;
  203. }
  204. this.calculation();
  205. },
  206. /**
  207. * 商品数量减少
  208. * @param {Object} data
  209. */
  210. dec(data) {
  211. if (data.card_item_id) {
  212. let _data = this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id];
  213. if (_data.num == 1) return;
  214. this.$refs.member.memberCardData.list[_data.card_index].total_use_num -= 1;
  215. this.$refs.member.memberCardData.list[_data.card_index].item_list[_data.index].use_num -= 1;
  216. if (this.$refs.member.memberCardData.index == _data.card_index) {
  217. this.$refs.member.memberCardData.currData.item_list[_data.index].use_num -= 1;
  218. this.$refs.member.memberCardData.currData.total_use_num -= 1;
  219. }
  220. this.goodsData['sku_' + data.sku_id + 'item_' + data.card_item_id].num -= 1;
  221. this.calculation();
  222. } else {
  223. if (this.goodsData['sku_' + data.sku_id].num == 1) return;
  224. this.goodsData['sku_' + data.sku_id].num -= 1;
  225. this.calculation();
  226. }
  227. },
  228. /**
  229. * 计算
  230. */
  231. calculation() {
  232. this.goodsIds = [];
  233. if (!Object.keys(this.goodsData).length) {
  234. this.orderData.goods_num = 0;
  235. return;
  236. }
  237. let sku_array = [],
  238. goodsIds = [];
  239. Object.keys(this.goodsData).forEach(key => {
  240. let item = this.goodsData[key];
  241. sku_array.push({
  242. sku_id: item.sku_id,
  243. num: item.num,
  244. card_item_id: item.item_id ? item.item_id : 0,
  245. money: item.money ? item.money : 0
  246. })
  247. if (!item.item_id) goodsIds.push(item.goods_id);
  248. })
  249. this.goodsIds = goodsIds;
  250. let data = {
  251. sku_array: JSON.stringify(sku_array),
  252. create_time: this.orderData.create_time
  253. };
  254. if (this.memberInfo) data.member_id = this.memberInfo.member_id;
  255. this.$api.sendRequest({
  256. url: '/cashier/storeapi/cashierordercreate/calculate',
  257. data: data,
  258. success: res => {
  259. if (res.code == 0) {
  260. Object.assign(this.orderData, res.data);
  261. uni.setStorageSync('orderData', this.orderData);
  262. this.$forceUpdate();
  263. } else {
  264. this.$util.showToast({
  265. title: res.message
  266. })
  267. }
  268. }
  269. })
  270. },
  271. /**
  272. * 挂单
  273. */
  274. hangingOrder() {
  275. if (Object.keys(this.goodsData).length) {
  276. let data = {
  277. goods: [],
  278. order_id: this.orderData.order_id,
  279. remark: this.orderData.remark
  280. };
  281. if (this.memberInfo) data.member_id = this.memberInfo.member_id;
  282. Object.keys(this.goodsData).forEach(key => {
  283. let item = this.goodsData[key];
  284. data.goods.push({
  285. goods_id: item.goods_id,
  286. sku_id: item.sku_id,
  287. num: item.num,
  288. money: item.money ? item.money : 0
  289. })
  290. })
  291. data.goods = JSON.stringify(data.goods);
  292. this.$api.sendRequest({
  293. url: this.orderData.order_id ? '/cashier/storeapi/pendorder/edit' :
  294. '/cashier/storeapi/pendorder/add',
  295. data: data,
  296. success: res => {
  297. if (res.code == 0) {
  298. this.orderData.order_id = 0;
  299. this.wholeOrderCancel();
  300. this.$refs.order.orderData.page = 0;
  301. this.$refs.order.getOrder();
  302. } else {
  303. this.$util.showToast({
  304. title: res.message
  305. })
  306. }
  307. }
  308. })
  309. } else if (this.orderNum) {
  310. this.type = 'order';
  311. } else {
  312. this.$util.showToast({
  313. title: '当前没有挂单'
  314. })
  315. }
  316. },
  317. /**
  318. * 取单
  319. * @param {Object} data
  320. */
  321. takeorder(data) {
  322. this.$refs.member.memberId = data.member_id;
  323. if (data.member_id) {
  324. this.$refs.member.getMemberInfo();
  325. } else {
  326. this.$store.commit('setMemberInfo', null);
  327. }
  328. let goodsData = {};
  329. data.order_goods.forEach(item => {
  330. if (item.goods_class == 'money') item.money = item.price;
  331. goodsData['sku_' + item.sku_id] = item;
  332. })
  333. this.goodsData = goodsData;
  334. this.orderData.order_id = data.order_id;
  335. this.orderData.goods_list = [];
  336. this.orderData.remark = data.remark;
  337. this.calculation();
  338. },
  339. /**
  340. * 整单取消
  341. */
  342. wholeOrderCancel(isInit = false) {
  343. if (Object.keys(this.goodsData).length) {
  344. // 清除当前会员
  345. this.$refs.member.memberId = 0;
  346. this.$refs.member.memberCardData.page = 0;
  347. this.$store.commit('setMemberInfo', null);
  348. // 清除商品数据
  349. this.goodsData = {};
  350. this.calculation();
  351. if (this.orderData.order_id) {
  352. this.$refs.order.deleteOrder(this.orderData);
  353. this.orderData.order_id = 0;
  354. }
  355. // 清除订单数据
  356. this.orderData = {
  357. goods_num: 0,
  358. pay_money: 0,
  359. goods_list: [],
  360. remark: '',
  361. create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
  362. }
  363. this.outTradeNo = '';
  364. this.orderId = 0;
  365. } else {
  366. if (!isInit) this.$util.showToast({
  367. title: '当前没有订单'
  368. })
  369. }
  370. },
  371. remarkConfirm() {
  372. this.orderData.remark = this.remark;
  373. this.$refs.remarkPopup.close();
  374. },
  375. /**
  376. * 支付
  377. */
  378. pay(type = '') {
  379. if (!Object.keys(this.goodsData).length || this.isRepeat) return;
  380. this.isRepeat = true;
  381. if (this.outTradeNo) {
  382. this.type = 'pay';
  383. if (type) this.$refs.payment.type = type;
  384. return;
  385. }
  386. let sku_array = [];
  387. Object.keys(this.goodsData).forEach(key => {
  388. let item = this.goodsData[key];
  389. sku_array.push({
  390. sku_id: item.sku_id,
  391. num: item.num,
  392. card_item_id: item.item_id ? item.item_id : 0,
  393. money: item.money ? item.money : 0
  394. })
  395. })
  396. let data = {
  397. sku_array: JSON.stringify(sku_array),
  398. remark: this.orderData.remark,
  399. create_time: this.orderData.create_time
  400. };
  401. if (this.memberInfo) data.member_id = this.memberInfo.member_id;
  402. this.$api.sendRequest({
  403. url: '/cashier/storeapi/cashierordercreate/create',
  404. data: data,
  405. success: res => {
  406. this.isRepeat = false;
  407. if (res.code == 0) {
  408. this.outTradeNo = res.data.out_trade_no;
  409. this.orderId = res.data.order_id;
  410. this.type = 'pay';
  411. if (type) this.$refs.payment.type = type;
  412. } else {
  413. this.$util.showToast({
  414. title: res.message,
  415. })
  416. }
  417. }
  418. })
  419. },
  420. cancelPayment() {
  421. this.$api.sendRequest({
  422. url: '/cashier/storeapi/cashierorder/deleteorder',
  423. data: {
  424. order_id: this.orderId
  425. },
  426. success: res => {
  427. if (res.code == 0) {
  428. this.outTradeNo = '';
  429. this.orderId = 0;
  430. this.type = 'goods';
  431. } else {
  432. this.$util.showToast({
  433. title: res.message,
  434. })
  435. }
  436. }
  437. })
  438. },
  439. paySuccess() {
  440. this.type = 'goods';
  441. this.wholeOrderCancel();
  442. this.searchText = '';
  443. this.$refs.goods.getGoods();
  444. },
  445. /**
  446. * 添加扫码监听事件
  447. */
  448. addScancodeEvent() {
  449. // #ifdef APP-PLUS
  450. plus.key.addEventListener('keyup', this.listenerScancode, true);
  451. // #endif
  452. // #ifdef H5
  453. window.addEventListener('keypress', this.listenerScancode, true);
  454. // #endif
  455. },
  456. /**
  457. * 移除扫码监听事件
  458. */
  459. removeScancodeEvent() {
  460. // #ifdef APP-PLUS
  461. plus.key.removeEventListener('keyup', this.listenerScancode, true);
  462. // #endif
  463. // #ifdef H5
  464. window.removeEventListener('keypress', this.listenerScancode, true);
  465. // #endif
  466. },
  467. /**
  468. * 监听扫码事件
  469. * @param {Object} e
  470. */
  471. listenerScancode(e) {
  472. const clearBarCode = () => {
  473. this.scanCode = {
  474. lastTime: 0,
  475. code: ''
  476. }
  477. }
  478. // #ifdef H5
  479. var currCode = e.keyCode || e.which || e.charCode;
  480. // #endif
  481. // #ifdef APP-PLUS
  482. const keycode = ['keycode_7': 0, 'keycode_8': 1, 'keycode_9': 2, 'keycode_10': 3, 'keycode_11': 4,
  483. 'keycode_12':
  484. 5, 'keycode_13': 6, 'keycode_14': 7, 'keycode_15': 8, 'keycode_16': 9
  485. ];
  486. var currCode = keyArr['keycode_' + e.keyCode] || '';
  487. // #endif
  488. var currTime = new Date().getTime();
  489. if (this.scanCode.lastTime > 0) {
  490. if (currTime - this.scanCode.lastTime <= 100) {
  491. this.scanCode.code += String.fromCharCode(currCode);
  492. } else if (currTime - this.scanCode.lastTime > 500) {
  493. // 输入间隔500毫秒清空
  494. clearBarCode();
  495. }
  496. } else {
  497. this.scanCode.code = String.fromCharCode(currCode);
  498. }
  499. this.scanCode.lastTime = currTime;
  500. // #ifdef H5
  501. var code = 13;
  502. // #endif
  503. // #ifdef APP-PLUS
  504. var code = 66;
  505. // #endif
  506. if (currCode == code) {
  507. if (this.scanCode.code && this.scanCode.code.length >= 8) this.getSkuBycode(this.scanCode.code)
  508. // 回车输入后清空
  509. clearBarCode();
  510. }
  511. },
  512. /**
  513. * 获取商品信息通过条形码
  514. */
  515. getSkuBycode(code) {
  516. if (this.type != 'goods' || (this.$refs.selectMember && this.$refs.selectMember.popupShow)) return;
  517. this.$api.sendRequest({
  518. url: '/cashier/storeapi/goods/skuinfo',
  519. data: {
  520. sku_no: code.trim()
  521. },
  522. success: res => {
  523. if (res.code == 0) {
  524. if (res.data) {
  525. if (res.data.stock == 0) {
  526. this.$util.showToast({
  527. title: '该商品库存不足!'
  528. })
  529. return;
  530. }
  531. this.selectGoods(res.data)
  532. } else {
  533. this.$util.showToast({
  534. title: '未找到该商品!'
  535. })
  536. }
  537. } else {
  538. this.$util.showToast({
  539. title: res.message,
  540. })
  541. }
  542. }
  543. })
  544. },
  545. // 点击称重商品调用弹窗
  546. callBox(data) {
  547. if (data.goods_class != 6) return false;
  548. data.is_edit = true; //表示称重商品在列表栏进行编辑
  549. this.$refs.goods.goodsSelect(data);
  550. }
  551. },
  552. computed: {
  553. orderNum() {
  554. return this.$store.state.pendOrderNum;
  555. }
  556. },
  557. watch: {
  558. $route(to, from) {
  559. if ((to.path == '/pages/billing/index' || to.path == '/') && this.$refs.member && this.memberInfo) {
  560. this.$refs.member.memberCardData.page = 0;
  561. this.$refs.member.memberCardData.list = [];
  562. this.$refs.member.memberCardData.total = 1;
  563. this.$refs.member.getMemberCard();
  564. }
  565. },
  566. type: function(nVal) {
  567. if (nVal != 'member') {
  568. this.$refs.member.search = false;
  569. }
  570. },
  571. orderNum: function(nVal) {
  572. if (nVal == 0) this.type = 'goods';
  573. },
  574. memberInfo: function(nVal, oVal) {
  575. if ((!this.orderData.order_id && nVal && oVal && nVal.member_id != oVal.member_id) || !nVal) {
  576. this.goodsData = {};
  577. }
  578. this.calculation();
  579. }
  580. }
  581. }