ソースを参照

feat(api): 添加最近商店接口并优化地址选择逻辑

zhangtao 6 日 前
コミット
6e4b2158e0

+ 1 - 0
src/api/apiDefinitions.ts

@@ -43,6 +43,7 @@ export default {
   'xsb.appAdvertInfo':['GET', '/smqjh-system/app-api/v1/appAdvertInfo'],
   'xsb.SearchTerm':['GET', '/smqjh-system/app-api/v1/SearchTerm/find'],
   'xsb.shopList':['GET', '/smqjh-pms/app-api/v1/shop/list'],
+  'xsb.nearestShop':['GET', '/smqjh-pms//app-api/v1/shop/nearestShop'],
   'xsb.orderList':['GET', '/smqjh-oms/api/v1/order/orderList'],
   'xsb.orderInfo':['GET', '/smqjh-oms/api/v1/order/orderInfo'],
   'xsb.cancelOrder':['GET', '/smqjh-oms/api/v1/order/cancelOrder'],

+ 16 - 11
src/api/core/handlers.ts

@@ -34,15 +34,17 @@ export async function handleAlovaResponse(
   // 处理401/403错误(如果不是在handleAlovaResponse中处理的)
   if ((statusCode === 401 || statusCode === 403)) {
     const { redirectName, token } = storeToRefs(useUserStore())
+    useSmqjhCartStore().$reset()
     // 如果是未授权错误,清除用户信息并跳转到登录页
     token.value = ''
-    useSmqjhCartStore().$reset()
-    globalToast.error({ msg: '登录已过期,请重新登录!', duration: 2000 })
     redirectName.value = getCurrentPath()
-    const timer = setTimeout(() => {
-      clearTimeout(timer)
-      router.replace({ name: 'smqjh-login' })
-    }, 2000)
+    useGlobalMessage().confirm({
+      title: '提示',
+      msg: '登录已过期,请重新登录!',
+      success: () => {
+        router.replace({ name: 'smqjh-login' })
+      },
+    })
 
     throw new ApiError('登录已过期,请重新登录!', statusCode, data)
   }
@@ -80,14 +82,17 @@ export function handleAlovaError(error: any, method: Method) {
   if (error instanceof ApiError && (error.code === 401 || error.code === 403)) {
     // 如果是未授权错误,清除用户信息并跳转到登录页
     const { redirectName, token } = storeToRefs(useUserStore())
+    useSmqjhCartStore().$reset()
     // 如果是未授权错误,清除用户信息并跳转到登录页
     token.value = ''
-    globalToast.error({ msg: '登录已过期,请重新登录!', duration: 2000 })
     redirectName.value = getCurrentPath()
-    const timer = setTimeout(() => {
-      clearTimeout(timer)
-      router.replace({ name: 'smqjh-login' })
-    }, 2000)
+    useGlobalMessage().confirm({
+      title: '提示',
+      msg: '登录已过期,请重新登录!',
+      success: () => {
+        router.replace({ name: 'smqjh-login' })
+      },
+    })
     throw new ApiError('登录已过期,请重新登录!', error.code, error.data)
   }
 

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

@@ -192,6 +192,16 @@ declare global {
       ): Alova2Method<listData<Api.sysDict>, 'sys.dictPage', Config>;
     }
     xsb: {
+      nearestShop<
+        Config extends Alova2MethodConfig<apiResData<{nearestShopId:number}>> & {
+          data: {
+            latitude: number;
+            longitude: number
+          };
+        }
+      >(
+        config: Config
+      ): Alova2Method<apiResData<{nearestShopId:number}>, 'xsb.nearestShop', Config>;
       categories<
         Config extends Alova2MethodConfig<apiResData<Api.xsbCategories[]>> & {
           data: {

+ 14 - 11
src/pages/index/index.vue

@@ -22,7 +22,7 @@ const { name } = storeToRefs(addressStore)
 const { userInfo } = storeToRefs(useUserStore())
 const { getTotalNum } = storeToRefs(useSmqjhCartStore())
 const { data: goodsList, isLastPage, page, reload, error, loading, refresh } = usePagination((pageNum, pageSize) =>
-  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: 1, channelId: userInfo.value.channelId || 1 } }), {
+  Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: 2, channelId: userInfo.value.channelId || 1 } }), {
   data: resp => resp.data?.list,
   initialData: [],
   initialPage: 1,
@@ -45,16 +45,19 @@ onReachBottom(() => {
     page.value++
   }
 })
-const navList = ref([
-  { icon: `${StaticUrl}/xsb.png`, title: '星闪豹', name: 'xsb-homeTabbar', show: true },
-  { icon: `${StaticUrl}/smqjh-index-cd.png`, title: '充电', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-sp.png`, title: '电影演出', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-vip.png`, title: '视频权益', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-diancan.png`, title: '大牌点餐', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-jiayou.png`, title: '加油', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-jiudian.png`, title: '酒店民宿', name: '', show: !unref(isOnlineAudit) },
-  { icon: `${StaticUrl}/smqjh-daijia.png`, title: '代驾', name: '', show: !unref(isOnlineAudit) },
-])
+const navList = computed(() => {
+  const list = [
+    { icon: `${StaticUrl}/xsb.png`, title: '星闪豹', name: 'xsb-homeTabbar', show: true },
+    { icon: `${StaticUrl}/smqjh-index-cd.png`, title: '充电', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-sp.png`, title: '电影演出', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-vip.png`, title: '视频权益', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-diancan.png`, title: '大牌点餐', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-jiayou.png`, title: '加油', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-jiudian.png`, title: '酒店民宿', name: '', show: !isOnlineAudit.value },
+    { icon: `${StaticUrl}/smqjh-daijia.png`, title: '代驾', name: '', show: !isOnlineAudit.value },
+  ]
+  return list
+})
 onMounted(() => {
   addressStore.getLocation()
   opcity.value = 0

+ 2 - 0
src/store/address.ts

@@ -51,6 +51,8 @@ export const useAddressStore = defineStore('address', {
     fetchActualLocation() {
       uni.getLocation({
         type: 'wgs84',
+        isHighAccuracy: true,
+        altitude: true,
         success: (res) => {
           console.log('位置获取成功', res)
           this.Location.latitude = res.latitude

+ 1 - 0
src/store/sys.ts

@@ -63,6 +63,7 @@ export const useSysStore = defineStore('system', {
     async getAudit() {
       const res = await Apis.sys.dictPage({ data: { typeCode: 'sys_applet' } })
       this.isOnlineAudit = res.data?.list[0].value === '0'
+      console.log(res.data?.list[0].value === '0')
     },
   },
 })

+ 21 - 2
src/subPack-common/addressList/index.vue

@@ -37,6 +37,25 @@ function handleSelectAddress(item: Api.addressList) {
   useUserStore().updateSelectedAddress(item)
   router.back()
 }
+async function handleAddAddress() {
+  await handleGetDeviceInfo()
+  router.push({ name: 'common-editAddress', params: { type: '1' } })
+}
+
+function handleGetDeviceInfo() {
+  return new Promise((resolve, reject) => {
+    const apltInfo = uni.getDeviceInfo()
+    if (apltInfo.platform === 'windows') {
+      useGlobalToast().show('不支持电脑操作地址,请使用手机打开')
+      reject(new Error('不支持电脑操作地址,请使用手机打开'))
+    }
+    resolve(1)
+  })
+}
+async function handleEditAddress(item: Api.addressList) {
+  await handleGetDeviceInfo()
+  router.push({ name: 'common-editAddress', params: { type: '2', id: `${item.id}` } })
+}
 </script>
 
 <template>
@@ -51,7 +70,7 @@ function handleSelectAddress(item: Api.addressList) {
             <image
               :src="`${StaticUrl}/edit-address.png`"
               class="h40rpx w40rpx"
-              @click.stop="router.push({ name: 'common-editAddress', params: { type: '2', id: `${item.id}` } })"
+              @click.stop="handleEditAddress(item)"
             />
           </view>
           <view class="mt24rpx text-24rpx text-#AAAAAA">
@@ -69,7 +88,7 @@ function handleSelectAddress(item: Api.addressList) {
 
     <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' } })">
+        <wd-button size="large" block @click="handleAddAddress">
           新增收货地址
         </wd-button>
       </view>

+ 7 - 3
src/subPack-xsb/goods/index.vue

@@ -15,7 +15,7 @@ definePage({
 const selectGoods = ref(false)
 const SelectGoodsNum = ref(1)
 const specId = ref()
-const { userInfo } = storeToRefs(useUserStore())
+const { userInfo, token } = storeToRefs(useUserStore())
 const { SelectShopInfo } = storeToRefs(useSysXsbStore())
 const { getTotalNum } = storeToRefs(useSmqjhCartStore())
 // const goodsTab = ref(0)
@@ -88,7 +88,7 @@ function handleGoCurren(id: number) {
 }
 
 async function getGoodsDetaile() {
-  const res = await Apis.xsb.getProductDetail({ data: { id: goodsId.value, shopId: Number(SelectShopInfo.value?.shopId) || 1, channelId: userInfo.value.channelId || 1 } })
+  const res = await Apis.xsb.getProductDetail({ data: { id: goodsId.value, shopId: Number(SelectShopInfo.value?.shopId) || 2, channelId: userInfo.value.channelId || 1 } })
   console.log(res, '请求')
   if (!res.data) {
     useGlobalToast().show('暂无该商品查看权限!')
@@ -102,6 +102,10 @@ async function handleConfimOrder() {
     useGlobalToast().show('库存不足,请调整购买数量')
     return
   }
+  if (!token.value) {
+    useGlobalToast().show('请先登录!')
+    return
+  }
   isLoging.value = true
   const res = await Apis.xsb.skuOrderConfirm({
     data: {
@@ -357,7 +361,7 @@ async function handleAddCart() {
 
           <view class="flex items-center">
             <view class="w220rpx">
-              <wd-button plain hairline block @click="selectGoods = true">
+              <wd-button hairline plain block @click="selectGoods = true">
                 加入购物车
               </wd-button>
             </view>

+ 10 - 6
src/subPack-xsb/order/index.vue

@@ -175,9 +175,11 @@ async function handleSubmitOrder(order: Api.xsbOrderList) {
             </view>
           </template>
           <template v-if="item.hbOrderStatus === OrderStatus.OrderCancel">
-            <wd-button size="small" plain type="info" @click.stop="handleDel(item)">
-              删除订单
-            </wd-button>
+            <view>
+              <wd-button size="small" plain type="info" @click.stop="handleDel(item)">
+                删除订单
+              </wd-button>
+            </view>
             <!-- <view class="ml20rpx">
               <wd-button size="small" plain type="error" @click.stop="handleDel(item)">
                 再次购买
@@ -185,9 +187,11 @@ async function handleSubmitOrder(order: Api.xsbOrderList) {
             </view> -->
           </template>
           <template v-if="item.hbOrderStatus === OrderStatus.OrderArrived">
-            <wd-button size="small" plain type="info" @click.stop="handleSubmitOrder(item)">
-              确认收货
-            </wd-button>
+            <view>
+              <wd-button size="small" plain type="info" @click.stop="handleSubmitOrder(item)">
+                确认收货
+              </wd-button>
+            </view>
           </template>
         </view>
       </view>

+ 3 - 19
src/subPack-xsb/selectAddress/index.vue

@@ -10,7 +10,7 @@ definePage({
   },
 })
 const { SelectShopInfo, xsbShopList: shopList, selectAddressId } = storeToRefs(useSysXsbStore())
-const { name, Location } = storeToRefs(useAddressStore())
+const { name } = storeToRefs(useAddressStore())
 const { addresses } = storeToRefs(useUserStore())
 
 const allShopList = computed(() => {
@@ -24,27 +24,11 @@ watch(() => SelectShopInfo.value, () => {
   router.back()
 })
 
-function handelChange(e: { value: number }) {
+async function handelChange(e: { value: number }) {
   const address = addresses.value.find(it => it.id === e.value)
   if (!address)
     return
-  Location.value.latitude = Number(address.latitude)
-  Location.value.longitude = Number(address.longitude)
-  let minDistance = Infinity
-  for (const shop of shopList.value) {
-    if (shop.shopLat && shop.shopLng) {
-      const distance = useSysXsbStore().getDistance(
-        Location.value.latitude,
-        Location.value.longitude,
-        Number(shop.shopLat),
-        Number(shop.shopLng),
-      )
-      if (distance < minDistance) {
-        minDistance = distance
-        handleClick({ ...shop, distance: Number(distance.toFixed(2)) })
-      }
-    }
-  }
+  await useSysXsbStore().getnNearestShop(Number(address.latitude), Number(address.longitude))
 }
 </script>
 

+ 17 - 34
src/subPack-xsb/store-xsb/sys.ts

@@ -1,4 +1,5 @@
 import { defineStore } from 'pinia'
+import type { apiResData } from '@/api/globals'
 
 interface SysState {
   opcity: number
@@ -51,48 +52,30 @@ export const useSysXsbStore = defineStore('system-xsb', {
     },
     async getAllShopList() {
       return new Promise((resolve, reject) => {
-        Apis.xsb.shopList({}).then((res) => {
+        Apis.xsb.shopList({}).then(async (res) => {
           this.xsbShopList = res.data
           const { Location } = storeToRefs(useAddressStore())
-          let minDistance = Infinity
-          for (const shop of res.data) {
-            if (shop.shopLat && shop.shopLng) {
-              const distance = this.getDistance(
-                Location.value.latitude || 113.264435,
-                Location.value.longitude || 23.129163,
-                Number(shop.shopLat),
-                Number(shop.shopLng),
-              )
-              if (distance < minDistance) {
-                minDistance = distance
-                if (!this.SelectShopInfo.shopId) {
-                  this.SelectShopInfo = { ...shop, distance: Number(distance.toFixed(2)) }
-                }
-              }
-            }
-          }
+          await this.getnNearestShop(Location.value.latitude || 26.648327, Location.value.longitude || 106.620256)
           resolve(res)
         }).catch((err) => { reject(err) })
       })
     },
     /**
-     * 计算距离
-     * @param lat1
-     * @param lng1
-     * @param lat2
-     * @param lng2
-     * @returns 计算距离
+     *  获取最近的门店
+     * @param latitude 纬度
+     * @param longitude 经度
+     * @returns Promise<apiResData<{ nearestShopId: number }>>
      */
-    getDistance(lat1: number, lng1: number, lat2: number, lng2: number) {
-      const R = 6371 // 地球半径(公里)
-      const dLat = (lat2 - lat1) * Math.PI / 180
-      const dLng = (lng2 - lng1) * Math.PI / 180
-      const a = Math.sin(dLat / 2) * Math.sin(dLat / 2)
-        + Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180)
-        * Math.sin(dLng / 2) * Math.sin(dLng / 2)
-      const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
-      return R * c // 距离(公里)
+    async getnNearestShop(latitude: number, longitude: number): Promise<apiResData<{ nearestShopId: number }>> {
+      return new Promise((resolve, reject) => {
+        Apis.xsb.nearestShop({ data: { longitude, latitude } }).then((res) => {
+          const newShop = this.xsbShopList.find(it => it.shopId === res.data.nearestShopId)
+          if (newShop) {
+            this.SelectShopInfo = newShop
+          }
+          resolve(res)
+        }).catch((err) => { reject(err) })
+      })
     },
-
   },
 })