This commit is contained in:
2026-04-10 19:00:01 +08:00
parent 32fa3e9bd2
commit 26e57e4891
6 changed files with 315 additions and 167 deletions

View File

@ -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";

View File

@ -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();
}

View File

@ -6,7 +6,7 @@
<!-- 可拖动联系客服组件 -->
<DraggableContact ref="draggableContact" :onClick="handleContactClick" />
<scroll-view class="homeContainer" scroll-y :show-scrollbar="false" :enhanced="true">
<scroll-view class="homeContainer" scroll-y :show-scrollbar="false" :enhanced="true" @scrolltolower="onLoadMore" :refresher-enabled="true" :refresher-triggered="refreshTriggered" @refresherrefresh="onRefresh">
<view class="swiperWrapper">
<swiper indicator-dots="true" autoplay="true" interval="3000" duration="500" circular="true"
class="swiper">
@ -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);
},
},
};
</script>

View File

@ -11,19 +11,19 @@
>
<image
class="goods-img"
:src="item.item_pic || item.product_pic"
:src="item.image "
mode="aspectFill"
/>
<view class="goods-content">
<view class="goods-name">{{
item.item_name || item.product_name
}}</view>
<!-- <view class="goods-name">{{
item.name
}}</view> -->
<view class="price-wrapper">
<text class="final-price-label">到手价</text>
<text class="final-price">¥{{ item.product_price || item.goods_price }}</text>
<text class="final-price">¥{{ item.price }}</text>
</view>
<view class="sales-info">
<text class="sales-count">{{ item.goods_name }}</text>
<text class="sales-count">{{ item.name }}</text>
</view>
</view>
</view>
@ -71,7 +71,7 @@
<view class="order-create-bottom">
<view class="price-info">
<text class="current-price">¥{{ payPrice.toFixed(2) }}</text>
<text class="current-price">¥{{ orderPrice.toFixed(2) }}</text>
</view>
<view class="pay-btn" @click="createOrder">
<text class="pay-btn-text">立即购买</text>
@ -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);

View File

@ -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,
// },
// ],
// });
// },
});
},
},

View File

@ -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