Bladeren bron

feat(api): 添加用户收货地址相关接口定义

- 添加addressList接口类型定义
- 定义收货地址增删改查相关API接口
- 扩展用户信息接口,添加企业名称字段
- 添加商品库存和规格相关字段定义

feat(store): 增加收货地址和支付路径状态管理

- 在用户store中添加收货地址列表和选中地址状态
- 在系统store中添加支付成功/失败页面跳转路径配置
- 实现获取用户收货地址列表功能
- 实现更新选中收货地址功能

feat(address): 实现收货地址列表和编辑功能

- 创建收货地址列表页面,支持设为默认地址
- 实现收货地址编辑页面,支持增删改操作
- 集成地图选择位置功能
- 添加表单验证和错误提示

feat(order): 实现确认订单页面和商品规格选择

- 创建确认订单页面,支持选择收货地址
- 实现商品规格弹窗选择功能
- 添加商品库存验证逻辑
- 重构商品详情页面规格显示

feat(payment): 完善支付成功页面跳转逻辑

- 实现支付成功页面订单查看跳转
- 添加支付失败页面返回首页功能
- 配置支付页面路径状态管理

feat(common): 优化公共组件和页面功能

- 修复售后页面滚动问题
- 优化积分页面空状态显示
- 调整客服按钮样式和层级
- 更新用户企业名称显示

refactor(config): 调整开发环境配置

- 更新开发环境服务器地址配置
- 优化页面路由配置

chore(deps): 更新页面配置和类型定义

- 同步页面配置文件更新
- 修正uni-pages类型定义
zhangtao 1 dag geleden
bovenliggende
commit
ba25bb114f

+ 6 - 1
src/App.vue

@@ -47,7 +47,12 @@ onLaunch(() => { })
   height: 0;
   color: transparent;
 }
-
+.zbutton{
+  all: unset;
+  &::after{
+    border: none;
+  }
+}
 .page-xsb {
   :deep() {
     .line {

+ 95 - 0
src/api/api.type.d.ts

@@ -1,5 +1,9 @@
 namespace Api {
   interface userInfo {
+    /**
+     * 企业名称
+     */
+    channelName: string
     /**
      * 渠道(企业ID)
      */
@@ -26,6 +30,18 @@ namespace Api {
     nickName?: string
     [property: string]: any
   }
+  interface addressList {
+    area?: string
+    city?: string
+    consigneeMobile?: string
+    consigneeName?: string
+    defaulted?: number
+    detailAddress?: string
+    id: number
+    memberId?: number
+    province?: string
+    [property: string]: any
+  }
 
   interface xsbCategoriesChildren {
     id: number
@@ -84,6 +100,10 @@ namespace Api {
     [property: string]: any
   }
   interface xsbProductDetail {
+    /**
+     * 商品库存
+     */
+    spuStock: number
     /**
      * 品牌名称
      */
@@ -133,6 +153,81 @@ namespace Api {
      * 单位
      */
     weightUnit?: string
+    /**
+     * 商品规格
+     */
+    skuList: xsbAppSkuDetailVO[]
+    [property: string]: any
+  }
+  interface xsbAppSkuDetailVO {
+    /**
+     * 业务类型
+     */
+    businessType?: string
+    /**
+     * 单品编码(海博)
+     */
+    hbSkuId?: string
+    /**
+     * 商品编码(海博)
+     */
+    hbSpuId?: string
+    /**
+     * 商品条形码
+     */
+    modelId?: string
+    /**
+     * 商家编码
+     */
+    partyCode?: string
+    /**
+     * sku图片
+     */
+    pic?: string
+    /**
+     * 价格
+     */
+    price?: number
+    /**
+     * 商品ID
+     */
+    prodId?: number
+    /**
+     * 商品名称
+     */
+    prodName?: string
+    /**
+     * 单品ID
+     */
+    skuId: number
+    /**
+     * sku名称
+     */
+    skuName?: string
+    /**
+     * 规格
+     */
+    spec?: string
+    /**
+     * 库存
+     */
+    stocks?: number
+    /**
+     * 第三方SkuID
+     */
+    thirdSkuId?: string
+    /**
+     * 体积
+     */
+    volume?: number
+    /**
+     * 重量
+     */
+    weight?: number
+    /**
+     * 单位
+     */
+    weightUnit?: string
     [property: string]: any
   }
   interface xsbFindUserPointsPage {

+ 5 - 0
src/api/apiDefinitions.ts

@@ -26,6 +26,11 @@ Some useful links:
 export default {
   'sys.auth': ['POST', '/smqjh-auth/oauth2/token'],
   'sys.userInfo': ['GET', '/smqjh-system/app-api/v1/members/me'],
+  'sys.addresses': ['GET', '/smqjh-system/app-api/v1/addresses'],
+  'sys.Addaddresses': ['POST', '/smqjh-system/app-api/v1/addresses'],
+  'sys.updateAddresses': ['PUT', '/smqjh-system/app-api/v1/addresses/updateAddress'],
+  'sys.deleteAddresses': ['DELETE', '/smqjh-system/app-api/v1/addresses/{ids}'],
+  'sys.addressesDetail': ['GET', '/smqjh-system/app-api/v1/addresses/{addressId}'],
   'sys.uploadFile': ['POST', '/smqjh-system/api/v1/files'],
   'sys.updateUserInfo': ['PUT', '/smqjh-system/app-api/v1/members/{memberId}'],
   'xsb.categories':['GET', '/smqjh-pms/app-api/v1/categories'],

+ 37 - 0
src/api/globals.d.ts

@@ -138,6 +138,41 @@ declare global {
         >(
         config: Config
       ): Alova2Method<{url:string}, 'sys.uploadFile', Config>;
+      addresses<
+        Config extends Alova2MethodConfig<Api.addressList[]>&{
+
+        }
+        >(
+        config: Config
+      ): Alova2Method<Api.addressList[], 'sys.addresses', Config>;
+      Addaddresses<
+        Config extends Alova2MethodConfig<any> & {
+          data:Api.addressList;
+        }
+        >(
+        config: Config
+      ): Alova2Method<any, 'sys.Addaddresses', Config>;
+      deleteAddresses<
+        Config extends Alova2MethodConfig<any> & {
+          pathParams: { ids: string };
+        }
+        >(
+        config: Config
+      ): Alova2Method<any, 'sys.deleteAddresses', Config>;
+      updateAddresses<
+        Config extends Alova2MethodConfig<any> & {
+          data:Api.addressList;
+        }
+        >(
+        config: Config
+      ): Alova2Method<any, 'sys.updateAddresses', Config>;
+      addressesDetail<
+        Config extends Alova2MethodConfig<Api.addressList> & {
+          pathParams: { addressId: number };
+        }
+        >(
+        config: Config
+      ): Alova2Method<Api.addressList, 'sys.addressesDetail', Config>;
     }
     xsb: {
       categories<
@@ -165,6 +200,8 @@ declare global {
         Config extends Alova2MethodConfig<Api.xsbProductDetail> & {
           data: {
             id: number;
+            shopId: number
+            channelId:number
           };
         }
       >(

+ 1 - 0
src/composables/useGlobalToast.ts

@@ -9,6 +9,7 @@ interface GlobalToast {
 const defaultOptions: ToastOptions = {
   duration: 2000,
   show: false,
+  zIndex: 99999999999,
 }
 export const useGlobalToast = defineStore('global-toast', {
   state: (): GlobalToast => ({

+ 2 - 2
src/config/index.ts

@@ -14,8 +14,8 @@ const mapEnvVersion = {
   // develop: 'http://192.168.1.166:8080', // 张
   // develop: 'http://192.168.1.101:8080',
   // develop: 'http://192.168.0.157:8080',
-  develop: 'http://192.168.1.253:8080',
-  // develop: 'http://192.168.1.89:8080', // 田
+  // develop: 'http://192.168.1.253:8080',
+  develop: 'http://192.168.1.89:8080', // 田
   // develop: 'http://47.109.84.152:8081',
   /**
    * 体验版

+ 9 - 9
src/pages.json

@@ -111,6 +111,15 @@
             "disableScroll": true
           }
         },
+        {
+          "path": "confirmOrder/index",
+          "type": "page",
+          "name": "xsb-confirmOrder",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "提交订单"
+          }
+        },
         {
           "path": "goods/index",
           "type": "page",
@@ -189,15 +198,6 @@
             "navigationBarTitleText": "售后列表"
           }
         },
-        {
-          "path": "confirmOrder/index",
-          "type": "page",
-          "name": "common-confirmOrder",
-          "islogin": true,
-          "style": {
-            "navigationBarTitleText": "提交订单"
-          }
-        },
         {
           "path": "editAddress/index",
           "type": "page",

+ 3 - 10
src/pages/my/index.vue

@@ -48,7 +48,7 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
                 {{ userInfo.nickName }}
               </view>
               <view class="mt12rpx rounded-8rpx bg-white px12rpx py4rpx text-24rpx text-[var(--them-color)] opacity-70">
-                中数未来(广州)信息技术有限公司
+                {{ userInfo.channelName }}
               </view>
             </view>
           </view>
@@ -103,7 +103,7 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
               <image :src="`${StaticUrl}/5.png`" class="h50rpx w50rpx" />
             </template>
             <template #title>
-              <button class="button" open-type="contact">
+              <button class="zbutton ml20rpx" open-type="contact">
                 联系平台客服
               </button>
             </template>
@@ -134,14 +134,7 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
 .header {
  background: linear-gradient( 113deg, #F7FFDC 0%, #E0FF8E 25%, #F2FFCE 51%, #E3FF98 83%, #F6FFD6 100%);
 }
-.button{
-  background-color: unset;
-  font-size: 24rpx;
-  line-height: 45rpx;
-  &::after{
-  border: none ;
-  }
-}
+
 .page-class {
   :deep() {
     .login-btn {

+ 27 - 0
src/store/sys.ts

@@ -10,12 +10,29 @@ interface SysState {
    * 胶囊按钮高度
    */
   MenuButtonHeight: number
+  /**
+   * 支付成功页面查看订单按钮跳转路径
+   *
+   */
+  paySuccessPath: string
+  /**
+   * 支付成功页面返回首页按钮跳转路径
+   */
+  payBackIndexPath: string
+  /**
+   * 支付失败页面返回首页按钮跳转路径
+   */
+  payFailPath: string
+
 }
 export const useSysStore = defineStore('system', {
   state: (): SysState => ({
     ScrollDown: false,
     statusBarHeight: 0,
     MenuButtonHeight: 0,
+    paySuccessPath: '',
+    payBackIndexPath: '',
+    payFailPath: '',
   }),
   actions: {
     getSystemData() {
@@ -24,5 +41,15 @@ export const useSysStore = defineStore('system', {
       this.statusBarHeight = Number(statusBarHeight)
       this.MenuButtonHeight = height
     },
+    /**
+     *
+     * @param payBackIndexPath 支付成功页面返回首页按钮跳转路径
+     *
+     * @param paySuccessPath 支付成功页面查看订单按钮跳转路径
+     */
+    setPaySuccessPath(paySuccessPath: string, payBackIndexPath: string) {
+      this.paySuccessPath = paySuccessPath
+      this.payBackIndexPath = payBackIndexPath
+    },
   },
 })

+ 34 - 1
src/store/user.ts

@@ -11,7 +11,15 @@ interface userStroe {
    * 用户登录信息
    */
   userInfo: Api.userInfo
-
+  /**
+   * 用户收货地址
+   */
+  addresses: Api.addressList[]
+  /**
+   * 用户选择的收货地址
+   *
+   */
+  selectedAddress: Api.addressList | null
 }
 export const useUserStore = defineStore('user', {
   state: (): userStroe => ({
@@ -20,7 +28,10 @@ export const useUserStore = defineStore('user', {
     userInfo: {
       id: 0,
       channelId: 0,
+      channelName: '',
     },
+    addresses: [],
+    selectedAddress: null,
   }),
   getters: {
     getUserAvatar(): string {
@@ -44,5 +55,27 @@ export const useUserStore = defineStore('user', {
       useGlobalToast().show({ msg: '修改成功' })
       this.getUserInfo()
     },
+    /**
+     * 获取用户收货地址列表
+     */
+    async getuserAddresslist() {
+      uni.showLoading({ mask: true })
+      const res = await Apis.sys.addresses({})
+      this.addresses = res || []
+      uni.hideLoading()
+    },
+    /**
+     * 更新用户选择的收货地址
+     */
+    updateSelectedAddress(address: Api.addressList) {
+      this.selectedAddress = address
+    },
+    /**
+     * 获取用户收货地址
+     * @description 默认选择默认地址,如无默认地址则不选择
+     */
+    getSelectedAddress() {
+      this.selectedAddress = this.addresses.find(it => it.defaulted === 1) ?? null
+    },
   },
 })

+ 57 - 20
src/subPack-common/addressList/index.vue

@@ -1,4 +1,5 @@
 <script setup lang="ts">
+import { createGlobalLoadingMiddleware } from '@/api/core/middleware'
 import { StaticUrl } from '@/config'
 import router from '@/router'
 
@@ -9,32 +10,62 @@ definePage({
     navigationBarTitleText: '收获地址',
   },
 })
+const defaultId = ref()
+const { addresses } = storeToRefs(useUserStore())
+const route = useRoute()
+const { send: updateData } = useRequest(data => Apis.sys.updateAddresses({
+  data,
+}), { middleware: createGlobalLoadingMiddleware({ loadingText: '设置中。。。' }), immediate: false })
+
+onShow(() => {
+  useUserStore().getuserAddresslist()
+})
+watch(() => addresses.value, () => {
+  defaultId.value = addresses.value.find(item => item.defaulted === 1)?.id
+})
+
+async function handleChange(e: { value: number }) {
+  const item = addresses.value.find(i => i.id === e.value)
+  if (item) {
+    updateData({ ...item, defaulted: 1 })
+  }
+}
+function handleSelectAddress(item: Api.addressList) {
+  if (!route.query?.type)
+    return
+  useUserStore().updateSelectedAddress(item)
+  router.back()
+}
 </script>
 
 <template>
   <view class="page">
     <view class="px24rpx py20rpx">
-      <view v-for="item in 10" :key="item" class="mb20rpx rounded-16rpx bg-white p24rpx">
-        <view class="flex items-center justify-between">
-          <view class="text-28rpx font-semibold">
-            杨锦新 18594565489
+      <wd-radio-group v-model="defaultId" @change="handleChange">
+        <view v-for="item in addresses" :key="item.id" class="mb20rpx rounded-16rpx bg-white p24rpx" @click="handleSelectAddress(item)">
+          <view class="flex items-center justify-between">
+            <view class="text-28rpx font-semibold">
+              {{ item.consigneeName }} {{ item.consigneeMobile }}
+            </view>
+            <image
+              :src="`${StaticUrl}/edit-address.png`"
+              class="h40rpx w40rpx"
+              @click="router.push({ name: 'common-editAddress', params: { type: '2', id: `${item.id}` } })"
+            />
           </view>
-          <image
-            :src="`${StaticUrl}/edit-address.png`"
-            class="h40rpx w40rpx"
-            @click="router.push({ name: 'common-editAddress', params: { type: '2' } })"
-          />
-        </view>
-        <view class="mt24rpx text-24rpx text-#AAAAAA">
-          贵阳省贵阳市观山湖区富力中心A座
+          <view class="mt24rpx text-24rpx text-#AAAAAA">
+            {{ item.province }}{{ item.city }}{{ item.detailAddress }}
+          </view>
+          <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+          <wd-radio :value="item.id" shape="dot" inline>
+            设为默认地址
+          </wd-radio>
         </view>
-        <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
-        <wd-checkbox v-model="value">
-          设为默认地址
-        </wd-checkbox>
-      </view>
-      <view class="ios h120rpx" />
+        <view class="ios h120rpx" />
+      </wd-radio-group>
+      <wd-status-tip v-if="!addresses.length" image="content" tip="暂无内容" />
     </view>
+
     <view class="ios fixed bottom-0 left-0 box-border w-full rounded-t-32rpx bg-white px24rpx">
       <view class="w-full py20rpx">
         <wd-button size="large" block @click="router.push({ name: 'common-editAddress', params: { type: '1' } })">
@@ -45,6 +76,12 @@ definePage({
   </view>
 </template>
 
-<style scoped>
-
+<style scoped lang="scss">
+.page{
+  :deep(){
+    .wd-radio-group{
+      background-color: unset !important;
+    }
+  }
+}
 </style>

+ 2 - 1
src/subPack-common/afterSales/index.vue

@@ -37,7 +37,8 @@ function handleSelectReson() {
 </script>
 
 <template>
-  <view class="page-xsb" :style="`overflow:${showReson ? 'hidden' : 'visible'};`">
+  <page-meta :page-style="showReson ? 'overflow: hidden;' : '' " />
+  <view class="page-xsb">
     <view class="box-border w-full flex items-center bg-#f8e3ca px24rpx py12rpx">
       <wd-icon name="info-circle-filled" size="22px" color="#FF941A" />
       <view class="ml16rpx text-28rpx">

+ 2 - 1
src/subPack-common/afterSalesDetail/index.vue

@@ -16,7 +16,8 @@ const dayId = ref(1)
 </script>
 
 <template>
-  <view class="page-xsb pt20rpx" :style="`overflow:${showTime ? 'hidden' : 'visible'};`">
+  <page-meta :page-style="showTime ? 'overflow: hidden;' : '' " />
+  <view class="page-xsb pt20rpx">
     <view class="mb24rpx">
       <wd-card>
         <view class="py24rpx">

+ 76 - 10
src/subPack-common/editAddress/index.vue

@@ -17,20 +17,78 @@ const title = computed(() => {
   return '编辑收获地址'
 })
 
-const modelForm = ref({
-  name: '',
-
+const modelForm = ref<Api.addressList>({
+  consigneeName: '',
+  consigneeMobile: '',
+  detailAddress: '',
+  defaulted: 1,
+  latitude: 0,
+  longitude: 0,
+  province: '',
+  city: '',
+  id: 0,
 })
 function handleSelectAddress() {
   uni.chooseLocation({
     success: (res) => {
-      console.log(res, '收获地址')
+      modelForm.value.latitude = res.latitude
+      modelForm.value.longitude = res.longitude
+      modelForm.value.province = res.address
+      modelForm.value.city = res.name
+      console.log(modelForm.value, '地址')
     },
     fail: (e) => {
       console.log('获取地址失败', e)
     },
   })
 }
+async function getData() {
+  const res = await Apis.sys.addressesDetail({ pathParams: { addressId: Number(route.query?.id) } })
+  modelForm.value = res
+}
+onMounted(() => {
+  if (route.query?.type === '2') {
+    getData()
+  }
+})
+async function handleSubmit() {
+  if (!modelForm.value.consigneeName) {
+    useGlobalToast().show('请输入收货人姓名')
+    return
+  }
+  if (!modelForm.value.consigneeMobile) {
+    useGlobalToast().show('请输入手机号码')
+    return
+  }
+  if (!modelForm.value.province) {
+    useGlobalToast().show('请选择所在地区')
+    return
+  }
+  if (!modelForm.value.detailAddress) {
+    useGlobalToast().show('请输入详细地址')
+  }
+  if (Number(route.query?.type) === 1) {
+    await Apis.sys.Addaddresses({ data: modelForm.value })
+    useGlobalToast().show({ msg: '添加成功' })
+  }
+  else {
+    await Apis.sys.updateAddresses({ pathParams: modelForm.value.id, data: modelForm.value })
+    useGlobalToast().show({ msg: '修改成功' })
+  }
+  setTimeout(() => {
+    router.back()
+  }, 2000)
+}
+async function handleDel() {
+  useGlobalMessage().confirm({
+    title: '删除地址',
+    msg: '确定要删除该地址吗?',
+    success: async () => {
+      await Apis.sys.deleteAddresses({ pathParams: { ids: route.query?.id } })
+      router.back()
+    },
+  })
+}
 </script>
 
 <template>
@@ -47,7 +105,7 @@ function handleSelectAddress() {
             收货人
           </view>
           <view class="flex-1">
-            <wd-input v-model="modelForm.name" no-border placeholder="姓名" />
+            <wd-input v-model="modelForm.consigneeName" no-border placeholder="姓名" />
           </view>
         </view>
         <view class="mt28rpx flex items-center">
@@ -55,7 +113,7 @@ function handleSelectAddress() {
             手机号码
           </view>
           <view class="flex-1">
-            <wd-input v-model="modelForm.name" no-border placeholder="11位手机号码" />
+            <wd-input v-model="modelForm.consigneeMobile" :maxlength="11" no-border placeholder="11位手机号码" />
           </view>
         </view>
         <view class="mt28rpx flex items-center">
@@ -63,9 +121,17 @@ function handleSelectAddress() {
             所在地区
           </view>
           <view class="flex flex-1 items-center justify-between" @click="handleSelectAddress">
-            <view class="text-28rpx text-[var(--them-color)]">
+            <view v-if="!modelForm.province" class="text-28rpx text-[var(--them-color)]">
               点击选择地址
             </view>
+            <view v-else class="text-24rpx">
+              <view class="font-semibold">
+                {{ modelForm.province }}
+              </view>
+              <view class="mt12rpx text-#AAAAAA">
+                {{ modelForm.city }}
+              </view>
+            </view>
             <wd-icon name="arrow-right" size="22px" color="#aaa" />
           </view>
         </view>
@@ -74,16 +140,16 @@ function handleSelectAddress() {
             详细地址
           </view>
           <view class="flex-1">
-            <wd-input v-model="modelForm.name" no-border placeholder="如楼号/单元号/门牌号" />
+            <wd-input v-model="modelForm.detailAddress" no-border placeholder="如楼号/单元号/门牌号" />
           </view>
         </view>
       </view>
       <view class="mt84rpx px100rpx">
-        <wd-button type="primary" block size="large">
+        <wd-button type="primary" block size="large" @click="handleSubmit">
           保存收货地址
         </wd-button>
         <view v-if="title == '编辑收获地址'" class="mt24rpx">
-          <wd-button plain block size="large">
+          <wd-button plain block size="large" @click="handleDel">
             删除收获地址
           </wd-button>
         </view>

+ 1 - 0
src/subPack-common/integral/index.vue

@@ -75,6 +75,7 @@ function handleScrollBottom() {
         </view>
         <view v-if="index < pointList.length - 1" class="mt24rpx h-2rpx w-full bg-#F0F0F0" />
       </view>
+      <wd-status-tip v-if="!pointList.length" image="content" tip="暂无内容" />
     </scroll-view>
   </view>
 </template>

+ 1 - 1
src/subPack-common/orderDetaile/index.vue

@@ -72,7 +72,7 @@ function handleCollapse() {
               联系商家
             </view>
           </view>
-          <view class="flex flex-col items-center" @click="router.push({ name: 'xsb-afterSales' })">
+          <view class="flex flex-col items-center" @click="router.push({ name: 'common-afterSales' })">
             <image
               :src="`${StaticUrl}/orderDetaile-shou.png`"
               class="h40rpx w40rpx"

+ 6 - 3
src/subPack-common/paySuccess/index.vue

@@ -11,10 +11,11 @@ definePage({
     disableScroll: true,
   },
 })
+const { paySuccessPath, payBackIndexPath } = storeToRefs(useSysStore())
+
 function handleBackIndex() {
-  const xsbIndex = 'subPack-xsb/commonTab/index'
   const pages = getCurrentPages()
-  const targetPageIndex = pages.findIndex(page => page.route === xsbIndex)
+  const targetPageIndex = pages.findIndex(page => page.route === unref(payBackIndexPath))
 
   if (targetPageIndex !== -1) {
     const delta = pages.length - targetPageIndex - 1
@@ -46,7 +47,9 @@ function handleBackIndex() {
           支付成功
         </view>
         <view class="mt60rpx flex items-center">
-          <wd-button type="info" block size="large">
+          <wd-button
+            type="info" block size="large" @click=" router.push({ name: unref(paySuccessPath) })"
+          >
             <text class="text-32rpx font-semibold">
               查看订单
             </text>

+ 3 - 10
src/subPack-xsb/commonTab/components/my.vue

@@ -19,6 +19,7 @@ const tabList = ref([
 ])
 
 const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
+useUserStore().getUserInfo()
 </script>
 
 <template>
@@ -46,7 +47,7 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
                 {{ userInfo.nickName }}
               </view>
               <view class="mt12rpx rounded-8rpx bg-white px12rpx py4rpx text-24rpx text-[var(--them-color)] opacity-70">
-                中数未来(广州)信息技术有限公司
+                {{ userInfo.channelName }}
               </view>
             </view>
           </view>
@@ -101,7 +102,7 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
               <image :src="`${StaticUrl}/5.png`" class="h50rpx w50rpx" />
             </template>
             <template #title>
-              <button class="button" open-type="contact">
+              <button class="zbutton ml20rpx" open-type="contact">
                 联系平台客服
               </button>
             </template>
@@ -132,12 +133,4 @@ const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
 .header {
  background: linear-gradient( 113deg, #F7FFDC 0%, #E0FF8E 25%, #F2FFCE 51%, #E3FF98 83%, #F6FFD6 100%);
 }
-.button{
-  background-color: unset;
-  font-size: 24rpx;
-  line-height: 45rpx;
-  &::after{
-  border: none ;
-  }
-}
 </style>

+ 1 - 1
src/subPack-xsb/commonTab/index.vue

@@ -26,7 +26,7 @@ const { ScrollDown, topNavActive, leftActive, backTop, SelectShopInfo } = storeT
 const { userInfo } = storeToRefs(useUserStore())
 const commonCategoryData = ref<Api.xsbCategories[]>([])
 const { data: goodsList, isLastPage, page, error, refresh } = usePagination((pageNum, pageSize) =>
-  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: userInfo.value.channelId } }), {
+  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: userInfo.value.channelId || 1 } }), {
   data: resp => resp.list,
   initialData: [],
   initialPage: 1,

+ 27 - 3
src/subPack-common/confirmOrder/index.vue → src/subPack-xsb/confirmOrder/index.vue

@@ -3,12 +3,18 @@ import { StaticUrl } from '@/config'
 import router from '@/router'
 
 definePage({
-  name: 'common-confirmOrder',
+  name: 'xsb-confirmOrder',
   islogin: true,
   style: {
     navigationBarTitleText: '提交订单',
   },
 })
+const { selectedAddress } = storeToRefs(useUserStore())
+onLoad(() => {
+  if (!selectedAddress.value) {
+    useUserStore().getSelectedAddress()
+  }
+})
 function handlePay() {
   router.replace({ name: 'common-paySuccess' })
 }
@@ -16,14 +22,32 @@ function handlePay() {
 
 <template>
   <view class="page px20rpx py20rpx">
-    <view class="mb20rpx rounded-16rpx bg-white p24rpx">
+    <view class="mb20rpx rounded-16rpx bg-white p24rpx" @click="router.push({ name: 'common-addressList', params: { type: 'select' } })">
       <view class="flex items-center justify-between">
-        <view class="flex items-center">
+        <view v-if="!selectedAddress" class="flex items-center">
           <wd-icon name="location" size="18px" />
           <view class="ml10rpx text-28rpx">
             请添加收货地址
           </view>
         </view>
+        <view v-else>
+          <view class="flex items-center">
+            <view v-if="selectedAddress.defaulted" class="mr20rpx">
+              <wd-tag type="primary">
+                默认
+              </wd-tag>
+            </view>
+            <view class="flex items-center text-28rpx font-semibold">
+              <view>{{ selectedAddress?.consigneeName }} </view>
+              <view class="ml20rpx">
+                {{ selectedAddress?.consigneeMobile }}
+              </view>
+            </view>
+          </view>
+          <view class="mt20rpx flex items-center text-24rpx text-#AAAAAA">
+            {{ selectedAddress?.province }} {{ selectedAddress?.city }} {{ selectedAddress?.detailAddress }}
+          </view>
+        </view>
         <wd-icon name="arrow-right" size="18px" color="#aaa" />
       </view>
     </view>

+ 94 - 13
src/subPack-xsb/goods/index.vue

@@ -11,6 +11,11 @@ definePage({
     navigationBarTitleText: '星闪豹商品详情',
   },
 })
+const selectGoods = ref(false)
+const SelectGoodsNum = ref(1)
+const specId = ref()
+const { userInfo } = storeToRefs(useUserStore())
+const { SelectShopInfo } = storeToRefs(useSysXsbStore())
 // const goodsTab = ref(0)
 const current = ref<number>(0)
 const currentDetaile = ref(0)
@@ -80,20 +85,29 @@ function handleGoCurren(id: number) {
 }
 
 async function getGoodsDetaile() {
-  const res = await Apis.xsb.getProductDetail({ data: { id: goodsId.value } })
+  const res = await Apis.xsb.getProductDetail({ data: { id: goodsId.value, shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: userInfo.value.channelId || 1 } })
   console.log(res, '请求')
   goodsInfo.value = res
+  specId.value = res.skuList?.[0].skuId
+}
+function handleConfimOrder() {
+  if (Number(unref(goodsInfo)?.spuStock) < unref(SelectGoodsNum)) {
+    useGlobalToast().show('库存不足,请调整购买数量')
+    return
+  }
+  router.push({ name: 'xsb-confirmOrder' })
 }
 </script>
 
 <template>
+  <page-meta :page-style="selectGoods ? 'overflow: hidden;' : '' " />
   <view class="page-xsb">
     <wd-navbar
       title="商品详情" :custom-style="`background-color:${isShowTab ? '#FFF !important' : 'transparent !important'}`" :bordered="false" :z-index="99"
       safe-area-inset-top left-arrow fixed @click-left="router.back()"
     />
     <template v-if="goodsInfo">
-      <wd-swiper v-model:current="current" :list="swiperList" autoplay :height="375">
+      <wd-swiper v-model:current="current" :list="swiperList" :autoplay="false" :height="375">
         <template #indicator="{ current: currentIndex, total }">
           <view class="custom-indicator absolute bottom-60rpx right-20rpx px26rpx">
             {{ currentIndex + 1 }}/{{ total }}
@@ -161,7 +175,7 @@ async function getGoodsDetaile() {
           <view class="flex items-center">
             <view class="flex-shrink-0">
               <view class="text-28rpx font-semibold">
-                {{ goodsInfo.weight }}
+                {{ goodsInfo.skuList[0].weight }}g
               </view>
               <view class="mt16rpx text-24rpx text-#AAAAAA">
                 重量
@@ -174,7 +188,7 @@ async function getGoodsDetaile() {
           <view class="flex items-center">
             <view class="flex-shrink-0">
               <view class="text-28rpx font-semibold">
-                {{ goodsInfo.weightUnit }}
+                {{ goodsInfo.skuList[0].weightUnit }}
               </view>
               <view class="mt16rpx text-24rpx text-#AAAAAA">
                 单位
@@ -275,13 +289,17 @@ async function getGoodsDetaile() {
               首页
             </view>
           </view>
-          <view class="mr36rpx">
-            <view class="h44rpx w44rpx">
-              <wd-button :icon="`${StaticUrl}/goods-kf.png`" type="icon" open-type="contact" />
-            </view>
-            <view class="text-20rpx">
-              客服
-            </view>
+          <view class="relative mr36rpx">
+            <image
+              :src="`${StaticUrl}/goods-kf.png`"
+              class="h44rpx w44rpx"
+            />
+
+            <button class="zbutton" open-type="contact">
+              <view class="text-20rpx">
+                客服
+              </view>
+            </button>
           </view>
           <view @click="router.replace({ name: 'xsb-homeTabbar', animationType: 'fade-out', params: { name: 'xsb-cart' } })">
             <image
@@ -294,11 +312,11 @@ async function getGoodsDetaile() {
           </view>
           <view class="flex items-center">
             <view class="w220rpx">
-              <wd-button hairline plain block>
+              <wd-button plain hairline block @click="selectGoods = true">
                 加入购物车
               </wd-button>
             </view>
-            <view class="ml20rpx w220rpx" @click="router.push({ name: 'common-confirmOrder' })">
+            <view class="ml20rpx w220rpx" @click="selectGoods = true">
               <wd-button block class="w-full">
                 立即购买
               </wd-button>
@@ -306,6 +324,66 @@ async function getGoodsDetaile() {
           </view>
         </view>
       </view>
+      <Zpopup v-model="selectGoods">
+        <view class="bg-white px24rpx py28rpx">
+          <view class="flex items-center">
+            <image
+              :src="goodsInfo.pic"
+              class="h200rpx w200rpx flex-shrink-0 rounded-16rpx"
+            />
+            <view class="ml20rpx">
+              <view class="flex items-end text-#FF4D3A font-semibold">
+                <view class="text-24rpx">
+                  ¥
+                </view>
+                <view class="text-36rpx line-height-[36rpx]">
+                  {{ goodsInfo?.channelProdPrice }}
+                </view>
+              </view>
+              <view class="mt20rpx flex items-center">
+                <view class="text-24rpx text-#AAAAAA">
+                  已选
+                </view>
+                <view class="ml20rpx text-28rpx font-semibold">
+                  {{ goodsInfo.skuList.find((it) => it.skuId === specId)?.spec }} {{ SelectGoodsNum }}件
+                </view>
+              </view>
+            </view>
+          </view>
+          <view class="my28rpx h2rpx w-full bg-#F0F0F0" />
+          <view class="mb20rpx">
+            <view class="text-28rpx font-semibold">
+              规格
+            </view>
+            <wd-radio-group v-model="specId" cell shape="button">
+              <wd-radio v-for="item in goodsInfo.skuList" :key="item.skuId" :value="item.skuId">
+                {{ item.spec }}
+              </wd-radio>
+            </wd-radio-group>
+          </view>
+          <view class="flex items-center justify-between">
+            <view class="text-28rpx font-semibold">
+              数量
+            </view>
+            <wd-input-number v-model="SelectGoodsNum" />
+          </view>
+          <view class="h200rpx" />
+        </view>
+        <view class="shadow-fixed ios fixed bottom-0 left-0 box-border w-full rounded-t-32rpx bg-white px24rpx">
+          <view class="box-border w-full flex items-center justify-between py20rpx">
+            <view class="w-48%">
+              <wd-button plain hairline block>
+                加入购物车
+              </wd-button>
+            </view>
+            <view class="w-48%">
+              <wd-button block @click="handleConfimOrder">
+                立即购买
+              </wd-button>
+            </view>
+          </view>
+        </view>
+      </Zpopup>
     </template>
   </view>
 </template>
@@ -338,6 +416,9 @@ async function getGoodsDetaile() {
     .ios .wd-button{
       min-width: unset !important;
     }
+    .wd-radio-group.is-button{
+      padding: 0!important;
+    }
   }
 }
 </style>

+ 1 - 1
src/uni-pages.d.ts

@@ -10,6 +10,7 @@ type _LocationUrl =
   "/pages/login/index" |
   "/pages/my/index" |
   "/subPack-xsb/commonTab/index" |
+  "/subPack-xsb/confirmOrder/index" |
   "/subPack-xsb/goods/index" |
   "/subPack-xsb/order/index" |
   "/subPack-xsb/search/index" |
@@ -18,7 +19,6 @@ type _LocationUrl =
   "/subPack-common/afterSales/index" |
   "/subPack-common/afterSalesDetail/index" |
   "/subPack-common/afterSalesList/index" |
-  "/subPack-common/confirmOrder/index" |
   "/subPack-common/editAddress/index" |
   "/subPack-common/integral/index" |
   "/subPack-common/nickName/index" |