feat: 商品详情联调

This commit is contained in:
zc 2025-11-05 17:34:49 +08:00
parent ade34f9f36
commit 93f5a8afab
6 changed files with 50 additions and 20 deletions

5
components.d.ts vendored
View File

@ -11,21 +11,16 @@ declare module 'vue' {
RouterLink: typeof import('vue-router')['RouterLink'] RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView'] RouterView: typeof import('vue-router')['RouterView']
VanArea: typeof import('vant/es')['Area'] VanArea: typeof import('vant/es')['Area']
VanButton: typeof import('vant/es')['Button']
VanCell: typeof import('vant/es')['Cell'] VanCell: typeof import('vant/es')['Cell']
VanCellGroup: typeof import('vant/es')['CellGroup'] VanCellGroup: typeof import('vant/es')['CellGroup']
VanField: typeof import('vant/es')['Field'] VanField: typeof import('vant/es')['Field']
VanForm: typeof import('vant/es')['Form'] VanForm: typeof import('vant/es')['Form']
VanIcon: typeof import('vant/es')['Icon'] VanIcon: typeof import('vant/es')['Icon']
VanNoticeBar: typeof import('vant/es')['NoticeBar'] VanNoticeBar: typeof import('vant/es')['NoticeBar']
VanPopover: typeof import('vant/es')['Popover']
VanPopup: typeof import('vant/es')['Popup'] VanPopup: typeof import('vant/es')['Popup']
VanSearch: typeof import('vant/es')['Search']
VanStepper: typeof import('vant/es')['Stepper'] VanStepper: typeof import('vant/es')['Stepper']
VanSwipe: typeof import('vant/es')['Swipe'] VanSwipe: typeof import('vant/es')['Swipe']
VanSwipeItem: typeof import('vant/es')['SwipeItem'] VanSwipeItem: typeof import('vant/es')['SwipeItem']
VanSwitch: typeof import('vant/es')['Switch'] VanSwitch: typeof import('vant/es')['Switch']
VanTab: typeof import('vant/es')['Tab']
VanTabs: typeof import('vant/es')['Tabs']
} }
} }

View File

@ -6,6 +6,7 @@ const shop = {
getReviewList: ['/comment/list'], // 获取评价接口 getReviewList: ['/comment/list'], // 获取评价接口
addCart: ['/shipping/cart/addOrUpdate'], // 添加购物车接口 addCart: ['/shipping/cart/addOrUpdate'], // 添加购物车接口
order: ['/order/add'], // 下单 order: ['/order/add'], // 下单
getWxPayParams: ['/order/getWxPayParams'], // 下单获取微信支付参数接口
// 订单 // 订单
orderList: ['/order/list'], // 订单列表 orderList: ['/order/list'], // 订单列表
} }

View File

@ -23,10 +23,10 @@ export const h5OpenMinProgram = (type = 'index', h5Url = '') => {
} }
if (h5Url && !h5Url.startsWith('https')) { if (h5Url && !h5Url.startsWith('https')) {
Object.assign(params, { Object.assign(params, {
query: `url=${encodeURIComponent(`${window.location.origin}${h5Url}`)}` query: `url=${encodeURIComponent(`${window.location.origin}${h5Url}`)}`,
}) })
} }
api.getSchemeUrl.post(params).then(res => { api.getSchemeUrl.post(params).then((res) => {
if (res.data) { if (res.data) {
window.location.href = res.data as any window.location.href = res.data as any
} else { } else {
@ -34,3 +34,29 @@ export const h5OpenMinProgram = (type = 'index', h5Url = '') => {
} }
}) })
} }
/**
* H5页面调用小程序支付
* @param {Object} paymentParams -
* @param {string} paymentParams.timeStamp -
* @param {string} paymentParams.nonceStr -
* @param {string} paymentParams.package - prepay_id参数值
* @param {string} paymentParams.signType - MD5
* @param {string} paymentParams.paySign -
*/
export const requestPayment = (paymentParams) => {
// 向小程序发送支付请求
console.warn('----- my data is window.wx111: ', window.wx)
if (window.wx && window.wx.miniProgram) {
// 微信环境
window.wx.miniProgram.postMessage({
data: {
type: 'pay',
data: paymentParams,
},
})
} else {
console.error('不在小程序环境中')
alert('请在微信小程序中打开')
}
}

View File

@ -48,6 +48,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import api from '@/api' import api from '@/api'
import { requestPayment } from '@/utils/wx-minprogram'
const model = defineModel<boolean>() const model = defineModel<boolean>()
const showAddressList = defineModel<boolean>('showAddressList') const showAddressList = defineModel<boolean>('showAddressList')
@ -78,13 +79,13 @@ const handleGetSkuList = (list: any[]) => {
const commodityValue = { id: item.id, imageUrl: item.imageUrl, salePrice: item.salePrice, price: item.promotionPrice, num: item.stock } const commodityValue = { id: item.id, imageUrl: item.imageUrl, salePrice: item.salePrice, price: item.promotionPrice, num: item.stock }
let commodityPropertyId = '' let commodityPropertyId = ''
if (i === 0) { if (i === 0) {
firstShopIds = item.vvSkuPropertyValueList.map((child) => ({ id: child.productPropertyValueId, productPropertyName: child.productPropertyName })) firstShopIds = item.vvSkuPropertyValueList.map((child) => ({ id: child.id, productPropertyName: child.productPropertyName }))
} }
item.vvSkuPropertyValueList.forEach((item2, index) => { item.vvSkuPropertyValueList.forEach((item2, index) => {
commodityPropertyId += item2.productPropertyValueId + (index < item.vvSkuPropertyValueList.length - 1 ? '_' : '') commodityPropertyId += item2.id + (index < item.vvSkuPropertyValueList.length - 1 ? '_' : '')
if (!result[item2.productPropertyName]) result[item2.productPropertyName] = [] if (!result[item2.productPropertyName]) result[item2.productPropertyName] = []
if (result[item2.productPropertyName].some((child) => child.propertyId === item2.productPropertyValueId)) return if (result[item2.productPropertyName].some((child) => child.propertyId === item2.id)) return
result[item2.productPropertyName].push({ propertyId: item2.productPropertyValueId, label: item2.productPropertyValue }) result[item2.productPropertyName].push({ propertyId: item2.id, label: item2.productPropertyValue })
}) })
commodityMap[commodityPropertyId] = commodityValue commodityMap[commodityPropertyId] = commodityValue
}) })
@ -108,7 +109,9 @@ const onSubmit = async () => {
await api.shop.addCart.post(formData.value) await api.shop.addCart.post(formData.value)
showToast('加入购物车成功') showToast('加入购物车成功')
} else { } else {
await api.shop.order.post({ buyerAddressId: 2, vvTradeOrderLineDTOList: [formData.value] }) // await api.shop.order.post({ buyerAddressId: 2, vvTradeOrderLineDTOList: [formData.value] })
// await api.shop.getWxPayParams.post(formData.value) // testzc
requestPayment({ a: 1, b: 2 })
showToast('下单成功') showToast('下单成功')
} }
} }

View File

@ -3,8 +3,12 @@
<header class="h-70 bg-[#aaa]"> <header class="h-70 bg-[#aaa]">
<van-swipe class="my-swipe" :autoplay="3000" indicator-color="white"> <van-swipe class="my-swipe" :autoplay="3000" indicator-color="white">
<van-swipe-item><img class="h-full w-full" :src="detail.mainImg" alt="" /></van-swipe-item> <van-swipe-item><img class="h-full w-full" :src="detail.mainImg" alt="" /></van-swipe-item>
<van-swipe-item v-if="detail.video">{{ detail.video }}</van-swipe-item> <van-swipe-item v-if="detail.video">
<van-swipe-item v-for="img in detail.subImgs" :key="img">{{ img }}</van-swipe-item> <video class="h-full w-full" :src="detail.video" autoplay muted loop></video>
</van-swipe-item>
<van-swipe-item v-for="img in detail.subImgs" :key="img">
<img class="h-full w-full" :src="img" alt="" />
</van-swipe-item>
</van-swipe> </van-swipe>
</header> </header>
<main> <main>
@ -31,7 +35,7 @@
</h3> </h3>
<!-- <info-table class="mt-3" /> --> <!-- <info-table class="mt-3" /> -->
<div class="imgs"> <div class="imgs">
<img v-for="img in detail.detailImgs" :src="img" alt="" class="w-full h-40" /> <div v-html="detail.contentHtml"></div>
</div> </div>
</div> </div>
<div class="wrap"> <div class="wrap">
@ -89,7 +93,7 @@ const detail = reactive({
mainImg: '', mainImg: '',
video: '', video: '',
subImgs: [], subImgs: [],
detailImgs: [], contentHtml: '',
title: '', title: '',
}) })
@ -116,6 +120,7 @@ const onShowAllReview = () => {
} }
// //
const onSubmit = (type: 'order' | 'cart') => { const onSubmit = (type: 'order' | 'cart') => {
console.warn('----- my data is window.wx: ', window.wx)
cartType.value = type cartType.value = type
showShopCart.value = true showShopCart.value = true
} }
@ -134,8 +139,8 @@ const handleGetCommodityDetail = (productId: number) => {
api.shop.getCommodityDetail.post<any>({ productId }).then((res) => { api.shop.getCommodityDetail.post<any>({ productId }).then((res) => {
detail.mainImg = res.data.mainImageUrl detail.mainImg = res.data.mainImageUrl
detail.video = res.data.videoUrl detail.video = res.data.videoUrl
detail.subImgs = res.data.vvProductDetailList.filter((item) => item.type === 1)?.map((item) => item.testzc) detail.subImgs = res.data.vvProductDetailList.filter((item) => item.type === 1)?.map((item) => item.detail)
detail.detailImgs = res.data.vvProductDetailList.find((item) => item.type === 2)?.testzc detail.contentHtml = res.data.vvProductDetailList.find((item) => item.type === 2)?.detail
detail.title = res.data.title detail.title = res.data.title
skuList.value = res.data.vvSkuList skuList.value = res.data.vvSkuList
}) })

View File

@ -10,7 +10,7 @@
<van-tab title="价格" name="2"></van-tab> <van-tab title="价格" name="2"></van-tab>
</van-tabs> </van-tabs>
<ul class="search-condition bg-white pt-2 flex-1 overflow-y-scroll"> <ul class="search-condition bg-white pt-2 flex-1 overflow-y-scroll">
<li v-for="item in searchList" :key="item.productId" class="flex item-center p-2 relative" @click="onGoDetail(item.productId)"> <li v-for="item in searchList" :key="item.id" class="flex item-center p-2 relative" @click="onGoDetail(item.id)">
<img :src="item.mainImageUrl" alt="" class="w-24 h-24" /> <img :src="item.mainImageUrl" alt="" class="w-24 h-24" />
<div class="ml-2"> <div class="ml-2">
<h4 class="text-[.13rem]">{{ item.title }}</h4> <h4 class="text-[.13rem]">{{ item.title }}</h4>
@ -82,7 +82,7 @@ const onSearch = async (searchValue: string, sort = '0') => {
const result = await api.shop.searchCommodityList.post<any>({ productName: searchValue, frontPage: 0, isTest: 0, ...sortParams }) // testzc const result = await api.shop.searchCommodityList.post<any>({ productName: searchValue, frontPage: 0, isTest: 0, ...sortParams }) // testzc
searchList.value = result.data.rows.map((item) => ({ searchList.value = result.data.rows.map((item) => ({
skuId: item.skuId, skuId: item.skuId,
productId: item.productId, id: item.id,
title: item.title, title: item.title,
mainImageUrl: item.mainImageUrl, mainImageUrl: item.mainImageUrl,
originPrice: String(item.showSalePrice), originPrice: String(item.showSalePrice),