From c7f22e193a1cae45dd025e65bff19b81885508e3 Mon Sep 17 00:00:00 2001 From: gyq <875626088@qq.com> Date: Tue, 14 Apr 2026 18:28:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=95=86=E5=93=81=E5=BA=93?= =?UTF-8?q?=E5=AD=98=E8=80=97=E6=9D=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/product/index.ts | 16 + src/components/refundConsModal.vue | 83 +++ src/store/modules/carts.ts | 80 ++- src/views/order/index/components/detail.vue | 1 - .../order/index/components/return-money.vue | 104 +++- src/views/product/categoryconfig/add.ts | 31 +- src/views/product/categoryconfig/edit.ts | 29 +- src/views/product/index.vue | 228 ++++--- src/views/product/indexconfig/TableFour.vue | 4 +- src/views/product/indexconfig/addgoods.vue | 583 +++++++++++------- src/views/product/indexconfig/content.ts | 45 +- src/views/shop/config/components/shopInfo.vue | 193 ++---- .../tool/Instead/components/goods-item.vue | 5 +- .../tool/Instead/components/return-cart.vue | 92 ++- src/views/tool/Instead/index.vue | 1 + 15 files changed, 967 insertions(+), 528 deletions(-) create mode 100644 src/components/refundConsModal.vue diff --git a/src/api/product/index.ts b/src/api/product/index.ts index e007f2d..1a54202 100644 --- a/src/api/product/index.ts +++ b/src/api/product/index.ts @@ -48,6 +48,14 @@ const AuthAPI = { data, }); }, + // 商品-标记自动售罄 + markIsAutoSoldOut(data: Object) { + return request({ + url: `${baseURL}/markIsAutoSoldOut`, + method: "post", + data, + }); + }, // 删除 deleteByIds(id: number | String) { return request({ @@ -88,6 +96,14 @@ const AuthAPI = { params }); }, + // 耗材列表 + consStock(params: any) { + return request({ + url: `/product/admin/product/cons/consStock`, + method: "get", + params + }); + }, // 上下架 onOff(data: any) { return request({ diff --git a/src/components/refundConsModal.vue b/src/components/refundConsModal.vue new file mode 100644 index 0000000..e873240 --- /dev/null +++ b/src/components/refundConsModal.vue @@ -0,0 +1,83 @@ + + + + + diff --git a/src/store/modules/carts.ts b/src/store/modules/carts.ts index c9647f4..4a7c0a1 100644 --- a/src/store/modules/carts.ts +++ b/src/store/modules/carts.ts @@ -3,6 +3,7 @@ import WebSocketManager, { type ApifoxModel, msgType } from "@/utils/websocket"; import orderApi from "@/api/order/order"; import { useUserStoreHook } from "@/store/modules/user"; import productApi from "@/api/product/index"; +import categoryApi from "@/api/product/productclassification"; import shopUserApi from '@/api/account/shopUser' import limitTimeDiscountApi from '@/api/market/limitTimeDiscount.js' import { BigNumber } from "bignumber.js"; @@ -82,8 +83,6 @@ export const useCartsStore = defineStore("carts", () => { default: productType = GoodsType.NORMAL; } - - return { ...item, id: item.id, @@ -350,11 +349,61 @@ export const useCartsStore = defineStore("carts", () => { } }); + const consList = await productApi.consStock({ shopId: localStorage.getItem("shopId") }) + + goods.value = addGoodsSoldOutStatus(goods.value, consList) + console.log('代客下单页面商品缓存.goods.value', goods.value); setGoodsMap(goods.value); } + + /** + * 给商品列表批量添加 isSoldOut 售罄状态字段 + * @param {Array} goodsList - 商品列表 [ { consList, isAutoSoldStock } ] + * @param {Array} consStockList - 真实耗材库存列表 [ { consId, stockNumber } ] + * @returns 带 isSoldOut 字段的新商品列表 + */ + function addGoodsSoldOutStatus(goodsList, consStockList) { + // console.log('addGoodsSoldOutStatus.goodsList', goodsList); + // console.log('addGoodsSoldOutStatus.consStockList', consStockList); + + // 耗材ID映射真实库存(保留) + const consMap = _.keyBy(consStockList, item => String(item.consId)); + + return _.map(goodsList, goods => { + let isSoldOut = false; + + // 开启自动售罄才判断 + if (goods.isAutoSoldStock === 1 || goods.isAutoSoldStock === true) { + const goodsConsList = goods.consList || []; + + // 无耗材 → 不售罄 + if (goodsConsList.length === 0) { + isSoldOut = false; + } else { + // 核心:只要有一个耗材 真实库存 < 商品需要量 → 售罄 + isSoldOut = _.some(goodsConsList, consItem => { + // 商品绑定的耗材ID(对应真实库存ID) + const consId = String(consItem.consInfoId); + // 商品需要消耗的数量(你的需求量) + const needStock = consItem.surplusStock || 0; + // 起售数量 + const suitNum = goods.type == 'single' ? goods.skuList[0].suitNum : 1; + // 真实库存 + const realStock = _.get(consMap, [consId, 'stockNumber'], 0); + + // 真实库存 < 需要量 * 起售数量 → 不足 → 售罄 + return realStock < needStock * suitNum; + }); + } + } + + return { ...goods, isSoldOut }; + }); + } + function setGoodsMap(goods: any[]) { for (let item of goods) { goodsMap[item.id] = item; @@ -660,7 +709,9 @@ export const useCartsStore = defineStore("carts", () => { sendMessage('add', { ...basic_msg, ...data }); } + // 添加购物车/编辑购物车 function add(data: any) { + // console.log('添加购物车/编辑购物车===', data); goods.value.map(item => { if (item.id == data.product_id) { data.is_time_discount = item.is_time_discount ? 1 : 0 @@ -675,8 +726,29 @@ export const useCartsStore = defineStore("carts", () => { console.log('carts.add===', data); if (hasCart) { + // console.log('编辑', msg); + if (hasCart.number * 1 + msg.number * 1 == 2) { + ElMessage({ + type: 'warning', + message: '购物车已有该商品,请确认是否重复', + duration: 4000 + }) + } update({ ...hasCart, ...msg, number: hasCart.number * 1 + msg.number * 1 }); } else { + // console.log('添加', msg); + let arr = _.flatten(_.values(oldOrder.value.detailMap)) + // console.log('添加.arr===', arr); + const isExist = _.some(arr, item => Number(item.productId) === msg.product_id) + + // console.log('添加.isExist===', isExist); + if (msg.number == 1 && isExist) { + ElMessage({ + type: 'warning', + message: '该商品已下单过,请确认是否重复', + duration: 4000 + }) + } sendMessage('add', msg); } } @@ -906,7 +978,7 @@ export const useCartsStore = defineStore("carts", () => { console.log("收到消息:", msg); if (!msg.status) { if (msg.hasOwnProperty('status') && msg.status !== 1 && msg.operate_type !== 'bulk_edit') { - return ElMessage.error(msg.message || '操作失败'); + return ElMessage.error(msg.msg || '操作失败'); } } if (msg?.data) { @@ -1068,8 +1140,6 @@ export const useCartsStore = defineStore("carts", () => { newUserDiscount.value = {} } - - return { disconnect, dinnerType, diff --git a/src/views/order/index/components/detail.vue b/src/views/order/index/components/detail.vue index e5eb91e..bad6751 100644 --- a/src/views/order/index/components/detail.vue +++ b/src/views/order/index/components/detail.vue @@ -433,7 +433,6 @@ export default { } console.log('tuikuan===', arr); - return this.$refs.refReturnMoney.open(arr, this.detail); }, diff --git a/src/views/order/index/components/return-money.vue b/src/views/order/index/components/return-money.vue index 6d2ee3b..3ae6991 100644 --- a/src/views/order/index/components/return-money.vue +++ b/src/views/order/index/components/return-money.vue @@ -4,11 +4,7 @@
退款商品
-
+
{{ goods.productName }} @@ -35,12 +31,7 @@
退款金额
- + 可退{{ canReturnMoney }}元
@@ -73,13 +64,8 @@
-
+
{{ tag.label }}
@@ -94,16 +80,22 @@ + +
- - - \ No newline at end of file diff --git a/src/views/product/indexconfig/content.ts b/src/views/product/indexconfig/content.ts index 0318c78..4061a59 100644 --- a/src/views/product/indexconfig/content.ts +++ b/src/views/product/indexconfig/content.ts @@ -73,13 +73,13 @@ const contentConfig: IContentConfig = { name: "sync", auth: "import", }, - { - icon: "edit", - text: "库存预警", - type: "danger", - name: "custom1", - auth: "import", - }, + // { + // icon: "edit", + // text: "库存预警", + // type: "danger", + // name: "custom1", + // auth: "import", + // }, { icon: "Download", text: "导出", @@ -98,15 +98,15 @@ const contentConfig: IContentConfig = { slotName: "type", }, // { label: "库存", align: "center", prop: "stockNumber" }, - { label: "库存", align: "center", slotName: "kucunedit", templet: "custom", prop: "stockNumber" }, + // { label: "库存", align: "center", slotName: "kucunedit", templet: "custom", prop: "stockNumber" }, { label: "耗材信息", align: "center", prop: "consName", slotName: "consumables", templet: "custom", }, - { - label: "库存开关", - align: "center", - prop: "isStock", - templet: "custom", - slotName: "isStock", - }, + // { + // label: "库存开关", + // align: "center", + // prop: "isStock", + // templet: "custom", + // slotName: "isStock", + // }, { label: "上架", align: "center", @@ -122,7 +122,14 @@ const contentConfig: IContentConfig = { slotName: "sellOut", }, { - label: "退款退回库存", + label: "自动售罄", + align: "center", + prop: "isAutoSoldStock", + templet: "custom", + slotName: "autoSellOut", + }, + { + label: "退菜是否退库存", align: "center", prop: "isRefundStock", templet: "custom", @@ -134,7 +141,11 @@ const contentConfig: IContentConfig = { fixed: "right", width: 280, templet: "tool", - operat: [{ text: "报损", name: '' }, { text: "编辑", icon: 'edit', name: "edit" }, { text: "删除", icon: 'delete', type: 'danger', name: "delete" }], + operat: [ + { text: "报损", icon: '', name: 'cons' }, + { text: "报损记录", name: 'consRecord' }, + { text: "编辑", icon: 'edit', name: "edit" }, + { text: "删除", icon: 'delete', type: 'danger', name: "delete" }], }, ], }; diff --git a/src/views/shop/config/components/shopInfo.vue b/src/views/shop/config/components/shopInfo.vue index 9346aa5..213ed4a 100644 --- a/src/views/shop/config/components/shopInfo.vue +++ b/src/views/shop/config/components/shopInfo.vue @@ -3,25 +3,14 @@
- + - +
- +
- + - + - + - +
- +
开启后,用户只能在店铺附近xx公里内点餐
- + @@ -263,23 +193,15 @@
- +
起菜到上菜的时间间隔,开启后会有超时提示
- + @@ -304,24 +226,11 @@
- - + + 点击上传 + + - - -