初始上传

This commit is contained in:
2026-04-04 17:27:12 +08:00
parent 4d80d28eb4
commit b7e11774ee
11191 changed files with 1588469 additions and 0 deletions

View File

@@ -0,0 +1,183 @@
<template>
<base-page>
<view class="uni-flex uni-row page-height" @click="restoreFocus">
<view class="common-wrap left-wrap">
<view class="cashregister-header-box">
<view class="order-time">
<view class="title">消费时间</view>
<uni-datetime-picker v-model="billingOrderData.create_time" type="datetime" :clearIcon="false" />
</view>
<view class="header" v-if="globalMemberInfo">
<view class="headimg" @click="showMember">
<image class="header-image" :src="globalMemberInfo.headimg ? $util.img(globalMemberInfo.headimg) : $util.img(defaultImg.head)" @error="globalMemberInfo.headimg = defaultImg.head"/>
<view v-if="globalMemberInfo.member_level" class="member-nameplate">
{{ globalMemberInfo.member_level_name }}
</view>
</view>
<view class="head-info" @click="showMember">
<view class="head-info-top">
<view class="name">
<block v-if="globalMemberInfo.mobile">
<view class="mobile">{{ globalMemberInfo.mobile }}</view>
<view class="text">
<text></text>
<text class="nickname">{{globalMemberInfo.nickname }}</text>
<text></text>
</view>
</block>
<text v-else>{{ globalMemberInfo.nickname }}</text>
</view>
</view>
<view class="head-info-bottom point">积分{{ globalMemberInfo.point }}</view>
<view class="head-info-bottom balance">余额{{ (parseFloat(globalMemberInfo.balance_money) + parseFloat(globalMemberInfo.balance)) | moneyFormat}}</view>
</view>
<button class="switch primary-btn member-open" @click="openMember()">更换会员</button>
<button class="switch primary-btn replace-member" @click="replaceMember()">散客</button>
</view>
<view class="header" v-else>
<view class="headimg">
<image class="header-image" :src="$util.img(defaultImg.head)" />
</view>
<view class="head-info">
<view class="name">散客</view>
</view>
<button class="switch primary-btn" @click="openMember()">查询会员</button>
</view>
</view>
<view class="content">
<view class="content-list common-scrollbar">
<block v-if="billingOrderData.goods_list.length && Object.keys(billingGoodsData).length">
<view class="content-item settlement-select-focus" :class="{ 'focus bg-primary-color-9': leftIndexFocus == index }"
v-for="(item, index) in billingOrderData.goods_list" :key="item.editKey"
@click="callBox(item)" tabindex="0" :data-tab-index="index"
@blur="leftTabOrderSelectBlur(item)">
<view class="item-img">
<image v-if="item.goods_image == '@/static/goods/goods.png'" src="@/static/goods/goods.png" mode="widthFix"/>
<image v-else :src="$util.img(item.goods_image.split(',')[0], { size: 'small' })" mode="widthFix" @error="item.goods_image = '@/static/goods/goods.png'"/>
</view>
<view class="uni-flex flex-1 info-wrap">
<view class="info-top">
<view class="uni-flex justify-between items-center">
<view class="item-name">{{ item.goods_name }}</view>
<view class="item-del" @click.stop="deleteGoods(item)">
<text class="iconfont iconshanchu"></text>
<text>删除</text>
</view>
</view>
<view class="item-spe" v-if="item.spec_name">已选{{ item.spec_name }}</view>
</view>
<view class="info-bottom">
<view class="uni-flex items-flex-end">
<view class="item-price">{{ item.price | moneyFormat }}{{item.card_item_id > 0 ? '×'+item.num : ''}}</view>
<view class="item-subtotal" v-if="item.goods_class != $util.goodsClassDict.service && item.card_item_id == 0">
<view>
<text class="unit"></text>
<text>{{ item.goods_money | moneyFormat }}</text>
</view>
</view>
<view class="item-num" v-if="item.goods_class != $util.goodsClassDict.service && item.card_item_id == 0 && item.pricing_type == 'num'">
<view class="num-dec" @click.stop="dec(item)">-</view>
<view class="num" v-if="item.card_item_id && billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id]">{{ billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id].num }}</view>
<view class="num" v-else-if="billingGoodsData['sku_' + item.sku_id]">{{ billingGoodsData['sku_' + item.sku_id].num }}</view>
<view class="num" v-else>{{ item.num }}</view>
<view class="num-inc" @click.stop="inc(item)">+</view>
</view>
<view class="item-num weight" v-if="item.goods_class == $util.goodsClassDict.weigh && item.pricing_type == 'weight'">
<view class="num" v-if="item.card_item_id && billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id]">
{{ billingGoodsData['sku_' + item.sku_id + '_item_' + item.card_item_id].num }}
</view>
<view class="num" v-else-if="billingGoodsData['sku_' + item.sku_id]">{{ billingGoodsData['sku_' + item.sku_id].num }}</view>
<view class="num" v-else>{{ item.num }}</view>
<view>{{ item.unit }}</view>
</view>
</view>
<view class="card-deduction" v-if="item.card_info && Object.keys(item.card_info).length">
<text>使用卡项{{ item.card_info.goods_name }}</text>
</view>
</view>
</view>
</view>
</block>
<view class="empty" v-else>
<image src="@/static/cashier/cart_empty.png" mode="widthFix"/>
<view class="tips">点击右侧商品选择商品进行结账</view>
</view>
</view>
</view>
<view class="bottom">
<view class="bottom-info">
<view class="bottom-left">合计 {{ billingOrderData.goods_num.toFixed(2) }} </view>
<view class="bottom-right">
<text class="pay-money">{{ billingOrderData.pay_money | moneyFormat }}</text>
</view>
</view>
<view class="bottom-btn justify-between">
<view class="tag-parent">
<button class="comp-btn" :class="type == 'order' ? 'primary-btn' : 'default-btn'" @click="hangingOrder">/取单</button>
<text class="num-tag" v-if="pendOrderNum > 0">{{ pendOrderNum < 100 ? pendOrderNum : '99+' }}</text>
</view>
<button class="default-btn comp-btn" @click="wholeOrderCancel(true,true)">整单取消</button>
<button class="primary-btn btn-right" :disabled="billingOrderData.goods_num == 0" @click="pay('')">结账</button>
</view>
</view>
<view class="pay-shade" v-show="type == 'pay'"></view>
</view>
<view class="uni-flex uni-row" style="flex: 1;">
<view class="list-wrap flex-1">
<!-- 商品 -->
<view class="content" v-show="type == 'goods'">
<ns-goods @openCashBox="openCashBox" :indexFocus="rightIndexFocus" ref="goods" />
</view>
<view class="content payment-content common-wrap" v-show="type == 'pay'">
<ns-payment ref="payment" storeRoute="billing" @cancel="cancelPayment" @success="paySuccess" :outTradeNo="outTradeNo"/>
</view>
</view>
</view>
</view>
<!-- 选择会员 -->
<ns-select-member ref="selectMember" />
<!-- 会员详情弹出框 -->
<ns-member-detail-popup ref="memberDetailPopup" isShowMemberCard/>
<!-- 挂单弹出框 -->
<ns-pend-order-popup ref="pendOrderPopup"/>
</base-page>
</template>
<script>
import billing from './public/js/billing.js';
import nsSelectMember from '@/components/ns-select-member/ns-select-member.vue';
import nsMemberDetail from '@/components/ns-member-detail/ns-member-detail.vue';
export default {
components: {
nsSelectMember,
nsMemberDetail
},
mixins: [billing]
};
</script>
<style lang="scss" scoped>
@import './public/css/index.scss';
</style>
<style>
.cashregister-header-box>>>.uni-select-lay-select {
padding-right: 0.1rem !important;
}
.cashregister-header-box>>>.uni-select-lay-icon {
display: none !important;
}
.cashregister-header-box>>>.uni-select-lay-input-close {
display: none !important;
}
</style>

View File

@@ -0,0 +1,435 @@
.left-wrap {
position: relative;
width: 4rem;
display: flex;
flex-direction: column;
margin-right: 0.2rem;
-ms-flex-negative: 0;
-webkit-flex-shrink: 0;
flex-shrink: 0;
border-radius: 0.04rem 0.04rem 0 0;
.pay-shade {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: rgba($color: #fff, $alpha: 0.6);
z-index: 10;
}
.order-time {
display: flex;
align-items: center;
.title {
user-select: none;
position: relative;
z-index: 3;
height: 0.3rem;
padding: 0 0.1rem 0 0.1rem;
box-sizing: border-box;
border-radius: 0.02rem;
border: 0.01rem solid #e5e5e5;
display: flex;
align-items: center;
font-size: 0.14rem;
color: #333;
}
.uni-date {
flex: 1;
margin-left: 0.1rem;
}
/deep/ .uni-date-x {
height: 0.28rem;
}
}
.content {
color: #303133;
flex: 1;
height: 0;
display: flex;
flex-direction: column;
.title {
font-size: 0.14rem;
display: flex;
justify-content: space-between;
}
.clear {
display: flex;
align-items: center;
text {
&:nth-child(1) {
font-size: 0.18rem;
}
&:nth-child(2) {
margin-left: 0.03rem;
font-size: 0.14rem;
}
}
}
.content-list {
flex: 1;
height: 0;
overflow-y: scroll;
padding: 0 0.2rem;
.content-head {
display: flex;
margin: 0.1rem 0;
view {
flex: 1;
font-size: 0.13rem;
}
.center {
text-align: center;
}
.right {
text-align: right;
}
}
.content-item {
position: relative;
display: flex;
align-items: start;
flex-wrap: wrap;
justify-content: space-between;
border-bottom: 0.01rem solid #e6e6e6;
padding-top: 0.08rem;
padding-bottom: 0.08rem;
&.focus,
&:focus {
outline: none;
}
.flex {
display: flex;
align-items: center;
}
.info-wrap {
margin-left: 0.1rem;
flex-wrap: wrap;
min-height: 0.6rem;
}
.item-img {
width: 0.6rem;
height: 0.6rem;
display: flex;
align-items: center;
image {
width: 100%;
}
}
.item-name {
font-size: 0.14rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 2.04rem;
height: 0.20rem;
font-weight: 500;
color: #222222;
line-height: 0.20rem;
}
.item-del {
cursor: pointer;
font-size: 0.14rem;
display: flex;
align-items: center;
&:hover{
color: $primary-color;
}
.iconfont.iconshanchu{
font-size: 0.2rem;
}
}
.item-spe {
font-size: 0.12rem;
margin-top: 0.04rem;
width: 2.04rem;
height: 0.17rem;
font-weight: 500;
color: #808695;
line-height: 0.17rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.info-top{
width: 100%;
}
.info-bottom{
width: 100%;
align-self: flex-end;
}
.item-price{
flex: 1;
}
.item-subtotal {
flex: 1;
display: flex;
align-items: end;
.unit{
font-size: 0.12rem;
}
}
.item-num {
display: flex;
flex: 1;
justify-content: flex-end;
align-items: center;
margin-left: 0.1rem;
.num-dec {
width: 0.25rem;
height: 0.25rem;
background: #e6e6e6;
border: 0.01rem solid #e6e6e6;
border-radius: 30%;
text-align: center;
line-height: 0.23rem;
font-size: 0.25rem;
margin-right: 0.1rem;
cursor: pointer;
transition: 0.3s;
}
.num-inc {
width: 0.25rem;
height: 0.25rem;
background: $primary-color;
border: 0.01rem solid #e6e6e6;
border-radius: 30%;
text-align: center;
line-height: 0.23rem;
font-size: 0.25rem;
margin-left: 0.1rem;
cursor: pointer;
transition: 0.3s;
color: #fff;
}
}
.weight {
flex: 1;
justify-content: end;
}
.item-total-price {
font-size: 0.14rem;
margin-left: 0.1rem;
color: #fe2278;
}
.card-deduction {
width: 100%;
font-size: 0.12rem;
margin-top: 0.05rem;
color: #999;
}
}
}
.empty {
text-align: center;
image {
width: 60%;
margin-top: 0.4rem;
}
.tips {
color: #999;
margin-top: 0.15rem;
}
}
}
.bottom {
width: 100%;
padding:0.2rem 0.2rem 0.24rem 0.2rem;
box-sizing: border-box;
background-color: #ffffff;
.bottom-info {
display: flex;
align-items: center;
justify-content: space-between;
color: #303133;
font-weight: 500;
height: 0.27rem;
line-height: 0.27rem;
margin-bottom: 0.12rem;
.bottom-left {
font-size: 0.14rem;
}
.bottom-right {
font-size: 0.14rem;
.pay-money{
font-size: 0.27rem;
height: 0.22rem;
font-weight: 600;
font-family: AlibabaPuHuiTiM;
color: $primary-color;
line-height: 0.22rem;
}
}
}
.bottom-btn {
display: flex;
align-items: center;
margin-top: 0.2rem;
button{
width: 0.98rem;
margin: 0 !important;
height: 0.40rem;
line-height: 0.38rem;
border: 0.01rem solid #e6e6e6 !important;
&::after{
display: none;
}
&:hover{
border:0.01rem solid $primary-color !important;
}
}
.tag-parent {
position: relative;
.num-tag {
position: absolute;
background-color: #f00;
color: #fff;
height: 0.18rem;
line-height: 0.18rem;
padding: 0 0.06rem;
border-radius: 0.1rem;
font-size: 0.12rem;
text-align: center;
z-index: 1;
top: 0;
right: 0.12rem;
transform: translateY(-50%) translateX(100%);
}
}
.btn-right {
width: 1.4rem;
height: 0.4rem;
line-height: 0.4rem;
border:0 !important;
&:hover{
border:0 !important;
}
}
}
}
}
.comp-wrap {
min-width: 1rem;
border: 0.01rem solid #e6e6e6;
border-radius: 0.02rem;
padding: 0.2rem 0.17rem;
.comp-btn {
overflow: initial;
margin-bottom: 0.2rem;
}
}
.payment-content {
border-left: 0.01rem solid #e6e6e6;
padding-left: 0.17rem;
}
.list-wrap {
height: 100%;
box-sizing: border-box;
.content {
height: 100%;
}
.comp-btn {
width: 80%;
margin-top: 0.2rem;
}
.header {
height: 0.66rem;
line-height: 0.66rem;
text-align: left;
border-bottom: 0.01rem solid #e6e6e6;
color: #303133;
font-size: 0.14rem;
}
.body {
padding: 0.3rem;
}
}
.page-height {
height: 100%;
}
.common-wrap {
height: 100%;
}
.remark-wrap {
width: 6rem;
background-color: #fff;
border-radius: 0.04rem;
box-shadow: 0 0.01rem 0.12rem 0 rgba(0, 0, 0, 0.1);
.header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 0 0.15rem;
height: 0.45rem;
line-height: 0.45rem;
border-bottom: 0.01rem solid #e8eaec;
.iconfont {
font-size: $uni-font-size-lg;
}
}
.body {
padding: 0.15rem 0.15rem 0.1rem;
textarea {
border: 0.01rem solid #e6e6e6;
width: 100%;
padding: 0.1rem;
box-sizing: border-box;
font-size: 0.14rem;
}
.placeholder-class {
font-size: 0.14rem;
}
}
.footer {
height: 0.5rem;
padding-bottom: 0.05rem;
display: flex;
align-items: center;
justify-content: center;
button {
width: 95%;
}
}
}

View File

@@ -0,0 +1,730 @@
import {calculate, create} from '@/api/order_create.js'
import {addPendOrder, editPendOrder} from '@/api/pendorder.js'
import {mapGetters} from 'vuex';
export default {
data() {
return {
type: 'goods',
outTradeNo: '',
isRepeat: false,
leftIndexFocus: -1, // 左侧订单项 焦点索引
rightIndexFocus: -1, // 右侧选择商品 焦点索引
}
},
computed: {
...mapGetters(['billingGoodsData', 'billingOrderData', 'pendOrderNum', 'billingActive', 'billingIsScanTrigger','billingPendOrderId','memberSearchWayConfig'])
},
watch: {
pendOrderNum: function (nVal) {
if (nVal == 0) this.type = 'goods';
},
// 会员发生变化,重新计算价格
globalMemberInfo: function (nVal, oVal) {
this.calculation();
},
billingActive(nVal) {
if (nVal == 'SelectGoodsAfter') {
this.rightIndexFocus = -1; // 选择完商品后,取消选中焦点
}
},
billingGoodsData: {
// 每个属性值发生变化就会调用这个函数
handler(newVal, oldVal) {
this.calculation();
},
// 深度监听 属性的变化
deep: true
}
},
onLoad() {
uni.hideTabBar();
},
onShow() {
this.$store.commit('billing/setOrderData', {
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
});
// 添加组件的键盘监听事件
this.addKeyDownEvent();
if (this.$refs.goods) {
this.$refs.goods.init();
this.$refs.goods.addKeyDownEvent();
this.$refs.goods.addScanCodeEvent();
}
if (this.$refs.payment) {
this.$refs.payment.addKeyDownEvent();
}
},
onHide() {
this.removeKeyDownEvent();
// 移除组件的键盘监听事件
this.$refs.goods.removeKeyDownEvent();
this.$refs.goods.removeScanCodeEvent();
this.$refs.payment.removeKeyDownEvent();
},
methods: {
switchStoreAfter() {
this.wholeOrderCancel(true,true);
},
openMember() {
if (this.$refs.selectMember) {
this.$store.commit('billing/setActive', 'ShowMember');
this.$refs.selectMember.open(() => {
this.$store.commit('billing/setActive', 'ShowMemberAfter');
});
}
},
showMember() {
this.$store.commit('billing/setActive', 'ShowMember');
if (!this.globalMemberInfo) {
// 选择会员
if (this.$refs.selectMember) this.$refs.selectMember.open(() => {
this.$store.commit('billing/setActive', 'ShowMemberAfter');
});
} else {
// 打开会员信息弹出框
this.$refs.memberDetailPopup.open();
this.$store.commit('billing/setActive', 'ShowMemberAfter');
}
},
/**
* 切换为散客,清除会员、订单信息
*/
replaceMember() {
this.type = 'goods';
this.$store.commit('app/setGlobalMemberInfo', null);
this.$store.commit('billing/setOrderData', {
goods_num: 0,
pay_money: 0,
goods_list: [],
remark: '',
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
});
},
deleteGoods(data) {
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
// 恢复调价
if (!data.card_item_id) {
for (let i = 0; i < this.$refs.goods.goodsData.list.length; i++) {
let item = this.$refs.goods.goodsData.list[i];
if (item.sku_id == data.sku_id) {
item.adjust_price = item.price;
item.adjust = {};
break;
}
}
}
delete _billingGoodsData[data.editKey];
//重组数据
var index = 0;
let tempGoodsData = {};
Object.keys(_billingGoodsData).forEach((key,index) =>{
if(_billingGoodsData[key].sku_id == data.sku_id){
let key_data = key.split('_');
key_data[key_data.length-1] = index;
index ++;
tempGoodsData[key_data.join('_')] = _billingGoodsData[key];
}else{
tempGoodsData[key] =_billingGoodsData[key];
}
});
let goodsIds = [];
Object.keys(tempGoodsData).forEach(key => {
let item = tempGoodsData[key];
if (!item.item_id && goodsIds.indexOf(item.goods_id) == -1) goodsIds.push(item.goods_id);
});
this.$store.commit('billing/setGoodsIds', goodsIds);
this.$store.commit('billing/setGoodsData', tempGoodsData);
if (!Object.keys(tempGoodsData).length) {
this.$store.commit('billing/setOrderData', {
goods_list: [],
goods_num: 0,
pay_money: 0,
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000))
});
}
},
/**
* 商品数量增加
* @param {Object} data
*/
inc(data) {
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
if (data.card_item_id) {
let _data = _billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id];
if (_data.num >= data.stock) {
this.$util.showToast({
title: '商品库存不足'
});
return;
}
_billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id].num += 1;
} else {
var _data = _billingGoodsData[data.editKey];
if (_data.num >= data.stock) {
this.$util.showToast({
title: '商品库存不足'
});
return;
}
_billingGoodsData[data.editKey].num += 1;
}
this.$store.commit('billing/setGoodsData', _billingGoodsData);
},
/**
* 商品数量减少
* @param {Object} data
*/
dec(data) {
var _billingGoodsData = this.$util.deepClone(this.billingGoodsData);
if (data.card_item_id) {
let _data = _billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id];
if (_data.num == 1) return;
_billingGoodsData['sku_' + data.sku_id + '_item_' + data.card_item_id].num -= 1;
} else {
if (_billingGoodsData[data.editKey].num == 1) return;
_billingGoodsData[data.editKey].num -= 1;
}
this.$store.commit('billing/setGoodsData', _billingGoodsData);
},
/**
* 计算
*/
calculation() {
if (!Object.keys(this.billingGoodsData).length) {
this.$store.commit('billing/setOrderData', {
goods_num: 0
});
return;
}
let sku_array = [];
let goodsIds = [];
let editKeyData = {};
Object.keys(this.billingGoodsData).forEach(key => {
let item = this.billingGoodsData[key];
let skuData = {
sku_id: item.sku_id,
num: item.num,
card_item_id: item.item_id ? item.item_id : 0,
money: item.money ? item.money : 0 // 无码商品价格
};
if (item.is_adjust) {
skuData.price = item.price; // 手动调整价格
}
if (item.goods_money) skuData.goods_money = item.goods_money;
sku_array.push(skuData);
if (!item.item_id && goodsIds.indexOf(item.goods_id) == -1) goodsIds.push(item.goods_id);
//保存editKey数据
let editKeyIndex = skuData.sku_id+':'+skuData.card_item_id;
editKeyData[editKeyIndex] = key;
});
this.$store.commit('billing/setGoodsIds', goodsIds);
let data = {
sku_array: JSON.stringify(sku_array),
create_time: this.billingOrderData.create_time
};
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
calculate(data).then(res => {
if (res.code == 0) {
let calculateOrderData = res.data;
calculateOrderData.goods_list.forEach((item, index) => {
let editKeyIndex = item.sku_id+':'+(item.card_item_id||0);
item.editKey = editKeyData[editKeyIndex];
});
this.$store.commit('billing/setOrderData', calculateOrderData);
} else {
this.$util.showToast({
title: res.message
})
}
})
},
/**
* 挂单
*/
hangingOrder() {
if (Object.keys(this.billingGoodsData).length) {
let data = {
goods: [],
order_id: this.billingPendOrderId,
remark: this.billingOrderData.remark
};
if (this.globalMemberInfo) data.member_id = this.globalMemberInfo.member_id;
Object.keys(this.billingGoodsData).forEach(key => {
let item = this.billingGoodsData[key];
let skuData = {
goods_id: item.goods_id,
sku_id: item.sku_id,
num: item.num,
money: item.money ? item.money : 0 // 无码商品价格
};
if (item.is_adjust) {
skuData.price = item.price; // 手动调整价格
}
data.goods.push(skuData)
});
data.goods = JSON.stringify(data.goods);
let api = this.billingPendOrderId ? editPendOrder(data) : addPendOrder(data);
api.then(res => {
if (res.code == 0) {
this.wholeOrderCancel();
this.$refs.pendOrderPopup.getOrder(0);
} else {
this.$util.showToast({
title: res.message
})
}
})
} else if (this.pendOrderNum) {
this.$refs.pendOrderPopup.open();
} else {
this.$util.showToast({
title: '当前没有挂单'
})
}
},
/**
* 整单取消
*/
wholeOrderCancel(isInit = false,isDelete = false) {
if (Object.keys(this.billingGoodsData).length) {
// 恢复调价
for (let i = 0; i < this.$refs.goods.goodsData.list.length; i++) {
let item = this.$refs.goods.goodsData.list[i];
item.adjust_price = item.price;
item.adjust = {};
}
// 清除当前会员
this.$store.commit('app/setGlobalMemberInfo', null);
// 清除商品数据
this.$store.commit('billing/setGoodsData', {});
this.$store.commit('billing/setGoodsIds', []);
if (isDelete && this.billingPendOrderId) {
this.$refs.pendOrderPopup.deleteOrder(this.billingPendOrderId);
}
this.$store.commit('billing/setPendOrderId',0);
// 清除订单数据
this.$store.commit('billing/setOrderData', {
goods_num: 0,
pay_money: 0,
goods_list: [],
remark: '',
create_time: this.$util.timeFormat(parseInt(new Date().getTime() / 1000)),
order_id: 0
});
this.outTradeNo = '';
} else {
if (!isInit) this.$util.showToast({
title: '当前没有订单数据!!'
})
}
},
/**
* 支付
*/
pay(type = '', callback) {
const memberId = this.globalMemberInfo ? this.globalMemberInfo.member_id : 0;
if (this.$refs.payment) this.$refs.payment.clearPay();
if (!Object.keys(this.billingGoodsData).length || this.isRepeat) return;
this.isRepeat = true;
if (this.outTradeNo) {
this.type = 'pay';
if (type) this.$refs.payment.type = type;
return;
}
this.$store.commit('billing/setActive', 'OrderCreate'); // 记录页面活跃值:创建订单
let data = {
remark: this.billingOrderData.remark,
create_time: this.billingOrderData.create_time,
member_id: memberId,
order_key: this.billingOrderData.order_key
};
create(data).then(res => {
this.isRepeat = false;
if (res.code == 0) {
this.outTradeNo = res.data.out_trade_no;
this.type = 'pay';
if (type) this.$refs.payment.type = type;
setTimeout(() => {
if (callback) callback();
}, 100)
} else {
this.$util.showToast({
title: res.message,
})
}
})
},
cancelPayment() {
this.outTradeNo = '';
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
this.type = 'goods';
},
paySuccess() {
this.type = 'goods';
this.$store.commit('billing/setActive', '');
this.isRepeat = false;
this.wholeOrderCancel(false,true);
this.$refs.goods.getGoods();
},
// 调整商品价格,数量
callBox(data) {
//服务商品不支持修改
if(data.goods_class == this.$util.goodsClassDict.service) return;
if(data.card_item_id > 0) return;
data.status = 'edit'; // 调整商品标识
this.$refs.goods.goodsSelect(data);
},
/**
* 添加键盘监听事件
*/
addKeyDownEvent() {
// #ifdef H5
window.addEventListener("keydown", this.listenerKeyDown, true);
window.addEventListener("focus", this.listenerFocus, true);
// 监听F1~F12BACKSPACE
window.POS_HOTKEY_CALLBACK = (control, code) => {
this.posHotKeyCallback(code);
};
// #endif
},
/**
* 移除键盘监听事件
*/
removeKeyDownEvent() {
// #ifdef H5
window.removeEventListener("keydown", this.listenerKeyDown, true);
window.removeEventListener("focus", this.listenerFocus, true);
delete window.POS_HOTKEY_CALLBACK;
// #endif
},
// 监听焦点事件
listenerFocus(e) {
if (this.billingActive == 'OrderCreate') return;
let tab = {
// 聚焦 获取商品选择
TabGoodsFocus: {
className: 'goods-select-focus',
focusField: 'rightIndexFocus'
},
// 聚焦 获取订单结算商品
TabOrderFocus: {
className: 'settlement-select-focus',
focusField: 'leftIndexFocus'
}
};
for (let key in tab) {
if (e.target.className && e.target.className.indexOf(tab[key].className) != -1) {
this.leftIndexFocus = -1;
this.rightIndexFocus = -1;
for (let i = 0; i < e.target.attributes.length; i++) {
var item = e.target.attributes[i];
if (item.name == 'data-tab-index') {
this[tab[key].focusField] = parseInt(item.value);
break;
}
}
if (this[tab[key].focusField] > -1) {
this.$store.commit('billing/setActive', key);
}
}
}
},
// 监听键盘按下事件
listenerKeyDown(e) {
var code = e.code;
if (code == 'Tab') return;
// console.log('监听键盘按下事件 KeyDown', this.type, code, this.billingActive, this.billingIsScanTrigger, this.billingOrderData, e);
// 按键ESC解除占用
if (this.billingIsScanTrigger && code == 'Escape') this.$store.commit('billing/setIsScanTrigger', false);
// 正在输入商品编码 商品/项目名称
if (this.billingActive == 'inputSearchText') return;
// 关闭商品弹出框
if (code == 'Escape' && this.billingActive == 'SelectGoodsSku' && this.type == 'goods') {
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
return;
}
if (this.type != 'pay' && this.billingActive != 'SelectGoodsSku' && code == 'KeyM') {
// 选择会员键盘快捷键【M】
this.openMember();
} else if (this.type == 'goods' && code == 'PageUp') {
// 切换左侧焦点
this.$store.commit('billing/setActive', 'TabOrderFocus');
this.leftIndexFocus = 0;
this.rightIndexFocus = -1;
code = 'ArrowUp';
} else if (this.type == 'goods' && code == 'PageDown') {
// 切换右侧焦点
this.$store.commit('billing/setActive', 'TabGoodsFocus');
this.rightIndexFocus = 0;
this.leftIndexFocus = -1;
code = 'ArrowLeft';
} else if (this.billingActive == 'TabGoodsFocus') {
// 使用tab键聚焦选择商品
this.tabGoodsFocusCallback(code);
} else if (this.billingActive == 'TabOrderFocus') {
// 使用tab键聚焦获取订单结算商品
this.tabOrderFocusCallback(code);
} else if(this.billingActive == 'ShowMember' && this.memberSearchWayConfig.way == 'list'){
// 按照会员列表进行搜索
if (code == 'Enter' || code == 'NumpadEnter') {
if(this.$refs.selectMember.searchFinish && this.$refs.selectMember.memberId){
this.$refs.selectMember.getMemberInfo(this.$refs.selectMember.memberId);
}
}
} else if (this.billingActive == 'ShowMemberAfter' || (this.billingOrderData.goods_num && this.billingActive == 'SelectGoodsAfter' && !this.billingIsScanTrigger)) {
// 活跃窗口:设置会员后,选择完商品后
if (code == 'Enter' || code == 'NumpadEnter') {
this.pay('');
}
}
},
/**
* 监听键盘事件回调
* @param {Object} code
*/
posHotKeyCallback(code) {
// console.log('POS ${code} 按键', code, this.type);
if (code == 'F2') {
// 选择商品
if (this.type != 'pay') {
this.type = 'goods';
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
}
} else if (code == 'F3') {
// 挂/取单
if (this.type != 'pay') {
this.hangingOrder();
}
} else if (code == 'F4') {
// 选择会员
if (this.type != 'pay') {
this.showMember();
}
} else if (code == 'F12') {
// 整单取消
if (this.type != 'pay') {
this.wholeOrderCancel(false,true);
}
} else if (code == 'BACKSPACE') {
// 退格键
if (this.billingActive == 'UnnumberedGoods' && this.type == 'goods') {
if (this.$refs.goods) this.$refs.goods.deleteCode();
} else if (this.billingActive == 'OrderCreate') {
if (this.$refs.payment) {
if (this.$refs.payment.active == 'OpenMoneyPopup') {
this.$refs.payment.deleteCode();
}
}
}
} else if (code == 'X') {
// 打开钱箱快捷键Alt+X
this.openCashBox();
} else if (this.type == 'goods' && code == 'PAGEUP') {
// 切换左侧焦点
this.$store.commit('billing/setActive', 'TabOrderFocus');
this.leftIndexFocus = 0;
this.rightIndexFocus = -1;
this.tabOrderFocusCallback('ArrowUp');
} else if (this.type == 'goods' && code == 'PAGEDOWN') {
// 切换右侧焦点
this.$store.commit('billing/setActive', 'TabGoodsFocus');
this.rightIndexFocus = 0;
this.leftIndexFocus = -1;
this.tabGoodsFocusCallback('ArrowLeft');
} else {
// 触发左侧菜单按键回调
this.menuTriggerKeyCodeCallBack(code);
}
},
// 打开钱箱
openCashBox() {
try {
let data = {
message: '打开钱箱'
};
this.$pos.send('OpenCashBox', JSON.stringify(data));
} catch (e) {
console.log('打开钱箱异常', e)
}
},
/**
* 使用tab键聚焦选择商品 事件回调
* @param {string} code 按键代码
*/
tabGoodsFocusCallback(code) {
if (!this.$refs.goods) return;
let list = document.querySelectorAll(`.${this.$refs.goods.type}-focus.table-item`);
if (code == 'Enter' || code == 'NumpadEnter') {
if (this.$refs.goods.type == 'goods') {
// 添加实物商品
this.$refs.goods.goodsSelect(this.$refs.goods.goodsData.list[this.rightIndexFocus]);
} else if (this.$refs.goods.type == 'service') {
// 添加项目商品
this.$refs.goods.goodsSelect(this.$refs.goods.serviceData.list[this.rightIndexFocus]);
}
} else if (code == 'ArrowUp' && this.rightIndexFocus > -1) {
// 上箭头商品goods项目service
const query = uni.createSelectorQuery().in(this);
query.select(`.goods-container .list-wrap.${this.$refs.goods.type}`).boundingClientRect(data => {
this.rightIndexFocus -= Math.floor(data.width / 270); // 单个元素宽度270
// 超出,选择第一个
if (this.rightIndexFocus <= 0) this.rightIndexFocus = 0;
list[this.rightIndexFocus].focus();
}).exec();
} else if (code == 'ArrowDown' && this.rightIndexFocus > -1) {
// 下箭头商品goods项目service
const query = uni.createSelectorQuery().in(this);
query.select(`.goods-container .list-wrap.${this.$refs.goods.type}`).boundingClientRect(data => {
this.rightIndexFocus += Math.floor(data.width / 270); // 单个元素宽度270
// 超出,选择最后一个
if (this.rightIndexFocus >= list.length) this.rightIndexFocus = list.length - 1;
list[this.rightIndexFocus].focus();
}).exec();
} else if (code == 'ArrowRight' && this.rightIndexFocus > -1) {
// 右箭头
if (this.rightIndexFocus + 1 >= list.length) return;
this.rightIndexFocus++;
list[this.rightIndexFocus].focus();
} else if (code == 'ArrowLeft' && this.rightIndexFocus > -1) {
// 左箭头
if (this.rightIndexFocus <= 0) return;
this.rightIndexFocus--;
list[this.rightIndexFocus].focus();
}
},
/**
* 使用tab键聚焦 获取订单结算商品 事件回调
* @param {string} code 按键代码
*/
tabOrderFocusCallback(code) {
// 按键回车,弹框调整商品数量,注意,此时只能修改商品数量,不能更改规格
if (code == 'Enter' || code == 'NumpadEnter') {
if (this.billingOrderData.goods_list[this.leftIndexFocus]) {
let data = this.$util.deepClone(this.billingOrderData.goods_list[this.leftIndexFocus]);
data.status = 'edit'; // 修改商品数量标识
if (this.$refs.goods) this.$refs.goods.goodsSelect(data);
}
} else if (code == 'ArrowUp' && this.leftIndexFocus > -1) {
// 上箭头
let list = document.querySelectorAll(`.settlement-select-focus`);
if (this.leftIndexFocus <= 0) return;
this.leftIndexFocus--;
list[this.leftIndexFocus].focus();
} else if (code == 'ArrowDown' && this.leftIndexFocus > -1) {
// 下箭头
let list = document.querySelectorAll(`.settlement-select-focus`);
if (this.leftIndexFocus + 1 >= list.length) return;
this.leftIndexFocus++;
list[this.leftIndexFocus].focus();
} else if (code == 'Delete' && this.leftIndexFocus > -1) {
this.deleteGoods(this.billingOrderData.goods_list[this.leftIndexFocus], this.leftIndexFocus);
}
},
// 恢复焦点下标
restoreFocus() {
this.leftIndexFocus = -1;
this.rightIndexFocus = -1;
},
leftTabOrderSelectBlur(item){
this.$store.commit('billing/setActive', 'SelectGoodsAfter');
}
},
}