cashier-ipad/pagesOrder/pay-order/pay-order.vue

1432 lines
36 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="bg-gray min-page u-p-30 u-font-28">
<view class="u-p-t-60 u-p-b-60 u-text-center">
<view class="u-font-32">
<text class="price-fuhao"></text>
<text class="font-bold price">{{
orderCostSummary.finalPayAmount
}}</text>
</view>
<view class="u-m-t-10 color-999 old-price" v-if="orderCostSummary.merchantReduction.actualAmount">
<text class="">¥</text>
<text class=" ">{{ returnMerchantReductionBeforeMoney }}</text>
</view>
<view class="u-m-t-10 u-flex u-row-center color-main">
<view @click="discountShow">修改</view>
</view>
<view class="u-m-t-10 u-flex u-row-center color-main">
<view @click="chooseUser()">选择用户</view>
</view>
</view>
<view class="content bg-fff border-r-12">
<view class="u-p-l-26 u-p-r-26 card top u-m-t-30">
<view
class="border-bottom-dashed u-p-b-30 u-p-t-30"
v-if="orderCostSummary.newUserDiscount"
>
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between">
<view>新客立减</view>
<view class="color-red">
-¥{{ orderCostSummary.newUserDiscount }}
</view>
</view>
</view>
<view
class="border-bottom-dashed u-p-b-30 u-p-t-30"
v-if="orderCostSummary.vipDiscountAmount"
>
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between">
<view>会员折扣</view>
<view class="color-red">
-¥{{ orderCostSummary.vipDiscountAmount }}
</view>
</view>
</view>
<view
class="border-bottom-dashed u-p-b-30 u-p-t-30"
v-if="orderCostSummary.merchantReduction.actualAmount"
>
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between">
<view>商家减免</view>
<view class="color-red">
-¥{{ orderCostSummary.merchantReduction.actualAmount }}
</view>
</view>
</view>
<view
class="border-bottom-dashed u-p-b-30 u-p-t-30"
v-if="discountSaleAmount * 1 > 0"
>
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between">
<view>单品打折优惠</view>
<view class="color-red"> -¥{{ discountSaleAmount }} </view>
</view>
</view>
<view class="border-bottom-dashed u-p-b-30 u-p-t-30">
<view class="u-flex u-p-l-24 u-p-r-24 u-row-between" @click="toQuan">
<view>优惠券</view>
<view class="color-999 u-flex u-col-center">
<text v-if="orderCostSummary.couponDeductionAmount <= 0"
>选择优惠券</text
>
<text class="color-red" v-else>
-¥{{ orderCostSummary.couponDeductionAmount }}
</text>
<view class="u-flex u-col-center">
<uni-icons type="right" color="#999"></uni-icons>
</view>
</view>
</view>
</view>
<view
class="border-bottom u-p-b-30"
v-if="discount.value || accountPoints.sel"
>
<view
class="u-flex u-p-l-24 u-p-r-24 u-row-between u-p-t-30"
v-if="discount.value"
>
<view>服务员改价</view>
<view class="u-flex u-col-center">
<text style="color: rgb(255, 95, 46)"
>-¥{{ to2(discount.value) }}</text
>
</view>
</view>
<view
class="u-flex u-p-l-24 u-p-r-24 u-row-between u-p-t-30"
v-if="orderCostSummary.pointDeductionAmount && accountPoints.sel"
>
<view>积分抵扣</view>
<view class="u-flex u-col-center">
<text style="color: rgb(255, 95, 46)"
>-¥{{ orderCostSummary.pointDeductionAmount }}</text
>
</view>
</view>
</view>
</view>
<view class="bg-fff border-r-12">
<view class="u-p-t-30 u-p-l-50 u-p-r-50 card bottom">
<my-tabs :list="pays.list" v-model="pays.selIndex"></my-tabs>
<template v-if="pays.selIndex == 0">
<view class="list">
<view
class="item"
@click="changePayType(index, item)"
:class="{ disabled: item.disabled }"
v-for="(item, index) in pays.payTypes.list"
:key="index"
>
<view
class="u-flex u-row-between u-p-t-30 u-p-b-30 border-bottom"
>
<view class="u-flex">
<image class="icon" :src="item.icon" mode=""></image>
<text class="u-m-l-10 no-wrap">{{ item.payName }}</text>
</view>
<view class="u-flex color-999 u-font-24">
<view
class="u-m-r-20"
v-if="item.payType == 'arrears' && pageData.buyer.id"
@click.stop="chooseBuyer"
>
<view>
<text>挂账人:</text>
<text class="u-m-r-4">{{ pageData.buyer.debtor }}</text>
</view>
<view>
<text>挂账额度:</text>
<text
>¥{{ pageData.buyer.remainingAmount || "0" }}</text
>
</view>
</view>
<view
class="u-m-r-20"
v-if="
item.payType == 'member-account' && pageData.user.id
"
@click.stop="chooseUser"
>
<view>
<text>会员:</text>
<text class="u-m-r-4">{{
pageData.user.phone || pageData.user.nickName
}}</text>
</view>
<view>
<text>余额:</text>
<text>¥{{ pageData.user.amount || "0" }}</text>
</view>
<!-- <view>
<text>积分:</text>
<text>{{user.accountPoints||'0'}}</text>
</view> -->
</view>
<view :class="{ op3: item.disabled }">
<my-radio
@click="changePayType(index, item)"
:modelValue="index == pays.payTypes.selIndex"
>
</my-radio>
</view>
</view>
</view>
</view>
</view>
<view class="border-bottom-dashed"></view>
<view
class="u-flex u-row-between u-p-t-24"
v-if="pageData.user.id"
@click="changeAccountPoints"
>
<view class="u-flex">
<view class="">积分抵扣</view>
<view class="color-999 u-m-l-10">
<text>(</text>
<text>{{ pageData.user.accountPoints || "0" }}</text>
<text>)</text>
</view>
<!-- <view><text class="color-red font-bold">{{accountPoints.price}}</text>元</view> -->
</view>
<view class="u-flex">
<view class="u-flex">
<view
><text>{{ accountPoints.num }}</text></view
>
<view
v-if="accountPoints.calcRes.usable"
@click.stop="refPointsOpen"
>
<up-icon name="edit-pen" size="16" color="#999"></up-icon>
</view>
</view>
<view
class="u-m-l-32 u-relative"
v-if="accountPoints.calcRes.usable"
>
<view class="u-absolute position-all"></view>
<my-radio :modelValue="accountPoints.sel"> </my-radio>
</view>
</view>
</view>
<view class="color-999 u-font-24 u-m-t-16">
<view class="" v-if="accountPoints.calcRes.unusableReason">
<text class="color-red">*</text>
<text>{{ accountPoints.calcRes.unusableReason }}</text>
</view>
<view class="" v-if="accountPoints.calcRes.usable">
<text class="color-red">*</text>
<text class="" v-if="accountPoints.calcRes.equivalentPoints"
>100积分等于{{
to2(accountPoints.calcRes.equivalentPoints * 100)
}}元,</text
>
<text>
最大抵扣积分{{ accountPoints.calcRes.maxUsablePoints }}
</text>
<text>, 最小抵扣积分0 </text>
</view>
</view>
<view class="u-m-t-60 u-p-b-30">
<my-button @click="payOrderClick">确认付款</my-button>
</view>
</template>
<template v-if="pays.selIndex == 1">
<view class="u-font-32 u-m-t-40 u-text-center"
>请让顾客使用微信/支付宝扫码</view
>
<view class="u-flex u-row-center u-m-t-40">
<up-qrcode cid="code" :size="140" :val="payCodeUrl"></up-qrcode>
</view>
</template>
</view>
<!-- 二维码支付扫码 -->
<template v-if="pays.selIndex == 1">
<view class="card border-bottom top u-m-t-32"> </view>
<view class="bg-fff card bottom border-r-12 u-p-32">
<view class="font-bold u-font-32 u-text-center">
¥{{ payPrice }}</view
>
<view class="u-flex u-row-center u-m-t-24">
<template v-if="order.status == 'unpaid'">
<up-loading-icon size="14" text="等待支付"></up-loading-icon>
</template>
<template v-if="order.status == 'done'">
<view class="u-flex pay-success">
<up-icon
color="#5CBB6F"
name="checkmark-circle-fill"
></up-icon>
<view class="u-m-l-6">支付成功</view>
</view>
</template>
</view>
</view>
</template>
</view>
</view>
<edit-discount
@confirm="editDiscountConfirm"
title="优惠金额"
:ref="setModel"
name="editMoney"
:price="returnMerchantReductionBeforeMoney"
:discount="discount.discount"
></edit-discount>
<up-modal
:title="modal.title"
:content="modal.content"
:show="modal.show"
:confirmText="modal.confirmText"
:cancelText="modal.cancelText"
showCancelButton
closeOnClickOverlay
@confirm="confirmModelConfirm"
@cancel="confirmModelCancel"
@close="confirmModelCancel"
width="300px"
/>
<edit-accountPoints
@confirm="pointsConfirm"
:price="accountPoints.num"
:accountPoints="accountPoints"
ref="refPoints"
></edit-accountPoints>
</view>
</template>
<script setup>
import {
reactive,
onMounted,
watch,
ref,
onBeforeUnmount,
computed,
inject,
} from "vue";
import { onLoad, onBackPress, onShow } from "@dcloudio/uni-app";
import BigNumber from "bignumber.js";
import go from "@/commons/utils/go.js";
import infoBox from "@/commons/utils/infoBox.js";
import { hasPermission } from "@/commons/utils/hasPermission.js";
import editDiscount from "@/components/my-components/edit-discount.vue";
import editAccountPoints from "./components/edit-accountPoints.vue";
import {
returnGoodsPayPriceMap,
returnProCoupStartIndex,
returnProductCoupAllPrice,
returnProductCanUseNum,
} from "../quan_util.js";
import { mathFloorPrice } from "@/commons/utils/goodsUtil.js";
import { getDiscountByUserId } from "@/http/yskApi/market/consumeDiscount.js";
// import { getCouponList } from '@/http/api/coupon.js'
import { getHistoryOrder } from "@/http/api/order.js";
import { getPayTypeList } from "@/http/api/payType.js";
import { shopUserDetail } from "@/http/api/shopUser.js";
import {
scanPay,
microPay,
cashPay,
vipPay,
creditPay,
getOrderPayUrl,
queryOrderStatus,
} from "@/http/api/pay.js";
import {
calcUsablePoints,
calcDeductionAmount,
payedDeductPoints,
consumeAwardPoints,
} from "@/http/api/points.js";
import yskUtils from "ysk-utils";
const websocketUtil = inject("websocketUtil"); // 注入 WebSocket 工具类实例
const modal = reactive({
title: "提示",
cancelText: "取消",
confirmText: "确认",
content: "",
key: "cash",
show: false,
data: "",
});
const pageData = reactive({
goodsList: [], //菜品列表
user: {
//会员信息
userId: null,
amount: 0,
},
shopInfo: uni.getStorageSync("shopInfo"),
buyer: {},
payUrlShow: false,
});
const order = reactive({
orderAmount: 0,
});
//商品数量从0到n每一个对应的价格
let $goodsPayPriceMap = {};
const pays = reactive({
list: ["扫码收款", "二维码收款"],
selIndex: 0,
payTypes: {
list: [],
selIndex: 0,
},
quan: [],
seatNum: 0,
});
//打折相关数据
const discount = reactive({
discount: 100,
currentPrice: 0,
value: 0,
});
const accountPoints = reactive({
sel: false,
num: 0,
calcRes: {
usable: false,
unusableReason: "",
minDeductionPoints: 0,
maxUsablePoints: 0,
},
price: 0,
});
let timer = null;
const refPoints = ref(null);
let payCodeUrl = ref(""); //收款二维码地址
onShow(() => {
watchChooseuser();
watchChoosebuyer();
watchChooseQuan();
});
const options = reactive({});
onLoad(async (opt) => {
Object.assign(order, opt);
Object.assign(options, opt);
getPayType();
init();
});
onBeforeUnmount(() => {
clearInterval(timer);
timer = null;
});
onBackPress(() => {
uni.$emit("orderDetail:update");
console.log("onBackPress");
});
function toDiancai() {
setTimeout(() => {
go.to("PAGES_CREATE_ORDER", {}, "redirect");
}, 1500);
}
/**
* 初始化
*/
async function init() {
// 获取订单详情
const { data: orderRes } = await getHistoryOrder({ orderId: order.orderId });
if (orderRes.status == "cancelled") {
uni.showToast({
title: "订单已取消",
icon: "none",
});
toDiancai();
return;
}
if (orderRes.status == "done") {
uni.showToast({
title: "订单已完成",
icon: "none",
});
toDiancai();
return;
}
Object.assign(order, orderRes);
pageData.goodsList = objToArrary(orderRes.detailMap);
$goodsPayPriceMap = returnGoodsPayPriceMap(pageData.goodsList);
// console.log("order===",order)
// console.log("pageData.user===",pageData.user)
// 获取用户信息
if (order.userId || pageData.user.userId) {
shopUserDetail({
userId: order.userId || pageData.user.userId,
}).then((res) => {
if (res.code == 200) {
pageData.user = res.data;
getCalcUsablePoints();
if (orderRes.pointsNum) {
accountPoints.sel = true;
}
}
});
}
pageData.seatNum = order.seatNum;
}
/**
* 判断是否是会员
*/
const isVip = computed(() => {
return (
uni.getStorageSync("shopInfo").isMemberPrice &&
pageData.user &&
pageData.user.id &&
pageData.user.isVip
);
});
const coupAllPrice = computed(() => {
const n = pays.quan.reduce((prve, cur) => {
return prve + cur.discountAmount * 1;
}, 0);
return n;
});
/**
* 菜品打包费
*/
const packAmount = computed(() => {
if (pageData.goodsList) {
let price = pageData.goodsList
.filter((v) => v.packNumber > 0 && v.status !== "return")
.reduce((a, b) => {
console.log(b);
return a + ((b.packAmount || 0) * b.packNumber).toFixed(2) * 1;
}, 0);
// console.log("菜品打包费===",price)
return price;
}
});
/**
* 桌位费
*/
const tableFee = computed(() => {
// console.log("桌位费===", order.seatNum > 0 ? order.seatNum*pageData.shopInfo.tableFee : 0)
return order.seatNum > 0 ? order.seatNum * pageData.shopInfo.tableFee : 0;
});
/**
* 菜品金额
*/
const originPrice = computed(() => {
if (pageData.goodsList) {
let goodsPrice = pageData.goodsList
.filter((v) => v.price != 0 && v.status !== "return")
.reduce((a, b) => {
return a + parseFloat(mathFloorPrice(b.num * b.price, b));
}, 0);
// console.log("菜品原金额===",goodsPrice)
return (
parseFloat(goodsPrice) +
parseFloat(tableFee.value) +
parseFloat(packAmount.value)
).toFixed(2);
}
});
const newOriginPrice = computed(() => {
if (pageData.goodsList) {
let goodsPrice = pageData.goodsList
.filter((v) => v.price != 0 && v.status !== "return")
.reduce((a, b) => {
let memberPrice = b.memberPrice ? b.memberPrice : b.price;
let tPrice = isVip.value ? memberPrice : b.price;
tPrice = b.discountSaleAmount ? b.discountSaleAmount : tPrice;
return (
a +
parseFloat(
mathFloorPrice(b.num * tPrice, b) * 1 -
mathFloorPrice(b.returnNum * tPrice, b) * 1 -
mathFloorPrice(b.refundNum * tPrice, b) * 1
)
);
}, 0);
// console.log("减去退款退费的菜品金额===",goodsPrice)
return (goodsPrice + tableFee.value + packAmount.value).toFixed(2);
}
});
/**
* 菜品折扣金额
*/
const discountSaleAmount = computed(() => {
if (pageData.goodsList) {
let price = pageData.goodsList
.filter((v) => v.discountSaleAmount > 0 && v.status !== "return")
.reduce((a, b) => {
return a + (b.num * b.price - b.num * b.discountSaleAmount);
}, 0);
// console.log("单品折扣金额====",price)
return price.toFixed(2);
}
});
/**
* 优惠券金额
*/
const fullCouponDiscountAmount = computed(() => {
return pays.quan
.filter((v) => v.type == 1)
.reduce((prve, cur) => {
// console.log("优惠券金额",prve + cur.discountAmount * 1)
return prve + cur.discountAmount * 1;
}, 0);
});
/**
* 商品券金额
*/
const productCouponDiscountAmount = computed(() => {
return pays.quan
.filter((v) => v.type == 2)
.reduce((prve, cur) => {
return prve + cur.discountAmount * 1;
}, 0);
});
// 计算商家减免前金额使用bignumber.js确保精度
const returnMerchantReductionBeforeMoney = computed(() => {
const total = BigNumber(orderCostSummary.value.finalPayAmount).plus(
orderCostSummary.value.merchantReduction.actualAmount
);
// 确保结果不小于0返回数字类型
return total.lte(0) ? 0 : total.toNumber();
});
//选择的优惠券
const selCoupon = ref([]);
//活动列表
const activityList = ref([]);
// 商家减免,初始配置:默认无减免(固定金额 0 元)
const merchantReductionConfig = reactive({
type: "fixed_amount",
fixedAmount: 0,
});
//积分规则
const pointDeductionRule = reactive({
pointsPerYuan: 0,
maxDeductionAmount: Infinity,
});
//餐费费
const seatFeeConfig = reactive({
pricePerPerson: pageData.shopInfo.tableFee || 0,
personCount: 0, //就餐人数
isEnabled: !pageData.shopInfo.isTableFee,
});
//使用积分数量
const userPoints = ref(0);
//是否使用会员价
const useVipPrice = computed(() => {
console.log("pageData.shopInfo", pageData.shopInfo);
if (pageData.shopInfo.isMemberPrice == 1 && pageData.user.isVip == 1) {
return true;
}
return false;
});
//新客立减
const newUserDiscount = ref(0);
//满减活动
const fullReductionActivities = ref([]);
// 商家霸王餐配置
const freeDineConfig = ref(null);
//店铺用户
const shopUserInfo = ref({});
//限时折扣
const limitTimeDiscount = ref(null);
// const orderExtraConfig = reactive({
// // 引用扩展后的商家减免配置
// merchantReduction: merchantReductionConfig,
// additionalFee: 0,
// pointDeductionRule: pointDeductionRule,
// seatFeeConfig: seatFeeConfig,
// currentStoreId: "",
// userPoints: userPoints.value,
// isMember: useVipPrice.value,
// memberDiscountRate: 1,
// newUserDiscount: newUserDiscount.value,
// fullReductionActivities: fullReductionActivities.value,
// currentDinnerType: options.dinnerType,
// isFreeDine: false, //霸王餐
// freeDineConfig: freeDineConfig.value,
// limitTimeDiscount: order.limitRate,
// shopUserInfo: shopUserInfo.value,
// });
const orderExtraConfig = computed(() => {
return {
// 引用扩展后的商家减免配置
merchantReduction: merchantReductionConfig,
additionalFee: 0,
pointDeductionRule: pointDeductionRule,
seatFeeConfig: seatFeeConfig,
currentStoreId: "",
userPoints: userPoints.value,
isMember: useVipPrice.value,
memberDiscountRate: 1,
newUserDiscount: newUserDiscount.value,
fullReductionActivities: fullReductionActivities.value,
currentDinnerType: options.dinnerType,
isFreeDine: false, //霸王餐
freeDineConfig: freeDineConfig.value,
limitTimeDiscount: order.limitRate,
shopUserInfo: pageData.user,
};
});
// 订单费用汇总
const orderCostSummary = computed(() => {
const costSummary = yskUtils.OrderPriceCalculator.calculateOrderCostSummary(
pageData.goodsList,
options.dinnerType,
selCoupon.value,
activityList.value,
orderExtraConfig.value,
{},
new Date()
);
console.log(" 订单费用汇总", costSummary);
return costSummary;
});
//积分可抵扣最大金额
const pointsCanDicountMaxMoney = computed(() => {
const maxMoney =
orderCostSummary.value.finalPayAmount +
orderCostSummary.value.pointDeductionAmount;
console.log("pointsCanDicountMaxMoney.value", maxMoney);
return maxMoney;
});
/**
* 支付金额
*/
const payPrice = computed(() => {
return orderCostSummary.value.finalPayAmount;
});
watch(
() => accountPoints.sel,
(newval) => {
if (newval) {
userPoints.value = accountPoints.num;
} else {
userPoints.value = 0;
}
}
);
watch(
() => accountPoints.num,
(newval) => {
if (accountPoints.sel) {
userPoints.value = newval;
}
}
);
watch(
() => pointsCanDicountMaxMoney.value,
(newval) => {
if (pageData.user.id) {
getCalcUsablePoints();
}
}
);
watch(
() => payPrice.value,
(newval) => {
if (pageData.payUrlShow) {
setTimeout(() => {
getPayUrl();
});
}
if (newval <= 0) {
const arr = ["cash", "member-account"];
pays.payTypes.list.map((v) => {
if (arr.includes(v.payType)) {
v.disabled = false;
} else {
v.disabled = true;
}
});
const index = pays.payTypes.list.findIndex((v) => !v.disabled);
pays.payTypes.selIndex = index;
} else {
pays.payTypes.list.map((v) => {
v.disabled = false;
});
}
}
);
watch(
() => pays.selIndex,
(newval) => {
clearInterval(timer);
if (newval) {
timer = setInterval(() => {
getHistoryOrder({ orderId: order.orderId }).then((res) => {
order.status = res.status;
if (res.status == "done") {
paySuccess();
}
});
}, 2000);
if (newval == 1) {
getPayUrl();
}
}
}
);
function getPayParam() {
let params = {
shopId: uni.getStorageSync("shopId"),
orderId: order.id,
originAmount: orderCostSummary.value.goodsRealAmount, //订单原金额(不包含打包费+餐位费)
discountRatio: 1,
discountAmount: orderCostSummary.value.merchantReduction.actualAmount, //手动优惠金额
productCouponDiscountAmount: orderCostSummary.value.productCouponDeduction, //商品优惠券抵扣金额
otherCouponDiscountAmount: orderCostSummary.value.fullCouponDeduction, //其他优惠券抵扣金额
couponList: selCoupon.value.map((v) => v.id), //用户使用的卡券
orderAmount: orderCostSummary.value.finalPayAmount, // 订单金额
roundAmount: 0, //抹零金额 减免多少钱
pointsDiscountAmount: orderCostSummary.value.pointDeductionAmount, //积分抵扣金额(tb_points_basic_setting表)
pointsNum: orderCostSummary.value.pointUsed, //(扣除各类折扣 enable_deduction后使用)
seatNum: options.dinnerType == "dine-in" ? seatFeeConfig.personCount : 0, //用餐人数
newCustomerDiscountAmount: orderCostSummary.value.newUserDiscount, //新客立减
newCustomerDiscountId:
orderCostSummary.value.newUserDiscount > 0
? cartStore.consumeDiscount.id
: "",
discountActAmount: orderCostSummary.value.fullReduction.actualAmount, //满减抵扣金额
discountActId: orderCostSummary.value.fullReduction.usedActivity
? orderCostSummary.value.fullReduction.usedActivity.id
: null,
vipPrice: orderCostSummary.value.vipDiscountAmount != 0 ? 1 : 0, // 是否使用会员价
limitRate:
order.limitRate && order.limitRate.id
? {
id: order.limitRate.id,
discountRate: order.limitRate.discountRate,
discountPriority: order.limitRate.discountPriority,
foodType: order.limitRate.foodType,
foods: order.limitRate.foods,
}
: null,
vipDiscountAmount: orderCostSummary.value.vipDiscountAmount, //会员折扣减免金额
};
if (pays.quan.length > 0) {
pays.quan.forEach((v) => {
params.couponList.push(v.id);
});
}
params.couponList = params.couponList.join(",");
// params.couponList = JSON.stringify(params.couponList)
return params;
}
/**
* 获取店铺订单支付URL
*/
function getPayUrl() {
console.log("支付参数 ===", getPayParam());
let par = getPayParam();
let params = {
shopId: uni.getStorageSync("shopId"),
...par,
};
if (order.userId || pageData.user.userId) {
params.userId = order.userId || pageData.user.userId;
}
delete params.limitRate;
getOrderPayUrl(params).then((res) => {
console.log(res, "tishi");
payCodeUrl.value = res.data;
pageData.payUrlShow = true;
});
}
/**
* 获取支付方式
*/
async function getPayType() {
const payTypeList = await getPayTypeList();
pays.payTypes.list = [];
payTypeList.data.map((v) => {
if (v.payType != "bank") {
pays.payTypes.list.push({
...v,
disabled: false,
});
}
});
}
/**
* 设置优惠券/商品券
* @param {Object} arr
*/
function setQuan(arr) {
selCoupon.value = arr;
console.log("赋值优惠券", arr);
}
/**
* 积分选择
*/
function refPointsOpen() {
if (!accountPoints.calcRes.usable && accountPoints.sel) {
return;
}
refPoints.value.open();
}
/**
* 积分确认
* @param {Object} e
*/
function pointsConfirm(e) {
accountPoints.num = e;
}
/**
* 获取积分信息
* @param {Object} orderAmount
*/
async function getCalcUsablePoints() {
if (!pageData.user.userId) {
return;
}
const res = await calcUsablePoints({
shopUserId: pageData.user.id,
orderAmount: pointsCanDicountMaxMoney.value,
});
console.log("getCalcUsablePoints", res.data);
pointDeductionRule.pointsPerYuan = res.data.equivalentPoints;
pointDeductionRule.maxDeductionAmount = res.data.maxDeductionAmount;
accountPoints.calcRes = res.data;
accountPoints.num = res.data.maxUsablePoints;
return res;
}
function changeAccountPoints() {
if (!accountPoints.calcRes.usable) {
return;
}
accountPoints.sel = !accountPoints.sel;
if (!accountPoints.sel) {
accountPoints.num = 0;
}
}
/**
* 选择优惠券
*/
function toQuan() {
console.log("toQuan", order);
console.log("pageData.user", pageData.user);
if (!order.userId && !pageData.user.id) {
return infoBox.showToast("请先选择会员", 0.5).then(() => {
chooseUser();
});
}
go.to("PAGES_ORDER_QUAN", {
orderId: order.id,
shopUserId: pageData.user.id,
orderPrice: (payPrice.value * 1 + coupAllPrice.value * 1).toFixed(2),
});
}
/**
* 判断是否可以修改金额
*/
async function discountShow() {
const bol = await hasPermission("yun_xu_da_zhe");
if (bol) {
showModel("editMoney", true);
}
}
/**
* 积分金额处理
* @param {Object} n
*/
function to2(n) {
if (!n) {
return "";
}
return Number(n).toFixed(2);
}
/**
* 优惠券选择
*/
function watchChooseQuan() {
uni.$off("selCoupon");
uni.$on("selCoupon", function (data) {
setQuan(data);
});
}
/**
* 删除优惠券
* @param {Object} i
*/
function delQuan(i) {
pays.quan.splice(i, 1);
discount.discount = 100;
discount.value = 0;
}
/**
* 选择用户
*/
function chooseUser() {
go.to("PAGES_CHOOSE_USER");
}
/**
* 更新选择用户
*/
function watchChooseuser() {
uni.$off("choose-user");
uni.$on("choose-user", (data) => {
if(pageData.user.id!=data.id){
selCoupon.value=[]
accountPoints.sel=false;
}
pageData.user = data;
if(data.id){
getNewUserDiscount()
}
init();
});
}
//获取用户新客立减
function getNewUserDiscount(){
getDiscountByUserId({
shopUserId: pageData.user.id
}).then(res=>{
if(res.data){
newUserDiscount.value=res.data.amount||0
}
})
}
/**
* 选择挂账人
*/
function chooseBuyer() {
go.to("PAGES_CHOOSE_BUYER");
}
/**
* 更新选择挂账人
*/
function watchChoosebuyer() {
uni.$off("choose-buyer");
uni.$on("choose-buyer", (data) => {
pageData.buyer = data;
});
}
/**
* 修改价格确认
* @param {Object} form
*/
function editDiscountConfirm(form) {
accountPoints.sel = false;
console.log(form);
const discount = BigNumber(returnMerchantReductionBeforeMoney.value)
.minus(form.currentPrice)
.toNumber();
merchantReductionConfig.fixedAmount = discount;
}
/**
* 支付方式选择
* @param {Object} i
* @param {Object} item
*/
function changePayType(i, item) {
if (item.disabled) {
return infoBox.showToast(item.payName + "不可用");
}
pays.payTypes.selIndex = i;
if (item.payType == "member-account" && !pageData.user.id) {
chooseUser();
}
if (item.payType == "arrears" && !pageData.buyer.id) {
chooseBuyer();
}
}
const models = new Map();
function setModel(el) {
if (el && el.$attrs["name"]) {
models.set(el.$attrs["name"], el);
}
}
function showModel(key) {
const model = models.get(key);
model && model.open();
}
let payStatus = "";
/**
* 确认付款
*/
const tipsMap = {
paying: "支付中",
success: "已支付成功",
};
function payOrderClick() {
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType;
if (payType == "scanCode" || payType == "deposit") {
return saomaPay(payType);
}
if (payType == "cash" && payPrice.value * 1 > 0) {
return cashConfirmShow();
}
if (
payType == "arrears" &&
pageData.buyer.remainingAmount < payPrice.value * 1
) {
return infoBox.showToast("挂账额度不足");
}
if (
payType == "member-account" &&
pageData.user.amount * 1 < payPrice.value * 1
) {
return infoBox.showToast("余额不足");
}
if (payStatus) {
return infoBox.showToast(tipsMap[payStatus]);
}
try {
pay();
} catch (e) {
//TODO handle the exception
payStatus = "";
}
}
/**
* 支付调佣
* @param {Object} par
*/
async function pay(par) {
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType;
let pars = getPayParam();
payStatus = "paying";
let params = {
shopId: uni.getStorageSync("shopId"),
checkOrderPay: {
...pars,
},
...par,
};
if (order.userId || pageData.user.userId) {
params.checkOrderPay.userId = order.userId || pageData.user.userId;
}
if (payType == "arrears") {
params.creditBuyerId = pageData.buyer.id;
}
let payRes = null;
try {
if (payType == "scanCode") {
payRes = await microPay(params);
}
if (payType == "cash") {
payRes = await cashPay(params);
}
if (payType == "arrears") {
payRes = await creditPay(params);
}
if (payType == "member-account" || payType == "deposit") {
if (pageData.user.amount * 1 >= payPrice.value * 1) {
params.payType = "userPay";
params.shopUserId = pageData.user.id;
payRes = await vipPay(params);
} else {
infoBox.showToast("余额不足");
return;
}
}
} catch (error) {
console.log(error);
let res;
let timer;
if (error.code == 211 && error.msg == "等待用户付款") {
uni.showLoading({
title: "支付中...",
});
timer = setInterval(async () => {
res = await queryOrderStatus({ orderId: pars.orderId });
if (res == "done") {
clearInterval(timer);
uni.hideLoading();
paySuccess();
}
console.log(res);
}, 1000);
}
if (error.code == 701) {
uni.removeStorageSync("table_code");
uni.navigateBack();
}
payStatus = "";
return false;
}
console.log(payRes);
if (payRes && payRes.code == 200) {
paySuccess();
} else {
uni.showToast({
title: payRes.msg || "支付失败",
icon: "none",
});
}
}
/**
* 支付成功回调
*/
function paySuccess() {
infoBox.showToast("支付成功");
payStatus = "success";
setTimeout(() => {
// uni.$emit('orderDetail:update')
uni.$emit("get:table");
uni.$emit("update:orderDetail");
uni.navigateBack({
delta: 1,
});
websocketUtil.send(
JSON.stringify({
type: "onboc",
account: uni.getStorageSync("iToken").loginId,
shop_id: uni.getStorageSync("shopId"),
operate_type: "cleanup",
table_code: order.tableCode,
})
);
}, 1500);
}
/**
* 弹窗关闭
*/
function confirmModelCancel() {
if (modal.key == "fullCoupon") {
// 取消改价
discount.discount = 100;
discount.value = 0;
}
modal.show = false;
modal.key = "";
modal.data = "";
}
/**
* 弹窗确认
*/
async function confirmModelConfirm() {
if (modal.key == "cash") {
await pay();
confirmModelCancel();
return;
}
if (modal.key == "fullCoupon") {
//删除满减券
const index = pays.quan.findIndex((v) => v.type == 1);
pays.quan.splice(index, 1);
return;
}
}
function objToArrary(obj) {
if (Object.values(obj) && Array.isArray(Object.values(obj)[0])) {
// 是数组
let arr = [];
Object.values(obj).forEach((item) => {
item.map((v) => {
v.salePrice = v.salePrice ? v.salePrice : v.price;
v.number = v.num;
return v;
});
arr = [...arr, ...item];
});
return arr;
} else {
// 不是数组
return Object.keys(obj).map((key) => {
return obj[key];
});
}
}
/**
* 扫码/储值卡支付
*/
function saomaPay() {
const item = pays.payTypes.list[pays.payTypes.selIndex];
uni.scanCode({
onlyFromCamera: true,
success: function (res) {
console.log("条码类型:" + res.scanType);
console.log("条码内容:" + res.result);
pay({
authCode: res.result,
});
},
});
}
/**
* 现金支付唤起
*/
function cashConfirmShow() {
modal.content = "是否确认已现金收款" + payPrice.value;
modal.key = "cash";
modal.show = true;
}
</script>
<style lang="scss" scoped>
$quan-color: #318afe;
.op3 {
opacity: 0.3;
}
.hui {
// background-color: $quan-color;
background-image: linear-gradient(
to right bottom,
rgb(254, 103, 4),
rgb(241, 50, 42)
);
padding: 4rpx 10rpx;
border-radius: 10rpx;
font-size: 24rpx;
color: #fff;
}
.box-shadow {
box-shadow: 0 0 5px #e5e5e5;
}
.pay-success {
color: #5cbb6f;
}
.icon {
width: 40rpx;
height: 40rpx;
}
.border-bottom-dashed {
border-bottom: 1px dashed #bbb;
}
.border-bottom {
border-color: rgb(240, 240, 240);
}
.list {
.item {
&.disabled {
color: #999;
}
}
.item:last-child {
.border-bottom {
border-bottom: none;
}
}
}
.old-price {
text-decoration: line-through;
}
.price-fuhao {
font-size: 24px;
}
.price {
font-size: 32px;
}
$dotSize: 20rpx;
$position: calc($dotSize / (-2));
.card {
position: relative;
&::after,
&:before {
content: "";
display: block;
position: absolute;
background-color: #f9f9f9;
width: $dotSize;
height: $dotSize;
border-radius: 50%;
}
&.top {
&::after {
right: $position;
bottom: $position;
}
&:before {
left: $position;
bottom: $position;
}
}
&.bottom {
&::after {
right: $position;
top: $position;
}
&:before {
left: $position;
top: $position;
}
}
}
</style>