From e597bea06545bb7389be19cc321b1c96755c8fc9 Mon Sep 17 00:00:00 2001 From: jqtmviyu Date: Mon, 5 May 2025 17:33:22 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20:sparkles:=20=E5=95=86=E5=93=81?= =?UTF-8?q?=E8=AF=A6=E6=83=85=E9=A1=B5=20sku=E6=A8=A1=E5=9D=97=20=E6=B8=B2?= =?UTF-8?q?=E6=9F=93=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../vk-data-goods-sku-popup.d.ts | 145 ++ .../vk-data-goods-sku-popup.vue | 1384 +++++++++++++++++ .../vk-data-input-number-box.vue | 474 ++++++ src/pages/goods/goods.vue | 42 +- 4 files changed, 2044 insertions(+), 1 deletion(-) create mode 100644 src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.d.ts create mode 100644 src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.vue create mode 100644 src/components/vk-data-input-number-box/vk-data-input-number-box.vue diff --git a/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.d.ts b/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.d.ts new file mode 100644 index 0000000..1ca47a6 --- /dev/null +++ b/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.d.ts @@ -0,0 +1,145 @@ +import { Component } from '@uni-helper/uni-app-types' + +/** SKU 弹出层 */ +export type SkuPopup = Component + +/** SKU 弹出层实例 */ +export type SkuPopupInstance = InstanceType + +/** SKU 弹出层属性 */ +export type SkuPopupProps = { + /** 双向绑定,true 为打开组件,false 为关闭组件 */ + modelValue: boolean + /** 商品信息本地数据源 */ + localdata: SkuPopupLocaldata + /** 按钮模式 1:都显示 2:只显示购物车 3:只显示立即购买 */ + mode?: 1 | 2 | 3 + /** 该商品已抢完时的按钮文字 */ + noStockText?: string + /** 库存文字 */ + stockText?: string + /** 点击遮罩是否关闭组件 */ + maskCloseAble?: boolean + /** 顶部圆角值 */ + borderRadius?: string | number + /** 最小购买数量 */ + minBuyNum?: number + /** 最大购买数量 */ + maxBuyNum?: number + /** 每次点击后的数量 */ + stepBuyNum?: number + /** 是否只能输入 step 的倍数 */ + stepStrictly?: boolean + /** 是否隐藏库存的显示 */ + hideStock?: false + /** 主题风格 */ + theme?: 'default' | 'red-black' | 'black-white' | 'coffee' | 'green' + /** 默认金额会除以100(即100=1元),若设置为0,则不会除以100(即1=1元) */ + amountType?: 1 | 0 + /** 自定义获取商品信息的函数(已知支付宝不支持,支付宝请改用localdata属性) */ + customAction?: () => void + /** 是否显示右上角关闭按钮 */ + showClose?: boolean + /** 关闭按钮的图片地址 */ + closeImage?: string + /** 价格的字体颜色 */ + priceColor?: string + /** 立即购买 - 按钮的文字 */ + buyNowText?: string + /** 立即购买 - 按钮的字体颜色 */ + buyNowColor?: string + /** 立即购买 - 按钮的背景颜色 */ + buyNowBackgroundColor?: string + /** 加入购物车 - 按钮的文字 */ + addCartText?: string + /** 加入购物车 - 按钮的字体颜色 */ + addCartColor?: string + /** 加入购物车 - 按钮的背景颜色 */ + addCartBackgroundColor?: string + /** 商品缩略图背景颜色 */ + goodsThumbBackgroundColor?: string + /** 样式 - 不可点击时,按钮的样式 */ + disableStyle?: object + /** 样式 - 按钮点击时的样式 */ + activedStyle?: object + /** 样式 - 按钮常态的样式 */ + btnStyle?: object + /** 字段名 - 商品表id的字段名 */ + goodsIdName?: string + /** 字段名 - sku表id的字段名 */ + skuIdName?: string + /** 字段名 - 商品对应的sku列表的字段名 */ + skuListName?: string + /** 字段名 - 商品规格名称的字段名 */ + specListName?: string + /** 字段名 - sku库存的字段名 */ + stockName?: string + /** 字段名 - sku组合路径的字段名 */ + skuArrName?: string + /** 字段名 - 商品缩略图字段名(未选择sku时) */ + goodsThumbName?: string + /** 被选中的值 */ + selectArr?: string[] + + /** 打开弹出层 */ + onOpen: () => void + /** 关闭弹出层 */ + onClose: () => void + /** 点击加入购物车时(需选择完SKU才会触发)*/ + onAddCart: (event: SkuPopupEvent) => void + /** 点击立即购买时(需选择完SKU才会触发)*/ + onBuyNow: (event: SkuPopupEvent) => void +} + +/** 商品信息本地数据源 */ +export type SkuPopupLocaldata = { + /** 商品 ID */ + _id: string + /** 商品名称 */ + name: string + /** 商品图片 */ + goods_thumb: string + /** 商品规格列表 */ + spec_list: SkuPopupSpecItem[] + /** 商品SKU列表 */ + sku_list: SkuPopupSkuItem[] +} + +/** 商品规格名称的集合 */ +export type SkuPopupSpecItem = { + /** 规格名称 */ + name: string + /** 规格集合 */ + list: { name: string }[] +} + +/** 商品SKU列表 */ +export type SkuPopupSkuItem = { + /** SKU ID */ + _id: string + /** 商品 ID */ + goods_id: string + /** 商品名称 */ + goods_name: string + /** 商品图片 */ + image: string + /** SKU 价格 * 100, 注意:需要乘以 100 */ + price: number + /** SKU 规格组成, 注意:需要与 spec_list 数组顺序对应 */ + sku_name_arr: string[] + /** SKU 库存 */ + stock: number +} + +/** 当前选择的sku数据 */ +export type SkuPopupEvent = SkuPopupSkuItem & { + /** 商品购买数量 */ + buy_num: number +} + +/** 全局组件类型声明 */ +declare module 'vue' { + export interface GlobalComponents { + 'vk-data-goods-sku-popup': SkuPopup + } +} diff --git a/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.vue b/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.vue new file mode 100644 index 0000000..08224d7 --- /dev/null +++ b/src/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup.vue @@ -0,0 +1,1384 @@ + + + + + + diff --git a/src/components/vk-data-input-number-box/vk-data-input-number-box.vue b/src/components/vk-data-input-number-box/vk-data-input-number-box.vue new file mode 100644 index 0000000..c34f5ae --- /dev/null +++ b/src/components/vk-data-input-number-box/vk-data-input-number-box.vue @@ -0,0 +1,474 @@ + + + + + + diff --git a/src/pages/goods/goods.vue b/src/pages/goods/goods.vue index 81103a8..eba8289 100644 --- a/src/pages/goods/goods.vue +++ b/src/pages/goods/goods.vue @@ -32,7 +32,7 @@ 选择 - 请选择商品规格 + 请选择商品规格 送至 @@ -115,6 +115,14 @@ + + + @@ -126,6 +134,7 @@ import { ref } from 'vue' import ServicePanel from './components/ServicePanel.vue' import AddressPanel from './components/AddressPanel.vue' import PageSkeleton from './components/PageSkeleton.vue' +import type { SkuPopupLocaldata } from '@/components/vk-data-goods-sku-popup/vk-data-goods-sku-popup' // 获取屏幕边界到安全区域距离 const { safeAreaInsets } = uni.getSystemInfoSync() @@ -143,6 +152,33 @@ const getGoods = async () => { const res = await getGoodsAPI(query.id) console.log(res.result) goods.value = res.result + // 设置 SKU 商品规格弹出层数据 + localdata.value = { + _id: res.result.id, + name: res.result.name, + goods_thumb: res.result.mainPictures[0], + spec_list: res.result.specs.map((item) => { + return { + name: item.name, + list: item.values.map((value) => { + return { + name: value.name, + } + }), + } + }), + sku_list: res.result.skus.map((item) => { + return { + _id: item.id, + goods_id: res.result.id, + goods_name: res.result.name, + image: item.picture, + price: item.price * 100, + sku_name_arr: item.specs.map((spec) => spec.valueName), + stock: item.inventory, + } + }), + } } // 当前滚动图索引 @@ -182,6 +218,10 @@ onLoad(async () => { await getGoods() isLoading.value = false }) + +// SKU 商品规格弹出层 +const isShowSkuPopup = ref(false) +const localdata = ref({} as SkuPopupLocaldata)