diff --git a/src/api/url.js b/src/api/url.js index dbf2279..f30c125 100644 --- a/src/api/url.js +++ b/src/api/url.js @@ -203,7 +203,7 @@ export const GET_GOODS_CATEGORY = "/product/type/list"; // 商品列表 export const GET_GOODS_LIST = "/douyin/goods/product/online/query"; // 商品详情 -export const GET_GOODS_DETAIL = "/product/detail"; +export const GET_GOODS_DETAIL = "/douyin/goods/product/detail"; // 获取优惠券列表 export const GET_COUPON_LIST = "/app/coupon/coupon_list"; diff --git a/src/pages/client/category/index.vue b/src/pages/client/category/index.vue index 81e8ebd..f32bf38 100644 --- a/src/pages/client/category/index.vue +++ b/src/pages/client/category/index.vue @@ -159,6 +159,8 @@ export default { total: 0, page: 1, size: 10, + nextCursor: '', + hasMore: true, refreshTriggered: false, isLoading: false, petOrderId: '', @@ -245,24 +247,39 @@ export default { this.changeId = item.id this.selectCategoryId = item.id; this.page = 1; // 切换分类时重置分页 + this.nextCursor = ''; + this.hasMore = true; this.goodsList = []; // 清空当前商品列表 this.showAllCategory = false; this.getShopList(true); // 切换分类时强制刷新 }, // 商品列表 getShopList(forceRefresh = false) { - // 如果不是第一页,直接请求不使用缓存(分页加载) + // 如果不是第一页且没有更多数据,直接返回 + if (this.page > 1 && !this.hasMore) { + return; + } + + const params = { + type: this.changeId, + p: this.page, + num: this.size, + keyword: "", + is_tui: 0, + cursor: this.nextCursor, + }; + + // 第一页使用缓存,后续页直接请求 if (this.page > 1) { - getGoodsListData({ - type: this.changeId, - p: this.page, - num: this.size, - keyword: "", - is_tui: 0, - }) + getGoodsListData(params) .then((res) => { - const list = res?.data || []; + const list = res?.data.data?.products || res?.data || []; + const hasMore = res?.data.data?.has_more; + const nextCursor = res?.data.data?.next_cursor || ''; + this.goodsList = [...this.goodsList, ...list]; + this.hasMore = hasMore; + this.nextCursor = nextCursor; this.total = res?.count || 0; }) .finally(() => { @@ -273,21 +290,19 @@ export default { } // 第一页使用缓存 - const params = { - type: this.changeId, - p: this.page, - num: this.size, - keyword: "", - is_tui: 0, - }; - getCategoryGoodsWithCache(params, forceRefresh) .then((res) => { - const list = res?.data || []; + const list = res?.data?.products || res?.data || []; + const hasMore = res?.data?.has_more; + const nextCursor = res?.data?.next_cursor || ''; + // 只有当数据有变化时才更新商品列表,避免不必要的刷新 if (res.hasChanged !== false || this.goodsList.length === 0) { this.goodsList = list; } + + this.hasMore = hasMore; + this.nextCursor = nextCursor; this.total = res?.count || list.length || 0; }) .catch((err) => { @@ -401,10 +416,12 @@ export default { this.page = 1; this.size = 10; this.total = 0; + this.nextCursor = ''; + this.hasMore = true; this.getShopList(true); // 下拉刷新时强制刷新 }, onLoadMore() { - if (!this.isLoading && this.total > this.goodsList.length) { + if (!this.isLoading && this.hasMore) { this.page++; this.getShopList(); } diff --git a/src/pages/client/home/index.vue b/src/pages/client/home/index.vue index 8087232..51b3ab2 100644 --- a/src/pages/client/home/index.vue +++ b/src/pages/client/home/index.vue @@ -6,7 +6,7 @@ - + @@ -114,6 +114,8 @@ export default { goodsList: [], // 商品列表 goodsTotal: 0, // 商品总数 goodPage: 1, // 当前页码 + nextCursor: '', // 下一页游标 + hasMore: true, // 是否还有更多数据 isLoadingGoods: false, // 是否正在加载商品 refreshTriggered: false, // 刷新是否已触发 cartCount: 0, // 购物车数量 @@ -178,7 +180,11 @@ export default { return this.cartCount > 9 ? "9+" : this.cartCount; } }, - created() { + created() { + this.goodPage = 1; + this.nextCursor = ''; + this.hasMore = true; + this.goodsList = []; this.getGoodsList() }, onShow() { @@ -188,17 +194,29 @@ export default { methods: { getGoodsList(forceRefresh = false) { if (this.isLoadingGoods) return; + if (!this.hasMore && this.goodPage > 1) return; this.isLoadingGoods = true; const params = { - type: 0 + type: 0, + cursor: this.nextCursor } getHomeGoodsWithCache(params, forceRefresh) .then((res) => { - const list = res?.data.data.products || []; + const list = res?.data.data?.products || res?.data.data || []; + const hasMore = res?.data.data?.has_more; + const nextCursor = res?.data.data?.next_cursor || ''; + // 只有当数据有变化时才更新商品列表,避免不必要的刷新 - if (res.hasChanged !== false || this.goodsList.length === 0) { - this.goodsList = list; + if (this.goodPage === 1) { + if (res.hasChanged !== false || this.goodsList.length === 0) { + this.goodsList = list; + } + } else { + this.goodsList = [...this.goodsList, ...list]; } + + this.hasMore = hasMore; + this.nextCursor = nextCursor; this.goodsTotal = res?.count || list.length || 0; }) .catch((err) => { @@ -362,24 +380,23 @@ export default { console.error('Error parsing image_list:', e); } } - uni.navigateTo({ - url: `/pages/client/order/create`, - success: (res) => { - // 通过eventChannel向被打开页面传送数据 - res.eventChannel.emit("createOrder", { - goodList: [{ - ...this.goodsData, - goods_id:goodsData.product.out_id, - // price_id:goodsData.prices[0].price_id, - product_pic: firstImageUrl, - number:1, - goods_name: goodsData.product.product_name, - price_name: goodsData?.product.product_name, - goods_price: goodsData.sku.actual_amount / 100 - }, ], - }); - }, + url: `/pages/client/order/create?product_id=${goodsData.product.product_id}`, + // success: (res) => { + // // 通过eventChannel向被打开页面传送数据 + // res.eventChannel.emit("createOrder", { + // goodList: [{ + // ...this.goodsData, + // goods_id:goodsData.product.out_id, + // // price_id:goodsData.prices[0].price_id, + // product_pic: firstImageUrl, + // number:1, + // goods_name: goodsData.product.product_name, + // price_name: goodsData?.product.product_name, + // goods_price: goodsData.sku.actual_amount / 100 + // }, ], + // }); + // }, }); }, @@ -403,6 +420,19 @@ export default { }); } }, + onLoadMore() { + if (!this.isLoadingGoods && this.hasMore) { + this.goodPage++; + this.getGoodsList(); + } + }, + onRefresh() { + this.refreshTriggered = true; + this.goodPage = 1; + this.nextCursor = ''; + this.hasMore = true; + this.getGoodsList(true); + }, }, }; diff --git a/src/pages/client/order/create.vue b/src/pages/client/order/create.vue index 2439017..440d929 100644 --- a/src/pages/client/order/create.vue +++ b/src/pages/client/order/create.vue @@ -11,19 +11,19 @@ > - {{ - item.item_name || item.product_name - }} + 到手价 - ¥{{ item.product_price || item.goods_price }} + ¥{{ item.price }} - {{ item.goods_name }} + {{ item.name }} @@ -71,7 +71,7 @@ - ¥{{ payPrice.toFixed(2) }} + ¥{{ orderPrice.toFixed(2) }} 立即购买 @@ -103,6 +103,10 @@ import { getAddressInfo } from "../../../api/address"; import { COUPON_TYPE_GOODS } from "../../../constants/app.business"; import { walletTransaction } from "../../../api/login"; import { imgPrefix, jumpToWeChat } from "@/utils/common"; +import { + addCart, + getGoodsDetail, + } from "@/api/shop"; const sliverList = [ { @@ -124,7 +128,9 @@ export default { }, data() { return { + orderData:[], payPrice: 0, + orPrice:0, type: "", orderData: [], addressInfo: {}, @@ -170,75 +176,89 @@ export default { }, }, onLoad(option) { - const { type, petOrderId = "", petOrderAddressId = "" } = option; - this.type = type; - this.petOrderId = petOrderId; - this.petOrderAddressId = petOrderAddressId; + console.log(option,'?') + this.getGoodsList(option.product_id ) + // const { type, petOrderId = "", petOrderAddressId = "" } = option; + // this.type = type; + // this.petOrderId = petOrderId; + // this.petOrderAddressId = petOrderAddressId; - if (petOrderAddressId) { - getAddressInfo(petOrderAddressId).then((res) => { - this.addressInfo = { - ...res?.info, - }; - }); - } - uni.$on("selectAddress", this.addressChange); + // if (petOrderAddressId) { + // getAddressInfo(petOrderAddressId).then((res) => { + // this.addressInfo = { + // ...res?.info, + // }; + // }); + // } + // uni.$on("selectAddress", this.addressChange); - const eventChannel = this.getOpenerEventChannel(); - eventChannel.on("createOrder", (data) => { - console.log(data,'--=?') - const extractFirstImage = (imageList) => { - if (!imageList) return ""; - try { - const parsedList = - typeof imageList === "string" ? JSON.parse(imageList) : imageList; - if (Array.isArray(parsedList) && parsedList.length > 0) { - return parsedList[0].url || parsedList[0] || ""; - } - } catch (e) { - console.error("Error parsing image_list:", e); - } - return ""; - }; + // const eventChannel = this.getOpenerEventChannel(); + // eventChannel.on("createOrder", (data) => { + // console.log(data,'--=?') + // const extractFirstImage = (imageList) => { + // if (!imageList) return ""; + // try { + // const parsedList = + // typeof imageList === "string" ? JSON.parse(imageList) : imageList; + // if (Array.isArray(parsedList) && parsedList.length > 0) { + // return parsedList[0].url || parsedList[0] || ""; + // } + // } catch (e) { + // console.error("Error parsing image_list:", e); + // } + // return ""; + // }; - this.orderData = (data?.goodList || []).map((item) => { - let processedItem = { ...item }; - if (processedItem.product_pic) { - if ( - typeof processedItem.product_pic === "string" && - (processedItem.product_pic.startsWith("[") || - processedItem.product_pic.startsWith("{")) - ) { - const extractedUrl = extractFirstImage(processedItem.product_pic); - if (extractedUrl) { - processedItem.product_pic = extractedUrl; - } - } else if (Array.isArray(processedItem.product_pic)) { - const extractedUrl = extractFirstImage(processedItem.product_pic); - if (extractedUrl) { - processedItem.product_pic = extractedUrl; - } - } - } - return processedItem; - }); + // this.orderData = (data?.goodList || []).map((item) => { + // let processedItem = { ...item }; + // if (processedItem.product_pic) { + // if ( + // typeof processedItem.product_pic === "string" && + // (processedItem.product_pic.startsWith("[") || + // processedItem.product_pic.startsWith("{")) + // ) { + // const extractedUrl = extractFirstImage(processedItem.product_pic); + // if (extractedUrl) { + // processedItem.product_pic = extractedUrl; + // } + // } else if (Array.isArray(processedItem.product_pic)) { + // const extractedUrl = extractFirstImage(processedItem.product_pic); + // if (extractedUrl) { + // processedItem.product_pic = extractedUrl; + // } + // } + // } + // return processedItem; + // }); - this.payPrice = this.orderData.reduce( - (sum, item) => - sum + - Number((item.product_price || item.goods_price) * item.number || 0), - 0 - ); - console.log(data, "--=?"); - const price = this.orderData.reduce( - (total, prev) => total + +prev.item_price, - 0 - ); - this.orderPrice = +price.toFixed(2); - this.confirmPrice = +(this.orderPrice - this.couponFee).toFixed(2); - }); + // this.payPrice = this.orderData.reduce( + // (sum, item) => + // sum + + // Number((item.product_price || item.goods_price) * item.number || 0), + // 0 + // ); + // console.log(data, "--=?"); + // const price = this.orderData.reduce( + // (total, prev) => total + +prev.item_price, + // 0 + // ); + // this.orderPrice = +price.toFixed(2); + // this.confirmPrice = +(this.orderPrice - this.couponFee).toFixed(2); + // }); }, methods: { + getGoodsList(id) { + getGoodsDetail({ + product_id:id, + }) + .then((res) => { + this.orderData = res.data + this.orPrice = res.data.price + this.orderPrice = res.data[0].price + // console.log(res,'--=') + }) + + }, createOrder(isPrePay) { return new Promise((resolve, reject) => { if (!isPrePay) { @@ -267,14 +287,14 @@ export default { tradeOption: res.data.tradeOption, payment: res.data.payment, success: (res) => { - const { orderId, outOrderNo } = res; - console.log("success res", res); - console.log("orderId", orderId, "outOrderNo", outOrderNo); - this.orderId = orderId; - this.outOrderNo = outOrderNo; - uni.navigateTo({ - url: "/pages/client/order/list", - }); + const { orderId, outOrderNo } = res; + console.log("success res", res); + console.log("orderId", orderId, "outOrderNo", outOrderNo); + this.orderId = orderId; + this.outOrderNo = outOrderNo; + uni.navigateTo({ + url: "/pages/client/order/list", + }); }, fail: (res) => { console.log("fail res", res); diff --git a/src/pages/client/shop/index.vue b/src/pages/client/shop/index.vue index 41f7a33..ecaa0b1 100644 --- a/src/pages/client/shop/index.vue +++ b/src/pages/client/shop/index.vue @@ -170,6 +170,8 @@ export default { total: 0, page: 1, size: 10, + nextCursor: '', + hasMore: true, showModal: false, addGoodInfo: null, showContactModal: false, @@ -263,6 +265,9 @@ export default { initData() { this.getCategoryList(); this.page = 1; + this.nextCursor = ''; + this.hasMore = true; + this.goodsList = []; this.getGoodsList(); this.getCartListData(); }, @@ -281,13 +286,25 @@ export default { // 商品列表 getGoodsList() { if (this.isLoading) return; + if (!this.hasMore && this.page > 1) return; this.isLoading = true; getGoodsListData({ type: this.selectCategoryId ? this.selectCategoryId : 0, + cursor: this.nextCursor, }) .then((res) => { const list = res?.data.data.products || []; - this.goodsList = list; + const hasMore = res?.data.data.has_more; + const nextCursor = res?.data.data.next_cursor || ''; + + if (this.page === 1) { + this.goodsList = list; + } else { + this.goodsList = [...this.goodsList, ...list]; + } + + this.hasMore = hasMore; + this.nextCursor = nextCursor; this.total = res?.count || 0; }) .finally(() => { @@ -300,10 +317,12 @@ export default { this.page = 1; this.size = 10; this.total = 0; + this.nextCursor = ''; + this.hasMore = true; this.getGoodsList(); }, onLoadMore() { - if (!this.isLoading && this.total > this.goodsList.length) { + if (!this.isLoading && this.hasMore) { this.page++; this.getGoodsList(); } @@ -378,20 +397,20 @@ export default { } uni.navigateTo({ - url: `/pages/client/order/create`, - success: (res) => { - // 通过eventChannel向被打开页面传送数据 - res.eventChannel.emit("createOrder", { - goodList: [{ - goods_id:goodsData.product.out_id, - product_pic: firstImageUrl, - number:1, - goods_name: goodsData.product.product_name, - price_name: goodsData?.product.product_name, - goods_price: goodsData.sku.actual_amount / 100 - }, ], - }); - }, + url: `/pages/client/order/create?product_id=${goodsData.product.product_id}`, + // success: (res) => { + // // 通过eventChannel向被打开页面传送数据 + // res.eventChannel.emit("createOrder", { + // goodList: [{ + // goods_id:goodsData.product.out_id, + // product_pic: firstImageUrl, + // number:1, + // goods_name: goodsData.product.product_name, + // price_name: goodsData?.product.product_name, + // goods_price: goodsData.sku.actual_amount / 100 + // }, ], + // }); + // }, }); }, // 购物车列表 @@ -419,31 +438,31 @@ export default { // 立即购买 handleBuyNow(good) { uni.navigateTo({ - url: `/pages/client/order/create`, - success: (res) => { - // 通过 eventChannel 向被打开页面传送数据 - res.eventChannel.emit("createOrder", { - goodList: [ - { - goods_id: good.product_id, - item_type: good.type, - price_id: good.prices?.[0]?.price_id, - price_desc: good.prices?.[0]?.price_desc, - item_name: good.product_name, - item_price: good.prices?.[0]?.actual_price, - item_pic: good.product_pic, - number: 1, - product_id: good.product_id, - product_name: good.product_name, - product_pic: good.product_pic, - goods_price: good.prices?.[0]?.actual_price / 100, - product_price: good.prices?.[0]?.actual_price / 100, - original_price: good.prices?.[0]?.original_price, - yunfei: good.yunfei || 0, - }, - ], - }); - }, + url: `/pages/client/order/create?product_id=${good.product.product_id}`, + // success: (res) => { + // // 通过 eventChannel 向被打开页面传送数据 + // res.eventChannel.emit("createOrder", { + // goodList: [ + // { + // goods_id: good.product_id, + // item_type: good.type, + // price_id: good.prices?.[0]?.price_id, + // price_desc: good.prices?.[0]?.price_desc, + // item_name: good.product_name, + // item_price: good.prices?.[0]?.actual_price, + // item_pic: good.product_pic, + // number: 1, + // product_id: good.product_id, + // product_name: good.product_name, + // product_pic: good.product_pic, + // goods_price: good.prices?.[0]?.actual_price / 100, + // product_price: good.prices?.[0]?.actual_price / 100, + // original_price: good.prices?.[0]?.original_price, + // yunfei: good.yunfei || 0, + // }, + // ], + // }); + // }, }); }, }, diff --git a/src/utils/goodsCache.js b/src/utils/goodsCache.js index 4aa77ba..9821e20 100644 --- a/src/utils/goodsCache.js +++ b/src/utils/goodsCache.js @@ -122,7 +122,9 @@ export function getHomeGoodsWithCache(params, forceRefresh = false) { // 无论是否有缓存,都请求最新数据进行对比 getGoodsListData(params).then(res => { - const newData = res?.data.data.products || [] + const newData = res?.data.data?.products || res?.data.data || [] + const hasMore = res?.data.data?.has_more + const nextCursor = res?.data.data?.next_cursor || '' const newHash = calculateDataHash(newData) // 检查数据是否有变化 @@ -136,6 +138,15 @@ export function getHomeGoodsWithCache(params, forceRefresh = false) { if (!cache || forceRefresh) { resolve({ ...res, + data: { + ...res.data, + data: { + ...res.data.data, + products: newData, + has_more: hasMore, + next_cursor: nextCursor + } + }, fromCache: false, hasChanged: true }) @@ -143,6 +154,15 @@ export function getHomeGoodsWithCache(params, forceRefresh = false) { // 如果已有缓存但数据有变化,通知更新 resolve({ ...res, + data: { + ...res.data, + data: { + ...res.data.data, + products: newData, + has_more: hasMore, + next_cursor: nextCursor + } + }, fromCache: false, hasChanged: true }) @@ -151,7 +171,13 @@ export function getHomeGoodsWithCache(params, forceRefresh = false) { // 数据没有变化,更新缓存时间戳 cache.timestamp = Date.now() resolve({ - data: { data: { products: cache.data } }, + data: { + data: { + products: cache.data, + has_more: hasMore, + next_cursor: nextCursor + } + }, fromCache: true, hasChanged: false }) @@ -160,7 +186,13 @@ export function getHomeGoodsWithCache(params, forceRefresh = false) { // 如果请求失败但有缓存,返回缓存 if (cache) { resolve({ - data: { data: { products: cache.data } }, + data: { + data: { + products: cache.data, + has_more: false, + next_cursor: '' + } + }, fromCache: true, error: err }) @@ -194,7 +226,9 @@ export function getCategoryGoodsWithCache(params, forceRefresh = false) { // 无论是否有缓存,都请求最新数据进行对比 getGoodsListData(params).then(res => { - const newData = res?.data || [] + const newData = res?.data.data?.products || res?.data || [] + const hasMore = res?.data.data?.has_more + const nextCursor = res?.data.data?.next_cursor || '' const newHash = calculateDataHash(newData) // 检查数据是否有变化 @@ -207,12 +241,30 @@ export function getCategoryGoodsWithCache(params, forceRefresh = false) { if (!cache || forceRefresh) { resolve({ ...res, + data: { + ...res.data, + data: { + ...res.data.data, + products: newData, + has_more: hasMore, + next_cursor: nextCursor + } + }, fromCache: false, hasChanged: true }) } else { resolve({ ...res, + data: { + ...res.data, + data: { + ...res.data.data, + products: newData, + has_more: hasMore, + next_cursor: nextCursor + } + }, fromCache: false, hasChanged: true }) @@ -221,7 +273,12 @@ export function getCategoryGoodsWithCache(params, forceRefresh = false) { // 数据没有变化,更新缓存时间戳 cache.timestamp = Date.now() resolve({ - data: cache.data, + data: newData, + data: { + products: cache.data, + has_more: hasMore, + next_cursor: nextCursor + }, count: cache.data.length, fromCache: true, hasChanged: false @@ -232,6 +289,11 @@ export function getCategoryGoodsWithCache(params, forceRefresh = false) { if (cache) { resolve({ data: cache.data, + data: { + products: cache.data, + has_more: false, + next_cursor: '' + }, count: cache.data.length, fromCache: true, error: err