From f961bf7d92a2bcb66c452ae66cbe2d58e999323d Mon Sep 17 00:00:00 2001 From: YeMingfei666 <1619116647@qq.com> Date: Fri, 21 Feb 2025 14:42:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=BB=A3=E5=AE=A2=E4=B8=8B?= =?UTF-8?q?=E5=8D=95=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 + src/api/product/index.ts | 304 +++++++++++- .../NavBar/components/Notification.vue | 40 +- src/router/index.ts | 2 +- src/store/modules/carts.ts | 228 +++++++++ src/store/modules/user.ts | 2 +- src/utils/websocket.ts | 75 ++- .../admim/system/miniAppPages/config/add.ts | 92 ++-- .../system/miniAppPages/config/config.ts | 30 +- .../system/miniAppPages/config/content.ts | 72 ++- .../admim/system/miniAppPages/config/edit.ts | 97 ++-- .../system/miniAppPages/config/search.ts | 27 +- src/views/admim/system/miniAppPages/index.vue | 11 +- .../shop/list/components/detailModal.vue | 2 +- .../tool/Instead/components/carts/item.vue | 465 ++++++++++++++++++ .../tool/Instead/components/carts/list.vue | 146 ++++++ src/views/tool/Instead/components/control.vue | 143 ++++++ .../Instead/components/dialog-goods-sel.vue | 147 ++++++ .../tool/Instead/components/goods-item.vue | 50 ++ src/views/tool/Instead/components/note.vue | 96 ++++ src/views/tool/Instead/components/pack.vue | 60 +++ src/views/tool/Instead/index.vue | 403 +++++++++++++++ src/views/tool/Instead/quan_util.js | 250 ++++++++++ src/views/tool/Instead/util.js | 231 +++++++++ 24 files changed, 2780 insertions(+), 199 deletions(-) create mode 100644 src/store/modules/carts.ts create mode 100644 src/views/tool/Instead/components/carts/item.vue create mode 100644 src/views/tool/Instead/components/carts/list.vue create mode 100644 src/views/tool/Instead/components/control.vue create mode 100644 src/views/tool/Instead/components/dialog-goods-sel.vue create mode 100644 src/views/tool/Instead/components/goods-item.vue create mode 100644 src/views/tool/Instead/components/note.vue create mode 100644 src/views/tool/Instead/components/pack.vue create mode 100644 src/views/tool/Instead/index.vue create mode 100644 src/views/tool/Instead/quan_util.js create mode 100644 src/views/tool/Instead/util.js diff --git a/README.md b/README.md index 97fb75b..8137a30 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ 基于 Vue3 + Vite5+ TypeScript5 + Element-Plus + Pinia 等主流技术栈构建 +## 宝塔 + +101.37.12.135:19928/mianban +chaozg +chaozg123 + ## API文档 [超掌柜收银机](https://app.apifox.com/project/5827475) diff --git a/src/api/product/index.ts b/src/api/product/index.ts index 42a00d8..de2d7f8 100644 --- a/src/api/product/index.ts +++ b/src/api/product/index.ts @@ -55,4 +55,306 @@ export interface Responseres { [property: string]: any; } -export default AuthAPI; \ No newline at end of file +export default AuthAPI; + + +export interface Response { + code: number; + data: Data; + msg: string; + [property: string]: any; +} + +export interface Data { + pageNumber: string; + pageSize: string; + records: Record[]; + totalPage: string; + totalRow: string; + [property: string]: any; +} + +export interface Record { + /** + * 分类id + */ + categoryId: string; + /** + * 分类名称 + */ + categoryName: string; + /** + * 封面图url + */ + coverImg: string; + /** + * 创建时间 + */ + createTime: string; + /** + * 定时上下架周期 + */ + days: string; + /** + * 起用结束时间 + */ + endTime: string; + /** + * 团购卷分类,可有多个分类 + */ + groupCategoryId: string; + /** + * 套餐内容 + */ + groupSnap: GroupSnap[]; + /** + * 套餐类型,0 固定套餐 1可选套餐 + */ + groupType: number; + /** + * 商品id + */ + id: string; + /** + * 封面图urls + */ + images: string[]; + /** + * 是否允许临时改价 + */ + isAllowTempModifyPrice: number; + /** + * 是否逻辑删除 + */ + isDel: number; + /** + * 是否推荐 + */ + isHot: number; + /** + * 退款是否退回库存 + */ + isRefundStock: number; + /** + * 是否上架 + */ + isSale: number; + /** + * 是否售罄 + */ + isSoldStock: number; + /** + * 是否启用库存 + */ + isStock: number; + /** + * 会员最低价 + */ + lowMemberPrice: number; + /** + * 商品最低价 + */ + lowPrice: number; + /** + * 商品名称 + */ + name: string; + /** + * 打包费 + */ + packFee: number; + /** + * 套餐详情入参使用 + */ + proGroupVo: string[]; + selectSpecInfo: { [key: string]: any }; + /** + * 店铺id + */ + shopId: string; + /** + * 商品介绍 + */ + shortTitle: string; + /** + * sku集合 + */ + skuList: SkuList[]; + /** + * 排序值 + */ + sort: number; + /** + * 规格完整名称 + */ + specFullName: string; + /** + * 规格id + */ + specId: null; + /** + * 规格名称 + */ + specName: string; + /** + * 起用开始时间 + */ + startTime: string; + /** + * 库存 + */ + stockNumber: number; + /** + * 商品类型,single-单规格商品 sku-多规格商品 package-套餐商品 weight-称重商品 coupon-团购券 + */ + type: string; + /** + * 单位id + */ + unitId: string; + /** + * 单位名称 + */ + unitName: string; + /** + * 更新时间 + */ + updateTime: string; + /** + * 库存警戒线 + */ + warnLine: number; + /** + * 重量 + */ + weight?: number; + [property: string]: any; +} + +export interface GroupSnap { + /** + * 套餐内商品总数 + */ + count: number; + /** + * 套餐内商品列表 + */ + goods: Good[]; + /** + * 可选套餐几选几,固定套餐没有值 + */ + number: number; + /** + * 可选套餐名称 + */ + title: string; + [property: string]: any; +} + +export interface Good { + /** + * 商品数量 + */ + number: string; + /** + * 商品单价 + */ + price: number; + /** + * 商品ID + */ + proId: number; + /** + * 商品名称 + */ + proName: string; + /** + * skuId + */ + skuId: number; + /** + * sku名称 + */ + skuName: string; + /** + * 单位名称 + */ + unitName: string; + [property: string]: any; +} + +export interface SkuList { + /** + * 条形码 + */ + barCode: string; + /** + * 成本价 + */ + costPrice: number; + /** + * 封面图 + */ + coverImg: string; + /** + * 创建时间 + */ + createTime: string; + /** + * sku-id + */ + id: string; + /** + * 是否已删除 + */ + isDel: number; + /** + * 是否上架 + */ + isGrounding: number; + /** + * 是否售罄 + */ + isPauseSale: number; + /** + * 会员价 + */ + memberPrice: number; + /** + * 原价 + */ + originPrice: number; + /** + * 商品id + */ + productId: string; + /** + * 销量 + */ + realSalesNumber: number; + /** + * 售价 + */ + salePrice: number; + /** + * 店铺id + */ + shopId: string; + /** + * 规格详情 + */ + specInfo: string; + /** + * 起售数量 + */ + suitNum: number; + /** + * 更新时间 + */ + updateTime: string; + /** + * 重量 + */ + weight: null; + [property: string]: any; +} \ No newline at end of file diff --git a/src/layout/components/NavBar/components/Notification.vue b/src/layout/components/NavBar/components/Notification.vue index aed67a3..3dd0920 100644 --- a/src/layout/components/NavBar/components/Notification.vue +++ b/src/layout/components/NavBar/components/Notification.vue @@ -181,27 +181,25 @@ onMounted(() => { // NoticeAPI.getMyNoticePage({ pageNum: 1, pageSize: 5, isRead: 0 }).then((data) => { // notices.value = data.list; // }); - - WebSocketManager.subscribeToTopic("/user/queue/message", (message) => { - console.log("收到消息:", message); - const data = JSON.parse(message); - const id = data.id; - if (!notices.value.some((notice) => notice.id == id)) { - notices.value.unshift({ - id, - title: data.title, - type: data.type, - publishTime: data.publishTime, - }); - - ElNotification({ - title: "您收到一条新的通知消息!", - message: data.title, - type: "success", - position: "bottom-right", - }); - } - }); + // WebSocketManager.subscribeToTopic("/user/queue/message", (message) => { + // console.log("收到消息:", message); + // const data = JSON.parse(message); + // const id = data.id; + // if (!notices.value.some((notice) => notice.id == id)) { + // notices.value.unshift({ + // id, + // title: data.title, + // type: data.type, + // publishTime: data.publishTime, + // }); + // ElNotification({ + // title: "您收到一条新的通知消息!", + // message: data.title, + // type: "success", + // position: "bottom-right", + // }); + // } + // }); }); // 阅读通知公告 diff --git a/src/router/index.ts b/src/router/index.ts index a13620e..673113e 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -311,7 +311,7 @@ export const constantRoutes: RouteRecordRaw[] = [ children: [ { path: "index", - component: () => import("@/views/tool/index.vue"), + component: () => import("@/views/tool/Instead/index.vue"), name: "toolIndex", meta: { title: "代客下单", diff --git a/src/store/modules/carts.ts b/src/store/modules/carts.ts new file mode 100644 index 0000000..e2a41d7 --- /dev/null +++ b/src/store/modules/carts.ts @@ -0,0 +1,228 @@ +import { store } from "@/store"; +import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket"; + +export interface CartsState { + id: string | number; + [property: string]: any; +} + +export const useCartsStore = defineStore("carts", () => { + //当前购物车数据 + const list = useStorage("carts", []); + //赠菜 + const giftList = useStorage("giftList", []); + let goodsMap: { [key: string]: any } = {}; + //当前选中cart + let selListIndex = ref(-1); + //当前选中商品是否是赠菜 + const isSelGift = ref(false); + const defaultCart = { + id: '', + number: 0, + } + const selCart = computed(() => { + if (isSelGift.value) { + return giftList.value[selListIndex.value] || defaultCart + } + return list.value[selListIndex.value] || defaultCart + }) + //赠菜总价 + const giftMoney = computed(() => { + return giftList.value.reduce((acc: number, cur: any) => { + return acc + cur.number * cur.salePrice + }, 0) + }) + const yiyouhui = computed(() => { + const youhui = giftMoney.value + if (youhui > 0) { + return '已优惠¥' + youhui.toFixed(2) + } + return '' + }) + + //支付总价 + const payMoney = computed(() => { + const money = list.value.reduce((acc: number, cur: any) => { + return acc + cur.number * cur.salePrice + }, 0) + return money.toFixed(2) + }) + //总计数量 + const totalNumber = computed(() => { + const cartNumber = list.value.reduce((acc: number, cur: any) => { + return acc + cur.number * 1 + }, 0) + const giftNumber = list.value.reduce((acc: number, cur: any) => { + return acc + cur.number * 1 + }, 0) + return cartNumber + giftNumber + }) + + + const table_code = ref(''); + function changeNumber(step: number, item: CartsState) { + if (item.number * 1 + step <= 0) { + del(item); + return; + } + update({ ...item, number: step * 1 }); + } + + function changeSelCart(cart: CartsState) { + console.log(cart) + if (!cart.id) { + return + } + if (cart.is_gift) { + isSelGift.value = true + selListIndex.value = giftList.value.findIndex((item: CartsState) => item.id === cart.id); + console.log(selListIndex.value) + + } else { + isSelGift.value = false + selListIndex.value = list.value.findIndex((item: CartsState) => item.id === cart.id); + } + } + function add(data: any) { + sendMessage('add', data); + } + function del(data: any) { + sendMessage('del', data); + } + + function update(data: any) { + console.log(data); + sendMessage('edit', data); + } + function updateTag(key: string, val: any) { + sendMessage('edit', { ...selCart.value, number: 0, [key]: val }); + } + function clear() { + sendMessage('cleanup', {}); + } + function getProductDetails(v: { product_id: string, sku_id: string }) { + const goods = goodsMap[v.product_id] + const skuData = goods?.skuList.find((sku: { id: string, salePrice: number }) => sku.id == v.sku_id); + if (skuData) { + return { + salePrice: skuData ? skuData.salePrice : 0, + coverImg: goods.coverImg, + name: goods.name + } + } else { + return undefined + } + } + + function init(initParams: ApifoxModel, $goodsMap: any) { + // 商品id对应的数据map + goodsMap = $goodsMap + table_code.value = initParams && initParams.table_code ? initParams.table_code : ''; + WebSocketManager.subscribeToTopic(initParams, (msg) => { + console.log("收到消息:", msg); + if (msg.hasOwnProperty('status') && msg.status != 1) { + return ElMessage.error(msg.message || '操作失败') + } + // 初始化 + if (msg.operate_type === "manage_init") { + // 设置单价 + list.value = msg.data.filter((v: { is_gift: any; }) => !v.is_gift).map((v: Record) => { + const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id }) + return { + ...skuData, + ...v, + } + }); + giftList.value = msg.data.filter((v: { is_gift: any; }) => v.is_gift).map((v: Record) => { + const skuData = getProductDetails({ product_id: v.product_id, sku_id: v.sku_id }) + return { + ...skuData, + ...v, + } + }); + console.log(giftList.value) + } + if (msg.operate_type === "manage_add") { + const skuData = getProductDetails({ product_id: msg.data[0].product_id, sku_id: msg.data[0].sku_id }) + list.value.push({ ...skuData, ...msg.data[0] }) + return ElMessage.success(msg.message || '添加成功') + + } + if (msg.operate_type === "manage_edit") { + const newCart = msg.data[0] + const index = list.value.findIndex((item) => item.id === newCart.id) + const giftIndex = giftList.value.findIndex((item) => item.id === newCart.id) + const cartItem = list.value[index]; + const giftItem = giftList.value[giftIndex]; + if (isSelGift.value) { + //操作赠菜 + if (newCart.is_gift != giftItem.is_gift) { + //修改了赠菜状态 + giftList.value.splice(giftIndex, 1) + list.value.push({ ...giftItem, ...newCart }) + selListIndex.value = -1 + } else { + giftList.value[giftIndex] = { ...giftItem, ...newCart } + } + return + } + if (!isSelGift.value) { + //操作非赠菜 + if (newCart.is_gift != cartItem.is_gift) { + list.value.splice(index, 1) + giftList.value.push({ ...cartItem, ...newCart }) + selListIndex.value = -1 + } else { + list.value[index] = { ...cartItem, ...newCart } + } + return + } + + } + if (msg.operate_type === "manage_del") { + if (!isSelGift.value) { + const index = list.value.findIndex((item) => item.id === msg.data.id) + if (index > -1) { + list.value.splice(index, 1) + if (list.value.length >= 1) { + selListIndex.value = index - 1; + } + return ElMessage.success(msg.message || '删除成功') + } + } else { + const index = giftList.value.findIndex((item) => item.id === msg.data.id) + if (index > -1) { + giftList.value.splice(index, 1) + if (giftList.value.length >= 1) { + selListIndex.value = index - 1; + } + return ElMessage.success(msg.message || '删除成功') + } + } + + + } + console.log(list.value) + }); + } + function sendMessage(operate_type: msgType, message: any) { + console.log({ ...message, operate_type: operate_type, table_code: table_code.value }) + WebSocketManager.sendMessage({ ...message, operate_type: operate_type, table_code: table_code.value }); + } + return { + updateTag, + list, + add, + del, + update, + init, + changeNumber, + selCart, totalNumber, + changeSelCart, payMoney, + clear, yiyouhui, giftList + }; +}); + +export function useDictStoreHook() { + return useCartsStore(store); +} diff --git a/src/store/modules/user.ts b/src/store/modules/user.ts index da9e44c..28fc8e4 100644 --- a/src/store/modules/user.ts +++ b/src/store/modules/user.ts @@ -23,7 +23,7 @@ export const useUserStore = defineStore("user", () => { return new Promise((resolve, reject) => { AuthAPI.login(loginRequest) .then((data) => { - Object.assign(userInfo.value, { ...data.shopInfo }); + Object.assign(userInfo.value, { ...data.shopInfo, shopId: data.shopInfo.id }); promissionList.value = data.promissionList; const token = data.tokenInfo.tokenValue; setToken(token); // Bearer eyJhbGciOiJIUzI1NiJ9.xxx.xxx diff --git a/src/utils/websocket.ts b/src/utils/websocket.ts index 3b3bf13..da3e637 100644 --- a/src/utils/websocket.ts +++ b/src/utils/websocket.ts @@ -1,6 +1,36 @@ +import qs from "qs"; +import { useUserStoreHook } from "@/store"; + +const user = useUserStoreHook() + +export interface ApifoxModel { + account: string; + /** + * 操作类型 + */ + operate_type: string; + shop_id: string; + /** + * 桌码 + */ + table_code?: string; + /** + * 消息类型 + */ + type: string; + [property: string]: any; +} +export type msgType = 'add' | 'reduce' | 'remove' | 'edit' | 'init' | 'cleanup' | 'del' class WebSocketManager { private client: WebSocket | null = null; private connected: boolean = false; + private initParams: ApifoxModel = { + type: 'manage', + account: `${user.userInfo.shopId}`, + operate_type: 'init', + table_code: '', + shop_id: `${user.userInfo.shopId}`, + }; private onMessage: (message: any) => void = function () { }; private messageHandlers: Map void)[]> = new Map(); private type: string = 'manage'; @@ -22,11 +52,13 @@ class WebSocketManager { console.log("客户端已存在并且连接正常"); return this.client; } - this.client = new WebSocket(endpoint) + const url = qs.stringify(this.initParams) + console.log(this.initParams) + this.client = new WebSocket(endpoint + '?' + url); this.client.onopen = () => { this.connected = true; console.log("WebSocket 连接已建立"); - this.sendMessage('test') + this.sendMessage(this.initParams) }; this.client.onclose = () => { this.connected = false; @@ -42,28 +74,45 @@ class WebSocketManager { }; this.client.onmessage = (event) => { const message = event.data; - this.getMessage(message) + const msg = JSON.parse(message) + if (msg && msg.msg_id) { + this.onMessageHandler({ msg_id: msg.msg_id }) + } + this.onMessage(msg); }; } - private getMessage(message: any) { - console.log("收到消息:", message); + + // 消息回执 + public onMessageHandler(data: any) { + if (this.client) { + this.client.send(JSON.stringify({ ...data, type: 'receipt' })); + } } // 订阅主题 - public subscribeToTopic(topic: string, onMessage: (message: string) => void) { - console.log(`正在订阅主题: ${topic}`); - if (!this.client || !this.connected) { - this.setupWebSocket(); - } - if (this.connected) { - this.onMessage = onMessage; + public subscribeToTopic(initParams: ApifoxModel, onMessage: (message: any) => void) { + console.log(`正在订阅主题: `); + console.log(initParams); + + this.initParams = { ...this.initParams, ...initParams } + if (this.client && this.connected) { + this.disconnect(); } + this.setupWebSocket(); + this.onMessage = onMessage; } public sendMessage(message: any) { if (this.client) { - this.client.send(message); + const msg = JSON.stringify({ + ...this.initParams, + ...message, + }) + this.client.send(msg); } } + public canSendMessage() { + return this.client && this.connected; + } // 断开 WebSocket 连接 public disconnect() { if (this.client) { diff --git a/src/views/admim/system/miniAppPages/config/add.ts b/src/views/admim/system/miniAppPages/config/add.ts index 17223ca..8743270 100644 --- a/src/views/admim/system/miniAppPages/config/add.ts +++ b/src/views/admim/system/miniAppPages/config/add.ts @@ -1,11 +1,10 @@ -import VersionApi, { type addRequest } from "@/api/system/version"; -import { sourceOptions, typeOptions, isForceOptions } from "./config"; +import API, { type addRequest } from "@/api/system/miniAppPages"; import type { IModalConfig } from "@/components/CURD/types"; const modalConfig: IModalConfig = { pageName: "sys:user", dialog: { - title: "新增版本", + title: "新增小程序页面", width: 800, draggable: true, }, @@ -13,75 +12,78 @@ const modalConfig: IModalConfig = { labelWidth: 140, }, formAction: function (data) { - return VersionApi.add({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] }); + if (data.icon) { + data.icon = typeof data.icon === "string" ? data.icon : data.icon[0] + } + return API.add(data); }, beforeSubmit(data) { console.log("提交之前处理", data); }, formItems: [ + { - label: "渠道", - prop: "source", - rules: [{ required: true, message: "请选择渠道", trigger: "blur" }], - type: "select", + type: "UpImage", + label: "图标", + prop: "icon", + rules: [{ required: false, message: "请上传图标", trigger: "blur" }], attrs: { - placeholder: "请选择渠道", + placeholder: "请上传图标", }, - options: sourceOptions, - }, - { - label: "类型", - prop: "type", - rules: [{ required: true, message: "请选择类型", trigger: "blur" }], - type: "select", - attrs: { - placeholder: "请选择类型", - }, - col: { - xs: 24, - sm: 12, - }, - options: typeOptions, }, { type: "input", - label: "版本号", - prop: "version", - rules: [{ required: true, message: "请输入版本号", trigger: "blur" }], + label: "小程序页面名称", + prop: "name", + rules: [{ required: true, message: "请输入小程序页面名称", trigger: "blur" }], attrs: { - placeholder: "请输入版本号", + placeholder: "请输入小程序页面名称", }, }, { - type: "radio", - label: "是否强制更新", - prop: "isForce", - rules: [{ required: true, message: "请输入版本号", trigger: "blur" }], + type: "input", + label: "小程序页面路径", + prop: "path", + rules: [{ required: true, message: "请输入小程序页面路径", trigger: "blur" }], attrs: { - placeholder: "请输入版本号", + placeholder: "请输入小程序页面路径", }, - initialValue: 0, - options: isForceOptions, }, { type: "textarea", - label: "更新提示内容", - prop: "message", - rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }], + label: "页面描述", + prop: "description", + rules: [{ required: false, message: "请输入页面描述", trigger: "blur" }], attrs: { - placeholder: "请输入更新提示内容", + placeholder: "请输入页面描述", }, }, { - type: "custom", - label: "版本文件", - prop: "url", - rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }], + type: "input-number", + label: "排序", + prop: "sort", + rules: [{ required: false, message: "请输入排序", trigger: "blur" }], attrs: { - placeholder: "请上传版本文件", + placeholder: "请输入排序", }, - initialValue: [], + initialValue: 0, }, + { + type: "radio-button", + label: "小程序页面状态", + prop: "status", + options: [ + { + label: "启用", + value: 1, + }, + { + label: "禁用", + value: 0, + }, + ], + initialValue: 1, + } ], }; diff --git a/src/views/admim/system/miniAppPages/config/config.ts b/src/views/admim/system/miniAppPages/config/config.ts index b956baa..8739ffe 100644 --- a/src/views/admim/system/miniAppPages/config/config.ts +++ b/src/views/admim/system/miniAppPages/config/config.ts @@ -1,31 +1,17 @@ import { property } from "lodash"; -export const sourceOptions: options[] = [ - { label: "桌面端", value: "pc" }, - { label: "管理端", value: "manager_app" }, - { label: "电话机点餐", value: "phone_book " }, -]; -export const typeOptions: options[] = [ - { label: "windows", value: "0" }, - { label: "安卓", value: "1" }, - { label: "IOS", value: "2" }, -]; -export const isForceOptions: options[] = [ - { label: "不强制更新", value: 0 }, - { label: "强制更新", value: 1 }, +export const statusOptions: options[] = [ + { label: "全部", value: '' }, + { label: "启用", value: 1 }, + { label: "禁用", value: 0 }, ]; -export type optionsType = "source" | "type" | "isForce"; + +export type optionsType = "status"; export function returnOptions(type: optionsType) { - if (type === "source") { - return sourceOptions; - } - if (type === "type") { - return typeOptions; - } - if (type === "isForce") { - return isForceOptions; + if (type === "status") { + return statusOptions; } } diff --git a/src/views/admim/system/miniAppPages/config/content.ts b/src/views/admim/system/miniAppPages/config/content.ts index 1590471..f20b18e 100644 --- a/src/views/admim/system/miniAppPages/config/content.ts +++ b/src/views/admim/system/miniAppPages/config/content.ts @@ -1,5 +1,4 @@ -import VersionApi from "@/api/system/version"; -import type { editRequest } from "@/api/system/version"; +import API, { type editRequest } from "@/api/system/miniAppPages"; import type { IContentConfig } from "@/components/CURD/types"; const contentConfig: IContentConfig = { @@ -15,61 +14,50 @@ const contentConfig: IContentConfig = { pageSizes: [10, 20, 30, 50], }, indexAction: function (params) { - return VersionApi.getList(); + return API.getList(params); }, - deleteAction: VersionApi.delete, + deleteAction: API.delete, // modifyAction: function (data) { - // // return VersionApi.edit(data); + // // return API.edit(data); // }, pk: "id", toolbar: ["add"], defaultToolbar: ["refresh", "filter", "search"], cols: [ { type: "selection", width: 50, align: "center" }, - { label: "id", align: "center", prop: "id", width: 100, show: true }, { - label: "渠道", + label: "小程序页面名称", align: "center", - prop: "source", - width: 120, + prop: "name", + }, + { + label: "图标", + align: "center", + prop: "icon", templet: "custom", - slotName: "options", + slotName: "icon", }, { - label: "类型", + label: "小程序页面路径", align: "center", - prop: "type", - width: 120, + prop: "path", + }, + { + label: "页面描述", + align: "center", + prop: "description", + }, + { + label: "排序", + align: "center", + prop: "sort", + }, + { + label: "状态", + align: "center", + prop: "status", templet: "custom", - slotName: "options", - }, - { - label: "版本号", - align: "center", - width: 120, - prop: "version", - }, - - { - label: "是否强制升级", - align: "center", - prop: "isForce", - width: 120, - templet: "switch", - slotName: "isForce", - }, - { - label: "更新内容", - align: "center", - prop: "message", - width: 240, - }, - { - label: "下载地址", - align: "center", - prop: "url", - templet: "url", - slotName: "url", + slotName: "status", }, { label: "操作", diff --git a/src/views/admim/system/miniAppPages/config/edit.ts b/src/views/admim/system/miniAppPages/config/edit.ts index 105f37c..58d5477 100644 --- a/src/views/admim/system/miniAppPages/config/edit.ts +++ b/src/views/admim/system/miniAppPages/config/edit.ts @@ -1,86 +1,91 @@ -import VersionApi, { type editRequest } from "@/api/system/version"; +import API, { type editRequest } from "@/api/system/miniAppPages"; import type { IModalConfig } from "@/components/CURD/types"; -import { sourceOptions, typeOptions, isForceOptions } from "./config"; const modalConfig: IModalConfig = { pageName: "sys:user", dialog: { - title: "编辑版本", + title: "编辑小程序页面", width: 800, draggable: true, }, - pk: "id", + form: { + labelWidth: 140, + }, formAction: function (data) { - return VersionApi.edit({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] }); + if (data.icon) { + data.icon = typeof data.icon === "string" ? data.icon : data.icon[0] + } + return API.edit(data); }, beforeSubmit(data) { console.log("提交之前处理", data); }, formItems: [ + { - label: "渠道", - prop: "source", - rules: [{ required: true, message: "请选择渠道", trigger: "blur" }], - type: "select", + type: "UpImage", + label: "图标", + prop: "icon", + rules: [{ required: false, message: "请上传图标", trigger: "blur" }], attrs: { - placeholder: "请选择渠道", + placeholder: "请上传图标", }, - options: sourceOptions, - }, - { - label: "类型", - prop: "type", - rules: [{ required: true, message: "请选择类型", trigger: "blur" }], - type: "select", - attrs: { - placeholder: "请选择类型", - }, - col: { - xs: 24, - sm: 12, - }, - options: typeOptions, }, { type: "input", - label: "版本号", - prop: "version", - rules: [{ required: true, message: "请输入版本号", trigger: "blur" }], + label: "小程序页面名称", + prop: "name", + rules: [{ required: true, message: "请输入小程序页面名称", trigger: "blur" }], attrs: { - placeholder: "请输入版本号", + placeholder: "请输入小程序页面名称", }, }, { - type: "radio", - label: "是否强制更新", - prop: "isForce", - rules: [{ required: true, message: "请输入版本号", trigger: "blur" }], + type: "input", + label: "小程序页面路径", + prop: "path", + rules: [{ required: true, message: "请输入小程序页面路径", trigger: "blur" }], attrs: { - placeholder: "请输入版本号", + placeholder: "请输入小程序页面路径", }, - initialValue: 0, - options: isForceOptions, }, { type: "textarea", - label: "更新提示内容", - prop: "message", - rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }], + label: "页面描述", + prop: "description", + rules: [{ required: false, message: "请输入页面描述", trigger: "blur" }], attrs: { - placeholder: "请输入更新提示内容", + placeholder: "请输入页面描述", }, }, { - type: "custom", - label: "版本文件", - prop: "url", - rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }], + type: "input-number", + label: "排序", + prop: "sort", + rules: [{ required: false, message: "请输入排序", trigger: "blur" }], attrs: { - placeholder: "请上传版本文件", + placeholder: "请输入排序", }, - initialValue: [], + initialValue: 0, }, + { + type: "radio-button", + label: "小程序页面状态", + prop: "status", + options: [ + { + label: "启用", + value: 1, + }, + { + label: "禁用", + value: 0, + }, + ], + initialValue: 1, + } ], }; +// 如果有异步数据会修改配置的,推荐用reactive包裹,而纯静态配置的可以直接导出 export default reactive(modalConfig); diff --git a/src/views/admim/system/miniAppPages/config/search.ts b/src/views/admim/system/miniAppPages/config/search.ts index 29cbdd9..915f0b2 100644 --- a/src/views/admim/system/miniAppPages/config/search.ts +++ b/src/views/admim/system/miniAppPages/config/search.ts @@ -1,20 +1,39 @@ import type { ISearchConfig } from "@/components/CURD/types"; - +import { statusOptions } from './config' const searchConfig: ISearchConfig = { pageName: "sys:user", formItems: [ { type: "input", - label: "版本号", - prop: "keywords", + label: "小程序页面路径", + prop: "name", attrs: { - placeholder: "请输入版本号", + placeholder: "请输入小程序页面路径", clearable: true, style: { width: "200px", }, }, }, + { + type: "input", + label: "小程序页面路径", + prop: "path", + attrs: { + placeholder: "请输入小程序页面路径", + clearable: true, + style: { + width: "200px", + }, + }, + }, + { + type: "radio-button", + label: "小程序页面状态", + prop: "status", + options: statusOptions, + initialValue: '', + } ], }; diff --git a/src/views/admim/system/miniAppPages/index.vue b/src/views/admim/system/miniAppPages/index.vue index 9653963..47f967e 100644 --- a/src/views/admim/system/miniAppPages/index.vue +++ b/src/views/admim/system/miniAppPages/index.vue @@ -25,6 +25,13 @@ {{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }} + @@ -99,8 +106,8 @@ async function handleEditClick(row: IObject) { editModalRef.value?.setModalVisible(); // 根据id获取数据进行填充 // const data = await Api.getFormData(row.id); - console.log({ ...row, url: [row.url] }); - editModalRef.value?.setFormData({ ...row, url: [row.url] }); + console.log({ ...row, icon: row.icon ? [row.icon] : [] }); + editModalRef.value?.setFormData({ ...row, icon: row.icon ? [row.icon] : [] }); } 1; // 其他工具栏 diff --git a/src/views/shop/list/components/detailModal.vue b/src/views/shop/list/components/detailModal.vue index 42e69d0..c7011aa 100644 --- a/src/views/shop/list/components/detailModal.vue +++ b/src/views/shop/list/components/detailModal.vue @@ -144,7 +144,7 @@ export default { \ No newline at end of file diff --git a/src/views/tool/Instead/components/carts/item.vue b/src/views/tool/Instead/components/carts/item.vue new file mode 100644 index 0000000..801a7b8 --- /dev/null +++ b/src/views/tool/Instead/components/carts/item.vue @@ -0,0 +1,465 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/carts/list.vue b/src/views/tool/Instead/components/carts/list.vue new file mode 100644 index 0000000..ce1cd2e --- /dev/null +++ b/src/views/tool/Instead/components/carts/list.vue @@ -0,0 +1,146 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/control.vue b/src/views/tool/Instead/components/control.vue new file mode 100644 index 0000000..c595053 --- /dev/null +++ b/src/views/tool/Instead/components/control.vue @@ -0,0 +1,143 @@ + + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/dialog-goods-sel.vue b/src/views/tool/Instead/components/dialog-goods-sel.vue new file mode 100644 index 0000000..06d6674 --- /dev/null +++ b/src/views/tool/Instead/components/dialog-goods-sel.vue @@ -0,0 +1,147 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/goods-item.vue b/src/views/tool/Instead/components/goods-item.vue new file mode 100644 index 0000000..9007ce9 --- /dev/null +++ b/src/views/tool/Instead/components/goods-item.vue @@ -0,0 +1,50 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/note.vue b/src/views/tool/Instead/components/note.vue new file mode 100644 index 0000000..da775bb --- /dev/null +++ b/src/views/tool/Instead/components/note.vue @@ -0,0 +1,96 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/components/pack.vue b/src/views/tool/Instead/components/pack.vue new file mode 100644 index 0000000..c6048c3 --- /dev/null +++ b/src/views/tool/Instead/components/pack.vue @@ -0,0 +1,60 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/index.vue b/src/views/tool/Instead/index.vue new file mode 100644 index 0000000..1036c6a --- /dev/null +++ b/src/views/tool/Instead/index.vue @@ -0,0 +1,403 @@ + + + + \ No newline at end of file diff --git a/src/views/tool/Instead/quan_util.js b/src/views/tool/Instead/quan_util.js new file mode 100644 index 0000000..14b4747 --- /dev/null +++ b/src/views/tool/Instead/quan_util.js @@ -0,0 +1,250 @@ +export function isTui(item) { + return item.status == 'return' || item.status == 'refund' || item.status == 'refunding' +} +//是否使用会员价 +export function isUseVipPrice(vipUser,goods){ + return vipUser.id&&vipUser.isVip&&goods.isMember +} + +//计算商品券优惠价格 +export function returnProductCouponPrice(coup, goodsArr, vipUser) { + const item = goodsArr.find(v => v.productId == coup.proId); + if (!item) { + return 0 + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0; + return price * coup.num + +} +//返回新的商品列表,过滤掉退菜的,退单的商品 +export function returnNewGoodsList(arr) { + let goodsMap = {} + return arr.filter(v => !isTui(v)) +} +//根据当前购物车商品以及数量,已选券对应商品数量,判断该商品券是否可用 +export function returnCoupCanUse(goodsArr = [], coup, selCoupArr = []) { + // if(!coup.use){ + // return false + // } + const findGoods = goodsArr.filter(v => v.productId == coup.proId) + if (!findGoods.length) { + return false + } + const findGoodsTotalNumber = findGoods.reduce((prve, cur) => { + return prve + cur.num * 1 + }, 0) + const selCoupNumber = selCoupArr.filter(v => v.proId == coup.proId).reduce((prve, cur) => { + return prve + cur.num * 1 + }, 0) + if (selCoupNumber >= findGoodsTotalNumber) { + return false + } + console.log(selCoupNumber,findGoodsTotalNumber); + return findGoodsTotalNumber < selCoupNumber ? false : true +} +//查找购物车商品根据购物车商品数据返回商品券信息(抵扣价格以及是否满足可用需求) +export function returnProductCoupon(coup, goodsArr, vipUser, selCoupArr = []) { + const newGoodsArr = returnNewGoodsList(goodsArr) + const item = newGoodsArr.find(v => v.productId == coup.proId); + if (!item) { + return { + ...coup, + discountAmount: 0, + use: false + } + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (isUseVipPrice(vipUser,item) ? memberPrice : item.price) : 0; + const discountAmount = (price * coup.num).toFixed(2) + console.log(discountAmount); + + // const canUse = !coup.use ? false : (discountAmount > 0 && returnCoupCanUse(goodsArr, coup, selCoupArr)) + // const canUse=discountAmount>0 + const canUse=coup.use + return { + ...coup, + discountAmount: discountAmount, + use: canUse + } + +} +/** + * 根据购物车商品计算商品券抵扣价格以及是否满足可用需求 + * 1.商品券对应商品数量大于购物车对应商品数量不可用 + * 2.未在购物车找到相关商品不可用 + * @param {*} coupArr + * @param {*} goodsArr + * @param {*} vipUser + * @returns + */ +export function returnProductAllCoup(coupArr, goodsArr, vipUser) { + return coupArr.map((v) => { + return returnProductCoupon(v, goodsArr, vipUser) + }) + +} +//返回商品实际支付价格 +export function returnProductPayPrice(goods,vipUser){ + const memberPrice = goods.memberPrice ? goods.memberPrice : goods.price; + const price = isUseVipPrice(vipUser,goods) ? memberPrice : goods.price; + return price +} +//返回商品券抵扣的商品价格 +export function returnProductCoupAllPrice(productPriceArr,startIndex,num,isMember=true){ + console.log(productPriceArr); + return productPriceArr.slice(startIndex,startIndex+num).reduce((prve,cur)=>{ + let curPrice=0 + if(typeof cur==='object'){ + curPrice=isMember?cur.memberPrice*1:cur.price + }else{ + curPrice=cur*1 + } + return prve+curPrice + },0) +} + +//返回商品券可抵扣的商品数量 +export function returnProductCanUseNum(productPriceArr,startIndex,num){ + console.log(productPriceArr); + console.log(num); + let n=0; + for(let i=0;i{ + return prve+cur.num*1 + },0) +} +//返回商品数量从0到n每一个对应的价格对照表 +export function returnGoodsPayPriceMap(goodsArr){ + return goodsArr.reduce((prve,cur)=>{ + if(!prve.hasOwnProperty(cur.productId)){ + prve[cur.productId]=[] + } + const arr=new Array(cur.num).fill(cur).map(v=>{ + return { + memberPrice:v.memberPrice?v.memberPrice:v.price, + price:v.price + } + }) + prve[cur.productId].push(...arr) + return prve + },{}) +} +//计算商品券总优惠价格 +export function returnProductCouponAllPrice(coupArr, goodsArr, vipUser) { + if (coupArr.length == 0) { + return 0; + } + //商品分组 + const goodsMap={} + //商品数量从0到n每一个对应的价格 + const goodsPayPriceMap={} + //商品券分组 + let coupMap={} + for(let i in coupArr){ + const coup=coupArr[i] + if(coupMap.hasOwnProperty(coup.proId)){ + coupMap[coup.proId].push(coup) + }else{ + coupMap[coup.proId]=[coup] + } + } + let total=0 + for(let key in coupMap){ + const arr=coupMap[key] + for(let i in arr){ + const coup=arr[i] + if(!goodsMap.hasOwnProperty(coup.proId)){ + goodsMap[coup.proId]=goodsArr.filter(v=>v.productId==coup.proId).map(v=>{ + return { + ...v, + payPrice:returnProductPayPrice(v,vipUser) + } + }).sort((a,b)=>{ + const aPrice=a.payPrice + const bPrice=b.payPrice + return aPrice-bPrice + }) + goodsPayPriceMap[coup.proId]=goodsMap[coup.proId].reduce((prve,cur)=>{ + const arr=new Array(cur.num).fill(cur.payPrice) + console.log(arr); + prve.push(...arr) + return prve + },[]) + } + const proCoupStartIndex=returnProCoupStartIndex(arr,i) + console.log(proCoupStartIndex); + const coupNum=Math.min(goodsPayPriceMap[coup.proId].length,coup.num) + console.log(coupNum); + total+=returnProductCoupAllPrice(goodsPayPriceMap[coup.proId],proCoupStartIndex,coupNum) + } + } + + return total.toFixed(2); + +} +//计算满减券总优惠价格 +export function returnFullReductionCouponAllPrice(coupArr) { + if (coupArr.length == 0) { + return 0; + } + return coupArr.filter(v => v.type == 1).reduce((a, b) => { + const price = b.discountAmount + return a + price; + }, 0).toFixed(2); + +} +//计算优惠券总价格 +export function returnCouponAllPrice(coupArr, goodsArr, vipUser) { + const poductAllprice = returnProductCouponAllPrice(coupArr, goodsArr, vipUser) + const pointAllPrice = returnFullReductionCouponAllPrice(coupArr) + return (poductAllprice * 1 + pointAllPrice * 1).toFixed(2); +} + +//返回当前满减券列表可用状态 +export function returnCanUseFullReductionCoupon(coupArr, payPrice, selCoup) { + return coupArr.map(v => { + if (v.id == selCoup.id) { + return {...v,use:true} + } + const isfullAmount = payPrice*1 >= v.fullAmount * 1 + if(payPrice<=0){ + return { + ...v, + use: false + } + } + return { + ...v, + use: v.use && isfullAmount + } + }).filter(v => v.use) +} + +//根据商品数量还有商品券数量返回优惠券可以使用的数量数组 +export function returnCanUseNumProductCoup(coupArr,){ + let productCoup = coupArr.filter(v => v.type == 2) + //商品券分组 + let coupMap={} + for(let i in productCoup){ + const coup=productCoup[i] + if(coupMap.hasOwnProperty(coup.proId)){ + coupMap[coup.proId].push(coup) + }else{ + coupMap[coup.proId]=[coup] + } + } + return arr +} \ No newline at end of file diff --git a/src/views/tool/Instead/util.js b/src/views/tool/Instead/util.js new file mode 100644 index 0000000..3c49399 --- /dev/null +++ b/src/views/tool/Instead/util.js @@ -0,0 +1,231 @@ +import {isTui} from '../../order_manage/order_goods_util.js' +//计算打包费 +export function returnPackFee(arr, isOld = true) { + if (isOld) { + return arr.reduce((a, b) => { + const bTotal = b.info + .filter((v) => v.isGift !== "true" && v.status !== "return") + .reduce((prve, cur) => { + return prve + (cur.packFee || cur.packAmount || 0); + }, 0); + return a + bTotal; + }, 0); + } else { + return arr.filter(v => v.status !== 'return' && v.isGift !== 'true').reduce((a, b) => { + return a + (b.packFee || b.packAmount || 0); + }, 0); + } + +} +//判断商品是否可以下单 +export function isCanBuy(skuGoods, goods) { + if (goods.typeEnum == 'normal') { + //单规格 + return goods.isGrounding && goods.isPauseSale == 0 && (goods.isStock ? goods.stockNumber > 0 : true); + } else { + //多规格 + return goods.isGrounding && goods.isPauseSale == 0 && skuGoods.isGrounding && skuGoods.isPauseSale == 0 && (goods.isStock ? goods.stockNumber > 0 : true); + + } +} +//字符匹配 +export function $strMatch(matchStr, str) { + return matchStr.toLowerCase().includes(str.toLowerCase()) +} + +// 一个数组是否包含另外一个数组全部元素 +export function arrayContainsAll(arr1, arr2) { + for (let i = 0; i < arr2.length; i++) { + if (!arr1.includes(arr2[i])) { + return false; + } + } + return true; +} + +//n项 n-1项组合,生成全部结果 +export function generateCombinations(arr, k) { + console.log(arr) + console.log(k) + let result = []; + + function helper(index, current) { + if (current.length === k) { + result.push(current.slice()); // 使用slice()来避免直接修改原始数组 + } else { + for (let i = index; i < arr.length; i++) { + current.push(arr[i]); // 将当前元素添加到组合中 + helper(i + 1, current); // 递归调用,索引增加以避免重复选择相同的元素 + current.pop(); // 回溯,移除当前元素以便尝试其他组合 + } + } + } + + helper(0, []); // 从索引0开始,初始空数组作为起点 + return result; +} + +export function returnReverseVal(val, isReturnString = true) { + const isBol = typeof val === "boolean"; + const isString = typeof val === "string"; + let reverseNewval = ""; + if (isBol) { + reverseNewval = !val; + } + if (isString) { + reverseNewval = val === "true" ? "false" : "true"; + } + return reverseNewval; +} + +export function returnGiftArr(arr) { + let result = [] + for (let i = 0; i < arr.length; i++) { + const info = arr[i].info + for (let j = 0; j < info.length; j++) { + if (info[j].isGift === 'true') { + result.push(info[j]) + } + } + } + return result +} + +export function formatOrderGoodsList(arr) { + const goodsMap = {} + for (let i in arr) { + const goods = arr[i] + if (goods.productName != '客座费') { + if (goodsMap.hasOwnProperty(goods.placeNum)) { + goodsMap[goods.placeNum || 1].push(goods) + } else { + goodsMap[goods.placeNum || 1] = [goods] + } + } + + } + return Object.entries(goodsMap).map(([key, value]) => ({ + info: value, + placeNum: key || 1 + })) +} + +export function returnIsSeatFee(item) { + if (!item) { + return false + } + return item.productId == "-999"?true:false; +} +/** + * 计算购物车会员优惠价格 + */ +export function returnVipDiscountPrice() { + +} + +//计算商品券优惠价格 +export function returnProductCouponPrice(coup, goodsArr, vipUser) { + const item = goodsArr.find(v => v.productId == coup.proId); + if(!item){ + return 0 + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (vipUser.isVip ? memberPrice : item.price) : 0; + return price*coup.num + +} +//返回新的商品列表,过滤掉退菜的,退单的商品 +export function returnNewGoodsList(arr) { + let goodsMap={} + return arr.filter(v => !isTui(v)) +} +//根据当前购物车商品以及数量,已选券对应商品数量,判断该商品券是否可用 +export function returnCoupCanUse(goodsArr=[],coup,selCoupArr=[]) { + if(!coup.use){ + return false + } + const findGoods=goodsArr.filter(v=>v.productId==coup.proId) + if(!findGoods.length){ + return false + } + const findGoodsTotalNumber=findGoods.reduce((prve,cur)=>{ + return prve+cur.num*1 + },0) + const selCoupNumber=selCoupArr.filter(v=>v.proId==coup.proId).reduce((prve,cur)=>{ + return prve+cur.num*1 + },0) + if(selCoupNumber>=findGoodsTotalNumber){ + return false + } + return findGoodsTotalNumber<(coup.num+selCoupNumber)?false:true +} +//查找购物车商品根据购物车商品数据返回商品券信息(抵扣价格以及是否满足可用需求) +export function returnProductCoupon(coup, goodsArr, vipUser,selCoupArr=[]) { + const newGoodsArr = returnNewGoodsList(goodsArr) + const item = newGoodsArr.find(v => v.productId == coup.proId); + if(!item){ + return {...coup, discountAmount: 0,use:false} + } + const memberPrice = item.memberPrice ? item.memberPrice : item.price; + const price = item ? (vipUser.isVip ? memberPrice : item.price) : 0; + const discountAmount=(price*coup.num).toFixed(2) + console.log(discountAmount); + const canUse=!coup.use?false:(discountAmount>0&&returnCoupCanUse(goodsArr,coup,selCoupArr)) + // const canUse=discountAmount>0 + return { ...coup, discountAmount: discountAmount,use:canUse} + +} +/** + * 根据购物车商品计算商品券抵扣价格以及是否满足可用需求 + * 1.商品券对应商品数量大于购物车对应商品数量不可用 + * 2.未在购物车找到相关商品不可用 + * @param {*} coupArr + * @param {*} goodsArr + * @param {*} vipUser + * @returns + */ +export function returnProductAllCoup(coupArr, goodsArr, vipUser){ + return coupArr.map((v) => { + return returnProductCoupon(v, goodsArr, vipUser) + }) + +} + +//计算商品券总优惠价格 +export function returnProductCouponAllPrice(coupArr, goodsArr, vipUser) { + if(coupArr.length == 0){ + return 0; + } + return coupArr.reduce((a, b) => { + const price = returnProductCouponPrice(b, goodsArr, vipUser) + return a + price; + }, 0).toFixed(2); + +} +//计算满减券总优惠价格 +export function returnFullReductionCouponAllPrice(coupArr) { + if(coupArr.length == 0){ + return 0; + } + return coupArr.filter(v => v.type == 1).reduce((a, b) => { + const price = b.discountAmount + return a + price; + }, 0).toFixed(2); + +} +//计算优惠券总价格 +export function returnCouponAllPrice(coupArr, goodsArr, vipUser) { + const poductAllprice=returnProductCouponAllPrice(coupArr, goodsArr, vipUser) + const pointAllPrice=returnFullReductionCouponAllPrice(coupArr) + return (poductAllprice*1+pointAllPrice*1).toFixed(2); +} + +//返回购物车商品价格 +export function returnCartPrice(goods, vipUser) { + const price=goods.price||goods.salePrice + if(!vipUser||!vipUser.id ||!vipUser.isVip){ + return price + } + const memberPrice = goods.memberPrice ? goods.memberPrice :price; + return memberPrice +} \ No newline at end of file