ソースを参照

feat(api): 添加店铺列表接口类型定义

- 新增 xsbShopList 接口类型定义,包含店铺相关字段如店铺ID、名称、地址、经纬度、营业状态等信息
- 添加详细的字段注释说明

feat(api): 添加店铺列表API接口定义

- 在apiDefinitions中添加 'xsb.shopList' 接口定义
- 配置GET请求路径 '/smqjh-pms/app-api/v1/shop/list'

feat(globals): 扩展全局类型定义

- 为搜索商品列表参数添加 shopId 和 channelId 字段
- 添加 shopList 方法的全局类型定义

chore(config): 更新开发环境服务器地址

- 将开发环境地址从 http://47.109.84.152:8081 更新为 http://192.168.1.253:8080

feat(address): 优化地址选择功能

- 将首页地址选择点击事件改为调用地址存储的获取地图地址方法
- 更新默认地址名称为"请选择位置"

feat(selectAddress): 实现店铺选择和距离计算功能

- 新增店铺列表获取和附近店铺距离计算逻辑
- 实现基于地理位置的最近店铺筛选功能
- 添加店铺列表展示和选择功能
- 优化地址选择页面UI和交互

fix(commonTab): 修复店铺信息显示问题

- 更新头部导航中店铺名称显示逻辑
- 调整加载更多组件位置

feat(commonTab): 添加店铺和渠道参数

- 为商品搜索接口添加 shopId 和 channelId 参数

feat(search): 添加店铺和渠道参数

- 为搜索接口添加 shopId 和 channelId 参数

feat(store): 添加店铺信息存储

- 在系统店铺存储中添加 SelectShopInfo 状态
- 用于存储选中的店铺信息
zhangtao 2 日 前
コミット
85ba8cc885

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

@@ -266,5 +266,154 @@ namespace Api {
     updateTime?: string
     [property: string]: any
   }
+  interface xsbShopList {
+    /**
+     * 店铺所在区域(描述)
+     * 店铺所在区域
+     */
+    area?: string
+    /**
+     * 店铺所在区域Id
+     */
+    areaId?: number
+    /**
+     * 营业执照
+     */
+    businessLicense?: string
+    /**
+     * 营业时间
+     */
+    businessTime?: string
+    /**
+     * 物品类型
+     */
+    category?: string
+    /**
+     * 店铺所在城市(描述)
+     */
+    city?: string
+    /**
+     * 店铺所在城市Id
+     */
+    cityId?: number
+    createTime?: string
+    /**
+     * 海博门店ID
+     */
+    hbStationId?: string
+    /**
+     * 海博门店编码
+     */
+    hbStationNo?: string
+    /**
+     * 身份证正面
+     */
+    identityCardFront?: string
+    /**
+     * 身份证反面
+     */
+    identityCardLater?: string
+    /**
+     * 店铺简介(可修改)
+     */
+    intro?: string
+    /**
+     * 分销设置(0关闭 1开启)
+     */
+    isDistribution?: number
+    /**
+     * 坐标类型 1 高德|腾讯 2 百度
+     */
+    mapType?: string
+    /**
+     * 店铺绑定的手机(登录账号:唯一)
+     * 店铺绑定的手机
+     */
+    mobile?: string
+    /**
+     * 店铺公告
+     */
+    notice?: string
+    /**
+     * ERP门店编码
+     */
+    outStationNo?: string
+    /**
+     * 登录密码
+     */
+    password?: string
+    /**
+     * 店铺所在省份(描述)
+     */
+    province?: string
+    /**
+     * 店铺所在省份Id
+     */
+    provinceId?: number
+    /**
+     * 经营状态(0:停业,1正常)
+     */
+    runStatus?: number
+    /**
+     * 店铺详细地址
+     */
+    shopAddress?: string
+    /**
+     * 配送平台店铺编码
+     */
+    shopCode?: string
+    /**
+     * 店铺id
+     */
+    shopId?: number
+    /**
+     * 店铺所在纬度(可修改)
+     * 店铺所在纬度
+     */
+    shopLat?: string
+    /**
+     * 店铺所在经度(可修改)
+     * 店铺所在经度
+     */
+    shopLng?: string
+    /**
+     * 店铺logo(可修改)
+     * 店铺logo
+     */
+    shopLogo?: string
+    /**
+     * 店铺名称(数字、中文,英文(可混合,不可有特殊字符),可修改)、不唯一
+     * 门店名称
+     */
+    shopName?: string
+    /**
+     * 店长
+     */
+    shopOwner?: string
+    /**
+     * 店铺状态(-1:未开通 0: 停业中 1:营业中),可修改
+     * 店铺状态(-1:未开通 0: 停业中 1:营业中)
+     */
+    shopStatus?: number
+    /**
+     * 是否同步到配送平台
+     */
+    sync?: boolean
+    /**
+     * 店铺联系电话
+     */
+    tel?: string
+    /**
+     * 第三方id
+     */
+    thirdPartyCode?: string
+    updateTime?: string
+    /**
+     * 店长用户id
+     * 店铺简介
+     */
+    userId?: string
+    [property: string]: any
+  }
 
 }

+ 1 - 0
src/api/apiDefinitions.ts

@@ -36,4 +36,5 @@ export default {
   'xsb.getSearchProductList':['POST', '/smqjh-pms/app-api/v1/spu/getSearchProductList'],
   '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'],
 };

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

@@ -209,6 +209,8 @@ declare global {
              * 销量排序不传时为空,默认不排 ASC:价格升序,DESC:价格倒序
              */
             salesNum?: string;
+            shopId:number
+            channelId:number
           };
         }
       >(
@@ -229,6 +231,12 @@ declare global {
       >(
         config: Config
       ): Alova2Method<Api.xsbSearchTerm[], 'xsb.SearchTerm', Config>;
+      shopList<
+        Config extends Alova2MethodConfig<Api.xsbShopList[]> & {
+        }
+      >(
+        config: Config
+      ): Alova2Method<Api.xsbShopList[], 'xsb.shopList', Config>;
     }
 
   }

+ 2 - 1
src/config/index.ts

@@ -14,7 +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://47.109.84.152:8081',
+  develop: 'http://192.168.1.253:8080',
+  // develop: 'http://47.109.84.152:8081',
   /**
    * 体验版
    */

+ 1 - 1
src/pages/index/index.vue

@@ -67,7 +67,7 @@ onShareAppMessage(() => {
     </wd-navbar>
     <view class="header-linear h320rpx px24rpx" :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }">
       <view class="box-border flex items-center">
-        <view class="flex items-center" @click="router.push({ name: 'common-selectAddress' })">
+        <view class="flex items-center" @click="useAddressStore().getMapAddress()">
           <image :src="`${StaticUrl}/location-black.png`" class="h33.8rpx min-w28.97rpx w28.97rpx" />
           <view class="ml18rpx max-w-180rpx truncate text-32rpx">
             {{ name }}

+ 1 - 1
src/store/address.ts

@@ -19,7 +19,7 @@ export const useAddressStore = defineStore('address', {
       latitude: null,
       longitude: null,
     },
-    name: '富力中心',
+    name: '请选择位置',
   }),
   actions: {
   // 获取地理位置的函数

+ 61 - 7
src/subPack-common/selectAddress/index.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
 import { StaticUrl } from '@/config/index'
+import router from '@/router'
 
 definePage({
   name: 'common-selectAddress',
@@ -8,8 +9,61 @@ definePage({
     navigationBarTitleText: '选择收获地址',
   },
 })
-const { name } = storeToRefs(useAddressStore())
+const { SelectShopInfo } = storeToRefs(useSysXsbStore())
+const { name, Location } = storeToRefs(useAddressStore())
+const nearbyAddress = ref<Api.xsbShopList>()
+
+const { data: shopList } = useRequest(() => Apis.xsb.shopList({})).onSuccess(() => {
+  if (!Location.value.longitude || !Location.value.latitude || !shopList.value) {
+    return null
+  }
+
+  const getDistance = (lat1: number, lng1: number, lat2: number, lng2: number): 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 // 距离(公里)
+  }
+
+  let minDistance = Infinity
+
+  for (const shop of shopList.value) {
+    if (shop.shopLat && shop.shopLng) {
+      const distance = getDistance(
+        Location.value.latitude,
+        Location.value.longitude,
+        Number(shop.shopLat),
+        Number(shop.shopLng),
+      )
+
+      if (distance < minDistance) {
+        minDistance = distance
+        nearbyAddress.value = { ...shop, distance: Number(distance.toFixed(2)) }
+      }
+    }
+  }
+})
 const selectAddressId = ref()
+
+const allShopList = computed(() => {
+  return shopList.value?.filter(it => it.shopId !== nearbyAddress.value?.shopId)
+})
+
+function handleClick(item: Api.xsbShopList) {
+  SelectShopInfo.value = item
+  router.back()
+}
+
+onUnload(() => {
+  if (!SelectShopInfo.value?.shopId) {
+    SelectShopInfo.value = nearbyAddress.value
+  }
+})
 </script>
 
 <template>
@@ -57,21 +111,21 @@ const selectAddressId = ref()
           </wd-radio-group>
         </view>
       </view>
-      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+      <view v-if="nearbyAddress" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx" @click="handleClick(nearbyAddress)">
         <view class="text-24rpx text-#AAAAAA">
           附近的门店
         </view>
         <view class="mt24rpx text-28rpx font-semibold">
-          海马购超市(红街店)
+          {{ nearbyAddress?.shopName }}
         </view>
         <view class="mt16rpx text-24rpx text-#AAAAAA">
           以为您选择距离最近的可配送店
         </view>
       </view>
-      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
-        <view v-for="item, idx in 5" :key="item" class="mb24rpx text-28rpx font-semibold">
-          海马购超市(红街店)
-          <view v-if="idx < 4" class="mt20rpx h2rpx w-full bg-#F0F0F0" />
+      <view v-if="allShopList" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view v-for="item, idx in allShopList" :key="item.shopId" class="text-28rpx font-semibold" @click="handleClick(item)">
+          {{ item.shopName }}
+          <view v-if="idx < allShopList.length - 1" class="mb24rpx mt20rpx h2rpx w-full bg-#F0F0F0" />
         </view>
       </view>
     </view>

+ 3 - 4
src/subPack-xsb/commonTab/components/index.vue

@@ -9,8 +9,7 @@ const emit = defineEmits(['changeNav', 'scrollBottom'])
 const { ScrollDown } = storeToRefs(useSysXsbStore())
 
 const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
-const { name } = storeToRefs(useAddressStore())
-const { topNavActive, leftActive, backTop } = storeToRefs(useSysXsbStore())
+const { topNavActive, leftActive, backTop, SelectShopInfo } = storeToRefs(useSysXsbStore())
 const swiperList = computed(() => props.swiper)
 const navActive = ref(0)
 const classfiylist = computed(() => props.categoryList.slice(0, 10))
@@ -85,7 +84,7 @@ watch(() => backTop.value, () => {
           <view class="ml10rpx flex items-center" @click.stop="router.push({ name: 'common-selectAddress' })">
             <image :src="`${StaticUrl}/location.png`" class="h33.8rpx w29rpx" />
             <view class="ml10rpx max-w-280rpx truncate text-32rpx text-white">
-              {{ name }}
+              {{ SelectShopInfo?.shopName || '请选择位置' }}
             </view>
           </view>
         </view>
@@ -269,10 +268,10 @@ watch(() => backTop.value, () => {
                   </view>
                 </view>
               </grid-view>
-              <wd-loadmore :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="emit('scrollBottom')" />
             </scroll-view>
           </view>
         </view>
+        <wd-loadmore :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="emit('scrollBottom')" />
       </view>
       <view class="h60rpx" />
     </scroll-view>

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

@@ -24,7 +24,7 @@ definePage({
 })
 const { ScrollDown, topNavActive, leftActive, backTop } = storeToRefs(useSysXsbStore())
 const commonCategoryData = ref<Api.xsbCategories[]>([])
-const { data: goodsList, isLastPage, page, error, refresh } = usePagination((pageNum, pageSize) => Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC' } }), { data: resp => resp.list, initialData: [], initialPage: 1, initialPageSize: 10, append: true })
+const { data: goodsList, isLastPage, page, error, refresh } = usePagination((pageNum, pageSize) => Apis.xsb.getSearchProductList({ data: { pageNum, pageSize, salesNum: 'DESC', shopId: 1, channelId: 1 } }), { data: resp => resp.list, initialData: [], initialPage: 1, initialPageSize: 10, append: true })
 const tabbarItems = ref([
   { name: 'xsb-home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
   { name: 'xsb-classfiy', value: null, active: false, title: '分类', icon1: class1, icon2: class2 },

+ 2 - 0
src/subPack-xsb/search/index.vue

@@ -24,6 +24,8 @@ const { data, send, isLastPage, page, error } = usePagination((pageNum, pageSize
   pageSize,
   priceSort: activeTab.value === 2 ? 'DESC' : '',
   salesNum: activeTab.value === 1 ? 'DESC' : '',
+  shopId: 1,
+  channelId: 1,
 } }), {
   immediate: false,
   data: resp => resp.list,

+ 7 - 0
src/subPack-xsb/store-xsb/sys.ts

@@ -15,6 +15,11 @@ interface SysState {
    * 回到顶部
    */
   backTop: boolean
+  /**
+   * 店铺名称
+   */
+  SelectShopInfo: Api.xsbShopList | undefined
+
 }
 export const useSysXsbStore = defineStore('system-xsb', {
   state: (): SysState => ({
@@ -23,6 +28,7 @@ export const useSysXsbStore = defineStore('system-xsb', {
     leftActive: '',
     searchList: [],
     backTop: false,
+    SelectShopInfo: {},
   }),
   actions: {
     getTabbarItemValue(name: string) {
@@ -30,5 +36,6 @@ export const useSysXsbStore = defineStore('system-xsb', {
 
       return 0
     },
+
   },
 })