From 9ff0984fe19867686d11ebe84a9f4870875a258c Mon Sep 17 00:00:00 2001 From: dzq Date: Sat, 14 Jun 2025 08:09:36 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E6=9C=BA=E6=9F=9C=E7=AE=A1=E7=90=86):=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=95=86=E5=93=81=E7=BB=91=E5=AE=9A=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=8F=8AAPI=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增商品绑定弹窗组件BindGoods,支持选择商品、设置库存和解绑 - 添加机柜商品管理相关API接口:configureGoodsCellsStock、changeGoodsCellsStock、clearGoodsCells - 扩展商品类型定义,新增ShopGoodsEntity和SearchGoodsDO接口 - 修改机柜页面布局,添加绑定商品按钮和弹窗 - 修复路由守卫中注释掉的isAdmin判断逻辑 --- src/common/apis/cabinet/index.ts | 24 +- src/common/apis/shop/index.ts | 10 +- src/common/apis/shop/type.ts | 65 +++- src/pages/cabinet/components/BindGoods.vue | 341 +++++++++++++++++++++ src/pages/cabinet/index.vue | 71 ++++- src/router/guard.ts | 4 +- types/auto/components.d.ts | 2 + 7 files changed, 502 insertions(+), 15 deletions(-) create mode 100644 src/pages/cabinet/components/BindGoods.vue diff --git a/src/common/apis/cabinet/index.ts b/src/common/apis/cabinet/index.ts index b931afa..665ead2 100644 --- a/src/common/apis/cabinet/index.ts +++ b/src/common/apis/cabinet/index.ts @@ -19,4 +19,26 @@ export function openCabinet(cabinetId: number, pinNo: number, data: OpenCabinetA method: 'post', data }) -} \ No newline at end of file +} + +export const configureGoodsCellsStock = (cellId: number, goodsId: number, stock: number) => { + return request>({ + url: `/cabinet/configureGoodsCellsStock/${cellId}/${goodsId}/${stock}`, + method: 'put' + }); +}; + +export const changeGoodsCellsStock = (cellId: number, stock: number) => { + return request>({ + url: `/cabinet/changeGoodsCellsStock/${cellId}/${stock}`, + method: 'put' + }); +}; + +export const clearGoodsCells = (cellId: number) => { + return request>({ + url: `/cabinet/clearGoodsCells/${cellId}`, + method: 'put' + }); +}; + diff --git a/src/common/apis/shop/index.ts b/src/common/apis/shop/index.ts index 942e132..e812d44 100644 --- a/src/common/apis/shop/index.ts +++ b/src/common/apis/shop/index.ts @@ -1,10 +1,18 @@ import { request } from "@/http/axios" -import { GetBalanceResponse, GetOrdersByOpenIdDTO, OpenCabinetApiData, QyLoginDTO, QyLoginRequestParams, ShopEntity, ShopGoodsResponseData, SubmitOrderRequestData, SubmitOrderResponseData } from './type' +import { GetBalanceResponse, GetOrdersByOpenIdDTO, OpenCabinetApiData, QyLoginDTO, QyLoginRequestParams, SearchGoodsDO, ShopEntity, ShopGoodsEntity, ShopGoodsResponseData, SubmitOrderRequestData, SubmitOrderResponseData } from './type' import { GetOpenIdRequestParams } from './type' /** 获取商品列表 */ +export function getShopGoodsListApi(corpid: string, belongType: number) { + return request>({ + url: "shop/goods/list", + method: "get", + params: { corpid, belongType } + }); +} + export function getShopGoodsApi(shopId: number|null) { return request({ url: "shop/goods", diff --git a/src/common/apis/shop/type.ts b/src/common/apis/shop/type.ts index be2f537..cee90f2 100644 --- a/src/common/apis/shop/type.ts +++ b/src/common/apis/shop/type.ts @@ -12,6 +12,39 @@ export type Goods = { belongType: number } +export interface ShopGoodsEntity { + /** 商品唯一ID */ + goodsId: number; + /** 商品名称 */ + goodsName: string; + /** 商品分类ID */ + categoryId: number; + /** 外部归属类型的商品ID */ + externalGoodsId?: number; + /** 企业微信id */ + corpid?: string; + /** 每人每月限购数量 */ + monthlyPurchaseLimit?: number; + /** 销售价格 */ + price: number; + /** 库存数量 */ + stock: number; + /** 商品状态(1上架 2下架) */ + status: number; + /** 免审批(0否 1是) */ + autoApproval?: number; + /** 封面图URL */ + coverImg?: string; + /** 商品详情(支持2000汉字+10个图片链接) */ + goodsDetail?: string; + /** 备注 */ + remark?: string; + /** 商品使用说明 */ + usageInstruction?: string; + /** 归属类型(0-借还柜 1-固资通) */ + belongType?: number; +} + export type category = { categoryId: number, categoryName: string, @@ -180,7 +213,33 @@ export interface OpenCabinetApiData { } export interface ShopEntity { - shopId: number - shopName: string - corpid: string + /** 主键ID */ + shopId: number; + /** 商店名称 */ + shopName: string; + /** 企业微信id */ + corpid: string; + /** 运行模式(0-支付模式 1-审批模式 2-借还模式 3-会员模式 4-耗材模式) */ + mode?: number; + /** 借呗支付(1-正常使用 0-禁止使用) */ + balanceEnable?: number; + /** 封面图URL */ + coverImg?: string; +} + +export interface SearchGoodsDO extends ShopGoodsEntity { + /** 分类名称 */ + categoryName?: string; + /** 柜子ID */ + cabinetId?: number; + /** 柜子名称 */ + cabinetName?: string; + /** 商店名称字符串 */ + shopNameStr?: string; + /** 格口编号 */ + cellNo?: number; + /** 格口编号字符串 */ + cellNoStr?: string; + /** 已分配库存 */ + totalStock?: number; } \ No newline at end of file diff --git a/src/pages/cabinet/components/BindGoods.vue b/src/pages/cabinet/components/BindGoods.vue new file mode 100644 index 0000000..caf8a9d --- /dev/null +++ b/src/pages/cabinet/components/BindGoods.vue @@ -0,0 +1,341 @@ + + + + + \ No newline at end of file diff --git a/src/pages/cabinet/index.vue b/src/pages/cabinet/index.vue index 76047a1..f635771 100644 --- a/src/pages/cabinet/index.vue +++ b/src/pages/cabinet/index.vue @@ -16,7 +16,7 @@
-
+
重选地址 @@ -55,9 +55,10 @@
- - 详情 + + 绑定商品 + 立即开启 @@ -66,6 +67,22 @@
+ + + + @@ -74,10 +91,13 @@ import { throttle } from 'lodash-es'; import { ref, onMounted, onBeforeUnmount, watch } from 'vue'; import { getShopListApi } from '@/common/apis/shop'; import { ShopEntity } from '@/common/apis/shop/type'; -import { getCabinetDetailApi, openCabinet } from '@/common/apis/cabinet'; +import { getCabinetDetailApi, openCabinet, changeGoodsCellsStock, clearGoodsCells } from '@/common/apis/cabinet'; import type { CabinetDetailDTO } from '@/common/apis/cabinet/type'; import { useWxStore, useWxStoreOutside } from '@/pinia/stores/wx'; import { publicPath } from "@/common/utils/path"; +import BindGoods from './components/BindGoods.vue'; +import VanPopup from 'vant/es/popup'; +import { showDialog, showToast } from 'vant'; const wxStore = useWxStore(); const { userid: qyUserid, name: qyName } = storeToRefs(wxStore); @@ -86,12 +106,15 @@ const activeCabinet = ref(0) const cabinetList = ref([]) const lockerList = ref([]) const openingLockerId = ref(null) +const showBindGoodsPopup = ref(false) +const currentLocker = ref(null) const cabinetData = ref([]); const scrollContainer = ref(); // 机柜地址选择相关状态 const showShopList = ref(true); const shopList = ref([]); const shopId = ref(0); +const selectedShop = ref(null); const headerHeight = ref(150); let scrollListener: any[] = []; @@ -158,10 +181,16 @@ const onCabinetChange = (index: number) => { } } -const showLockerDetail = (locker: LockerItem) => { - // 实现详情弹窗逻辑 +const showBindGoods = (locker: LockerItem) => { + currentLocker.value = locker; + showBindGoodsPopup.value = true; } +const handleBindSuccess = () => { + showBindGoodsPopup.value = false; + loadCabinetDetail(); +}; + const handleOpenLocker = async (locker: LockerItem) => { openingLockerId.value = locker.lockerId try { @@ -204,7 +233,11 @@ const getShopList = async () => { // 选择商店 const handleShopSelect = (selectedShopId: number) => { - shopId.value = selectedShopId; + const shop = shopList.value.find(s => s.shopId === selectedShopId); + if (shop) { + selectedShop.value = shop; + shopId.value = selectedShopId; + } showShopList.value = false; loadCabinetDetail(selectedShopId); }; @@ -222,6 +255,14 @@ const throttledScroll = throttle(() => { headerHeight.value = Math.max(150 - scrollTop * 0.5, 60); }, 100); + + +const handleStockUpdate = (newStock: number) => { + if (currentLocker.value) { + currentLocker.value.stock = newStock; + } +}; + onMounted(() => { init(); scrollListener.push(window.addEventListener('scroll', throttledScroll)); @@ -257,6 +298,10 @@ onBeforeUnmount(() => { height: calc(100vh - var(--van-tabbar-height)); } +.left-container { + width: 90px; +} + /* 机柜选择相关样式 */ .shop { display: flex; @@ -333,7 +378,7 @@ onBeforeUnmount(() => { } .cabinet-sidebar { - width: 120px; + width: 90px; height: 100%; overflow-y: auto; } @@ -494,4 +539,14 @@ onBeforeUnmount(() => { align-items: center; width: 100%; } + +.adjust-btn { + background-color: #4e80ee; + border: none; +} + +.unbind-btn { + color: #999; + border-color: #999; +} \ No newline at end of file diff --git a/src/router/guard.ts b/src/router/guard.ts index 423a8c6..ecc3f9c 100644 --- a/src/router/guard.ts +++ b/src/router/guard.ts @@ -25,10 +25,10 @@ export function registerNavigationGuard(router: Router) { if (corpid) { return true; } - /* const isAdmin = urlParams.get('isAdmin') || undefined; + const isAdmin = urlParams.get('isAdmin') || undefined; if (isAdmin) { return true; - } */ + } // useAb98UserStore位置不能放在外面,否则会导致路由守卫无法正常工作 const ab98UserStore = useAb98UserStore(); diff --git a/types/auto/components.d.ts b/types/auto/components.d.ts index 7767bc2..cd0a65a 100644 --- a/types/auto/components.d.ts +++ b/types/auto/components.d.ts @@ -17,6 +17,7 @@ declare module 'vue' { VanCol: typeof import('vant/es')['Col'] VanConfigProvider: typeof import('vant/es')['ConfigProvider'] VanDivider: typeof import('vant/es')['Divider'] + VanEmpty: typeof import('vant/es')['Empty'] VanField: typeof import('vant/es')['Field'] VanForm: typeof import('vant/es')['Form'] VanGrid: typeof import('vant/es')['Grid'] @@ -32,6 +33,7 @@ declare module 'vue' { VanSearch: typeof import('vant/es')['Search'] VanSidebar: typeof import('vant/es')['Sidebar'] VanSidebarItem: typeof import('vant/es')['SidebarItem'] + VanStepper: typeof import('vant/es')['Stepper'] VanTabbar: typeof import('vant/es')['Tabbar'] VanTabbarItem: typeof import('vant/es')['TabbarItem'] VanTag: typeof import('vant/es')['Tag']