feat: 代客下单更新,修复店铺列表编辑展示问题

This commit is contained in:
2025-03-04 10:34:19 +08:00
parent b71ca19c0d
commit bd59f05d26
19 changed files with 953 additions and 312 deletions

View File

@@ -46,7 +46,7 @@
<div class="note" v-if="item.remark">备注:{{ item.remark }}</div>
<div class="note flex" v-else>
<span>备注:</span>
<el-icon @click="editNote" color="#999"><EditPen /></el-icon>
<el-icon v-if="!isOld" @click="editNote" color="#999"><EditPen /></el-icon>
</div>
</div>
<div class="note" v-if="placeNum != 0 && item.note">备注:{{ item.remark || "" }}</div>
@@ -83,22 +83,26 @@
<div>0</div>
<div class="free-price">
<span v-if="isSeatFee">{{ to2(item.totalAmount) }}</span>
<span v-else>{{ to2(isShowVipPrice ? vipAllPrice : allPrice) }}</span>
<span v-else>{{ to2(useVipPrice ? vipAllPrice : allPrice) }}</span>
</div>
</template>
<template v-else-if="item.discountSaleAmount">
<div>{{ discountNewPrice }}</div>
<!-- 单品改价 -->
<template
v-else-if="item.discount_sale_amount * 1 > 0 && discount_before_price != allPrice"
>
<div>{{ to2(allPrice) }}</div>
<div class="free-price">
<span>{{ to2(isShowVipPrice ? vipAllPrice : allPrice) }}</span>
<span>{{ to2(discount_before_price) }}</span>
</div>
</template>
<template v-else>
<div v-if="isSeatFee">{{ to2(item.totalAmount) }}</div>
<div v-else>
<div v-if="isShowVipPrice && vipAllPrice != allPrice">{{ vipAllPrice }}</div>
<div>
<div v-if="useVipPrice && vipAllPrice * 1 != allPrice * 1">
{{ to2(vipAllPrice) }}
</div>
<div
:class="{
'free-price': isShowVipPrice && vipAllPrice != allPrice,
'free-price': useVipPrice && vipAllPrice != allPrice,
}"
>
<span>{{ to2(allPrice) }}</span>
@@ -116,10 +120,6 @@ const props = defineProps({
type: Boolean,
default: false,
},
isShowVipPrice: {
type: Boolean,
default: false,
},
//是否是餐位费
isSeatFee: {
type: Boolean,
@@ -180,9 +180,13 @@ const discountNewPrice = computed(() => {
return 0;
});
const vipAllPrice = computed(() => {
return 0;
const n = (props.item.memberPrice || props.item.salePrice) * props.item.number;
return n;
});
const allPrice = computed(() => {
if (props.item.discount_sale_amount * 1 > 0) {
return props.item.discount_sale_amount * props.item.number;
}
if (props.useVipPrice) {
const memberPrice = props.item.memberPrice || props.item.salePrice;
return memberPrice * props.item.number;
@@ -195,7 +199,12 @@ const allPrice = computed(() => {
}
return props.item.number * props.item.salePrice;
});
const discount_before_price = computed(() => {
if (props.useVipPrice) {
return props.item.number * (props.item.memberPrice || props.item.salePrice);
}
return props.item.number * props.item.salePrice;
});
const isActive = computed(() => {
return props.item.id == props.selCart.id ? "active" : "";
});

View File

@@ -14,6 +14,20 @@
></carts-item>
</div>
</template>
<!-- 赠菜 -->
<div class="cart-title" v-if="carts.giftList.length > 0"><span>以下是优惠菜品</span></div>
<div v-for="(item, index) in carts.giftList" :key="index">
<carts-item
:item="item"
@changeNumber="changeNumber"
:useVipPrice="carts.useVipPrice"
:selCart="carts.selCart"
@itemClick="itemClick(item)"
@editNote="editNote"
></carts-item>
</div>
<el-empty :image-size="60" v-if="carts.isEmpty" description="点餐列表为空" />
<!-- 打包费 -->
<template v-if="carts.packNum > 0">
<div class="cart-title"><span>打包费</span></div>
@@ -24,20 +38,6 @@
<div class="cart-title"><span>餐位费</span></div>
<extra-fee name="餐位费" :number="perpole" :price="canWeiFee"></extra-fee>
</template>
<!-- 赠菜 -->
<div class="cart-title" v-if="carts.giftList.length > 0"><span>以下是优惠菜品</span></div>
<div v-for="(item, index) in carts.giftList" :key="index">
<carts-item
:item="item"
@changeNumber="changeNumber"
:selCart="carts.selCart"
@itemClick="itemClick(item)"
@editNote="editNote"
></carts-item>
</div>
<el-empty :image-size="60" v-if="carts.isEmpty" description="点餐列表为空" />
<!-- 历史订单 -->
<template v-for="(item, index) in carts.oldOrder.detailMap" :key="index">
<div class="cart-title">
@@ -46,6 +46,7 @@
<div v-for="(detaiItem, index) in item" :key="index">
<carts-item
:useVipPrice="carts.useVipPrice"
:canChangeNumber="false"
isOld
:item="detaiItem"
@@ -60,7 +61,29 @@
<!-- <div class="color-666 u-font-14">订单备注:{{ "123" }}</div> -->
</div>
<div class="bottom">
<div class="yiyouhui">{{ carts.yiyouhui }}</div>
<div class="u-flex u-row-right">
<el-tooltip
placement="top"
effect="light"
popper-class="youhui-tips"
:popper-options="{
'background-color': '#fff',
}"
>
<template #content>
<div class="u-flex color-000 u-font-14 u-row-between">
<span class="font-bold">会员优惠</span>
<span class="u-m-l-30">{{ carts.vipDiscount }}</span>
</div>
<div class="u-flex color-000 u-font-14 u-row-between">
<span class="font-bold">单品改价优惠</span>
<span class="u-m-l-30">{{ carts.singleDiscount }}</span>
</div>
</template>
<div class="yiyouhui">{{ carts.yiyouhui }}</div>
</el-tooltip>
</div>
<div class="u-flex u-row-between">
<el-link type="primary">打印制作单</el-link>
<div>
@@ -180,7 +203,8 @@ function init() {
for (let goods of props.goodsList) {
goodsMap[goods.id] = goods;
}
console.log(props.table);
console.log("cartsinit");
console.log(props.oldOrder);
carts.init({ table_code: props.table.tableCode }, goodsMap, props.oldOrder);
}
@@ -193,9 +217,6 @@ function changeNumber(step, item) {
carts.changeNumber(step * 1, item);
}
const totalMoney = computed(() => {
console.log(carts.payMoney);
console.log(carts.oldOrder.originAmount);
return (carts.payMoney * 1 + (carts.oldOrder.originAmount || 0) * 1).toFixed(2);
});
defineExpose({

View File

@@ -7,33 +7,42 @@
<div class="color-red u-font-18 font-600">{{ form.money }}</div>
<!-- <el-input :value="form.money" disabled> </el-input> -->
</el-form-item>
<el-form-item label="减免金额">
<el-input
<el-form-item label="优惠类型" v-if="shopUser.isShopAdmin">
<el-radio-group v-model="discountType">
<el-radio-button label="金额" :value="0"></el-radio-button>
<el-radio-button label="折扣" :value="1"></el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="减免金额" v-if="discountType == 0">
<el-input-number
v-model="form.reduceMoney"
clearable
autofocus
type="number"
@keyup.enter="init('reduceMoney')"
@blur="init('reduceMoney')"
@change="init('reduceMoney')"
>
<template #append></template>
</el-input>
</el-input-number>
</el-form-item>
<el-form-item label="优惠折扣">
<el-input
<el-form-item label="优惠折扣" v-if="discountType == 1">
<el-input-number
v-model="form.discount"
:step="1"
step-strictly
type="number"
@keyup.enter="init('discount')"
@blur="init('discount')"
@change="init('discount')"
>
<template #append>%</template>
</el-input>
</el-input-number>
<span>%</span>
</el-form-item>
<el-form-item label="实收金额">
<el-input
v-model="form.curretnMoney"
type="number"
clearable
disabled
@keyup.enter="init('curretnMoney')"
@blur="init('curretnMoney')"
>
@@ -49,7 +58,11 @@
</div>
</el-dialog>
</template>
<script>
<script setup>
import { useUserStore } from "@/store/modules/user";
import { ElMessage } from "element-plus";
const shopUser = useUserStore();
function toFixedNoRounding(num) {
// 转换为字符串
var numStr = num.toString();
@@ -62,99 +75,103 @@ function toFixedNoRounding(num) {
// 拼接回数字字符串并返回
return parts.join(".");
}
//折扣类型
const discountType = ref(1);
export default {
props: {
title: {
type: String,
default: "优惠金额",
},
value: {
type: [String, Number],
default: 0,
},
const props = defineProps({
title: {
type: String,
default: "优惠金额",
},
data() {
return {
form: {
money: 0,
discount: 100,
reduceMoney: 0,
curretnMoney: 0,
},
number: "0",
show: false,
};
value: {
type: [String, Number],
default: 0,
},
methods: {
init(key) {
const { money, reduceMoney, discount, curretnMoney } = this.form;
if (key == "reduceMoney") {
if (reduceMoney < 0) {
this.$message.error("减免金额不能小于0");
this.form.reduceMoney = 0;
}
if (reduceMoney > money) {
this.$message.error("减免金额不能大于总金额");
this.form.reduceMoney = money;
}
this.form.curretnMoney = (money - this.form.reduceMoney).toFixed(2);
this.form.discount = toFixedNoRounding(((this.form.curretnMoney / money) * 100).toFixed(3));
return;
}
if (key == "discount") {
if (discount < 0) {
this.$message.error("折扣不能小于0");
this.form.discount = 0;
}
if (discount > 100) {
this.$message.error("折扣不能大于100");
this.form.discount = 100;
}
this.form.curretnMoney = ((money * this.form.discount) / 100).toFixed(2);
this.form.reduceMoney = ((money * (100 - this.form.discount)) / 100).toFixed(2);
return;
}
if (key == "curretnMoney") {
if (curretnMoney < 0) {
this.$message.error("实收金额不能小于0");
this.form.curretnMoney = 0;
}
if (curretnMoney > money) {
this.$message.error("实收金额不能大于总金额");
this.form.curretnMoney = this.form.money;
}
this.form.reduceMoney = (money - this.form.curretnMoney).toFixed(2);
this.form.discount = toFixedNoRounding(((this.form.curretnMoney / money) * 100).toFixed(3));
return;
}
this.form.curretnMoney = ((money * discount) / 100).toFixed(2);
this.form.reduceMoney = (money - this.form.curretnMoney).toFixed(2);
},
changeKey(key, val) {
this[key] = val;
},
});
confirm() {
console.log(this.form.discount / 100);
this.$emit("confirm", this.form);
this.close();
},
open(data) {
console.log(data);
this.form.money = data.amount * 1;
this.form.discount = data.discount ? toFixedNoRounding(data.discount.toFixed(3)) : 100;
this.show = true;
this.init();
},
close() {
this.show = false;
},
const state = reactive({
form: {
money: 0,
discount: 100,
reduceMoney: 0,
curretnMoney: 0,
},
mounted() {
this.number = `${this.value}`;
},
};
number: "0",
show: false,
});
const { form, number, show } = toRefs(state);
function init(key) {
const { money, reduceMoney, discount, curretnMoney } = form.value;
if (key == "reduceMoney") {
if (reduceMoney < 0) {
ElMessage.error("减免金额不能小于0");
form.value.reduceMoney = 0;
}
if (reduceMoney > money) {
ElMessage.error("减免金额不能大于总金额");
form.value.reduceMoney = money;
}
form.value.curretnMoney = (money - form.value.reduceMoney).toFixed(2);
form.value.discount = toFixedNoRounding(((form.value.curretnMoney / money) * 100).toFixed(3));
return;
}
if (key == "discount") {
if (discount < 0) {
ElMessage.error("折扣不能小于0");
form.value.discount = 0;
}
if (discount > 100) {
ElMessage.error("折扣不能大于100");
form.value.discount = 100;
}
form.value.curretnMoney = (money * (form.value.discount / 100)).toFixed(2);
form.value.reduceMoney = ((money * (100 - form.value.discount)) / 100).toFixed(2);
return;
}
if (key == "curretnMoney") {
if (curretnMoney < 0) {
ElMessage.error("实收金额不能小于0");
form.value.curretnMoney = 0;
}
if (curretnMoney > money) {
ElMessage.error("实收金额不能大于总金额");
form.value.curretnMoney = form.value.money;
}
form.value.reduceMoney = (money - form.value.curretnMoney).toFixed(2);
form.value.discount = toFixedNoRounding(((form.value.curretnMoney / money) * 100).toFixed(3));
return;
}
form.value.curretnMoney = ((money * discount) / 100).toFixed(2);
form.value.reduceMoney = (money - form.value.curretnMoney).toFixed(2);
}
const emits = defineEmits(["confirm"]);
function confirm() {
console.log(form.value);
if (discountType.value == 1) {
emits("confirm", { discount: form.value.discount });
} else {
emits("confirm", { discountAmount: form.value.reduceMoney });
}
close();
}
function open(data) {
console.log(data);
form.value.money = data.amount * 1;
form.value.discount = data.discount ? toFixedNoRounding(data.discount.toFixed(3)) : 100;
show.value = true;
init();
}
function close() {
show.value = false;
}
onMounted(() => {
number.value = `${props.value}`;
});
defineExpose({
close,
open,
});
</script>
<style lang="scss" scoped>

View File

@@ -17,7 +17,7 @@
</div>
<div class="userinfo" v-else @click="chooseUser">
<el-avatar class="avatar" :size="50" />
<div class="u-m-l-12">
<div class="u-m-l-12 no-wrap">
<p>
<span class="name u-font-16">服务员下单</span>
</p>
@@ -27,45 +27,47 @@
</p>
</div>
</div>
<div class="score">
<div class="u-flex u-col-center u-m-t-10">
<span class="u-font-14 font-bold u-m-r-20">积分抵扣</span>
<el-radio-group v-model="score.sel" size="small" class="">
<el-radio :value="0">
<span class="u-font-14">全部抵扣</span>
</el-radio>
<el-radio :value="1">
<span class="u-font-14">部分抵扣</span>
</el-radio>
</el-radio-group>
<template v-if="user.id">
<div class="score">
<div class="u-flex u-col-center u-m-t-10">
<span class="u-font-14 font-bold u-m-r-20">积分抵扣</span>
<el-radio-group v-model="score.sel" size="small" class="">
<el-radio :value="0">
<span class="u-font-14">全部抵扣</span>
</el-radio>
<el-radio :value="1">
<span class="u-font-14">部分抵扣</span>
</el-radio>
</el-radio-group>
</div>
<p class="u-font-14 color-666 u-m-t-10">
<span class="color-red">*</span>
<span>积分不足或小于最低使用门槛1</span>
</p>
</div>
<p class="u-font-14 color-666 u-m-t-10">
<span class="color-red">*</span>
<span>积分不足或小于最低使用门槛1</span>
</p>
</div>
<div class="u-flex u-col-center u-m-t-20 no-wrap">
<span class="u-font-14 font-bold u-m-r-20">团购代金券</span>
<div class="u-flex my-select">
<span class="u-m-r-10">代金券名称</span>
<el-icon><ArrowDown /></el-icon>
<div class="u-flex u-col-center u-m-t-20 no-wrap">
<span class="u-font-14 font-bold u-m-r-20">团购代金券</span>
<div class="u-flex my-select">
<span class="u-m-r-10">代金券名称</span>
<el-icon><ArrowDown /></el-icon>
</div>
<svg-icon iconClass="scan" size="30" class="u-m-l-10 cur-pointer"></svg-icon>
</div>
<svg-icon iconClass="scan" size="30" class="u-m-l-10 cur-pointer"></svg-icon>
</div>
<div class="u-flex u-col-center u-m-t-20 no-wrap">
<span class="u-font-14 font-bold u-m-r-20">优惠券</span>
<div class="u-flex my-select">
<span class="u-m-r-10">选择优惠券</span>
<el-icon><ArrowDown /></el-icon>
<div class="u-flex u-col-center u-m-t-20 no-wrap">
<span class="u-font-14 font-bold u-m-r-20">优惠券</span>
<div class="u-flex my-select" @click="openCoupon">
<span class="u-m-r-10">选择优惠券</span>
<el-icon><ArrowDown /></el-icon>
</div>
</div>
</div>
</template>
</div>
<div class="u-m-t-30">
<el-button size="large" @click="discountShow">整单打折/减免</el-button>
</div>
<div class="u-m-t-30">
<p class="u-font-16 font-bold u-m-r-20 font-bold">选择支付方式</p>
<p class="u-font-16 font-bold u-m-r-20 font-bold u-flex">选择支付方式</p>
<div class="u-m-t-20">
<el-button
v-for="(item, index) in payTypes.list"
@@ -91,65 +93,90 @@
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">餐位费</span>
<span class="u-m-l-10 value">{{ orderInfo.seatAmount }}</span>
<span class="u-m-l-10 value">{{ orderInfo.seatAmount }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">打包费</span>
<span class="u-m-l-10 value">{{ orderInfo.packFee }}</span>
<span class="u-m-l-10 value">{{ orderInfo.packFee }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">总价</span>
<span class="u-m-l-10 value">{{ orderInfo.orderAmount }}</span>
<span class="u-m-l-10 value">{{ carts.payMoney }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">优惠券</span>
<span class="u-m-l-10 value">{{ coupDiscount }}</span>
<span class="u-m-l-10 value">{{ coupDiscount }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">积分抵扣</span>
<span class="u-m-l-10 value">{{ orderInfo.pointsDiscountAmount || 0 }}</span>
<span class="u-m-l-10 value">-{{ orderInfo.pointsDiscountAmount || 0 }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">整单改价</span>
<span class="u-m-l-10 value"></span>
<span class="u-m-l-10 value">-{{ checkOrderPay.discountAmount || 0 }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">抹零</span>
<span class="u-m-l-10 value"></span>
<span class="u-m-l-10 value">-{{ orderInfo.pointsDiscountAmount || 0 }}</span>
</div>
<div class="u-flex u-m-b-10 u-row-between">
<span class="title">应付金额</span>
<span class="u-m-l-10 value">{{ payMoney }}</span>
<span class="u-m-l-10 value price">{{ currentpayMoney }}</span>
</div>
</div>
</div>
<!-- 扫码 -->
<scanPay ref="refScanPay" :order="orderInfo"></scanPay>
<scanPay
ref="refScanPay"
:order="orderInfo"
@paySuccess="paySuccess"
@confirm="refScanPayConfirm"
></scanPay>
<!-- 打折 -->
<discount ref="refDiscount" @confirm="discountConfirm"></discount>
<!-- 优惠券 -->
<popup-coupon ref="refCoupon" @confirm="refCouponConfirm"></popup-coupon>
</div>
</template>
<script setup>
import { useCartsStore } from "@/store/modules/carts";
const carts = useCartsStore();
import popupCoupon from "./popup-coupon.vue";
import PointsApi from "@/api/account/points";
import payTypeApi from "@/api/account/payType";
import payApi from "@/api/order/pay";
import scanPay from "./scan-pay.vue";
import discount from "./discount.vue";
import { ElLoading } from "element-plus";
import { ElMessage, ElMessageBox } from "element-plus";
//优惠券
const refCoupon = ref();
function openCoupon() {
refCoupon.value.open();
}
function couponChange(data) {}
//打折
const refDiscount = ref();
const checkOrderPay = reactive({
discountAmount: 0, //手动优惠金额
discount: 0,
});
function discountConfirm(e) {
console.log(e);
checkOrderPay.discountAmount = e.reduceMoney;
Object.assign(checkOrderPay, e);
if (e.discount) {
checkOrderPay.discountAmount =
carts.payMoney - (carts.payMoney * (e.discount / 100).toFixed(2)).toFixed(2);
}
}
function discountShow(e) {
refDiscount.value.open({
amount: props.orderInfo.originAmount,
amount: carts.payMoney,
});
}
@@ -160,13 +187,44 @@ const props = defineProps({
},
user: {
type: Object,
default: () => {},
default: () => {
return { id: "" };
},
},
orderInfo: {
type: Object,
default: () => {},
},
});
watch(
() => props.user.id,
(newval) => {
if (newval !== "") {
pointsInit();
}
}
);
watch(
() => props.orderInfo.id,
(newval) => {
if (newval !== "") {
pointsInit();
}
}
);
//002-获取订单可用积分及抵扣金额(支付页面使用)
function pointsInit() {
if (!props.user.id) {
return;
}
PointsApi.calcOrderUsablePoints({
userId: props.user.id,
orderAmount: (carts.payMoney - checkOrderPay.discountAmount).toFixed(2),
});
}
const emits = defineEmits(["chooseUser", "paysuccess"]);
function chooseUser() {
emits("chooseUser");
@@ -191,78 +249,118 @@ const payTypes = reactive({
const refScanPay = ref();
function changePayType(i) {
if (payTypes.list[i].payType === "scanCode") {
return refScanPay.value.open({
money: props.orderInfo.orderAmount,
shopId: localStorage.getItem("shopId"),
checkOrderPay: {
orderId: props.orderInfo.id,
discountRatio: 1,
orderAmount: props.orderInfo.orderAmount,
seatNum: props.orderInfo.seatNum,
originAmount: props.orderInfo.originAmount,
discountAmount: props.orderInfo.discountAmount,
productCouponDiscountAmount: props.orderInfo.productCouponDiscountAmount,
orderAmount: props.orderInfo.orderAmount,
roundAmount: props.orderInfo.roundAmount,
pointsDiscountAmount: props.orderInfo.pointsDiscountAmount,
pointsNum: props.orderInfo.pointsNum,
fullCouponDiscountAmount: props.orderInfo.fullCouponDiscountAmount,
},
});
}
const payType = payTypes.list[i].payType;
refScanPayOpen(payType);
payTypes.sel = i;
}
function returnPayParams() {
return {
shopId: localStorage.getItem("shopId"),
authCode: "",
checkOrderPay: {
orderId: props.orderInfo.id,
// discountRatio: (checkOrderPay.discount / 100).toFixed(2),
discountRatio: 0,
seatNum: props.orderInfo.seatNum,
originAmount: carts.payMoney * 1,
discountAmount: checkOrderPay.discountAmount * 1,
productCouponDiscountAmount: props.orderInfo.productCouponDiscountAmount || 0,
orderAmount: currentpayMoney.value * 1,
roundAmount: props.orderInfo.roundAmount,
pointsDiscountAmount: props.orderInfo.pointsDiscountAmount || 0,
pointsNum: props.orderInfo.pointsNum,
fullCouponDiscountAmount: props.orderInfo.fullCouponDiscountAmount || 0,
},
};
}
function refScanPayOpen(payType) {
if (payType == "deposit") {
return refScanPay.value.open(returnPayParams(), "deposit");
}
if (payType == "scanCode") {
return refScanPay.value.open(returnPayParams(), "scanCode");
}
}
async function getPaytype() {
const res = await payTypeApi.getList();
payTypes.list = res;
}
function nowPayClick() {
const payType = payTypes.list[payTypes.sel].payType;
console.log(payType);
if (payType === "cash") {
ElMessageBox.confirm("是否确认已现金收款:" + payMoney.value + "元", "快捷支付", {
ElMessageBox.confirm("是否确认已现金收款:" + currentpayMoney.value + "元", "快捷支付", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
payApi
.cashPay({
shopId: localStorage.getItem("shopId"),
checkOrderPay: {
orderId: props.orderInfo.id,
discountRatio: 1,
orderAmount: props.orderInfo.orderAmount,
seatNum: props.orderInfo.seatNum,
originAmount: props.orderInfo.originAmount,
discountAmount: props.orderInfo.discountAmount,
productCouponDiscountAmount: props.orderInfo.productCouponDiscountAmount,
orderAmount: props.orderInfo.orderAmount,
roundAmount: props.orderInfo.roundAmount,
pointsDiscountAmount: props.orderInfo.pointsDiscountAmount,
pointsNum: props.orderInfo.pointsNum,
fullCouponDiscountAmount: props.orderInfo.fullCouponDiscountAmount,
},
})
.then((res) => {
ElMessage.success("支付成功");
emits("paysuccess");
});
payOrder("cash");
})
.catch(() => {});
return;
}
refScanPayOpen(payType);
}
const payMoney = computed(() => {
if (!props.orderInfo.orderAmount) {
return "";
function refScanPayConfirm(authCode, isScan) {
const payType = payTypes.list[payTypes.sel].payType;
payParams.authCode = authCode;
payOrder(payType, isScan);
}
let payTimer = null;
//是否是正扫
async function payOrder(payType, isScan) {
clearTimeout(payTimer);
const loading = ElLoading.service({
lock: true,
text: "支付中,请稍等……",
background: "rgba(0, 0, 0, 0.7)",
});
payTimer = setTimeout(() => {
ElMessage.error("支付超时");
loading.close();
}, 1000 * 20);
let res = undefined;
try {
if (payType == "scanCode") {
res = isScan
? await payApi.scanPay(returnPayParams())
: await payApi.microPay(returnPayParams());
}
if (payType == "cash") {
res = await payApi.cashPay(returnPayParams());
}
if (payType == "deposit") {
res = await payApi.vipPay({ ...returnPayParams(), payType: "scanCode" });
}
} catch (error) {
clearTimeout(payTimer);
loading.close();
}
return (props.orderInfo.orderAmount - checkOrderPay.discountAmount).toFixed(2);
if (res) {
clearTimeout(payTimer);
ElMessage.success("支付成功");
emits("paysuccess");
loading.close();
}
}
//应付金额
const currentpayMoney = computed(() => {
if (checkOrderPay.discount) {
return (carts.payMoney * (checkOrderPay.discount / 100)).toFixed(2);
}
return (carts.payMoney - checkOrderPay.discountAmount).toFixed(2);
});
onMounted(() => {
getPaytype();
pointsInit();
});
</script>

View File

@@ -0,0 +1,273 @@
<template>
<el-dialog width="700px" :title="title" v-model="show" top="20px" @close="reset">
<div class="u-p-15">
<div class="">
<el-tabs v-model="activeName" @tab-click="tabClick">
<el-tab-pane label="优惠券(单选)" name="youhui">
<el-table
ref="table"
empty-text="无可用优惠券"
:data="quans.fullReductionCoupon"
@cell-click="fullReductionCouponClick"
>
<el-table-column type="index" label="">
<template v-slot="scope">
<el-checkbox
@change="fullReductionCouponClick(scope.row)"
:value="scope.row.id == fullReductionCouponSel.id"
></el-checkbox>
</template>
</el-table-column>
<el-table-column type="index" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="券类型" width="80">
<template v-slot="scope">
{{ scope.row.type == 1 ? "优惠券" : "商品券" }}
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="抵扣">
<template v-slot="scope">
<span class="color-red">{{ scope.row.discountAmount }}</span>
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="限制" width="120">
<template v-slot="scope">
<div class="u-flex">
<span>支付满</span>
<span class="color-red no-wrap">
{{ scope.row.fullAmount }}
</span>
<span>元可用</span>
</div>
</template>
</el-table-column>
<el-table-column prop="useRestrictions" label="描述"></el-table-column>
</el-table>
</el-tab-pane>
<el-tab-pane label="商品券(多选)" name="goods">
<el-table
ref="table1"
@cell-click="productCouponClick"
empty-text="无可用商品券"
:data="quans.productCoupon"
style="width: 100%"
>
<el-table-column>
<template v-slot="scope">
<el-checkbox
@change="productCouponClick(scope.row)"
:value="scope.row.checked"
></el-checkbox>
</template>
</el-table-column>
<el-table-column type="index" width="50" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="商品信息" width="120">
<template v-slot="scope">
<div class="u-flex">
<div class="u-flex">
<el-image
:src="scope.row.productCover"
fit="cover"
style="width: 40px; height: 40px"
:preview-src-list="[scope.row.productCover]"
></el-image>
</div>
<div class="u-p-l-10">
<div class="">{{ scope.row.productName }}</div>
<div class="">x{{ scope.row.num || "" }}</div>
</div>
</div>
</template>
</el-table-column>
<!-- <el-table-column prop="discountAmount" label="抵扣">
<template v-slot="scope">
<span class="color-red">
{{ scope.row.discountAmount }}
</span>
</template>
</el-table-column> -->
<el-table-column label="券类型">
<template v-slot="scope">
{{ scope.row.type == 1 ? "优惠券" : "商品券" }}
</template>
</el-table-column>
<el-table-column prop="useRestrictions" label="描述"></el-table-column>
<!-- <el-table-column prop="useRestrictions" label="是否可用">
<template v-slot="scope">
{{ scope.row.use ? "可以" : "不可用" }}
</template>
</el-table-column> -->
</el-table>
</el-tab-pane>
</el-tabs>
<div v-if="quansSelArr.length > 0">
<div class="font-bold u-m-b-10">已选优惠券</div>
<el-table empty-text="未选择优惠券" :data="quansSelArr">
<el-table-column type="index" width="50" label="#"></el-table-column>
<el-table-column prop="name" label="券名称"></el-table-column>
<el-table-column label="券类型" width="80">
<template v-slot="scope">
{{ scope.row.type == 1 ? "优惠券" : "商品券" }}
</template>
</el-table-column>
<el-table-column label="商品信息" width="120">
<template v-slot="scope">
<div class="u-flex" v-if="scope.row.type == 2">
<div class="u-flex">
<el-image
:src="scope.row.productCover"
fit="cover"
style="width: 40px; height: 40px"
:preview-src-list="[scope.row.productCover]"
></el-image>
</div>
<div class="u-p-l-10">
<div class="">{{ scope.row.productName }}</div>
<div class="">x{{ scope.row.num || "" }}</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="discountAmount" label="抵扣">
<template v-slot="scope">
<span class="color-red" v-if="scope.row.type == 1">
{{ scope.row.discountAmount }}
</span>
<span class="color-red" v-if="scope.row.type == 2">
{{ returnProDiscount(scope.row, scope.row.index) }}
</span>
</template>
</el-table-column>
<el-table-column prop="useRestrictions" label="描述"></el-table-column>
<el-table-column prop="useRestrictions" label="">
<template v-slot="scope">
<el-button type="danger" size="mini" @click="delQuan(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="u-flex u-row-between u-m-t-20">
<div class="u-flex">
<span>抵扣金额:</span>
<span class="color-red">{{ AllCouponPrice }}</span>
</div>
<div class="u-flex u-relative">
<span>支付金额:</span>
<span class="color-red">{{ payPrice }}</span>
<div
class="u-absolute u-flex line-th color-999"
style="right: 0; bottom: 100%"
v-if="orderPrice * 1 != payPrice * 1"
>
<span class="">{{ orderPrice }}</span>
</div>
</div>
</div>
<div class="u-flex u-row-center u-m-t-50">
<el-button size="medium" @click="close">取消</el-button>
<el-button size="medium" type="primary" @click="confirm">确定</el-button>
</div>
</div>
</div>
</el-dialog>
</template>
<script setup>
const props = defineProps({
title: {
type: String,
default: "选择优惠券",
},
goodsArr: {
type: Array,
default: [],
},
vipUser: {
type: Object,
default: () => {
return {
isVip: false,
};
},
},
});
function tabClick() {}
const state = reactive({
discount: 1,
orderPrice: 0,
fullReductionCouponSel: {
id: "",
},
quansSelArr: [],
quans: {
fullReductionCoupon: [],
productCoupon: [],
},
currentRow: null,
multipleSelection: null,
fullReductionCouponSelId: "",
activeName: "youhui",
form: {},
show: false,
isSetProductCoup: false,
});
const {
discount,
orderPrice,
fullReductionCouponSel,
quansSelArr,
quans,
currentRow,
multipleSelection,
fullReductionCouponSelId,
activeName,
form,
show,
isSetProductCoup,
} = toRefs(state);
const AllCouponPrice = computed(() => {
return 0;
});
const payPrice = computed(() => {
return 0;
});
function open() {
show.value = true;
}
function close() {
show.value = false;
}
const emits = defineEmits(["confirm"]);
function confirm() {
emits("confirm");
}
function reset() {}
defineExpose({
close,
open,
});
</script>
<style lang="scss" scoped>
.line-th {
text-decoration: line-through;
}
.codeImg {
width: 160px;
border: 1px solid rgb(220, 223, 230);
height: 160px;
}
:deep(.el-input .el-input__inner::-webkit-inner-spin-button) {
-webkit-appearance: none;
margin: 0;
}
:deep(.el-input .el-input__inner::-webkit-outer-spin-button) {
-webkit-appearance: none;
margin: 0;
}
</style>

View File

@@ -1,7 +1,7 @@
<template>
<el-dialog width="400px" :title="title" v-model="show" @close="reset">
<div class="u-p-15">
<div v-if="openSwitch">
<div v-if="openSwitch" class="u-m-b-20">
<el-button
@click="changeKey('paysSel', index)"
v-for="(item, index) in pays"
@@ -11,7 +11,7 @@
{{ item.text }}
</el-button>
</div>
<div class="u-m-t-20">
<div class="">
<el-alert :closable="false" v-if="tips" :title="tips" type="warning" show-icon></el-alert>
</div>
<div class="u-m-t-20">
@@ -24,6 +24,7 @@
<el-input
v-model="form.code"
@change="codeInputChange"
autofocus
placeholder="请扫码或者输入付款码"
ref="refInputCode"
></el-input>
@@ -43,9 +44,9 @@
<!-- <img :src="codeImg" class="codeImg" alt="" /> -->
</div>
<div class="color-333 u-font-20 u-m-t-20">{{ to2(price) }}</div>
<div class="color-333 u-font-20 u-m-t-20">{{ form.money }}</div>
<div class="color-aaa u-font-12 u-m-t-10">
<i class="el-icon-loading"></i>
<el-icon class="loading-ani"><Loading /></el-icon>
<span>等待用户支付</span>
</div>
</div>
@@ -61,18 +62,10 @@ import payApi from "@/api/order/pay";
export default {
props: {
openSwitch: {
type: Boolean,
default: true,
},
order: {
type: Object,
default: () => ({}),
},
title: {
type: String,
default: "支付",
},
price: {
type: [String, Number],
default: 0,
@@ -84,6 +77,8 @@ export default {
},
data() {
return {
title: "支付",
openSwitch: false,
tips: "",
paymentQrcode: "",
paysSel: 0,
@@ -119,11 +114,13 @@ export default {
if (newval == 0) {
this.clear();
this.tips = "请使用扫码枪扫微信/支付宝收款码";
this.$refs.refInputCode.focus();
this.$nextTick(() => {
this.$refs.refInputCode.focus();
});
} else {
this.getPayUrl();
this.tips = "请用户使用微信/支付宝扫描付款码";
// this.startGetOrderInfo();
this.startGetOrderInfo();
}
},
number(newval) {
@@ -142,7 +139,7 @@ export default {
shopId: localStorage.getItem("shopId"),
orderId: this.order.id,
});
if (res.status == "closed") {
if (res.status == "done") {
this.clear();
this.$emit("paySuccess");
}
@@ -173,10 +170,12 @@ export default {
return this.$message.error("请输入或扫付款码");
}
this.close();
this.$emit("confirm", this.form.code);
this.$emit("confirm", this.form.code, this.paysSel ? true : false);
},
async getPayUrl() {
const res = await payApi.microPay(this.payPar);
const formdata = { ...this.payPar, ...this.payPar.checkOrderPay };
delete formdata.checkOrderPay;
const res = await payApi.orderPayUrl(formdata);
console.log(res);
this.paymentQrcode = res;
this.$nextTick(() => {
@@ -190,7 +189,16 @@ export default {
);
});
},
open(data) {
open(data, payType) {
if (payType == "deposit") {
// 储值卡
this.openSwitch = false;
this.title = "储值卡支付";
}
if (payType == "scanCode") {
this.openSwitch = true;
this.title = "扫码支付";
}
this.show = true;
this.form.money = Number(data.money).toFixed(2);
this.payPar = data;
@@ -198,7 +206,9 @@ export default {
// this.getPayUrl();
}
this.$nextTick(() => {
this.$refs.refInputCode.focus();
setTimeout(() => {
this.$refs.refInputCode.focus();
}, 100);
});
},
close() {
@@ -226,4 +236,18 @@ export default {
height: 164px;
overflow: hidden;
}
@keyframes rotating {
0% {
-webkit-transform: rotate(0deg);
transform: rotate(0deg);
}
to {
-webkit-transform: rotate(1turn);
transform: rotate(1turn);
}
}
.loading-ani {
animation: rotating 2s linear infinite;
}
</style>

View File

@@ -20,10 +20,12 @@
</div>
<div>
<div class="u-flex">
<div class="ft-13 color-000">{{ user.nickName }}</div>
<div class="ft-13 color-000 no-wrap">{{ user.nickName }}</div>
<div class="vip" v-if="user.isVip">VIP{{ user.isVip }}</div>
</div>
<div style="margin-top: 2px" class="color-666 ft-12">余额{{ user.amount }}</div>
<div style="margin-top: 2px" class="no-wrap color-666 ft-12">
余额{{ user.amount }}
</div>
</div>
</div>
</div>
@@ -219,8 +221,12 @@ import productApi from "@/api/product/index";
import tableApi from "@/api/account/table";
import $status from "@/views/tool/table/status.js";
import orderApi from "@/api/order/order";
import shopUserApi from "@/api/account/shopUser";
import { useCartsStore } from "@/store/modules/carts";
import { useUserStore } from "@/store/modules/user";
import { ElLoading } from "element-plus";
const carts = useCartsStore();
const shopUser = useUserStore();
@@ -245,9 +251,8 @@ function showDinerNumber() {
let user = ref({});
const refChooseUser = ref();
function chooseUserConfirm(e) {
console.log(e);
user.value = e;
refCart.value.carts.changeUser(e);
user.value = e ? e : {};
refCart.value.carts.changeUser(e ? e : {});
}
function showChooseUser() {
refChooseUser.value.open();
@@ -258,42 +263,62 @@ const showOrder = ref(false);
function hideOrder() {
showOrder.value = false;
}
const oldOrder = ref({});
const oldOrder = ref({ detailMap: [] });
const orderInfo = ref({});
let createOrderTimer = null;
async function createOrder(key) {
console.log(refCart.value.carts.table_code);
const res = await orderApi.add({
orderId: oldOrder.value.id || "",
shopId: shopUser.userInfo.id,
userId: user.value.userId,
seatNum: 0,
packFee: refCart.value.carts.packFee * 1,
originAmount: refCart.value.carts.payMoney * 1,
tableCode: refCart.value.carts.table_code,
dineMode: diners.sel == 0 ? "dine-in" : "take-out",
remark: "",
seatNum: perpole.value * 1,
placeNum: 1,
waitCall: false,
vipPrice: user.value.id && user.value.isVip,
clearTimeout(createOrderTimer);
const loading = ElLoading.service({
lock: true,
text: "订单生成中,请稍等……",
background: "rgba(0, 0, 0, 0.7)",
});
if (res) {
refCart.value.carts.clear();
if (key == "only-create") {
router.replace(route.path);
return;
createOrderTimer = setTimeout(() => {
ElMessage.error("订单生成超时");
loading.close();
}, 1000 * 20);
try {
const res = await orderApi.add({
orderId: oldOrder.value.id || "",
shopId: shopUser.userInfo.id,
userId: user.value.userId,
seatNum: 0,
packFee: refCart.value.carts.packFee * 1,
originAmount: refCart.value.carts.payMoney * 1,
tableCode: refCart.value.carts.table_code,
dineMode: diners.sel == 0 ? "dine-in" : "take-out",
remark: "",
seatNum: perpole.value * 1,
placeNum: oldOrder.value.placeNum * 1 + 1,
waitCall: false,
vipPrice: user.value.id && user.value.isVip,
});
clearTimeout(createOrderTimer);
loading.close();
if (res) {
refCart.value.carts.clear();
if (key == "only-create") {
router.replace(route.path);
return;
}
if (res.id) {
// 获取历史订单数据
const res1 = await orderApi.getHistoryList({
orderId: res.id,
});
oldOrder.value = res1;
orderInfo.value = res1;
refCart.value.carts.init();
}
showOrder.value = true;
// oldOrder.value = res;
}
if (key == "to-pay" && oldOrder.value.id) {
// 获取历史订单数据
const res = await orderApi.getHistoryList({
orderId: oldOrder.value.id,
});
oldOrder.value = res;
}
orderInfo.value = res;
showOrder.value = true;
// oldOrder.value = res;
} catch (error) {
clearTimeout(createOrderTimer);
}
}
@@ -580,12 +605,21 @@ onMounted(async () => {
};
if (noPayStatus[res.status]) {
ElMessage.error(noPayStatus[res.status]);
refresh();
router.replace(route.path);
console.log(route.path);
setTimeout(() => {
refCart.value.carts.dataReset();
refresh();
}, 2000);
return;
}
if (res.tableCode) {
table.value = { tableCode: res.tableCode };
}
if (res.userId) {
const userRes = await shopUserApi.get({ userId: res.userId });
user.value = userRes;
}
if (res) {
oldOrder.value = res;
orderInfo.value = res;
@@ -599,7 +633,10 @@ onMounted(async () => {
});
function refresh() {
router.go(0);
router.replace(route.path);
setTimeout(() => {
router.go(1000);
}, 1500);
}
</script>