零售收银终端CheckoutPad_ox_as
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

609 lines
17 KiB

<template>
<view class="main-page">
<!-- <page-standby v-if="showPageStandby" @click="showPageStandby=!showPageStandby"></page-standby> -->
<view>
<view-header class="mheader" @closeStandby="handle_closeStandby"></view-header>
<view class="holdplace" :style="{ height: 100 + 'rpx' }"></view>
<block v-for="(e,i) in shopList" :key="i">
<list-item :mkey="i" :mitem="e" @addItem="handle_add" @minusItem="handle_minus"
@delItem="handle_del"></list-item>
</block>
<view class="holdplace" :style="{ height:'340rpx' }"></view>
<!-- <view class="holdplace" :style="{ height: footerHeight + 'px' }"></view> -->
<view ref="mfooter" class="mfooter" v-if="true">
<view-footer :tolPrice="shopListTotalPrice" :tolCount="shopListTotalCount" @clickQR="handle_clickQR"
@clickVIP="handle_clickVIP" @clickToPay = "clickToPay"></view-footer>
</view>
<!-- 条形码输入框 -->
<input-qr-box v-if="showQRInputBox" :maskHeight="screenHeight" :maxInput="20"
@showIt="handle_closeQRInputBox" @clickCommit="handle_clickCommit_qr"></input-qr-box>
<!-- 手机尾号后4位数验证 -->
<input-box-end-phone v-if="showEndPhoneBox" :maskHeight="screenHeight" :maxInput="4"
@showIt="handle_closeEndPhoneBox" @clickCommit="handle_clickCommit_qr"></input-box-end-phone>
</view>
<keyboard-listener style="height: 1px;" @keyup="onKeyup" @keydown="onKeydown"></keyboard-listener>
</view>
</template>
<script>
import util from "@/utils/util.js"
import dictKeyboard from '@/utils/dictOfKeyboard'
import {
API
} from "@/utils/api";
import {
ox
} from "@/utils/server";
import pageStandby from '@/components/index/page_standby.vue'; //待机页
import viewHeader from '@/components/index/view_header.nvue'; //头部
import viewFooter from '@/components/index/view_footer.nvue'; //底部
import listItem from '@/components/index/list_item.vue'; //列表项
import inputQrBox from '@/components/index/keyboard/input_box_QR.vue'; //条形码
import inputBoxEndPhone from '@/components/index/keyboard/input_box_end_phone.vue'; //手机号尾号
import keyboardListener from '@/components/index/keyboard/keyboard_listener.vue'; //键盘监听
// import { uni } from "@dcloudio/uni-h5";
// import { ref } from 'vue';
// import { onLoad,onReady } from '@dcloudio/uni-app';
// #ifdef APP-NVUE
let dom = weex.requireModule("dom");
// #endif
let app = "";
export default {
components: {
'page-standby': pageStandby,
'view-header': viewHeader,
'view-footer': viewFooter,
'list-item': listItem,
'input-qr-box': inputQrBox,
'input-box-end-phone': inputBoxEndPhone,
'keyboard-listener': keyboardListener,
},
watch: {
//已拆分standby到单独页面, 不再需要计算在本nvue页面高度
// showPageStandby(ov,nv){
// if(nv){
// // #ifdef APP-NVUE
// setTimeout(async()=>{
// dom = weex.requireModule("dom");
// let size = await util.getNvueRefSize(this,dom,"mfooter");
// this.footerHeight = size.height.toFixed(2)
// },200)
// // #endif
// }
// }
},
computed: {
shopListTotalPrice() {
let _total = 0
if (!this.shopList||this.shopList.length<1) return 0
this.shopList.forEach(item => {
_total += item.shopCountPrice
})
return _total
},
shopListTotalCount() {
let _total = 0
if (!this.shopList||this.shopList.length<1) return 0
this.shopList.forEach(item => {
_total += item.shopCount
})
return _total
},
//已拆分standby到单独页面, 不再需要计算在本nvue页面高度
// footerHeight(){
// return this.screenHeight - 100
// }
},
data() {
return {
// showPageStandby: false,
showQRInputBox: false,
showEndPhoneBox: false,
screenHeight: '',
footerHeight: '',
// globalData: app.globalData,
globalData: "",
shopList: [],
decryptList: [],
strResult: "",
}
},
async onLoad(res) {
console.log("onload:", res)
this.clearShopList();
// this.searchGoodBySku = util.searchGoodBySku
if(res.skulist){
this.acceptSKUList(res.skulist)
}
},
async onReady() {
// this.clearShopList();
this.screenHeight = await util.getPageHeight()
console.log(`the index page onReady----` + this.screenHeight)
app = getApp();
setTimeout(async () => {
// await this.updateGoodsList().then(async () => {
// // console.log("skulist:", this.shopList)
// })
this.setFooterHeight()
// this.setTestSku() //在页面加载后,直接进行sku测试
}, 1000)
},
methods: {
searchGoodBySku: async (sku) => {
util.showLoad()
let {brand_id,stadium_id,token} = util.getPostParams()
let urlParams = {
brand_id,token,stadium_id,
"sku": sku,
}
console.log("searchGoodBySku urlParams:", urlParams)
return ox.post({
url: API.getGoodsBySKU,
data: urlParams,
isDefaultGet: true,
failMsg: '操作失败!'
})
.then(res => {
util.hideLoad();
console.log("searchGoodBySku suc: ", res)
res = [res]
//为列表中每一项设置shopCountPrice,shopCount
res.forEach(item => {
item.shopCount = 1
// item.shopCountPrice = item.erp_goods.erp_goods_price
item.shopCountPrice = item.user_price
})
util.hideLoad()
return res
}).finally(()=>{
util.hideLoad()
})
},
clearShopList(){
console.log("clearShopList")
this.shopList = []
},
acceptSKUList(skulist){
skulist = JSON.parse(decodeURIComponent(skulist));
console.log("acceptSKUList:",skulist)
if(skulist&&skulist.length>0)this.shopList = this.combinedList(this.shopList, skulist)
},
acceptSKUListFromGlobalData(){
let skulist = app.globalData.skulist
console.log("acceptSKUListFromGlobalData:",skulist)
this.shopList = this.combinedList(this.shopList, skulist)
},
async setTestSku() {
console.log("Test set SKU 10000012")
let skulist = await this.searchGoodBySku("6934024512123")
this.shopList = this.shopList.concat(skulist)
},
async clickToPay() {
// 将shopList进行精简为 {
// "id": 57,
// "name": "光明纯牛奶",
// "price": 1,
// "nums": 1,
// "unit": "袋"
// }组成的数组
let shopListData = this.shopList.map(item => {
return {
// id: item.erp_goods.id,
id: item.id,
// name: item.erp_goods.erp_goods_name,
// price: item.erp_goods.erp_goods_price,
name:item.goods_name,
price:item.user_price,
nums: item.shopCount,
unit: item.erp_goods.erp_goods_unit
}
})
// shopCount
let _query = {
shopList: shopListData,
shopListTotalPrice: this.shopListTotalPrice.toFixed(2),
shopListTotalCount: this.shopListTotalCount
}
console.log("clickToPay", _query)
if(this.shopListTotalPrice<=0){
return util.showNone("请先添加商品")
}
util.showLoad()
await this.makeOrder(_query).then((order_res)=>{
util.hideLoad()
if(order_res.order_no){
_query["order_no"]=order_res.order_no
util.routeTo(`/pages/pay/index?query=${JSON.stringify(_query)}`, 'rL');
}else{
util.showNone(order_res.message||order_res.msg||"error:生成订单失败")
}
console.log(order_res)
}).catch((err)=>{
util.hideLoad()
console.log(err)
util.showNone(err)
})
},
async makeOrder(res){
let {brand_id,token} = getApp().globalData.accountInfo
let store_id = uni.getStorageSync("stadiumInfo").id||""
let _dataQuery = {
goods_data:res.shopList,
amount:res.shopListTotalPrice,
}
let {goods_data,amount} = _dataQuery
brand_id = parseInt(brand_id)
amount = parseFloat(amount)
let urlParams = {
store_id,brand_id,token,amount,
"goods_data": goods_data,
"pay_type": 7,
"other_pay_type":"付款码支付",
"card_no": "",
"mark": ""
}
console.log("makeOrder urlParams:", urlParams)
return ox.post({
url: API.makeOrder,
data: urlParams,
isDefaultGet: true,
failMsg: '操作失败!'
})
.then(res => {
util.hideLoad();
console.log("makeOrder suc: ", res)
return res
})
},
clickToUse() {
util.routeTo(`/pages/login/success`, 'nT');
},
handle_closeStandby(val) {
console.log("handle_closeSetting", val)
this.showPageStandby = !this.showPageStandby
},
handle_closeQRInputBox(val) {
console.log("handle_closeKeyboardBox", val)
this.showQRInputBox = !this.showQRInputBox
},
handle_closeEndPhoneBox(val) {
console.log("handle_closeEndPhoneBox", val)
this.showEndPhoneBox = !this.showEndPhoneBox
},
handle_clickQR() {
// util.showNone("输入条形码")
this.showQRInputBox = !this.showQRInputBox
},
handle_clickCommit_qr(res) {
console.log("handle_clickCommit_qr", typeof(res.goods),res)
console.log(JSON.stringify(res.goods))
// util.showNone("条码"+res.inputCode+"-"+res.goods.length)
util.showNone("添加商品成功,数量:" + res.goods.length + "个");
if(res.goods&&res.goods.length>0)this.shopList = this.combinedList(this.shopList, res.goods)
// this.shopList = this.shopList.concat(res.goods)
this.showQRInputBox = !this.showQRInputBox
},
handle_clickVIP() {
util.showNone("会员登录")
this.showEndPhoneBox = !this.showEndPhoneBox
},
combinedList(list1, list2) {//购物车list,添加商品list
//当商品sku查询list中, 含有库存不足商品, 过滤掉库存不足商品, 并提示
console.log("combinedList", list1, list2)
if(!list2)return util.showNone("未找到商品")
let _list = list1
let _list_cannot_add = []
let _list_can_add = []
list2.forEach(item => {
let _index = _list.findIndex(_item => _item.id == item.id)
if (_index != -1) {//添加商品已在购物车
if(this.checkStock(_list[_index])){
this.handle_add(_index)
}else{
item.shopCount = 1;
_list_cannot_add.push(item)
}
// _list[_index].shopCount += 1
// _list[_index].shopCountPrice = _list[_index].erp_goods.erp_goods_price * _list[_index].shopCount
} else {//不在
_list_can_add.push(item)
}
})
_list.push(..._list_can_add)
console.log("_list_cannot_add:",_list_cannot_add)
if(_list_cannot_add.length>0){
util.showNone("存在库存不足商品")
}
return _list
},
async setFooterHeight() {
console.log("Auto setFooterHeight")
// #ifdef APP-NVUE
console.log("APP-NVUE setFooterHeight")
let size_app = await util.getNvueRefSize(this, dom, "mfooter");
this.footerHeight = size_app.height.toFixed(2)
// #endif
// #ifdef H5
let size_web = await util.getH5RefSize(this, "mfooter");
this.footerHeight = size_web.height.toFixed(2)
// #endif
},
// 按键松开事件
async onKeyup(event) {
// console.log("按键松开: ", event)
// decryptList, strResult
let res = dictKeyboard.dict[event.keyCode];
// console.log("keyCode from keyboard:", res);
this.decryptList.push(res);
if (event.keyCode != 13) {
console.log("继续接收:", this.decryptList)
return
};
this.decryptList.pop();
this.strResult = await dictKeyboard.resultScan(this.decryptList);
// console.log("扫码结果-step-1:", this.strResult)
this.orderQrcode = this.strResult
// console.log("decryptList-before-splice: ", this.decryptList)
this.decryptList.splice(0);
// console.log("decryptList-after-splice: " + this.decryptList)
//过滤结果中的down_arrow
if (this.strResult.indexOf("down_arrow") != -1) {
this.strResult = this.strResult.replace("down_arrow", "")
}
// console.log("扫码结果-step-2:", this.strResult)
let skulist = await this.searchGoodBySku(this.strResult).then(res => {
console.log("searchGoodBySku suc: ", res)
return res
}).catch(err => {
console.log("searchGoodBySku err: ", err)
util.showNone(err.res.data?.message||"未找到商品-i")
})
//将skulist合并到shopList
if(skulist&&skulist.length>0)this.shopList = this.combinedList(this.shopList, skulist)
// this.shopList = this.shopList.concat(skulist)
// console.log("skulist:", this.shopList)
},
// 监听按键按下事件
onKeydown(event) {
// console.log("按键按下: ", event)
},
handle_add(i) {
console.log("handle_add", i)
if(!this.checkStock(this.shopList[i])) return util.showNone("该商品库存不足")
this.shopList[i].shopCount++
this.shopList[i].shopCountPrice = (this.shopList[i].user_price || 0) * this.shopList[i]
.shopCount
},
handle_minus(i) {
console.log("handle_minus", i)
if (this.shopList[i].shopCount > 1) {
this.shopList[i].shopCount--
this.shopList[i].shopCountPrice = (this.shopList[i].user_price || 0) * this.shopList[i]
.shopCount
} else {
util.showNone("商品数量不能小于1")
}
},
checkStock(item){ //检测商品库存与购物车数量差
let item_stock = item.erp_goods.stock_num
let use_stock = item.shopCount||0
if (item_stock-use_stock>=1)return true
return false
},
handle_del(i) {
let that = this
console.log("handle_del", i)
that.shopList.splice(i, 1)
util.showNone("删除成功")
// 真机异常, 会导致白屏, 原因未知
// uni.showModal({
// title: '提示',
// content: '确定删除该商品吗?',
// success: function (res) {
// if (res.confirm) {
// that.shopList.splice(i,1)
// uni.showToast({
// title: '删除成功',
// icon: 'success'
// });
// } else if (res.cancel) {
// uni.showToast({
// title: '取消删除',
// icon: 'none'
// });
// }
// }
// });
},
test() {
console.log("test")
let url =
"https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
//将url请求的参数转化为json对象并打印
let urlParams = util.getUrlParams(url);
console.log("urlParams:", urlParams)
return ox.post({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: false
}).then(res => {
console.log("test suc: ", res)
return res
})
},
// 业务逻辑
getGoodFromPad(sku, brand_id) {
return ox.post({
url: API.getGoodFromPad,
data: {
sku,
brand_id
},
isDefaultGet: true
})
.then(res => {
util.hideLoad();
if (res.data.code == 0) {}
return res
})
},
// 更新商品列表
async updateGoodsList() {
let _list = await this.getGoodsList()
//打印信息
console.log("app.globaldata: ", app.globalData)
//测试库存限制
// _list.list = _list.list.map(e=>{
// e.erp_goods.stock_num = 2
// return e
// })
app.globalData.goodsList = _list
},
// 更新购物车列表
updateShopList() {
app.globalData.shopList = this.shopList
},
getGoodsList() {
// let url =
// "https://testmanager.ouxuanzhineng.cn/admin/erpRetailGoods/list?brand_id=63&stadium_id=167&type_key=&key=&page=1&page_size=9999&is_sale=1&is_show_on_assistant=1&token=e6cabeae-0c1a-11ee-aa40-5254005df464";
// let urlParams = util.getUrlParams(url);
// console.log("getGoodsList需要适配urlParams:", urlParams)
let {brand_id,stadium_id,token} = util.getPostParams()
let urlParams = {
brand_id,stadium_id,token,
"type_key": "",
"key": "",
"page": "1",
"page_size": "9999",
"is_sale": "1",
"is_show_on_assistant": "1",
}
return ox.post({
url: API.getGoodsList,
data: urlParams,
isDefaultGet: true,
failMsg: "获取商品列表失败"
})
.then(res => {
util.hideLoad();
console.log("getGoodsList suc: ", res)
//为res.list中每一项设置shopCountPrice,shopCount
res.list.forEach(item => {
item.shopCount = 1
// item.shopCountPrice = item.erp_goods.erp_goods_price
item.shopCountPrice = item.user_price
})
return res
})
},
// searchGoodBySku(sku) {
// console.error(1231231)
// return new Promise((resolve, reject) => {
// let _list = app.globalData.goodsList.list
// // let _good = _list.find(item=>item.erp_goods.erp_goods_sku == sku)
// //sku可能不唯一, 返回数组
// let _goods = _list.filter(item => {
// let sku_check = (item.erp_goods.erp_goods_sku == sku)
// let stock_check = (item.erp_goods.stock_num>100)
// console.log(999,item,sku_check,stock_check)
// return sku_check&&stock_check
// })
// if (_goods.length) {
// resolve(_goods)
// } else {
// reject(false)
// }
// })
// },
}
}
</script>
<style lang="scss" scoped>
// page{
// background: #F5F7F8;
// }
.main-page {
// background-color: red;
width: 750rpx;
@include fls(flex-start);
flex-direction: column;
// height: auto;
// padding-top: 100rpx;
// padding-bottom: 120rpx;
.holdplace {
height: 110rpx;
}
// height: 1000rpx;
// width: 100%;
// height: 100%;
// background-color: #fff;
// display: flex;
// flex-direction: column;
// align-items: center;
// justify-content: center;
.mheader {
position: fixed;
top: 0;
left: 0;
width: 750rpx;
height: 100rpx;
// background: #fff;
z-index: 5;
}
.mfooter {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
z-index: 5;
}
}
</style>