Procházet zdrojové kódy

feat: 预下单接口调试

liangan před 3 týdny
rodič
revize
5867b12c0a

+ 24 - 0
src/api/order.ts

@@ -0,0 +1,24 @@
+import { qs } from '@/utils'
+import { http } from '@/utils/http'
+
+/**
+ * 商品预下单
+ * @returns
+ */
+export function preOrder(data: any) {
+  return http.post<any>(`/mall/order/pre/order`, data)
+}
+/**
+ * 加载预下单
+ * @returns
+ */
+export function loadPre(data: any) {
+  return http.post<any>(`/mall/order/load/pre?${qs(data)}`)
+}
+/**
+ * 计算订单价格
+ * @returns
+ */
+export function computedPrice(data: any) {
+  return http.post<any>(`/mall/order/computed/price`, data)
+}

+ 7 - 0
src/api/product.ts

@@ -18,3 +18,10 @@ export function getDetail(data: any) {
   const { extract } = extractAndRetained(data, ['id'])
   return http.post<any>(`/mall/product/detail?${qs(extract)}`)
 }
+/**
+ * 获取商品的拼团信息
+ * @returns data.list[]
+ */
+export function pinkList(data: any) {
+  return http.post<any>(`/mall/pink/list`, data)
+}

+ 0 - 2
src/main.ts

@@ -1,4 +1,3 @@
-import { VueQueryPlugin } from '@tanstack/vue-query'
 import { createSSRApp } from 'vue'
 import App from './App.vue'
 import { prototypeInterceptor, requestInterceptor, routeInterceptor } from './interceptors'
@@ -21,7 +20,6 @@ export function createApp() {
   app.use(routeInterceptor)
   app.use(requestInterceptor)
   app.use(prototypeInterceptor)
-  app.use(VueQueryPlugin)
 
   return {
     app,

+ 21 - 0
src/pages/productDetail/checkOut.vue

@@ -10,12 +10,33 @@
 </route>
 
 <script lang="ts" setup>
+import { computedPrice, loadPre } from '@/api/order'
 import DialogBox from '@/components/DialogBox/DialogBox.vue'
 import { DialogUtils } from '@/components/DialogBox/utils'
+import { useUserStore } from '@/store'
+import { getPageParams } from '@/utils/page'
 
 defineOptions({
   name: 'CheckOut', // 结账页面
 })
+const userStore = useUserStore()
+const userInfo = computed(() => {
+  return userStore.userInfo
+})
+const orderId = ref('')
+onLoad((options) => {
+  const params = getPageParams(options)
+  orderId.value = params.orderId
+  getPrice()
+})
+const orderDetail = ref<any>({})
+async function getPrice() {
+  const preOrderDetail = await loadPre({ preOrderNo: orderId.value })
+  console.log(preOrderDetail)
+  orderDetail.value = preOrderDetail.data.orderInfoVo.orderDetailList
+  const res = await computedPrice({ preOrderNo: orderId.value, userId: userInfo.value.userId, shippingType: 1 })
+  console.log(res)
+}
 
 // 商品信息
 const productInfo = ref({

+ 70 - 37
src/pages/productDetail/productDetail.vue

@@ -12,15 +12,21 @@
 // eslint-disable-next-line unused-imports/no-unused-imports
 import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
 import useZPaging from 'z-paging/components/z-paging/js/hooks/useZPaging.js'
-import { getDetail } from '@/api/product'
+import { preOrder as _preOrder } from '@/api/order'
+import { getDetail, pinkList } from '@/api/product'
+import { useUserStore } from '@/store/user'
 import { formatNumber } from '@/utils/index'
-import { getPageParams, goBack } from '@/utils/page'
+import { getPageParams, goBack, toPage } from '@/utils/page'
 import CustomTooltip from './components/CustomTooltip.vue'
 import NotificationCarousel from './components/NotificationCarousel.vue'
 
 defineOptions({
   name: 'ProductDetail', // 商品详情
 })
+const userStore = useUserStore()
+const userInfo = computed(() => {
+  return userStore.userInfo
+})
 // 获取屏幕边界到安全区域距离
 const systemInfo = uni.getSystemInfoSync()
 const safeAreaInsets = systemInfo.safeAreaInsets
@@ -45,7 +51,12 @@ onPageScroll((e) => {
     navBgColor.value = 'transparent'
   }
 })
-
+const id = ref('')
+const detail = ref<any>({
+  sliderImage: '',
+  flatPattern: '',
+})
+const pinkInfo = ref<any>([])
 // 添加通知轮播数据
 const notifications = ref([
   { id: 1, name: 'Aamir Khan', time: '10s' },
@@ -86,18 +97,20 @@ const avatarList = ref([
   '/static/images/avatar.jpg',
 ])
 
+// 拼团类型 join-加团 open-开团
+const groupType = ref('open')
+
 // sku 逻辑
 const showSku = ref(false)
-
+function openSku(type: string) {
+  showSku.value = true
+  groupType.value = type
+}
 const formData = ref({
-  num: 1,
+  productNum: 1,
   selectedSpecs: {}, // 存储选中的规格 { 颜色: '红色', 尺寸: 'M' }
 })
 
-const detail = ref<any>({
-  sliderImage: '',
-  flatPattern: '',
-})
 const matchedAttrValue = ref<any>({})
 
 // 计算选中规格的文案
@@ -184,23 +197,23 @@ function findMatchingAttrValue(selectedSpecs) {
     return selectedKeys.every(key => selectedSpecs[key] === attrValueSpecs[key])
   })
 }
-
-function toPage() {
-  uni.navigateTo({
-    url: '/pages/productDetail/checkOut',
-  })
-}
-async function queryDetail(id) {
-  const res = await getDetail({ id })
+// 查询商品详情
+async function queryDetail() {
+  const res = await getDetail({ id: id.value })
   console.log(res)
   detail.value = res.data
-
   // 默认选择第一个规格
   setDefaultSpecs()
-
   paging.value.complete()
 }
 
+// 查询商品拼团信息
+async function queryPinkInfo() {
+  const res = await pinkList({ id: id.value })
+  console.log(res)
+  pinkInfo.value = res.data.list
+}
+
 // 设置默认规格选择
 function setDefaultSpecs() {
   if (detail.value.attr && detail.value.attr.length > 0) {
@@ -233,17 +246,35 @@ function setDefaultSpecs() {
     }
   }
 }
-const id = ref('')
+
+// 预下单
+async function preOrder() {
+  const data = {
+    orderDetails: {
+      attrValueId: matchedAttrValue.value.id,
+      productId: id.value,
+      productNum: formData.value.productNum,
+    },
+    preOrderType: 'buyNow',
+    userId: userInfo.value.userId,
+  }
+  const res = await _preOrder(data)
+  console.log(res)
+  toPage('/pages/productDetail/checkOut', { orderId: res.data })
+}
+
+// 商品详情初始化
 onLoad((options) => {
   console.log(options)
   const params = getPageParams(options)
   id.value = params.id
-  queryDetail(id.value)
+  queryDetail()
+  queryPinkInfo()
 })
 </script>
 
 <template>
-  <z-paging ref="paging" use-page-scroll refresher-only @on-refresh="queryDetail(id)" @click="handlePageClick">
+  <z-paging ref="paging" use-page-scroll refresher-only @on-refresh="queryDetail" @click="handlePageClick">
     <wd-navbar :bordered="false" safe-area-inset-top fixed :left-arrow="false" :custom-style="`background: ${navBgColor}; transition: background 0.3s;`" custom-class="h-auto!">
       <template #title>
         <view class="box-border h-full flex items-center justify-between p-24rpx">
@@ -295,7 +326,7 @@ onLoad((options) => {
         <view class="line-clamp-2font-bold mb-16rpx">
           {{ detail.storeName }}
         </view>
-        <view class="flex items-center justify-between" @click="showSku = true">
+        <view class="flex items-center justify-between" @click="openSku('open')">
           <view>
             <text class="mr-20rpx">
               Selected
@@ -335,30 +366,32 @@ onLoad((options) => {
         </text>
       </view>
       <view class="flex flex-col gap-24rpx">
-        <view v-for="i in 3" :key="i" class="flex items-center justify-between">
+        <view v-for="(item, index) in pinkInfo" :key="index" class="flex items-center justify-between">
           <view class="flex items-center">
             <view>
               <!-- 头像组 最多五个 -->
               <view class="mr-16rpx flex items-center">
                 <view
-                  v-for="(avatar, index) in avatarList.slice(0, 5)"
-                  :key="index"
-                  :style="{ marginLeft: index !== 0 ? '-20rpx' : '0', zIndex: 10 - index }"
+                  v-for="(e, i) in avatarList.slice(0, 5)"
+                  :key="i"
+                  :style="{ marginLeft: i !== 0 ? '-20rpx' : '0', zIndex: 10 - i }"
                   class="h-56rpx w-56rpx overflow-hidden border-2rpx border-white rounded-full border-solid"
                 >
-                  <image :src="avatar" class="h-full w-full" mode="aspectFill" />
+                  <image :src="e" class="h-full w-full" mode="aspectFill" />
                 </view>
               </view>
             </view>
             <view>
-              <view class="text-28rpx font-bold">
-                Need <text class="text-[var(--wot-color-theme)]">
+              <view class="text-28rpx">
+                Need
+                <text class="text-[var(--wot-color-theme)]">
                   5
-                </text> More
+                </text>
+                More
               </view>
             </view>
           </view>
-          <wd-button size="small">
+          <wd-button size="small" @click="openSku('join')">
             Join Group
           </wd-button>
         </view>
@@ -398,7 +431,7 @@ onLoad((options) => {
         </view>
         <view class="flex flex-1 items-center justify-end text-32rpx">
           <view class="relative">
-            <view class="rounded-l-full bg-#2F2D31 px-34rpx py-18rpx text-white" @click="showSku = true">
+            <view class="rounded-l-full bg-#2F2D31 px-34rpx py-18rpx text-white" @click="openSku('open')">
               Open Group
             </view>
             <CustomTooltip
@@ -407,7 +440,7 @@ onLoad((options) => {
               highlight-text2="$1.8"
             />
           </view>
-          <view class="rounded-r-full bg-[var(--wot-color-theme)] px-34rpx py-18rpx text-white">
+          <view class="rounded-r-full bg-[var(--wot-color-theme)] px-34rpx py-18rpx text-white" @click="openSku('join')">
             Join Group
           </view>
         </view>
@@ -469,11 +502,11 @@ onLoad((options) => {
       </view>
       <view class="mb-100rpx flex items-center justify-between text-32rpx">
         <view>Quantity</view>
-        <wd-input-number v-model="formData.num" />
+        <wd-input-number v-model="formData.productNum" />
       </view>
       <view class="py-24rpx">
-        <wd-button block @click="toPage">
-          Join Group
+        <wd-button block :style="{ backgroundColor: groupType === 'open' ? '#2F2D31' : 'var(--wot-color-theme)' }" @click="preOrder">
+          {{ groupType === 'open' ? 'Open Group' : 'Join Group' }}
         </wd-button>
       </view>
     </view>

+ 2 - 2
src/utils/http.ts

@@ -19,12 +19,12 @@ export function http<T>(options: CustomRequestOptions) {
             resolve(res.data as IResData<T>)
           }
           else if (res.data.code === '401') {
-            reject(res.data)
             toast.error((res.data as IResData<T>).message || '未登录')
+            reject(res.data)
           }
           else {
-            reject(res.data)
             toast.error((res.data as IResData<T>).message || '请求错误')
+            reject(res.data)
           }
         }
         else if (res.statusCode === 401) {