diff --git a/src/App.vue b/src/App.vue index 38bd4e6..2720cbe 100644 --- a/src/App.vue +++ b/src/App.vue @@ -338,7 +338,7 @@ html { .empty { display: flex; justify-content: center; - padding-top: 100px; + padding-top: var(--el-font-size-base); } /*定义滚动条高宽及背景 diff --git a/src/api/account.js b/src/api/account.js index 07205ff..6821911 100644 --- a/src/api/account.js +++ b/src/api/account.js @@ -77,3 +77,16 @@ export function shopTable(params) { params, }); } + +/** + * 支付方式列表 + * @param {*} params + * @returns + */ +export function getPayType(params) { + return request({ + method: "get", + url: "/account/admin/payType", + params, + }); +} diff --git a/src/api/order.js b/src/api/order.js index 376d52f..7747fc2 100644 --- a/src/api/order.js +++ b/src/api/order.js @@ -31,11 +31,11 @@ export function cashPay(data) { * @param {*} data * @returns */ -export function orderList(data) { +export function orderList(params) { return request({ - method: "post", - url: "/order/admin/order", - data, + method: "get", + url: `/order/admin/order`, + params, }); } @@ -64,3 +64,16 @@ export function historyOrder(params) { params, }); } + +/** + * 订单退款 + * @param {*} data + * @returns + */ +export function refundOrder(data) { + return request({ + method: "post", + url: "/order/admin/order/refundOrder", + data, + }); +} diff --git a/src/components/payCard/payCard.vue b/src/components/payCard/payCard.vue index 829c8aa..598ab8c 100644 --- a/src/components/payCard/payCard.vue +++ b/src/components/payCard/payCard.vue @@ -25,7 +25,7 @@ {{ item.payName }} -
挂账 -
+
-->
储值:¥{{ money }}
@@ -62,7 +62,7 @@
+ :selecttype="props.selecttype" :payType="payType" :payData="payData" @success="scanCodeSuccess" /> @@ -147,6 +147,8 @@ import { queryMembermember, createMembermember, membermemberScanPay, accountPaym import { useUser } from "@/store/user.js" import { clearNoNum, formatDecimal } from '@/utils' +import { getPayType } from '@/api/account.js' + import scanModal from '@/components/payCard/scanModal.vue' import { ElMessage } from "element-plus"; import { useGlobal } from '@/store/global.js' @@ -202,6 +204,7 @@ const payActive = ref(0) const payType = ref('') const payList = ref([]) const payLoading = ref(false) +const payData = ref({}) // 挂账人 start const showBuyer = ref(false) @@ -281,8 +284,8 @@ function scanCodeSuccess() { // 切换支付类型 async function payTypeChange(index, item) { try { - await staffPermission('yun_xu_shou_kuan') - if (item.disabled) return + // await staffPermission('yun_xu_shou_kuan') + // if (item.disabled) return payActive.value = index payType.value = item.payType if (item.payType == 'scanCode') { @@ -310,27 +313,11 @@ async function confirmOrder() { try { payLoading.value = true // 暂时使用现金支付 - await cashPay({ - shopId: store.shopInfo.id, - checkOrderPay: { - orderId: goodsStore.orderInfo.id, - userId: '', - seatNum: 0, // 用餐人数 - originAmount: goodsStore.orderInfo.originAmount, // 订单原金额(包含打包费+餐位费) 不含折扣价格 - discountRatio: 1, // 折扣比例(计算时 向上取整保留 两位小数) - discountAmount: 0, // 手动优惠金额 - productCouponDiscountAmount: 0, // 商品优惠券抵扣金额 - fullCouponDiscountAmount: 0, // 满减优惠券抵扣金额 - couponList: [], // 用户使用的卡券 - orderAmount: goodsStore.orderInfo.originAmount, // 订单金额 - roundAmount: 0, // 抹零金额 减免多少钱 - pointsDiscountAmount: 0, // 积分抵扣金额(tb_points_basic_setting表) - pointsNum: 0 // 使用的积分数量 (扣除各类折扣 enable_deduction后使用) - } - }) + await cashPay(payData.value) payLoading.value = false ElMessage.success('支付成功') + goodsStore.successDeleteCartItem() emit('paySuccess') return await staffPermission('yun_xu_shou_kuan') @@ -418,9 +405,7 @@ function delHandle() { // 获取支付方式 async function queryPayTypeAjax() { try { - const res = await queryPayType({ - shopId: store.userInfo.shopId - }) + const res = await getPayType() res.map(item => { if (props.amount <= 0 && item.payType == 'scanCode') { @@ -431,7 +416,7 @@ async function queryPayTypeAjax() { }) payList.value = res - if ((res[0].payType == 'scanCode' && !res[0].disabled) || res[0].payType == 'deposit') { + if (res[0].payType == 'scanCode' && !res[0].disabled) { scanModalRef.value.show() payType.value = res[0].payType } @@ -506,7 +491,28 @@ function cancelDiscount() { onMounted(() => { money.value = `${formatDecimal(props.amount)}` - // queryPayTypeAjax() + + payData.value = { + shopId: store.shopInfo.id, + buyerRemark: '', // 订单备注 + checkOrderPay: { + orderId: goodsStore.orderListInfo.id, + userId: '', + seatNum: goodsStore.tableInfo.num, // 用餐人数 + originAmount: goodsStore.orderListInfo.originAmount, // 订单原金额(包含打包费+餐位费) 不含折扣价格 + discountRatio: 1, // 折扣比例(计算时 向上取整保留 两位小数) + discountAmount: 0, // 手动优惠金额 + productCouponDiscountAmount: 0, // 商品优惠券抵扣金额 + fullCouponDiscountAmount: 0, // 满减优惠券抵扣金额 + couponList: [], // 用户使用的卡券 + orderAmount: goodsStore.orderListInfo.originAmount, // 订单金额 + roundAmount: 0, // 抹零金额 减免多少钱 + pointsDiscountAmount: 0, // 积分抵扣金额(tb_points_basic_setting表) + pointsNum: 0 // 使用的积分数量 (扣除各类折扣 enable_deduction后使用) + } + } + + queryPayTypeAjax() }) diff --git a/src/components/payCard/scanModal.vue b/src/components/payCard/scanModal.vue index 028519c..adf5091 100644 --- a/src/components/payCard/scanModal.vue +++ b/src/components/payCard/scanModal.vue @@ -58,6 +58,8 @@ import { scanpay, queryOrder, quickPay, queryQuickPayStatus, accountPay, querySc import { useUser } from "@/store/user.js"; import { useGlobal } from '@/store/global.js' import { formatDecimal } from '@/utils' +import { microPay } from '@/api/order.js' + const store = useUser(); const global = useGlobal() import { @@ -93,6 +95,10 @@ const props = defineProps({ money: { type: [Number, String], default: 0, + }, + payData: { + type: Object, + default: {} } }); @@ -112,14 +118,7 @@ async function submitHandle() { if (!scanCode.value) return; loading.value = true; if (props.selecttype == 1) { - await membermemberScanPay({ - shopId: store.userInfo.shopId, - memberId: props.orderId, - amount: props.amount, - authCode: scanCode.value, - // payAmount: props.money < props.amount ? props.money : '', - // discountAmount: props.money < props.amount ? formatDecimal(props.amount - props.money) : '' - }); + await microPay(props.payData); } else { if (props.fast) { await quickPay({ @@ -129,11 +128,10 @@ async function submitHandle() { }); } else { if (props.payType == 'scanCode') { - await scanpay({ - orderId: props.orderId, - authCode: scanCode.value, - payAmount: props.money < props.amount ? props.money : '', - discountAmount: props.money < props.amount ? formatDecimal(props.amount - props.money) : '' + // 正常下单扫码支付 + await microPay({ + ...props.payData, + authCode: scanCode.value }); } if (props.payType == 'deposit') { diff --git a/src/store/global.js b/src/store/global.js index 4ffbbfc..3ee18d7 100644 --- a/src/store/global.js +++ b/src/store/global.js @@ -1,25 +1,120 @@ import { defineStore } from "pinia"; -export const useGlobal = defineStore({ - id: "global", +export const useGlobal = defineStore("global", { state: () => ({ // 是否监听叫号 isCallNumber: true, - orderMemberInfo: {}, - tableInfo: {}, + orderStatus: [ + { + type: "unpaid", + label: "待支付", + }, + { + type: "in-production", + label: "制作中", + }, + { + type: "wait-out", + label: "待取餐", + }, + { + type: "done", + label: "订单完成", + }, + { + type: "refunding", + label: "申请退单", + }, + { + type: "refund", + label: "退单", + }, + { + type: "part-refund", + label: "部分退单", + }, + { + type: "cancelled", + label: "取消订单", + }, + ], + orderType: [ + { + type: "cash", + label: "收银", + }, + { + type: "miniapp", + label: "小程序", + }, + ], + platformType: [ + { + type: "WX", + label: "微信小程序", + }, + { + type: "ALI", + label: "支付宝小程序", + }, + { + type: "PC", + label: "收银机客户端", + }, + { + type: "APC", + label: "PC管理端", + }, + { + type: "APP", + label: "APP管理端", + }, + ], + dineMode: [ + { + type: "dine-in", + label: "堂食", + }, + { + type: "take-out", + label: "外带", + }, + { + type: "take-away", + label: "外卖", + }, + ], + payType: [ + { + type: "main-scan", + label: "主扫", + }, + { + type: "back-scan", + label: "被扫", + }, + { + type: "wechat-mini", + label: "微信小程序", + }, + { + type: "alipay-mini", + label: "支付宝小程序", + }, + { + type: "vip-pay", + label: "会员支付", + }, + { + type: "cash-pay", + label: "现金支付", + }, + ], }), actions: { // 更新状态 updateData(state) { this.isCallNumber = state; }, - // 设置订单会员信息 - setOrderMember(obj) { - this.orderMemberInfo = obj; - }, - // 设置订单台桌信息 - setOrderTable(obj) { - this.tableInfo = obj; - }, }, }); diff --git a/src/store/goods.js b/src/store/goods.js index 46b811c..09a0b6f 100644 --- a/src/store/goods.js +++ b/src/store/goods.js @@ -5,13 +5,23 @@ import { historyOrder } from "@/api/order.js"; import { useUser } from "@/store/user.js"; import { useSocket } from "@/store/socket.js"; import useStorage from "@/utils/useStorage.js"; +import { formatDecimal } from "@/utils/index.js"; import { ElMessage } from "element-plus"; // 商品store + 购物车store export const useGoods = defineStore("goods", { state: () => ({ vipUserInfo: {}, // 会员信息 - tableInfo: {}, // 台桌信息 + tableInfo: { + name: "A1", + num: 4, + tableCode: "66666666", + }, // 台桌信息 + // tableInfo: { + // name: "", + // num: "", + // tableCode: "", + // }, // 台桌信息 cartActiveIndex: 0, // 购物车激活索引, isCartInit: false, cartList: [], // 购物车列表 @@ -22,6 +32,7 @@ export const useGoods = defineStore("goods", { gifNumberAmount: 0, saleNumber: 0, saleNumberAmount: 0, + tableFee: 0, }, // 购物车信息, goodsName: "", // 商品名称, categoryIndex: useStorage.get("categoryIndex") || 0, // 商品分类索引, @@ -30,16 +41,26 @@ export const useGoods = defineStore("goods", { goodsList: [], // 商品列表 originGoodsList: [], // 原始商品列表 orderList: [], // 订单列表 - orderInfo: {}, // 生成的订单信息 + orderListInfo: "", // 历史订单信息 }), actions: { // 手动选择台桌 selectTable(tableInfo = {}) { const socket = useSocket(); + const store = useUser(); + this.tableInfo = tableInfo; + this.isCartInit = false; // 选择台桌后将购物车初始化 - socket.cartInit(this.tableInfo.tableCode || ""); - // this.historyOrderAjax(this.tableInfo.tableCode); + socket.cartInit(); + if (store.shopInfo.registerType == "after" && this.tableInfo.tableCode) { + this.historyOrderAjax(this.tableInfo.tableCode); + } + + if (!this.tableInfo.tableCode) { + this.orderList = []; + this.orderListInfo = ""; + } }, // 获取订单列表 async historyOrderAjax(tableCode) { @@ -48,8 +69,22 @@ export const useGoods = defineStore("goods", { tableCode: tableCode, }); - // val = this.completeGoodsInfo(val); - // this.orderList = res.records; + if (res) { + this.orderListInfo = res; + + let arr = []; + for (let key in res.detailMap) { + arr.push({ + orderNum: key, + goods: res.detailMap[key].map((item) => { + return this.comleteOrderInfo(item); + }), + }); + } + // val = this.completeGoodsInfo(val); + this.orderList = arr; + console.log(this.orderList); + } } catch (error) { console.log(error); } @@ -145,6 +180,8 @@ export const useGoods = defineStore("goods", { }, // 获取购物车列表,数据必须由长链接返回 async getCartList(arr) { + const store = useUser(); + arr.map((val, index) => { val = this.completeGoodsInfo(val); val.active = false; @@ -157,9 +194,9 @@ export const useGoods = defineStore("goods", { this.isCartInit = true; this.calcCartInfo(); - // if (arr.length && arr[0].table_code) { - // this.historyOrderAjax(arr[0].table_code); - // } + if (this.tableInfo.tableCode && store.shopInfo.registerType == "after") { + this.historyOrderAjax(this.tableInfo.tableCode); + } console.log("getCartList.cartList===", this.cartList); }, // 更新商品列表的角标 @@ -250,7 +287,7 @@ export const useGoods = defineStore("goods", { let sku = val.skuList.find((sku) => sku.id == item.sku_id); let group_text = ""; - if (val.type == "package") { + if (val.type == "package" && item.pro_group_info) { group_text = JSON.parse(item.pro_group_info) .flat() .map((item) => item.proName) @@ -260,11 +297,14 @@ export const useGoods = defineStore("goods", { item.lowPrice = val.lowPrice; item.product_name = val.name; item.sku_name = sku && sku.specInfo; + item.suitNum = sku.suitNum; item.group_type = val.groupType; item.goods_type = val.type; item.skuList = val.skuList; item.selectSpecInfo = val.selectSpecInfo; item.group_text = group_text; + item.packFee = val.packFee; + item.unitName = val.unitName; } }); @@ -275,6 +315,35 @@ export const useGoods = defineStore("goods", { return item; } }, + // 补全订单列表商品信息 + comleteOrderInfo(item) { + this.originGoodsList.map((val) => { + if (val.id == item.productId) { + let sku = val.skuList.find((sku) => sku.id == item.skuId); + + let group_text = ""; + if (val.type == "package") { + group_text = JSON.parse(item.proGroupInfo) + .flat() + .map((item) => item.proName) + .join("、"); + } + + item.lowPrice = val.lowPrice; + item.product_name = val.name; + item.sku_name = sku && sku.specInfo; + item.group_type = val.groupType; + item.goods_type = val.type; + item.skuList = val.skuList; + item.selectSpecInfo = val.selectSpecInfo; + item.group_text = group_text; + item.packFee = val.packFee; + item.unitName = val.unitName; + item.number = item.num; + } + }); + return item; + }, // 删除购物车商品 deleteCartItem() { let tableCode = ""; @@ -322,6 +391,8 @@ export const useGoods = defineStore("goods", { }, // 计算购物车信息 calcCartInfo() { + const store = useUser(); + this.updateGoodsNumber(); let total = 0; // 总数量 @@ -330,10 +401,17 @@ export const useGoods = defineStore("goods", { let gifNumberAmount = 0; // 赠送总金额 let saleNumber = 0; // 打折总数量 let saleNumberAmount = 0; // 打折总金额 + let packFee = 0; // 打包费 + let packFeeNumber = 0; // 打包数量 this.cartList.map((val, index) => { total += +val.number; + if (+val.pack_number && !store.shopInfo.isTableFee) { + packFeeNumber += +val.pack_number; + packFee += +val.pack_number * +val.packFee; + } + if (val.is_temporary) { if (val.is_gift) { gifNumber += +val.number; @@ -380,10 +458,44 @@ export const useGoods = defineStore("goods", { this.cartInfo.saleNumber = saleNumber; this.cartInfo.saleNumberAmount = saleNumberAmount; + this.cartInfo.packFee = packFee; + this.cartInfo.packFeeNumber = packFeeNumber; + this.cartInfo.total = total; - this.cartInfo.totalAmount = totalAmount; + + let tableFee = 0; + if (this.tableInfo.name) { + tableFee = this.tableInfo.num * store.shopInfo.tableFee; + this.tableInfo.tableFee = tableFee; + } + + this.cartInfo.totalAmount = totalAmount + packFee; console.log("this.cartInfo===", this.cartInfo); + + const discountInfo = []; + + if (this.cartInfo.gifNumberAmount) { + discountInfo.push( + `赠送:${formatDecimal(this.cartInfo.gifNumberAmount, 2, true)}元` + ); + } + if (this.cartInfo.saleNumberAmount) { + discountInfo.push( + `改价优惠:${formatDecimal( + this.cartInfo.saleNumberAmount, + 2, + true + )}元` + ); + } + if (this.cartInfo.packFee) { + discountInfo.push( + `打包费:${formatDecimal(this.cartInfo.packFee, 2, true)}元` + ); + } + + this.cartInfo.discountInfo = discountInfo.join(","); }, // 购物车操作 async operateCart(data, operate_type = "add") { diff --git a/src/store/socket.js b/src/store/socket.js index 1867bcd..6585dd6 100644 --- a/src/store/socket.js +++ b/src/store/socket.js @@ -35,13 +35,14 @@ export const useSocket = defineStore("socket", { ), cartInit(tableCode = "") { const store = useUser(); + const goodsStore = useGoods() this.ws.send( JSON.stringify({ type: "cashier", account: `cashier_${store.shopInfo.id}`, operate_type: "init", shop_id: store.shopInfo.id, - table_code: tableCode, // 后期选台桌号 + table_code: goodsStore.tableInfo.tableCode, }) ); }, diff --git a/src/utils/request.js b/src/utils/request.js index a22cb4e..01bdaec 100644 --- a/src/utils/request.js +++ b/src/utils/request.js @@ -9,7 +9,7 @@ const service = axios.create({ ? "/api/" : import.meta.env.VITE_API_URL, // withCredentials: true, // 跨域请求时发送 cookies - timeout: 5000, // 请求超时 + timeout: 10000, // 请求超时 }); // 请求拦截器 diff --git a/src/views/home/components/cartItem.vue b/src/views/home/components/cartItem.vue new file mode 100644 index 0000000..08f3bfa --- /dev/null +++ b/src/views/home/components/cartItem.vue @@ -0,0 +1,231 @@ + + + + + \ No newline at end of file diff --git a/src/views/home/components/cartOperation.vue b/src/views/home/components/cartOperation.vue index 6288cb1..76421a8 100644 --- a/src/views/home/components/cartOperation.vue +++ b/src/views/home/components/cartOperation.vue @@ -1,7 +1,7 @@ \ No newline at end of file diff --git a/src/views/home/components/tableMerging.vue b/src/views/home/components/tableMerging.vue index 20fddb8..c28a066 100644 --- a/src/views/home/components/tableMerging.vue +++ b/src/views/home/components/tableMerging.vue @@ -42,6 +42,7 @@ \ No newline at end of file diff --git a/src/views/order/index copy.vue b/src/views/order/index copy.vue new file mode 100644 index 0000000..ae576c5 --- /dev/null +++ b/src/views/order/index copy.vue @@ -0,0 +1,1209 @@ + + + + + diff --git a/src/views/order/index.vue b/src/views/order/index.vue index ae576c5..fb5f232 100644 --- a/src/views/order/index.vue +++ b/src/views/order/index.vue @@ -1,1209 +1,214 @@