This commit is contained in:
2026-04-07 17:51:16 +08:00
parent 3b8c991e1a
commit 41f6f612fa
8 changed files with 213 additions and 82 deletions

View File

@ -236,7 +236,7 @@ export const CREATE_CART_ORDER = "/douyin/goods/order/create";
// 订单支付 // 订单支付
export const PAY_ORDER_NEW = "/ttpay/jsapi"; export const PAY_ORDER_NEW = "/ttpay/jsapi";
// 订单列表 // 订单列表
export const SHOP_ORDER_LIST = "/product/order/list"; export const SHOP_ORDER_LIST = "/douyin/goods/order/list";
// 订单详情 // 订单详情
export const SHOP_ORDER_DETAILS = "/product/order/show"; export const SHOP_ORDER_DETAILS = "/product/order/show";
// 取消订单 // 取消订单

View File

@ -78,31 +78,30 @@
"mp-baidu" : { "mp-baidu" : {
"usingComponents" : true "usingComponents" : true
}, },
"mp-toutiao": { "mp-toutiao" : {
"usingComponents": true, "usingComponents" : true,
"appid": "tte57093cd7a7fbf2401", "appid" : "tte57093cd7a7fbf2401",
"libVersion": "2.0.0", "libVersion" : "2.0.0",
"setting": { "setting" : {
"urlCheck": false, "urlCheck" : false,
"minified": true, "minified" : true,
"postcss": true, "postcss" : true,
"es6": true, "es6" : true,
"minifyJS": true, "minifyJS" : true,
"minifyWXML": true, "minifyWXML" : true,
"minifyWXSS": true "minifyWXSS" : true
},
"privacy" : {
"usePrivacyCheck" : true,
"requiredPrivateInfos" : [ "makePhoneCall" ]
},
"plugins" : {
"lifeServicePlugin" : {
"version" : "*",
"provider" : "tta5a3d31e3aecfb9b11"
}
}
}, },
"privacy": {
"usePrivacyCheck": true,
"requiredPrivateInfos": ["makePhoneCall"]
},
"plugins": {
"lifeServicePlugin": {
"version": "*",
"provider": "tta5a3d31e3aecfb9b11"
}
}
},
"mp-qq" : { "mp-qq" : {
"usingComponents" : true "usingComponents" : true
} }

View File

@ -396,7 +396,7 @@ export default {
flex-direction: row; flex-direction: row;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
margin-top: 16rpx; margin-top: 40rpx;
.goods-list-item { .goods-list-item {
flex: 1; flex: 1;

View File

@ -4,7 +4,7 @@
<image class="good-icon" :src="data[0].product_pic" mode="aspectFill" @click="$emit('clickGoodImg', data[0])" /> <image class="good-icon" :src="data[0].product_pic" mode="aspectFill" @click="$emit('clickGoodImg', data[0])" />
<view class="good-content" @click="$emit('clickGoodInfo', data[0])"> <view class="good-content" @click="$emit('clickGoodInfo', data[0])">
<view class="goods-row-first"> <view class="goods-row-first">
<view class="goods-name">{{ data[0].product_name || "" }}</view> <view class="goods-name">{{ data[0].goods_name || "" }}</view>
<text class="goods-price">¥{{ data[0].goods_price || actual_price }}</text> <text class="goods-price">¥{{ data[0].goods_price || actual_price }}</text>
</view> </view>
<view class="goods-row-second"> <view class="goods-row-second">
@ -24,7 +24,7 @@
<view class="good-info-right"> <view class="good-info-right">
<text class="good-total-price">¥{{ actual_price }}</text> <text class="good-total-price">¥{{ actual_price }}</text>
<text class="fs-24 app-fc-normal good-num"> <text class="fs-24 app-fc-normal good-num">
{{ goodsImgs.length }} 1
</text> </text>
</view> </view>
</view> </view>

View File

@ -44,7 +44,7 @@
</view> </view>
</view> </view>
<view class="order-content" :class="{ 'split-border': showStatusBtn }" @click="jumpToDetails"> <view class="order-content" :class="{ 'split-border': showStatusBtn }" @click="jumpToDetails">
<good-info :data="data.items" :actual_price="data.actual_price" /> <good-info :data="data" :actual_price="data.actual_price" />
<view v-if="data.type && data.type !== 1" class="fs-24 app-fc-mark order-type"> <view v-if="data.type && data.type !== 1" class="fs-24 app-fc-mark order-type">
随车订单 随车订单
</view> </view>

View File

@ -197,24 +197,29 @@ export default {
eventChannel.on("createOrder", (data) => { eventChannel.on("createOrder", (data) => {
// Helper function to extract first image from image_list // Helper function to extract first image from image_list
const extractFirstImage = (imageList) => { const extractFirstImage = (imageList) => {
if (!imageList) return ''; if (!imageList) return "";
try { try {
const parsedList = typeof imageList === 'string' ? JSON.parse(imageList) : imageList; const parsedList =
typeof imageList === "string" ? JSON.parse(imageList) : imageList;
if (Array.isArray(parsedList) && parsedList.length > 0) { if (Array.isArray(parsedList) && parsedList.length > 0) {
return parsedList[0].url || parsedList[0] || ''; return parsedList[0].url || parsedList[0] || "";
} }
} catch (e) { } catch (e) {
console.error('Error parsing image_list:', e); console.error("Error parsing image_list:", e);
} }
return ''; return "";
}; };
this.orderData = (data?.goodList || []).map(item => { this.orderData = (data?.goodList || []).map((item) => {
// Check if product_pic is actually an image_list that needs parsing // Check if product_pic is actually an image_list that needs parsing
let processedItem = { ...item }; let processedItem = { ...item };
if (processedItem.product_pic) { if (processedItem.product_pic) {
// If product_pic looks like an array or JSON string, try to parse it // If product_pic looks like an array or JSON string, try to parse it
if (typeof processedItem.product_pic === 'string' && (processedItem.product_pic.startsWith('[') || processedItem.product_pic.startsWith('{'))) { if (
typeof processedItem.product_pic === "string" &&
(processedItem.product_pic.startsWith("[") ||
processedItem.product_pic.startsWith("{"))
) {
const extractedUrl = extractFirstImage(processedItem.product_pic); const extractedUrl = extractFirstImage(processedItem.product_pic);
if (extractedUrl) { if (extractedUrl) {
processedItem.product_pic = extractedUrl; processedItem.product_pic = extractedUrl;
@ -262,14 +267,76 @@ export default {
uni.hideLoading(); uni.hideLoading();
// Check if tt and requirePlugin are available // Check if tt and requirePlugin are available
if (typeof tt !== 'undefined' && tt.requirePlugin) { if (typeof tt !== "undefined" && tt.requirePlugin) {
try { try {
const plugin = tt.requirePlugin("lifeServicePlugin"); const plugin = tt.requirePlugin("lifeServicePlugin");
if (plugin && plugin.createOrder) { if (plugin && plugin.createOrder) {
// let res1 = {
// data: {
// businessLine: 1,
// skuList: [
// {
// quantity: 1,
// skuId: "1861281775887367",
// skuType: 1,
// price: 12000,
// goodsInfo: {
// goodsName:
// "狗狗移动上门赛级洗护| 狗狗洗澡| 体重【5-10kg】",
// goodsPhoto:
// "https://static.wagoo.pet/statics/dog5to10base.png",
// goodsId: "7625864573682075667",
// goodsType: 1,
// },
// },
// ],
// bookInfo: {
// itemBookInfoList: [
// {
// poiId: "7620725019240319028",
// shopName: "WAGOO·上海市",
// outShopId: "life_7620725019240319028",
// goodsId: "7625864573682075667",
// bookStartTime: 1775613600000,
// bookEndTime: 1775622600000,
// },
// ],
// },
// payment: {
// totalAmount: 12000,
// },
// contactInfo: {
// phoneNumber: "13773726377",
// contactName: "老王",
// },
// storeInfo: {
// storeName: "WAGOO·上海市",
// },
// callbackData: {
// douyin_product_id: "7625864573682075667",
// douyin_sku_id: "1861281775887367",
// goods_id: 183,
// order_date: "2026-04-08",
// period_id: 1,
// test: 999999,
// },
// tradeOption: {
// life_trade_flag: 1,
// },
// },
// };
// console.log(res.data,'???')
plugin.createOrder({ plugin.createOrder({
skuList: res.data.skuList, skuList: res.data.skuList,
bookInfo: res.data.bookInfo,
contactInfo: res.data.contactInfo,
callbackData: res.data.callbackData,
storeInfo: res.data.storeInfo,
tradeOption: res.data.tradeOption,
payment: res.data.payment, payment: res.data.payment,
bookInfo:res.data.bookInfo, // callbackData:res.data.callbackData,
// tradeOption:res.data.tradeOption,
// goodsList:res.data.goodsList,
success: (res) => { success: (res) => {
const { orderId, outOrderNo } = res; const { orderId, outOrderNo } = res;
console.log("success res", res); console.log("success res", res);
@ -283,39 +350,46 @@ export default {
}, },
fail: (res) => { fail: (res) => {
console.log("fail res", res); console.log("fail res", res);
const { orderId, outOrderNo, errNo, errMsg, errLogId } = res; const { orderId, outOrderNo, errNo, errMsg, errLogId } =
res;
if (errLogId) { if (errLogId) {
console.log("预下单失败", errNo, errMsg, errLogId); console.log("预下单失败", errNo, errMsg, errLogId);
} }
if (orderId || outOrderNo) { if (orderId || outOrderNo) {
console.log("支付失败", errNo, errMsg, orderId, outOrderNo); console.log(
"支付失败",
errNo,
errMsg,
orderId,
outOrderNo
);
} }
console.log(errNo, errMsg); console.log(errNo, errMsg);
uni.showToast({ uni.showToast({
title: errMsg || '支付失败', title: errMsg || "支付失败",
icon: 'none' icon: "none",
}); });
}, },
}); });
} else { } else {
console.error('Plugin or createOrder method not found'); console.error("Plugin or createOrder method not found");
uni.showToast({ uni.showToast({
title: '支付插件初始化失败', title: "支付插件初始化失败",
icon: 'none' icon: "none",
}); });
} }
} catch (error) { } catch (error) {
console.error('Error requiring plugin:', error); console.error("Error requiring plugin:", error);
uni.showToast({ uni.showToast({
title: '支付插件加载失败', title: "支付插件加载失败",
icon: 'none' icon: "none",
}); });
} }
} else { } else {
console.log('TikTok Mini Program environment not detected'); console.log("TikTok Mini Program environment not detected");
uni.showToast({ uni.showToast({
title: '请在抖音小程序中打开', title: "请在抖音小程序中打开",
icon: 'none' icon: "none",
}); });
} }
@ -323,10 +397,10 @@ export default {
}) })
.catch((err) => { .catch((err) => {
uni.hideLoading(); uni.hideLoading();
console.error('createCartOrder error:', err); console.error("createCartOrder error:", err);
uni.showToast({ uni.showToast({
title: '创建订单失败', title: "创建订单失败",
icon: 'none' icon: "none",
}); });
reject(err); reject(err);
}); });

View File

@ -271,11 +271,11 @@
:order-status="1" :order-status="1"
:refund-total-amount="Math.round((orderData.actual_price || 0) * 100)" :refund-total-amount="Math.round((orderData.actual_price || 0) * 100)"
:apply-refund-params="{ :apply-refund-params="{
reasonCode: [410], reasonCode: [410],
note: '用户申请退款', note: '用户申请退款',
applySource: 101, applySource: 101,
afterSaleType: 3, afterSaleType: 3,
needRefundPackFee: true needRefundPackFee: true
}" }"
style="width:280rpx;height:100rpx;text-align:center;line-height: 100rpx;" style="width:280rpx;height:100rpx;text-align:center;line-height: 100rpx;"
@refund="handleRefundSuccess" @refund="handleRefundSuccess"

View File

@ -56,14 +56,24 @@
@scrolltolower="onLoadMore" @scrolltolower="onLoadMore"
> >
<view class="goods-list"> <view class="goods-list">
<good-item <view class="goods-list-item left">
v-for="good in goodsList" <good-item
:key="good.product_id" v-for="(good, i) in leftColumnGoods"
:ref="`goodItem_${good.product_id}`" :index="2 * i"
:data="good" :key="2 * i"
@addToCar="addToCar" :data="good"
@buyNow="handleBuyNow" @addToCar="addToCar"
/> />
</view>
<view class="goods-list-item right">
<good-item
v-for="(good, i) in rightColumnGoods"
:index="2 * i + 1"
:key="2 * i + 1"
:data="good"
@addToCar="addToCar"
/>
</view>
</view> </view>
<view v-if="isLoading" class="loading-wrapper flex-center"> <view v-if="isLoading" class="loading-wrapper flex-center">
<uni-load-more status="loading" :show-text="false" /> <uni-load-more status="loading" :show-text="false" />
@ -98,7 +108,7 @@
<script> <script>
import { imgPrefix } from "@/utils/common"; import { imgPrefix } from "@/utils/common";
import GoodItem from "../category/components/GoodItem.vue"; import GoodItem from "../shop/components/GoodItem.vue";
import AddGoodsModal from "@/components/goods/AddGoodsModal.vue"; import AddGoodsModal from "@/components/goods/AddGoodsModal.vue";
import ContactModal from "@/components/ContactModal.vue"; import ContactModal from "@/components/ContactModal.vue";
import WeChatCopyModal from "@/components/WeChatCopyModal.vue"; import WeChatCopyModal from "@/components/WeChatCopyModal.vue";
@ -179,6 +189,12 @@ export default {
cartShowCount() { cartShowCount() {
return this.cartCount > 9 ? "9+" : this.cartCount; return this.cartCount > 9 ? "9+" : this.cartCount;
}, },
leftColumnGoods() {
return this.goodsList.filter((v, i) => i % 2 === 0);
},
rightColumnGoods() {
return this.goodsList.filter((v, i) => i % 2 === 1);
},
}, },
mounted() { mounted() {
this.initData(); this.initData();
@ -267,14 +283,11 @@ export default {
if (this.isLoading) return; if (this.isLoading) return;
this.isLoading = true; this.isLoading = true;
getGoodsListData({ getGoodsListData({
type: this.selectCategoryId ? this.selectCategoryId : 1, type: this.selectCategoryId ? this.selectCategoryId : 0,
p: this.page,
num: this.size,
keyword: this.searchKeyword,
}) })
.then((res) => { .then((res) => {
const list = res?.data || []; const list = res?.data.data.products || [];
this.goodsList = list; this.goodsList = list;
this.total = res?.count || 0; this.total = res?.count || 0;
}) })
.finally(() => { .finally(() => {
@ -348,11 +361,38 @@ export default {
this.cartCountBounce = false; this.cartCountBounce = false;
}, 600); }, 600);
}, },
addToCar(good) { addToCar(goodsData) {
this.showModal = true; // Parse image_list and get the first image URL
this.addGoodInfo = { let firstImageUrl = '';
...good, const imageList = goodsData.product.attr_key_value_map.image_list;
}; if (imageList) {
try {
// Try to parse as JSON if it's a string
const parsedList = typeof imageList === 'string' ? JSON.parse(imageList) : imageList;
if (Array.isArray(parsedList) && parsedList.length > 0) {
firstImageUrl = parsedList[0].url || parsedList[0] || '';
}
} catch (e) {
console.error('Error parsing image_list:', e);
}
}
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
}, ],
});
},
});
}, },
// 购物车列表 // 购物车列表
getCartListData() { getCartListData() {
@ -597,4 +637,22 @@ export default {
.loading-wrapper { .loading-wrapper {
padding: 10rpx 0; padding: 10rpx 0;
} }
.goods-list {
display: flex;
flex-direction: row;
justify-content: flex-start;
align-items: flex-start;
margin-top: 40rpx;
padding: 0 20rpx;
.goods-list-item {
flex: 1;
min-width: 0;
&.left {
margin-right: 20rpx;
}
}
}
</style> </style>