Browse Source

feat(manifest): 启用懒加载配置并升级组件库版本

更新 manifest.config.ts 文件,添加 lazyCodeLoading 配置项以启用组件懒加载功能。
同时将 wot-design-uni 组件库从 v1.11.1 升级至 v1.13.0,
移除了不再需要的 uni-echarts 依赖。
zhangtao 1 week ago
parent
commit
1ca0bd7a3a
58 changed files with 3080 additions and 387 deletions
  1. 0 4
      .husky/commit-msg
  2. 10 2
      .husky/pre-commit
  3. 2 0
      manifest.config.ts
  4. 1 2
      package.json
  5. 250 308
      pnpm-lock.yaml
  6. 93 2
      src/App.vue
  7. 1 1
      src/api/core/instance.ts
  8. 24 7
      src/api/createApis.ts
  9. 1 1
      src/api/globals.d.ts
  10. 8 0
      src/auto-imports.d.ts
  11. 3 0
      src/components.d.ts
  12. 209 0
      src/components/CollapsePanel.vue
  13. 19 0
      src/components/Zpopup.vue
  14. 35 0
      src/components/Zupload.vue
  15. 3 3
      src/composables/useTabbar.ts
  16. 71 0
      src/composables/useXsbTabbar.ts
  17. 44 0
      src/config/index.ts
  18. 3 2
      src/manifest.json
  19. 108 1
      src/pages.json
  20. 4 2
      src/pages/cart/index.vue
  21. 12 21
      src/pages/index/index.vue
  22. 35 0
      src/pages/login/index.vue
  23. 11 14
      src/pages/my/index.vue
  24. BIN
      src/static/my/1.png
  25. BIN
      src/static/my/2.png
  26. BIN
      src/static/my/3.png
  27. BIN
      src/static/my/4.png
  28. BIN
      src/static/my/5.png
  29. BIN
      src/static/my/6.png
  30. BIN
      src/static/my/7.png
  31. BIN
      src/static/my/8.png
  32. BIN
      src/static/my/9.png
  33. BIN
      src/static/my/cart.png
  34. BIN
      src/static/my/logo.png
  35. BIN
      src/static/tab/class-tab0.png
  36. BIN
      src/static/tab/class-tab1.png
  37. 1 1
      src/store/manualThemeStore.ts
  38. 16 0
      src/store/sys.ts
  39. 1 1
      src/store/themeStore.ts
  40. 13 0
      src/store/user.ts
  41. 53 0
      src/subPack-xsb/cart/index.vue
  42. 264 0
      src/subPack-xsb/classfiy/index.vue
  43. 63 0
      src/subPack-xsb/components/xsbTabbar/index.vue
  44. 315 0
      src/subPack-xsb/goods/index.vue
  45. 239 0
      src/subPack-xsb/home/index.vue
  46. 226 0
      src/subPack-xsb/my/afterSales/index.vue
  47. 249 0
      src/subPack-xsb/my/afterSalesDetail/index.vue
  48. 66 0
      src/subPack-xsb/my/afterSalesList/index.vue
  49. 131 0
      src/subPack-xsb/my/index.vue
  50. 150 0
      src/subPack-xsb/my/order/index.vue
  51. 39 0
      src/subPack-xsb/my/order/order-data.ts
  52. 257 0
      src/subPack-xsb/my/orderDetaile/index.vue
  53. 12 0
      src/subPack-xsb/store-xsb/sys.ts
  54. 11 0
      src/subPack-xsb/store-xsb/tabbar.ts
  55. 12 1
      src/uni-pages.d.ts
  56. 2 2
      src/utils/index.ts
  57. 1 2
      tsconfig.json
  58. 12 10
      vite.config.ts

+ 0 - 4
.husky/commit-msg

@@ -1,4 +0,0 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
-npx commitlint --edit $1

+ 10 - 2
.husky/pre-commit

@@ -1,4 +1,12 @@
 #!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
 
-npx lint-staged --allow-empty $1
+if [ "$SKIP_SIMPLE_GIT_HOOKS" = "1" ]; then
+    echo "[INFO] SKIP_SIMPLE_GIT_HOOKS is set to 1, skipping hook."
+    exit 0
+fi
+
+if [ -f "$SIMPLE_GIT_HOOKS_RC" ]; then
+    . "$SIMPLE_GIT_HOOKS_RC"
+fi
+
+pnpm lint-staged

+ 2 - 0
manifest.config.ts

@@ -67,6 +67,8 @@ export default defineManifestConfig({
       },
     },
     embeddedAppIdList: ['wxbc64403830bb13c5', 'wx9894a01b9e92c368'],
+    lazyCodeLoading: 'requiredComponents',
+    // componentFramework: 'glass-easel',
     // darkmode: false,
     // themeLocation: 'theme.json',
   },

+ 1 - 2
package.json

@@ -83,10 +83,9 @@
     "alova": "^3.3.4",
     "echarts": "^6.0.0",
     "pinia": "^2.3.1",
-    "uni-echarts": "^1.1.2",
     "vue": "~3.4.38",
     "vue-i18n": "^9.14.0",
-    "wot-design-uni": "^1.11.1"
+    "wot-design-uni": "^1.13.0"
   },
   "devDependencies": {
     "@alova/wormhole": "^1.1.2",

File diff suppressed because it is too large
+ 250 - 308
pnpm-lock.yaml


+ 93 - 2
src/App.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
-onLaunch(() => {})
+useSysStore().getSystemData()
+onLaunch(() => { })
 </script>
 
 <style lang="scss">
@@ -7,10 +8,100 @@ onLaunch(() => {})
   min-height: calc(100vh - var(--window-top));
   box-sizing: border-box;
   background: #f6f6f6;
-  --them-color:#9ED605
+  --them-color: #9ED605
 }
 
 .wot-theme-dark.page-wraper {
   background: #222;
 }
+
+.ios {
+  padding-bottom: constant(safe-area-inset-bottom);
+  padding-bottom: env(safe-area-inset-bottom);
+}
+
+.header-linear {
+  background: linear-gradient(180deg, var(--them-color) 0%, rgba(255, 255, 255, 0) 100%);
+}
+
+.xsb-linear {
+  background: linear-gradient(179deg, rgba(190, 255, 13, 0.4) 0%, rgba(220, 255, 125, 0.2) 49%, rgba(158, 214, 5, 0) 100%);
+}
+
+/* 隐藏滚动条安卓机会出现滚动条 */
+::-webkit-scrollbar {
+  display: none;
+  width: 0;
+  height: 0;
+  color: transparent;
+}
+
+.page-xsb {
+  :deep() {
+    .line {
+      .wd-divider {
+        padding: 0 !important;
+        margin: 20rpx 0 20rpx 0 !important;
+      }
+    }
+
+    .wd-sort-button {
+      height: 100% !important;
+      line-height: 0 !important;
+
+      .wd-sort-button__left {
+        font-size: 24rpx !important;
+      }
+    }
+
+    .custom-tab {
+      border-radius: 28rpx 28rpx 0 0;
+      box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.09);
+    }
+
+    .notice-bar {
+      padding: 0 !important;
+    }
+
+    .card-zt {
+      margin: 0 !important;
+      padding: 0 0 24rpx 0 !important;
+    }
+
+    .swiper-img {
+      .custom-indicator-class {
+        bottom: -20rpx !important;
+
+        .wd-swiper-nav__item--dots-bar {
+          background: #F0F0F0 !important;
+        }
+
+        .is-active {
+          background: var(--them-color) !important;
+        }
+      }
+
+    }
+     .swiper .wd-swiper__item {
+        height: 142rpx;
+        flex-direction: column;
+        align-items: center;
+        justify-content: center;
+
+        image {
+          height: 72rpx !important;
+          width: 72rpx !important;
+        }
+
+        text {
+          position: unset !important;
+          color: #222222 !important;
+          font-size: 24rpx !important;
+          text-align: center;
+          margin-top: 12rpx;
+        }
+      }
+  }
+
+}
 </style>

+ 1 - 1
src/api/core/instance.ts

@@ -1,6 +1,6 @@
+import AdapterUniapp from '@alova/adapter-uniapp'
 import { createAlova } from 'alova'
 import vueHook from 'alova/vue'
-import AdapterUniapp from '@alova/adapter-uniapp'
 import { handleAlovaError, handleAlovaResponse } from './handlers'
 // import { BASE_URL } from '@/config'
 

+ 24 - 7
src/api/createApis.ts

@@ -26,9 +26,14 @@ import type { Alova, MethodType, AlovaGenerics, AlovaMethodCreateConfig } from '
 import { Method } from 'alova';
 import apiDefinitions from './apiDefinitions';
 
+const cache = Object.create(null);
 const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova<AlovaGenerics>, configMap: any) => {
+  const apiPathKey = array.join('.') as keyof typeof apiDefinitions;
+  if (cache[apiPathKey]) {
+    return cache[apiPathKey];
+  }
   // create a new proxy instance
-  return new Proxy(function () {}, {
+  const proxy = new Proxy(function () {}, {
     get(_, property) {
       // record the target property, so that it can get the completed accessing paths
       const newArray = [...array, property];
@@ -36,7 +41,6 @@ const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova<
       return createFunctionalProxy(newArray, alovaInstance, configMap);
     },
     apply(_, __, [config]) {
-      const apiPathKey = array.join('.') as keyof typeof apiDefinitions;
       const apiItem = apiDefinitions[apiPathKey];
       if (!apiItem) {
         throw new Error(`the api path of \`${apiPathKey}\` is not found`);
@@ -47,7 +51,7 @@ const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova<
       };
       const [method, url] = apiItem;
       const pathParams = mergedConfig.pathParams;
-      const urlReplaced = url.replace(/\{([^}]+)\}/g, (_, key) => {
+      const urlReplaced = url!.replace(/\{([^}]+)\}/g, (_, key) => {
         const pathParam = pathParams[key];
         return pathParam;
       });
@@ -57,16 +61,27 @@ const createFunctionalProxy = (array: (string | symbol)[], alovaInstance: Alova<
         let hasBlobData = false;
         const formData = new FormData();
         for (const key in data) {
-          formData.append(key, data[key]);
-          if (data[key] instanceof Blob) {
-            hasBlobData = true;
+          if (Array.isArray(data[key])) {
+            for (const ele of data[key]) {
+              formData.append(key, ele);
+              if (ele instanceof Blob) {
+                hasBlobData = true;
+              }
+            }
+          } else {
+            formData.append(key, data[key]);
+            if (data[key] instanceof Blob) {
+              hasBlobData = true;
+            }
           }
         }
         data = hasBlobData ? formData : data;
       }
-      return new Method(method.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data);
+      return new Method(method!.toUpperCase() as MethodType, alovaInstance, urlReplaced, mergedConfig, data);
     }
   });
+  cache[apiPathKey] = proxy;
+  return proxy;
 };
 
 export const createApis = (alovaInstance: Alova<AlovaGenerics>, configMap: any) => {
@@ -77,10 +92,12 @@ export const createApis = (alovaInstance: Alova<AlovaGenerics>, configMap: any)
   });
   return Apis;
 };
+
 export const mountApis = (Apis: Apis) => {
   // define global variable `Apis`
   (globalThis as any).Apis = Apis;
 };
+
 type MethodConfig<T> = AlovaMethodCreateConfig<
   (typeof import('./index'))['alovaInstance'] extends Alova<infer AG> ? AG : any,
   any,

+ 1 - 1
src/api/globals.d.ts

@@ -23,7 +23,7 @@ Some useful links:
  * **Do not edit the file manually.**
  */
 import type { Alova, AlovaMethodCreateConfig, AlovaGenerics, Method } from 'alova';
-import type { $$userConfigMap, alovaInstance } from '.';
+import type { $$userConfigMap, alovaInstance } from './index';
 import type apiDefinitions from './apiDefinitions';
 
 type CollapsedAlova = typeof alovaInstance;

+ 8 - 0
src/auto-imports.d.ts

@@ -296,6 +296,7 @@ declare global {
   const useSupported: typeof import('@vueuse/core')['useSupported']
   const useSwipe: typeof import('@vueuse/core')['useSwipe']
   const useSysStore: typeof import('./store/sys')['useSysStore']
+  const useSysXsbStore: typeof import('./subPack-xsb/store-xsb/sys')['useSysXsbStore']
   const useTabbar: typeof import('./composables/useTabbar')['useTabbar']
   const useTemplateRef: typeof import('vue')['useTemplateRef']
   const useTemplateRefsList: typeof import('@vueuse/core')['useTemplateRefsList']
@@ -320,6 +321,7 @@ declare global {
   const useTransition: typeof import('@vueuse/core')['useTransition']
   const useUrlSearchParams: typeof import('@vueuse/core')['useUrlSearchParams']
   const useUserMedia: typeof import('@vueuse/core')['useUserMedia']
+  const useUserStore: typeof import('./store/user')['useUserStore']
   const useVModel: typeof import('@vueuse/core')['useVModel']
   const useVModels: typeof import('@vueuse/core')['useVModels']
   const useVibrate: typeof import('@vueuse/core')['useVibrate']
@@ -332,6 +334,8 @@ declare global {
   const useWindowFocus: typeof import('@vueuse/core')['useWindowFocus']
   const useWindowScroll: typeof import('@vueuse/core')['useWindowScroll']
   const useWindowSize: typeof import('@vueuse/core')['useWindowSize']
+  const useXsbTabbar: typeof import('./composables/useXsbTabbar')['useXsbTabbar']
+  const useXsbTabbarStore: typeof import('./subPack-xsb/store-xsb/tabbar')['useXsbTabbarStore']
   const watch: typeof import('vue')['watch']
   const watchArray: typeof import('@vueuse/core')['watchArray']
   const watchAtMost: typeof import('@vueuse/core')['watchAtMost']
@@ -649,6 +653,7 @@ declare module 'vue' {
     readonly useSupported: UnwrapRef<typeof import('@vueuse/core')['useSupported']>
     readonly useSwipe: UnwrapRef<typeof import('@vueuse/core')['useSwipe']>
     readonly useSysStore: UnwrapRef<typeof import('./store/sys')['useSysStore']>
+    readonly useSysXsbStore: UnwrapRef<typeof import('./subPack-xsb/store-xsb/sys')['useSysXsbStore']>
     readonly useTabbar: UnwrapRef<typeof import('./composables/useTabbar')['useTabbar']>
     readonly useTemplateRefsList: UnwrapRef<typeof import('@vueuse/core')['useTemplateRefsList']>
     readonly useTextDirection: UnwrapRef<typeof import('@vueuse/core')['useTextDirection']>
@@ -672,6 +677,7 @@ declare module 'vue' {
     readonly useTransition: UnwrapRef<typeof import('@vueuse/core')['useTransition']>
     readonly useUrlSearchParams: UnwrapRef<typeof import('@vueuse/core')['useUrlSearchParams']>
     readonly useUserMedia: UnwrapRef<typeof import('@vueuse/core')['useUserMedia']>
+    readonly useUserStore: UnwrapRef<typeof import('./store/user')['useUserStore']>
     readonly useVModel: UnwrapRef<typeof import('@vueuse/core')['useVModel']>
     readonly useVModels: UnwrapRef<typeof import('@vueuse/core')['useVModels']>
     readonly useVibrate: UnwrapRef<typeof import('@vueuse/core')['useVibrate']>
@@ -684,6 +690,8 @@ declare module 'vue' {
     readonly useWindowFocus: UnwrapRef<typeof import('@vueuse/core')['useWindowFocus']>
     readonly useWindowScroll: UnwrapRef<typeof import('@vueuse/core')['useWindowScroll']>
     readonly useWindowSize: UnwrapRef<typeof import('@vueuse/core')['useWindowSize']>
+    readonly useXsbTabbar: UnwrapRef<typeof import('./composables/useXsbTabbar')['useXsbTabbar']>
+    readonly useXsbTabbarStore: UnwrapRef<typeof import('./subPack-xsb/store-xsb/tabbar')['useXsbTabbarStore']>
     readonly watch: UnwrapRef<typeof import('vue')['watch']>
     readonly watchArray: UnwrapRef<typeof import('@vueuse/core')['watchArray']>
     readonly watchAtMost: UnwrapRef<typeof import('@vueuse/core')['watchAtMost']>

+ 3 - 0
src/components.d.ts

@@ -7,6 +7,7 @@ export {}
 
 declare module 'vue' {
   export interface GlobalComponents {
+    CollapsePanel: typeof import('./components/CollapsePanel.vue')['default']
     GlobalLoading: typeof import('./components/GlobalLoading.vue')['default']
     GlobalMessage: typeof import('./components/GlobalMessage.vue')['default']
     GlobalToast: typeof import('./components/GlobalToast.vue')['default']
@@ -43,5 +44,7 @@ declare module 'vue' {
     WdTextarea: typeof import('wot-design-uni/components/wd-textarea/wd-textarea.vue')['default']
     WdToast: typeof import('wot-design-uni/components/wd-toast/wd-toast.vue')['default']
     WdUpload: typeof import('wot-design-uni/components/wd-upload/wd-upload.vue')['default']
+    Zpopup: typeof import('./components/Zpopup.vue')['default']
+    Zupload: typeof import('./components/Zupload.vue')['default']
   }
 }

+ 209 - 0
src/components/CollapsePanel.vue

@@ -0,0 +1,209 @@
+<script setup lang="ts">
+interface Props {
+  // 默认展示的行数
+  inline?: number
+  // 是否默认展开
+  defaultExpanded?: boolean
+  // 展开按钮文字
+  expandText?: string
+  // 收起按钮文字
+  collapseText?: string
+  // 行高(px),用于计算行数
+  lineHeight?: number
+}
+const props = withDefaults(defineProps<Props>(), {
+  inline: 3,
+  defaultExpanded: false,
+  expandText: '展开',
+  collapseText: '收起',
+  lineHeight: 100,
+})
+
+const emit = defineEmits<{
+  (e: 'toggle', isExpanded: boolean): void
+}>()
+
+const _this = getCurrentInstance()
+
+// 响应式数据
+const isExpanded = ref(props.defaultExpanded)
+const contentHeight = ref(0)
+const showToggle = ref(false)
+
+// 计算属性
+const toggleText = computed(() =>
+  isExpanded.value ? props.collapseText : props.expandText,
+)
+
+const contentStyle = computed(() => {
+  const style: Record<string, string> = {}
+  if (isExpanded.value) {
+    // 展开状态,不限制高度
+    style.overflow = 'visible'
+  }
+  else {
+    // 收起状态,限制行数
+    style.overflow = 'hidden'
+    style.maxHeight = `${props.inline * props.lineHeight}rpx`
+  }
+
+  return style
+})
+
+// 方法
+function handleToggle() {
+  isExpanded.value = !isExpanded.value
+  emit('toggle', isExpanded.value)
+}
+
+// 获取内容高度
+function getContentHeight() {
+  return new Promise<number>((resolve) => {
+    const query = uni.createSelectorQuery().in(_this)
+    query.select('.collapse-panel__content').boundingClientRect()
+    query.exec((res) => {
+      if (res && res[0]) {
+        resolve(res[0].height)
+      }
+      else {
+        resolve(0)
+      }
+    })
+  })
+}
+
+// 检查是否需要显示展开按钮
+async function checkNeedToggle() {
+  await nextTick()
+
+  try {
+    const height = await getContentHeight()
+    contentHeight.value = height
+    const maxHeightInPx = (props.inline * props.lineHeight) / 2
+    showToggle.value = height > maxHeightInPx
+  }
+  catch (error) {
+    console.error('获取内容高度失败:', error)
+  }
+}
+
+// 暴露方法给父组件
+defineExpose({
+  expand: () => {
+    isExpanded.value = true
+    emit('toggle', true)
+  },
+  collapse: () => {
+    isExpanded.value = false
+    emit('toggle', false)
+  },
+  toggle: handleToggle,
+  refresh: checkNeedToggle,
+  isExpanded: computed(() => isExpanded.value),
+})
+
+// 监听inline变化,重新检查
+watch(() => props.inline, () => {
+  if (!isExpanded.value) {
+    checkNeedToggle()
+  }
+})
+
+onMounted(() => {
+  // 使用setTimeout确保DOM已渲染
+  setTimeout(() => {
+    checkNeedToggle()
+  }, 100)
+})
+</script>
+
+<template>
+  <view class="collapse-panel">
+    <view
+      class="collapse-panel__content"
+      :class="{
+        'collapse-panel__content--collapsed': !isExpanded,
+        'collapse-panel__content--expanded': isExpanded,
+      }"
+      :style="contentStyle"
+    >
+      <slot />
+    </view>
+
+    <view
+      v-if="showToggle"
+      class="collapse-panel__toggle"
+      @tap="handleToggle"
+    >
+      <text class="collapse-panel__toggle-text">
+        {{ toggleText }}
+      </text>
+      <view class="collapse-panel__toggle-icon" :class="{ 'collapse-panel__toggle-icon--expanded': isExpanded }">
+        <wd-icon name="arrow-down" size="22px" />
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.collapse-panel {
+  width: 100%;
+
+  &__content {
+    overflow: hidden;
+    transition: max-height 0.3s ease;
+    line-height: 1.5;
+
+    &--collapsed {
+      position: relative;
+
+      // 添加渐变遮罩效果(可选)
+      &::after {
+        content: '';
+        position: absolute;
+        bottom: 0;
+        left: 0;
+        right: 0;
+        height: 60rpx;
+        background: linear-gradient(to bottom, transparent, #ffffff);
+        pointer-events: none;
+      }
+    }
+  }
+
+  &__toggle {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    padding: 16rpx 0;
+    color: #222222;
+    font-size: 28rpx;
+
+    &-text {
+      margin-right: 8rpx;
+    }
+
+    &-icon {
+      transition: transform 0.3s ease;
+      font-size: 24rpx;
+      display: flex;
+      align-items: center;
+      justify-content: center;
+      width: 32rpx;
+      height: 32rpx;
+
+      &--expanded {
+        transform: rotate(180deg);
+      }
+    }
+  }
+}
+
+// 如果在小程序中需要更精确的文本行数控制,可以使用以下样式类
+.text-lines {
+  display: -webkit-box;
+  -webkit-box-orient: vertical;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+</style>

+ 19 - 0
src/components/Zpopup.vue

@@ -0,0 +1,19 @@
+<script setup lang="ts">
+const show = defineModel({ default: false })
+</script>
+
+<template>
+  <wd-popup v-model="show" custom-style="border-radius:32rpx;32rpx 0rpx 0rpx" :z-index="999999" position="bottom">
+    <view class="bg-#F6F6F6">
+      <slot />
+      <view class="h150rpx" />
+      <view class="footer ios fixed bottom-0 left-0 box-border w-full rounded-t-32rpx bg-white px24rpx pt20rpx">
+        <slot name="footer" />
+      </view>
+    </view>
+  </wd-popup>
+</template>
+
+<style scoped>
+
+</style>

+ 35 - 0
src/components/Zupload.vue

@@ -0,0 +1,35 @@
+<script setup lang="ts">
+import { uploadProps } from 'wot-design-uni/components/wd-upload/types'
+import { BASE_URL, StaticUrl } from '@/config'
+
+const props = defineProps(uploadProps)
+const emit = defineEmits(['update:value'])
+const fileSubmitList = computed({
+  get() {
+    console.log(props.fileList, ' props.fileList')
+
+    return props.fileList
+  },
+  set(val) {
+    const fileData = val.map((item) => {
+      return {
+        url: JSON.parse(String(item.response)).data.url,
+      }
+    })
+    emit('update:value', fileData)
+  },
+})
+</script>
+
+<template>
+  <wd-upload
+    v-bind="props" v-model:file-list="fileSubmitList" image-mode="aspectFill"
+    :action="`${BASE_URL}/smqjh-system/api/v1/files`" :header="{
+      authorization: 'Bearer eyJraWQiOiJkYjRiYjA3MS1iYmJlLTQ4NDctODI0NS1mZGJiYTE3MGY4YWIiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsImlzcyI6Imh0dHA6Ly8xOTIuMTY4LjEuMTAxOjkwMDAiLCJkZXB0SWQiOjIsImRhdGFTY29wZSI6MCwidXNlcklkIjoyLCJhdXRob3JpdGllcyI6WyJBRE1JTiJdLCJhdWQiOiJtYWxsLWFkbWluIiwibmJmIjoxNzY1OTQzNDk4LCJzY29wZSI6WyJvcGVuaWQiLCJwcm9maWxlIl0sImV4cCI6MTc2ODUzNTQ5OCwiaWF0IjoxNzY1OTQzNDk4LCJqdGkiOiIxYTliMzkwNy1jNDkwLTQ2MzEtYTUyZi05ZTg3NjUyZTk4ZjkiLCJ1c2VybmFtZSI6ImFkbWluIn0.Dc-uxgCS-9-wuE7n20WfHV8dMZbIGtrWZnPluDwlhE32GRWaMVFL2UO8s-NR8lljDV4kRv5obQuGaJwtj3IXBJ_lZBG0MKmdTaZ9o3F68TCrdqxOpSMlzN2k95_m-6xOM_abNd1QXUy0W_H7RtOcWSr8xdMC8JWKuHiIPDPx8hur7M7rEiP5WrSDFlKa9tXnuvxyzeqITzKr7VE-vk71JbMCzOz_EUxo4HSGrR6DQCXpbWlZq-yrOcp8WwMlkCfzCgSs0PJ7PlWuqWHJFrTSHj-EWAbMcwWwVVNE8n3rdDbAsigJSmtKN-2rScd1B8FqD2jv56CVArk6cH9Rtq0YSQ',
+    }"
+  >
+    <view class="h120rpx w120rpx flex items-center justify-center rounded-32rpx bg-white">
+      <image :src="`${StaticUrl}/upload.png`" class="h40rpx w40rpx" />
+    </view>
+  </wd-upload>
+</template>

+ 3 - 3
src/composables/useTabbar.ts

@@ -13,9 +13,9 @@ export interface TabbarItem {
 }
 
 const tabbarItems = ref<TabbarItem[]>([
-  { name: 'home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
-  { name: 'cart', value: null, active: false, title: '购物车', icon1: icon3, icon2: icon4 },
-  { name: 'my', value: null, active: false, title: '我的', icon1: icon5, icon2: icon6 },
+  { name: 'smqjh-home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
+  { name: 'smqjh-cart', value: null, active: false, title: '购物车', icon1: icon3, icon2: icon4 },
+  { name: 'smqjh-my', value: null, active: false, title: '我的', icon1: icon5, icon2: icon6 },
 ])
 
 export function useTabbar() {

+ 71 - 0
src/composables/useXsbTabbar.ts

@@ -0,0 +1,71 @@
+import icon3 from '@/static/tab/cart1.png'
+import icon4 from '@/static/tab/cart2.png'
+import class1 from '@/static/tab/class-tab0.png'
+import class2 from '@/static/tab/class-tab1.png'
+import icon5 from '@/static/tab/my1.png'
+import icon6 from '@/static/tab/my2.png'
+
+export interface TabbarItem {
+  name: string
+  value: number | null
+  active: boolean
+  title: string
+  icon2: string
+  icon1: string
+}
+
+const tabbarItems = ref<TabbarItem[]>([
+  { name: 'xsb-home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
+  { name: 'xsb-classfiy', value: null, active: false, title: '分类', icon1: class1, icon2: class2 },
+  { name: 'xsb-cart', value: null, active: false, title: '购物车', icon1: icon3, icon2: icon4 },
+  { name: 'xsb-my', value: null, active: false, title: '我的', icon1: icon5, icon2: icon6 },
+])
+
+export function useXsbTabbar() {
+  const route = useRoute()
+  const tabbarList = computed(() => tabbarItems.value)
+
+  const activeTabbar = computed(() => {
+    const item = tabbarItems.value.find(item => item.active)
+    return item || tabbarItems.value[0]
+  })
+
+  const getTabbarItemValue = (name: string) => {
+    const item = tabbarItems.value.find(item => item.name === name)
+    return item && item.value ? item.value : null
+  }
+
+  const setTabbarItem = (name: string, value: number) => {
+    const tabbarItem = tabbarItems.value.find(item => item.name === name)
+    if (tabbarItem) {
+      tabbarItem.value = value
+    }
+  }
+
+  const setTabbarItemActive = (name: string) => {
+    tabbarItems.value.forEach((item) => {
+      if (item.name === name) {
+        item.active = true
+      }
+      else {
+        item.active = false
+      }
+    })
+  }
+  watch(
+    () => route.name,
+    (newRouteName) => {
+      if (newRouteName) {
+        setTabbarItemActive(newRouteName as string)
+      }
+    },
+    { immediate: true },
+  )
+  return {
+    tabbarList,
+    activeTabbar,
+    getTabbarItemValue,
+    setTabbarItem,
+    setTabbarItemActive,
+  }
+}

+ 44 - 0
src/config/index.ts

@@ -6,3 +6,47 @@ export const ZSWLXSB_APPID = 'wxbc64403830bb13c5'
 export const ZSWLZSDD_APPID = 'wx9894a01b9e92c368'
 
 export const VITE_OSS_BASE_URL = 'https://zswl-shop.oss-cn-chengdu.aliyuncs.com/'
+
+const mapEnvVersion = {
+  /**
+   * 开发版
+   */
+  // develop: 'http://192.168.1.101:8080',
+  develop: 'http://192.168.0.157:8080',
+  /**
+   * 体验版
+   */
+  // trial: "http://192.168.1.166:8080/jeecg-boot",
+  // trial: "http://192.168.0.11:8080/jeecg-boot",
+  trial: 'http://192.168.1.101:8080',
+  /**
+   * 正式版
+   */
+  release: '',
+}
+
+const mapEnvStaticVersion = {
+  /**
+   * 测试环境
+   */
+  develop: 'http://192.168.1.242/static',
+  /**
+   * 体验环境
+   */
+  trial: 'http://192.168.1.242/static',
+  /**
+   * 正式环境
+   */
+  release: 'http://192.168.1.242/static',
+}
+/**
+ * Base URL请求基本url
+ */
+export const BASE_URL
+  = mapEnvVersion[uni.getAccountInfoSync().miniProgram.envVersion]
+
+/**
+ * 静态资源服务
+ */
+
+export const StaticUrl = mapEnvStaticVersion[uni.getAccountInfoSync().miniProgram.envVersion]

+ 3 - 2
src/manifest.json

@@ -63,7 +63,8 @@
     "embeddedAppIdList": [
       "wxbc64403830bb13c5",
       "wx9894a01b9e92c368"
-    ]
+    ],
+    "lazyCodeLoading": "requiredComponents"
   },
   "mp-alipay": {
     "usingComponents": true,
@@ -86,4 +87,4 @@
     "darkmode": true,
     "themeLocation": "theme.json"
   }
-}
+}

+ 108 - 1
src/pages.json

@@ -21,6 +21,14 @@
         "navigationBarTitleText": "购物车"
       }
     },
+    {
+      "path": "pages/login/index",
+      "type": "page",
+      "name": "smqjh-login",
+      "style": {
+        "navigationBarTitleText": "市民请集合"
+      }
+    },
     {
       "path": "pages/my/index",
       "type": "page",
@@ -66,5 +74,104 @@
       }
     ]
   },
-  "subPackages": []
+  "subPackages": [
+    {
+      "root": "subPack-xsb",
+      "pages": [
+        {
+          "path": "cart/index",
+          "type": "page",
+          "name": "xsb-cart",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "星闪豹购物车",
+            "disableScroll": true
+          }
+        },
+        {
+          "path": "classfiy/index",
+          "type": "page",
+          "name": "xsb-classfiy",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "星闪豹分类",
+            "disableScroll": true
+          }
+        },
+        {
+          "path": "goods/index",
+          "type": "page",
+          "name": "xsb-goods",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "星闪豹商品详情"
+          }
+        },
+        {
+          "path": "home/index",
+          "type": "page",
+          "name": "xsb-home",
+          "style": {
+            "navigationStyle": "custom",
+            "backgroundColor": "#9ED605",
+            "backgroundColorTop": "#9ED605",
+            "navigationBarTitleText": "星闪豹首页",
+            "backgroundColorBottom": "#fff"
+          }
+        },
+        {
+          "path": "my/index",
+          "type": "page",
+          "name": "xsb-my",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "星闪豹我的",
+            "disableScroll": true
+          }
+        },
+        {
+          "path": "my/afterSales/index",
+          "type": "page",
+          "name": "xsb-afterSales",
+          "style": {
+            "navigationBarTitleText": "申请售后"
+          }
+        },
+        {
+          "path": "my/afterSalesDetail/index",
+          "type": "page",
+          "name": "xsb-afterSalesDetail",
+          "style": {
+            "navigationBarTitleText": "售后详情"
+          }
+        },
+        {
+          "path": "my/afterSalesList/index",
+          "type": "page",
+          "name": "xsb-afterSalesList",
+          "style": {
+            "navigationBarTitleText": "售后列表"
+          }
+        },
+        {
+          "path": "my/order/index",
+          "type": "page",
+          "name": "xsb-order",
+          "style": {
+            "navigationStyle": "custom",
+            "navigationBarTitleText": "星闪豹订单列表",
+            "disableScroll": true
+          }
+        },
+        {
+          "path": "my/orderDetaile/index",
+          "type": "page",
+          "name": "xsb-orderDetaile",
+          "style": {
+            "navigationBarTitleText": "订单详情"
+          }
+        }
+      ]
+    }
+  ]
 }

+ 4 - 2
src/pages/cart/index.vue

@@ -1,6 +1,8 @@
 <script setup lang="ts">
+import { StaticUrl } from '@/config'
+
 definePage({
-  name: 'cart',
+  name: 'smqjh-cart',
   layout: 'tabbar',
   style: {
     navigationBarTitleText: '购物车',
@@ -34,7 +36,7 @@ function setNavBack() {
   <view class="box-border w-full flex items-center justify-center">
     <view class="mt220rpx flex flex-col items-center">
       <image
-        src="@/static/my/cart.png"
+        :src="`${StaticUrl}/cart.png`"
         class="h110rpx w110rpx"
       />
       <view class="mb20rpx mt20rpx text-24rpx">

+ 12 - 21
src/pages/index/index.vue

@@ -1,8 +1,9 @@
 <script setup lang="ts">
-import { VITE_OSS_BASE_URL, ZSWLXSB_APPID, ZSWLZSDD_APPID } from '@/config'
+import { StaticUrl, VITE_OSS_BASE_URL } from '@/config'
+import router from '@/router'
 
 definePage({
-  name: 'home',
+  name: 'smqjh-home',
   layout: 'tabbar',
   style: {
     navigationBarTitleText: '首页',
@@ -11,13 +12,12 @@ definePage({
     backgroundColorTop: '#9ED605',
   },
 })
-const { statusBarHeight } = uni.getSystemInfoSync()
-const { height } = uni.getMenuButtonBoundingClientRect()
+
 const addressStore = useAddressStore()
-const { ScrollDown } = storeToRefs(useSysStore())
+const { ScrollDown, statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
 const { name } = storeToRefs(addressStore)
 const navList = ref([
-  { icon: `${VITE_OSS_BASE_URL}2025/11/4dabcf9b8d794d3c99aa6b49be34f205.png`, title: '星闪豹' },
+  { icon: `${VITE_OSS_BASE_URL}2025/11/4dabcf9b8d794d3c99aa6b49be34f205.png`, title: '星闪豹', name: 'xsb-home' },
   { icon: `${VITE_OSS_BASE_URL}2025/11/40cb38e287234a83885d68f30c9c39bc.png`, title: '充电' },
   { icon: `${VITE_OSS_BASE_URL}2025/11/9981d979739b4ae6b4eec941b7d2c9b0.png`, title: '电影演出' },
   { icon: `${VITE_OSS_BASE_URL}2025/11/f2b15ec1048e4b5689fe1ba26f6058e1.png`, title: '视频权益' },
@@ -37,13 +37,8 @@ onPageScroll((e) => {
     ScrollDown.value = false
   }
 })
-function handleClick(title: string) {
-  if (title === '星闪豹') {
-    navCommonMiniProgram(ZSWLXSB_APPID)
-  }
-  if (title === '充电') {
-    navCommonMiniProgram(ZSWLZSDD_APPID)
-  }
+function handleClick(name: string) {
+  router.push({ name })
 }
 </script>
 
@@ -55,10 +50,10 @@ function handleClick(title: string) {
       :bordered="false" :z-index="99" safe-area-inset-top fixed
     >
       <template #left>
-        <image class="h48rpx w202rpx" src="@/static/my/logo.png" />
+        <image class="h48rpx w202rpx" :src="`${StaticUrl}/logo.png`" />
       </template>
     </wd-navbar>
-    <view class="header h320rpx px24rpx" :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + height + 12}px` }">
+    <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="addressStore.getMapAddress">
           <image :src="`${VITE_OSS_BASE_URL}2025/11/9b914bd06e584af09c7e9055b9bfeaf9.png`" class="h33.8rpx min-w28.97rpx w28.97rpx" />
@@ -85,7 +80,7 @@ function handleClick(title: string) {
       <view class="grid grid-cols-4 mt24rpx rounded-16rpx bg-white py24rpx">
         <view
           v-for="item in navList" :key="item.icon" class="flex flex-col items-center justify-center"
-          @click="handleClick(item.title)"
+          @click="handleClick(String(item.name))"
         >
           <image :src="item.icon" class="h120rpx w120rpx" />
           <view class="text-24rpx">
@@ -137,7 +132,7 @@ function handleClick(title: string) {
           </view>
         </view>
       </view>
-      <view class="mt20rpx">
+      <view class="mt20rpx" @click="router.push({ name: 'smqjh-login' })">
         <view class="flex items-center">
           <scroll-view scroll-y type="custom">
             <grid-view type="masonry" cross-axis-count="2" main-axis-gap="10" cross-axis-gap="10">
@@ -363,10 +358,6 @@ function handleClick(title: string) {
 </template>
 
 <style scoped lang="scss">
-.header {
-  background: linear-gradient(180deg, var(--them-color) 0%, rgba(255, 255, 255, 0) 100%);
-}
-
 .flex-box-item {
  background: linear-gradient( 180deg, #EBFFB4 0%, #FFFFFF 46%, #FFFFFF 100%);
 }

+ 35 - 0
src/pages/login/index.vue

@@ -0,0 +1,35 @@
+<script setup lang="ts">
+definePage({
+  name: 'smqjh-login',
+  style: {
+    navigationBarTitleText: '市民请集合',
+  },
+})
+async function handleGetPhone(e: WechatMiniprogram.ButtonGetPhoneNumber) {
+  console.log(e, '手机号')
+  // uni.showLoading({ mask: true })
+  // await Apis.sys.auth({ data: {
+  //   grant_type: 'wechat',
+  //   mobile: '',
+  // } })
+}
+</script>
+
+<template>
+  <view class="h80vh px24rpx">
+    <view class="mt300rpx">
+      <wd-button block size="large" open-type="getRealtimePhoneNumber" @getrealtimephonenumber="handleGetPhone">
+        手机号快捷登录
+      </wd-button>
+      <view class="mt20rpx">
+        <wd-button block size="large" type="info">
+          手机号快捷登录
+        </wd-button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

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

@@ -1,11 +1,8 @@
 <script setup lang="ts">
-import wait from '@/static/my/1.png'
-import wait1 from '@/static/my/2.png'
-import down from '@/static/my/6.png'
-import refund from '@/static/my/3.png'
+import { StaticUrl } from '@/config'
 
 definePage({
-  name: 'my',
+  name: 'smqjh-my',
   layout: 'tabbar',
   style: {
     navigationBarTitleText: '个人中心',
@@ -14,10 +11,10 @@ definePage({
 })
 
 const tabList = ref([
-  { title: '待支付', icon: wait },
-  { title: '待收货', icon: wait1 },
-  { title: '已完成', icon: down },
-  { title: '退款售后', icon: refund },
+  { title: '待支付', icon: `${StaticUrl}/1.png` },
+  { title: '待收货', icon: `${StaticUrl}/2.png` },
+  { title: '已完成', icon: `${StaticUrl}/6.png` },
+  { title: '退款售后', icon: `${StaticUrl}/3.png` },
 ])
 </script>
 
@@ -29,7 +26,7 @@ const tabList = ref([
     />
     <view class="header relative h-408rpx rounded-18px">
       <view class="absolute bottom-100rpx left-0 box-border w-full flex items-center justify-between pl48rpx pr58rpx">
-        <image src="@/static/my/9.png" alt="" class="h100rpx w100rpx" />
+        <image :src="`${StaticUrl}/9.png`" alt="" class="h100rpx w100rpx" />
         <view class="text-32rpx font-semibold">
           请登录后使用完整功能
         </view>
@@ -69,12 +66,12 @@ const tabList = ref([
         <wd-cell-group custom-class="cell-group">
           <wd-cell title="收货地址" custom-title-class="cell-title" clickable is-link>
             <template #icon>
-              <image src="@/static/my/4.png" class="h50rpx w50rpx" />
+              <image :src="`${StaticUrl}/4.png`" class="h50rpx w50rpx" />
             </template>
           </wd-cell>
           <wd-cell title="联系平台客服" custom-title-class="cell-title" clickable is-link>
             <template #icon>
-              <image src="@/static/my/5.png" class="h50rpx w50rpx" />
+              <image :src="`${StaticUrl}/5.png`" class="h50rpx w50rpx" />
             </template>
           </wd-cell>
         </wd-cell-group>
@@ -85,12 +82,12 @@ const tabList = ref([
         <wd-cell-group custom-class="cell-group">
           <wd-cell title="积分" custom-title-class="cell-title" clickable is-link>
             <template #icon>
-              <image src="@/static/my/7.png" class="h50rpx w50rpx" />
+              <image :src="`${StaticUrl}/7.png`" class="h50rpx w50rpx" />
             </template>
           </wd-cell>
           <wd-cell title="评价" custom-title-class="cell-title" clickable is-link>
             <template #icon>
-              <image src="@/static/my/8.png" class="h50rpx w50rpx" />
+              <image :src="`${StaticUrl}/8.png`" class="h50rpx w50rpx" />
             </template>
           </wd-cell>
         </wd-cell-group>

BIN
src/static/my/1.png


BIN
src/static/my/2.png


BIN
src/static/my/3.png


BIN
src/static/my/4.png


BIN
src/static/my/5.png


BIN
src/static/my/6.png


BIN
src/static/my/7.png


BIN
src/static/my/8.png


BIN
src/static/my/9.png


BIN
src/static/my/cart.png


BIN
src/static/my/logo.png


BIN
src/static/tab/class-tab0.png


BIN
src/static/tab/class-tab1.png


+ 1 - 1
src/store/manualThemeStore.ts

@@ -1,5 +1,5 @@
-import { defineStore } from 'pinia'
 import type { ThemeColorOption, ThemeMode, ThemeState } from '@/composables/types/theme'
+import { defineStore } from 'pinia'
 import { themeColorOptions } from '@/composables/types/theme'
 
 /**

+ 16 - 0
src/store/sys.ts

@@ -2,11 +2,27 @@ import { defineStore } from 'pinia'
 
 interface SysState {
   ScrollDown: boolean
+  /**
+   * 状态栏高度
+   */
+  statusBarHeight: number
+  /**
+   * 胶囊按钮高度
+   */
+  MenuButtonHeight: number
 }
 export const useSysStore = defineStore('system', {
   state: (): SysState => ({
     ScrollDown: false,
+    statusBarHeight: 0,
+    MenuButtonHeight: 0,
   }),
   actions: {
+    getSystemData() {
+      const { statusBarHeight } = uni.getSystemInfoSync()
+      const { height } = uni.getMenuButtonBoundingClientRect()
+      this.statusBarHeight = Number(statusBarHeight)
+      this.MenuButtonHeight = height
+    },
   },
 })

+ 1 - 1
src/store/themeStore.ts

@@ -1,5 +1,5 @@
-import { defineStore } from 'pinia'
 import type { SystemThemeState, ThemeMode } from '@/composables/types/theme'
+import { defineStore } from 'pinia'
 import { themeColorOptions } from '@/composables/types/theme'
 
 /**

+ 13 - 0
src/store/user.ts

@@ -0,0 +1,13 @@
+import { defineStore } from 'pinia'
+
+interface userStroe {
+  token: string
+}
+export const useUserStore = defineStore('user', {
+  state: (): userStroe => ({
+    token: '',
+  }),
+  actions: {
+
+  },
+})

+ 53 - 0
src/subPack-xsb/cart/index.vue

@@ -0,0 +1,53 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import xsbTabbar from '@/subPack-xsb/components/xsbTabbar/index.vue'
+
+definePage({
+  name: 'xsb-cart',
+  style: {
+    navigationStyle: 'custom',
+    navigationBarTitleText: '星闪豹购物车',
+    disableScroll: true,
+  },
+})
+</script>
+
+<template>
+  <view class="page-xsb">
+    <wd-navbar
+      title="" custom-style="background-color:transparent !important" :bordered="false" :z-index="99"
+      safe-area-inset-top fixed
+    />
+    <view class="xsb-linear h406rpx" />
+    <view class="-mt220rpx">
+      <view class="flex items-center justify-between px20rpx text-36rpx font-semibold">
+        <view>购物车</view>
+        <view>管理</view>
+      </view>
+      <view class="content">
+        <scroll-view scroll-y>
+          <view class="box-border w-full flex items-center justify-center">
+            <view class="mt220rpx flex flex-col items-center">
+              <image :src="`${StaticUrl}/cart.png`" class="h110rpx w110rpx" />
+              <view class="mb20rpx mt20rpx text-24rpx">
+                你还没有添加商品哦~
+              </view>
+              <wd-button plain>
+                去逛逛
+              </wd-button>
+            </view>
+          </view>
+        </scroll-view>
+      </view>
+    </view>
+    <xsbTabbar />
+  </view>
+</template>
+
+<style scoped lang="scss">
+.content {
+  height: calc(100vh - var(--window-top) - 340rpx);
+  height: calc(100vh - var(--window-top) - constant(safe-area-inset-bottom) - 340rpx);
+  height: calc(100vh - var(--window-top) - env(safe-area-inset-bottom) - 340rpx);
+}
+</style>

+ 264 - 0
src/subPack-xsb/classfiy/index.vue

@@ -0,0 +1,264 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import xsbTabbar from '@/subPack-xsb/components/xsbTabbar/index.vue'
+
+const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
+const classfiylist = ref([
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+])
+const topNavActive = ref(0)
+const sortClassBtn = ref(1)
+const show = ref(false)
+definePage({
+  name: 'xsb-classfiy',
+  style: {
+    navigationStyle: 'custom',
+    navigationBarTitleText: '星闪豹分类',
+    disableScroll: true,
+  },
+})
+const navHeight = computed(() => {
+  return (`${Number(MenuButtonHeight.value) + Number(statusBarHeight.value)}px`)
+})
+function handleTopNavChange(idx: number) {
+  topNavActive.value = idx
+}
+function handleOpen() {
+  show.value = true
+  console.log(navHeight.value, '打开')
+}
+
+const active = ref<number>(1)
+const scrollTop = ref<number>(0)
+const itemScrollTop = ref<number[]>([])
+
+const subCategories = Array.from({ length: 24 }).fill({ title: '标题文字', label: '这是描述这是描述' }, 0, 24)
+const categories = ref([
+  {
+    label: '分类一',
+    title: '标题一',
+    items: subCategories,
+  },
+  {
+    label: '分类二',
+    title: '标题二',
+    items: subCategories,
+  },
+  {
+    label: '分类三',
+    title: '标题三',
+    items: subCategories.slice(0, 18),
+  },
+  {
+    label: '分类四',
+    title: '标题四',
+    items: subCategories.slice(0, 21),
+  },
+  {
+    label: '分类五',
+    title: '标题五',
+    items: subCategories,
+  },
+  {
+    label: '分类六',
+    title: '标题六',
+    items: subCategories.slice(0, 18),
+  },
+  {
+    label: '分类七',
+    title: '标题七',
+    items: subCategories,
+  },
+])
+
+function handleChange({ value }) {
+  active.value = value
+  scrollTop.value = itemScrollTop.value[value]
+}
+function onScroll(e) {
+  const { scrollTop } = e.detail
+  const threshold = 50 // 下一个标题与顶部的距离
+  if (scrollTop < threshold) {
+    active.value = 0
+    return
+  }
+  const index = itemScrollTop.value.findIndex(top => top > scrollTop && top - scrollTop <= threshold)
+  if (index > -1) {
+    active.value = index
+  }
+}
+</script>
+
+<template>
+  <view class="page-xsb">
+    <wd-navbar
+      title="" custom-style="background-color:#F4FFD1" :bordered="false" :z-index="99" safe-area-inset-top
+      fixed
+    >
+      <template #left>
+        <view class="flex items-center">
+          <view class="h60rpx w-474rpx flex items-center justify-between border-2rpx border-[var(--them-color)] rounded-40rpx border-solid bg-white pr6rpx">
+            <view class="flex items-center pb14rpx pl24rpx pt16rpx">
+              <wd-icon name="search" size="14" color="#ccc" />
+              <view class="search ml12rpx h-full w-full overflow-hidden">
+                <wd-notice-bar :text="['霸王茶姬', '牛奶', '洗衣机']" custom-class="notice-bar" color="#ccc" background-color="#fff" direction="vertical" />
+              </view>
+            </view>
+            <view class="flex items-center pr28rpx">
+              <wd-divider vertical />
+              <view class="ml6rpx text-28rpx text-[var(--them-color)] font-semibold">
+                搜索
+              </view>
+            </view>
+          </view>
+        </view>
+      </template>
+    </wd-navbar>
+    <view
+      class="h162rpx flex items-center justify-between bg-#F4FFD1 pl24rpx"
+      :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
+    >
+      <scroll-view scroll-x class="scrollx w-90% flex-shrink-0 whitespace-nowrap">
+        <view class="flex items-end pb10rpx">
+          <view v-for="item, idx in classfiylist" :key="idx" class="mr24rpx flex flex-col items-center justify-center" @click="handleTopNavChange(idx)">
+            <image
+              :src="item.icon"
+              :class="[topNavActive == idx ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h84rpx w-84rpx' : 'h72rpx w-72rpx']"
+            />
+            <view class="mt16rpx text-22rpx" :class="[topNavActive == idx ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']">
+              {{ item.title }}
+            </view>
+          </view>
+        </view>
+      </scroll-view>
+      <view class="right-nav box-border h144rpx w64rpx flex flex-shrink-0 flex-col items-center justify-center px20rpx text-24rpx font-semibold" @click="handleOpen">
+        展开
+        <image
+          :src="`${StaticUrl}/xia.png`"
+          class="mt20rpx h20rpx w20rpx"
+        />
+      </view>
+      <wd-popup v-model="show" position="top" custom-style="border-radius:32rpx;">
+        <view class="box-border bg-#F4FFD1 p24rpx" :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }">
+          <view class="mb24rpx mt24rpx text-28rpx font-semibold">
+            全部一级分类
+          </view>
+          <view class="h400rpx overflow-y-scroll">
+            <view class="grid grid-cols-5 box-border gap-x-24rpx gap-y-24rpx">
+              <view v-for="item, idx in classfiylist" :key="idx" class="box-border h150rpx w114rpx flex flex-col items-center justify-center" @click="handleTopNavChange(idx)">
+                <image
+                  :src="item.icon"
+                  :class="[topNavActive == idx ? 'overflow-hidden border-solid border-[var(--them-color)] border-2rpx rounded-26rpx h88rpx w-88rpx' : 'h76rpx w-76rpx']"
+                />
+                <view class="mt16rpx whitespace-nowrap text-nowrap text-22rpx" :class="[topNavActive == idx ? 'bg-[var(--them-color)] rounded-18rpx px-8rpx py2rpx text-white text-24rpx' : '']">
+                  {{ item.title }}
+                </view>
+              </view>
+            </view>
+          </view>
+          <view class="mt24rpx w-full flex items-center justify-center" @click="show = false">
+            <view class="mr8rpx text-24rpx">
+              点击收起
+            </view>
+            <wd-icon name="arrow-down" size="18px" />
+          </view>
+        </view>
+      </wd-popup>
+    </view>
+    <view class="wraper">
+      <wd-sidebar v-model="active" @change="handleChange">
+        <wd-sidebar-item v-for="(item, index) in categories" :key="index" :value="index" :label="item.label" />
+      </wd-sidebar>
+      <view class="content">
+        <view class="p20rpx">
+          <image
+            :src="`${StaticUrl}/class.png`"
+            class="h144rpx w-full"
+          />
+          <view class="my20rpx flex items-center justify-end rounded-16rpx bg-#F6F6F6 px20rpx py8rpx">
+            <view class="mr40rpx text-24rpx">
+              销量
+            </view>
+            <wd-sort-button v-model="sortClassBtn" :line="false" title="价格" />
+          </view>
+        </view>
+        <scroll-view :style="{ height: `calc(100vh - ${navHeight} - 600rpx)` }" scroll-y scroll-with-animation :scroll-top="scrollTop" :throttle="false" @scroll="onScroll">
+          <view class="p20rpx">
+            <view v-for="item in 20" :key="item">
+              <view class="flex">
+                <view class="mr20rpx h172rpx w172rpx flex-shrink-0 rounded-16rpx bg-#F6F6F6" />
+                <view>
+                  <view class="text-left text-28rpx font-semibold">
+                    <view v-for="i in 2" :key="i" class="mr5px inline-block">
+                      <wd-tag type="primary">
+                        新品{{ i }}
+                      </wd-tag>
+                    </view>
+                    海湾高盐特大白虾200g
+                  </view>
+                  <view class="text-22rpx text-#AAAAAA">
+                    <view class="mt10rpx flex items-center">
+                      <view>一年一季</view>
+                      <wd-divider vertical />
+                      <view>新鲜翠绿</view>
+                    </view>
+                    <view class="mt6rpx">
+                      已售3.6万+
+                    </view>
+                  </view>
+                  <view class="flex items-center justify-between">
+                    <view class="text-#FF4D3A font-semibold">
+                      <text class="text-24rpx">
+                        ¥
+                      </text> <text class="text-36rpx">
+                        9.99
+                      </text>
+                    </view>
+                    <view>
+                      <image
+                        :src="`${StaticUrl}/cart-yes.png`"
+                        class="h52rpx w52rpx"
+                      />
+                    </view>
+                  </view>
+                </view>
+              </view>
+              <view class="line">
+                <wd-divider color="#F0F0F0" />
+              </view>
+            </view>
+            <view class="h60rpx" />
+          </view>
+        </scroll-view>
+      </view>
+    </view>
+    <xsbTabbar />
+  </view>
+</template>
+
+<style scoped lang="scss">
+.right-nav{
+  background: linear-gradient( 180deg, #FAFFEC 0%, #F6FFDE 11%, #E7FFA5 100%);
+  box-shadow: -10rpx 0rpx 12rpx 2rpx rgba(0,0,0,0.07);
+}
+.wraper {
+  display: flex;
+  height: calc(100vh - var(--window-top) - v-bind(navHeight) - 290rpx);
+  height: calc(100vh - var(--window-top) - constant(safe-area-inset-bottom) - v-bind(navHeight) - 290rpx);
+  height: calc(100vh - var(--window-top) - env(safe-area-inset-bottom) - v-bind(navHeight) - 290rpx);
+}
+
+.content {
+  flex: 1;
+  background: #fff;
+}
+</style>

+ 63 - 0
src/subPack-xsb/components/xsbTabbar/index.vue

@@ -0,0 +1,63 @@
+<script setup lang="ts">
+import router from '@/router'
+import icon2 from '@/static/tab/index1.png'
+import icon1 from '@/static/tab/index2.png'
+
+const route = useRoute()
+const { ScrollDown } = storeToRefs(useSysXsbStore())
+
+const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useXsbTabbar()
+
+function handleTabbarChange({ value }: { value: string }) {
+  setTabbarItemActive(value)
+  router.push({ name: value })
+}
+
+onMounted(() => {
+  // #ifdef APP-PLUS
+  uni.hideTabBar()
+  // #endif
+  nextTick(() => {
+    if (route.name && route.name !== activeTabbar.value.name) {
+      setTabbarItemActive(route.name)
+    }
+  })
+})
+function handleClick() {
+  uni.pageScrollTo({
+    duration: 50,
+    scrollTop: 0,
+  })
+}
+</script>
+
+<template>
+  <wd-tabbar
+    :model-value="activeTabbar.name" safe-area-inset-bottom placeholder fixed :bordered="false"
+    custom-class="custom-tab" @change="handleTabbarChange"
+  >
+    <wd-tabbar-item
+      v-for="(item, index) in tabbarList" :key="index" :name="item.name"
+      :value="getTabbarItemValue(item.name)" :title="index == 0 && item.active ? '' : item.title"
+      @change="handleTabbarChange"
+    >
+      <template #icon="{ active }">
+        <template v-if="index == 0 && !active">
+          <image src="@/static/tab/index.png" class="h44rpx w44rpx" />
+        </template>
+        <template v-else-if="index == 0 && active">
+          <image v-if="ScrollDown" :src="icon1" class="h74rpx w74rpx" @click="handleClick" />
+          <image v-else :src="icon2" class="h74rpx w74rpx" />
+        </template>
+        <template v-else-if="index != 0">
+          <image v-if="active" :src="item.icon2" class="h44rpx w44rpx" />
+          <image v-else :src="item.icon1" class="h44rpx w44rpx" />
+        </template>
+      </template>
+    </wd-tabbar-item>
+  </wd-tabbar>
+</template>
+
+<style scoped>
+
+</style>

+ 315 - 0
src/subPack-xsb/goods/index.vue

@@ -0,0 +1,315 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import router from '@/router'
+
+const { statusBarHeight, MenuButtonHeight } = useSysStore()
+definePage({
+  name: 'xsb-goods',
+  style: {
+    navigationStyle: 'custom',
+    navigationBarTitleText: '星闪豹商品详情',
+  },
+})
+const goodsTab = ref(0)
+const current = ref<number>(0)
+const currentDetaile = ref(0)
+const goodsTabList = ref([
+  { title: '相似商品', id: 0 },
+  { title: '经常一起买', id: 1 },
+])
+const goodsDetaileTabList = ref([
+  { title: '商品', id: 0 },
+  { title: '评价', id: 1 },
+  { title: '详情', id: 2 },
+  { title: '推荐', id: 3 },
+])
+const goodsTabData = ref([])
+const isShowTab = ref(false)
+const currentTabGoods = ref(0)
+
+const swiperList = ref([
+  'https://wot-ui.cn/assets/redpanda.jpg',
+  'https://wot-ui.cn/assets/capybara.jpg',
+  'https://wot-ui.cn/assets/panda.jpg',
+  'https://wot-ui.cn/assets/moon.jpg',
+  'https://wot-ui.cn/assets/meng.jpg',
+])
+onMounted(() => {
+  goodsTabData.value = splitArrayToPages([{ id: 1, name: '商品' }, { id: 2, name: '商品' }, { id: 3, name: '商品' }, { id: 4, name: '商品' }, { id: 8, name: '商品' }, { id: 5, name: '商品' }, { id: 10, name: '商品' }, { id: 6, name: '商品' }, { id: 9, name: '商品' }, { id: 7, name: '商品' }, { id: 11, name: '商品' }])
+
+  console.log(goodsTabData.value, 'goodsTabData')
+})
+function splitArrayToPages<T>(arr: T[]): T[][] {
+  const PAGE_SIZE = 6
+  const MAX_PAGES = 3
+  const result: T[][] = []
+  for (let i = 0; i < Math.min(MAX_PAGES, Math.ceil(arr.length / PAGE_SIZE)); i++) {
+    const start = i * PAGE_SIZE
+    const end = start + PAGE_SIZE
+    result.push(arr.slice(start, end))
+  }
+  return result
+}
+onPageScroll((e) => {
+  if (e.scrollTop >= 315) {
+    isShowTab.value = true
+  }
+  else {
+    isShowTab.value = false
+  }
+})
+function handleGoCurren(id: number) {
+  currentDetaile.value = id
+  uni.pageScrollTo({ selector: `.view-${id}` })
+}
+</script>
+
+<template>
+  <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()"
+    />
+    <wd-swiper v-model:current="current" :list="swiperList" autoplay :height="375">
+      <template #indicator="{ current: currentIndex, total }">
+        <view class="custom-indicator absolute bottom-60rpx right-20rpx px26rpx">
+          {{ currentIndex + 1 }}/{{ total }}
+        </view>
+      </template>
+    </wd-swiper>
+    <view class="header view-0 relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
+      <view class="flex items-center justify-between">
+        <view class="flex items-end text-#FF4D3A font-semibold">
+          <view class="text-24rpx">
+            ¥
+          </view>
+          <view class="text-36rpx line-height-[36rpx]">
+            1.395
+          </view>
+        </view>
+        <view>
+          <image class="h40rpx w40rpx" :src="`${StaticUrl}/collect-yes.png`" />
+        </view>
+      </view>
+    </view>
+    <view v-show="isShowTab" class="sticky left-0 z-99 box-border h84rpx w-full flex items-center justify-between bg-white px24rpx" :style="{ top: `${statusBarHeight + MenuButtonHeight}px` }">
+      <view v-for="item in goodsDetaileTabList" :key="item.id" class="relative flex items-center text-32rpx font-semibold" @click="handleGoCurren(item.id)">
+        {{ item.title }}
+        <view v-show="currentDetaile == item.id" class="line absolute left-50% h12rpx w40rpx rounded-8rpx bg-[var(--them-color)] -bottom-15rpx -translate-x-50%" />
+      </view>
+    </view>
+    <view class="px24rpx">
+      <view class="mt24rpx">
+        <view class="text-left text-28rpx font-semibold">
+          <view v-for="i in 2" :key="i" class="mr5px inline-block">
+            <wd-tag type="primary">
+              新品{{ i }}
+            </wd-tag>
+          </view>
+          大荔冬枣大果250g
+        </view>
+      </view>
+      <view class="mt16rpx text-24rpx text-#AAAAAA">
+        优选产地,皮薄核小,维c满满
+      </view>
+      <view class="mt20rpx flex items-center">
+        <view
+          v-for="item in 2" :key="item"
+          class="mr16rpx flex items-center justify-center border-1rpx border-#BC9264 rounded-8rpx border-solid bg-[#FFF5E9] px16rpx py6rpx text-24rpx text-#BC9264 font-semibold"
+        >
+          一口化渣{{ item }}
+        </view>
+      </view>
+      <view class="mt20rpx flex items-center justify-between rounded-16rpx bg-white p24rpx">
+        <view class="flex items-center">
+          <view class="flex-shrink-0">
+            <view class="text-28rpx font-semibold">
+              大荔冬枣
+            </view>
+            <view class="mt16rpx text-24rpx text-#AAAAAA">
+              品牌
+            </view>
+          </view>
+          <view class="mx24rpx">
+            <wd-divider vertical color="#F0F0F0" />
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="flex-shrink-0">
+            <view class="text-28rpx font-semibold">
+              大荔冬枣
+            </view>
+            <view class="mt16rpx text-24rpx text-#AAAAAA">
+              产地(以实际商品批次为准)
+            </view>
+          </view>
+          <view class="mx24rpx">
+            <wd-divider vertical color="#F0F0F0" />
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="flex-shrink-0">
+            <view class="text-28rpx font-semibold">
+              30天
+            </view>
+            <view class="mt16rpx text-24rpx text-#AAAAAA">
+              保质期
+            </view>
+          </view>
+        </view>
+        <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
+      </view>
+      <view class="view-1 mt20rpx flex items-center rounded-16rpx bg-white p24rpx">
+        <view class="w-full flex items-center justify-between">
+          <view class="text-32rpx font-semibold">
+            评价(10万+)
+          </view>
+          <view class="flex items-center">
+            <view class="mr10rpx flex items-center text-28rpx text-#FF4D3A">
+              <view>好评率</view>
+              <view class="ml5rpx font-semibold">
+                99.8%
+              </view>
+            </view>
+            <wd-icon name="chevron-right" size="22px" color="#AAAAAA" />
+          </view>
+        </view>
+      </view>
+      <view class="mt20rpx rounded-16rpx bg-white p24rpx">
+        <wd-tabs v-model="goodsTab">
+          <block v-for="item in goodsTabList" :key="item.id">
+            <wd-tab :title="item.title" />
+          </block>
+        </wd-tabs>
+        <swiper class="mt20rpx h900rpx" indicator-active-color="var(--them-color)" @change="(e) => currentTabGoods = e.detail.current">
+          <swiper-item
+            v-for="items in goodsTabData" :key="items"
+            class="grid grid-cols-3 items-start gap-x-16rpx gap-y-16rpx pb20rpx"
+          >
+            <view
+              v-for="goods in items" :key="goods"
+              class="box-border w204rpx border border-2rpx border-#F0F0F0 rounded-16rpx border-solid px4rpx py8rpx"
+            >
+              <image lazy-load :src="`${StaticUrl}/shu.png`" class="h188rpx w198rpx" />
+              <view class="mt20rpx px16rpx text-24rpx font-semibold">
+                新鲜现宰杀肋排200g
+              </view>
+              <view class="mt12rpx truncate px16rpx text-24rpx text-#AAAAAA">
+                维c满满,营养qweqwe
+              </view>
+              <view class="my20rpx flex items-center justify-between px16rpx">
+                <view class="flex items-end text-#FF4D3A font-semibold">
+                  <view class="text-24rpx">
+                    ¥
+                  </view>
+                  <view class="text-32rpx line-height-[32rpx]">
+                    1.395
+                  </view>
+                </view>
+                <image :src="`${StaticUrl}/cart-yes.png`" class="h44rpx w44rpx" />
+              </view>
+            </view>
+          </swiper-item>
+        </swiper>
+        <view class="mt24rpx flex items-center justify-center">
+          <view v-for="item, idx in goodsTabData" :key="idx" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentTabGoods == idx ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
+        </view>
+      </view>
+    </view>
+    <view class="view-2 mt20rpx bg-white">
+      <view class="p24rpx text-32rpx font-semibold">
+        商品详情
+      </view>
+      <view class="h-200rpx">
+        图片
+      </view>
+    </view>
+    <view class="view-3 mt28rpx flex items-center justify-center">
+      <view class="flex items-center">
+        <image
+          :src="`${StaticUrl}/goods-recommend.png`"
+          class="mr12rpx h25rpx w26rpx"
+        />
+        <view class="text-36rpx text-[var(--them-color)] font-semibold">
+          为你推荐
+        </view>
+        <image
+          :src="`${StaticUrl}/goods-recommend.png`"
+          class="ml12rpx h25rpx w26rpx"
+        />
+      </view>
+    </view>
+    <view class="h180rpx" />
+    <view class="ios shadow-fixed fixed bottom-0 left-0 w-full rounded-t-32rpx bg-white">
+      <view class="flex items-center justify-between px24rpx py20rpx">
+        <view class="mr36rpx">
+          <image
+            :src="`${StaticUrl}/goods-home.png`"
+            class="h44rpx w44rpx"
+          />
+          <view class="text-20rpx">
+            首页
+          </view>
+        </view>
+        <view class="mr36rpx">
+          <image
+            :src="`${StaticUrl}/goods-kf.png`"
+            class="h44rpx w44rpx"
+          />
+          <view class="text-20rpx">
+            客服
+          </view>
+        </view>
+        <view>
+          <image
+            :src="`${StaticUrl}/goods-cart.png`"
+            class="h44rpx w44rpx"
+          />
+          <view class="text-20rpx">
+            购物车
+          </view>
+        </view>
+        <view class="flex items-center">
+          <view class="w220rpx">
+            <wd-button plain hairline block>
+              加入购物车
+            </wd-button>
+          </view>
+          <view class="ml20rpx w220rpx">
+            <wd-button block class="w-full">
+              立即购买
+            </wd-button>
+          </view>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.custom-indicator {
+  border-radius: 16rpx;
+  background: rgba(0, 0, 0, 0.5);
+  color: #ffffff;
+  font-size: 24rpx;
+}
+.shadow-fixed{
+  box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0,0,0,0.09);
+}
+.header {
+  background: linear-gradient(180deg, #FFFFFF 0%, #FFFFFF 62%, #F6F6F6 100%);
+}
+
+.page-xsb {
+  :deep() {
+    .wd-tabs__nav-item {
+      .wd-tabs__nav-item-text {
+        font-size: 32rpx !important;
+      }
+    }
+    .ios .wd-button{
+      min-width: unset !important;
+    }
+  }
+}
+</style>

+ 239 - 0
src/subPack-xsb/home/index.vue

@@ -0,0 +1,239 @@
+<script setup lang="ts">
+import { StaticUrl, VITE_OSS_BASE_URL } from '@/config'
+import router from '@/router'
+import xsbTabbar from '@/subPack-xsb/components/xsbTabbar/index.vue'
+
+const { ScrollDown } = storeToRefs(useSysXsbStore())
+definePage({
+  name: 'xsb-home',
+  style: {
+    navigationStyle: 'custom',
+    backgroundColor: '#9ED605',
+    backgroundColorTop: '#9ED605',
+    navigationBarTitleText: '星闪豹首页',
+    backgroundColorBottom: '#fff',
+  },
+})
+const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
+const current = ref(0)
+const swiperList = ref([
+  'https://wot-ui.cn/assets/redpanda.jpg',
+  'https://wot-ui.cn/assets/capybara.jpg',
+  'https://wot-ui.cn/assets/panda.jpg',
+  'https://wot-ui.cn/assets/moon.jpg',
+  'https://wot-ui.cn/assets/meng.jpg',
+])
+const navActive = ref(0)
+const classfiylist = ref([
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/shu.png` },
+])
+const swiperClassList = ref([
+  { title: '露营季', icon: `${StaticUrl}/zhi.png` },
+  { title: '方便菜', icon: `${StaticUrl}/zhi.png` },
+  { title: '日用清洁', icon: `${StaticUrl}/zhi.png` },
+  { title: '个护美妆', icon: `${StaticUrl}/zhi.png` },
+  { title: '轻食沙拉', icon: `${StaticUrl}/zhi.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/zhi.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/zhi.png` },
+  { title: '蔬菜豆品', icon: `${StaticUrl}/zhi.png` },
+])
+const navList = ref([
+  { title: '为你推荐' },
+  { title: '疯狂折扣' },
+  { title: '' },
+  { title: '地道特产' },
+  { title: '预售' },
+])
+const textArray = ref([
+  '这是一条消息提示信息',
+  '这是第二条消息',
+  '这是第三条消息',
+])
+
+function handleLoaction() {
+  console.log('定位')
+}
+function handleChangeNav(idx: number) {
+  navActive.value = idx
+}
+onPageScroll((e) => {
+  if (e.scrollTop >= 80) {
+    ScrollDown.value = true
+  }
+  else {
+    ScrollDown.value = false
+  }
+})
+function handleCommonName(name: string) {
+  router.push({ name })
+}
+</script>
+
+<template>
+  <view class="page-xsb">
+    <wd-navbar
+      title=""
+      :custom-style="`background-color:${ScrollDown ? 'var(--them-color)' : 'transparent !important'}`"
+      :bordered="false" :z-index="99" safe-area-inset-top left-arrow fixed @click-left="router.replaceAll({ name: 'smqjh-home' })"
+    >
+      <template #left>
+        <view class="h-full flex items-center">
+          <wd-icon name="arrow-left" size="22px" color="#fff" />
+          <view class="ml10rpx flex items-center" @click.stop="handleLoaction">
+            <image :src="`${StaticUrl}/location.png`" class="h33.8rpx w29rpx" />
+            <view class="ml10rpx text-32rpx text-white">
+              富力中心
+            </view>
+          </view>
+        </view>
+      </template>
+    </wd-navbar>
+    <view
+      class="header-linear h320rpx px24rpx"
+      :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
+    >
+      <view class="h60rpx w-full flex items-center justify-between rounded-40rpx bg-white pr6rpx">
+        <view class="flex items-center pb14rpx pl24rpx pt16rpx">
+          <wd-icon name="search" size="14" color="#ccc" />
+          <view class="search ml12rpx h-full w-full overflow-hidden">
+            <wd-notice-bar :text="['霸王茶姬', '牛奶', '洗衣机']" custom-class="notice-bar" color="#ccc" background-color="#fff" direction="vertical" />
+          </view>
+        </view>
+        <view
+          class="h50rpx w96rpx flex items-center justify-center rounded-26rpx bg-[var(--them-color)] text-24rpx text-white font-semibold"
+        >
+          搜索
+        </view>
+      </view>
+      <scroll-view scroll-x class="mb20rpx mt20rpx h44rpx whitespace-nowrap">
+        <view class="h-full flex items-center">
+          <view v-for="item in 10" :key="item" class="mr32rpx h-full flex items-center justify-center rounded-22rpx bg-[rgba(255,255,255,.5)] px16rpx text-24rpx">
+            {{ item }}苹果
+          </view>
+        </view>
+      </scroll-view>
+    </view>
+    <view class="px24rpx -mt180rpx">
+      <wd-swiper v-model:current="current" :autoplay="false" :list="swiperList" :height="138" :indicator="false" />
+      <view class="mt20rpx">
+        <wd-card title="" custom-class="card-zt">
+          <view class="px24rpx pt24rpx">
+            <view class="grid grid-cols-5 gap-x-38rpx gap-y-24rpx">
+              <view v-for="item, index in classfiylist" :key="index">
+                <image
+                  :src="item.icon"
+                  class="h100rpx w100rpx"
+                />
+                <view class="mt12rpx text-24rpx text-#222">
+                  {{ item.title }}
+                </view>
+              </view>
+            </view>
+          </view>
+          <view class="swiper-img swiper pb20rpx">
+            <wd-swiper
+              :list="swiperClassList"
+              :indicator="{ type: 'dots-bar' }"
+              height="80"
+              :display-multiple-items="5"
+              :autoplay="false"
+              :loop="false"
+              custom-indicator-class="custom-indicator-class"
+              value-key="icon"
+              text-key="title"
+              image-mode="aspectFit"
+            />
+          </view>
+        </wd-card>
+      </view>
+      <view class="mt20rpx">
+        <wd-notice-bar direction="vertical" :text="textArray" :delay="3" color="#222222" background-color="#fff">
+          <template #prefix>
+            <view class="mr20rpx">
+              <wd-icon name="sound" size="22px" color="var(--them-color)" />
+            </view>
+          </template>
+        </wd-notice-bar>
+      </view>
+      <view class="mt20rpx">
+        <image
+          :src="`${VITE_OSS_BASE_URL}2025/12/6671332ceef64985858aa8b548027bd3.png`"
+          class="h236rpx w-full"
+        />
+      </view>
+      <scroll-view scroll-x class="mb20rpx mt20rpx whitespace-nowrap">
+        <view class="flex items-center">
+          <view v-for="item, idx in navList" :key="idx" class="relative mr44rpx" @click="handleChangeNav(idx)">
+            <image
+              v-show="idx == 2"
+              :src="`${StaticUrl}/chaozhi.png`"
+              class="relative z-2 h-29.06rpx w-105.34rpx"
+            />
+            <text v-show="idx != 2" class="relative z-2 text-32rpx" :class="[navActive == idx ? 'text-36rpx font-semibold' : '']">
+              {{ item.title }}
+            </text>
+            <view v-show="navActive == idx" class="nav-line absolute bottom-0rpx left-50% z-1 h18rpx w80rpx rounded-10rpx -translate-x-50%" />
+          </view>
+        </view>
+      </scroll-view>
+      <view class="mt20rpx">
+        <view class="flex items-center">
+          <scroll-view scroll-y type="custom">
+            <grid-view type="masonry" cross-axis-count="2" main-axis-gap="10" cross-axis-gap="10">
+              <wd-swiper v-model:current="current" :autoplay="false" :list="swiperList" :height="231" />
+              <view v-for="it in 20" :key="it" class="overflow-hidden rounded-16rpx bg-white pb16rpx" @click="handleCommonName('xsb-goods')">
+                <view class="relative h344rpx">
+                  <image :src="`${VITE_OSS_BASE_URL}2025/11/9d42892888304abf85487deea0271f62.png`" class="h344rpx w344rpx" />
+                </view>
+                <view class="mt20rpx px20rpx">
+                  <view class="text-left text-28rpx font-semibold">
+                    <view v-for="i in 2" :key="i" class="mr5px inline-block">
+                      <wd-tag type="primary">
+                        新品{{ i }}
+                      </wd-tag>
+                    </view>
+                    海湾高盐特大白虾200g
+                  </view>
+                  <view class="mt12rpx text-22rpx text-#AAAAAA">
+                    已售5999
+                  </view>
+
+                  <view class="mt10rpx flex items-center justify-between">
+                    <view>
+                      <view class="mt20rpx flex items-end text-#FF4D3A font-semibold">
+                        <view class="text-24rpx">
+                          ¥
+                        </view>
+                        <view class="text-36rpx line-height-[36rpx]">
+                          1.395
+                        </view>
+                      </view>
+                    </view>
+                    <image
+                      :src="`${StaticUrl}/cart-yes.png`"
+                      class="h52rpx w52rpx"
+                    />
+                  </view>
+                </view>
+              </view>
+            </grid-view>
+          </scroll-view>
+        </view>
+      </view>
+    </view>
+    <xsbTabbar />
+  </view>
+</template>
+
+<style scoped lang="scss">
+
+</style>

+ 226 - 0
src/subPack-xsb/my/afterSales/index.vue

@@ -0,0 +1,226 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import router from '@/router'
+
+definePage({
+  name: 'xsb-afterSales',
+  style: {
+    navigationBarTitleText: '申请售后',
+  },
+})
+const afterSalesType = ref(1)
+const isSeletAllGoods = ref(false)
+const selectGoods = ref([])
+const fileList = ref([])
+const showReson = ref(false)
+const resonId = ref()
+const resonName = ref('请选择退款原因')
+const resonList = [
+  { id: 1, name: '暂不需要商品(买错/多买/漏买)' },
+  { id: 2, name: '冰品融化' },
+  { id: 3, name: '订单中有商品发错' },
+  { id: 4, name: '商品斤两不足' },
+  { id: 5, name: '商品临期到期' },
+  { id: 6, name: '商品破损/包装破损' },
+]
+function handleSubmit() {
+  console.log(fileList.value, 'fileList')
+  router.push({ name: 'xsb-afterSalesDetail' })
+}
+function handleSelectReson() {
+  if (!resonId.value)
+    return uni.showToast({ title: '请选择退款原因', icon: 'none' })
+  showReson.value = false
+  resonName.value = resonList.find(item => item.id === resonId.value)?.name || '请选择退款原因'
+}
+</script>
+
+<template>
+  <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">
+        部分退款时,有积分消费的,优先返还积分。
+      </view>
+    </view>
+    <view class="px24rpx py24rpx">
+      <view class="rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="mb24rpx text-32rpx font-semibold">
+          售后类型
+        </view>
+        <wd-radio-group v-model="afterSalesType" shape="dot" inline>
+          <wd-radio :value="1">
+            <view>
+              <view class="text-left text-28rpx font-semibold">
+                我要退款
+              </view>
+              <view class="mt16rpx text-24rpx text-#AAAAAA">
+                没收到货,货已收到货与商家协商后无需退货只退款
+              </view>
+            </view>
+          </wd-radio>
+          <view class="mt24rpx">
+            <wd-radio :value="2">
+              <view>
+                <view class="text-left text-28rpx font-semibold">
+                  我要退货退款
+                </view>
+                <view class="mt16rpx text-24rpx text-#AAAAAA">
+                  已收到货,需要退还已收到的商品
+                </view>
+              </view>
+            </wd-radio>
+          </view>
+        </wd-radio-group>
+      </view>
+      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="flex items-center justify-between">
+          <view class="text-32rpx font-semibold">
+            退款商品
+          </view>
+          <view class="text-28rpx text-#FF4D3A font-semibold">
+            退款金额:¥21
+          </view>
+        </view>
+        <view class="mt24rpx">
+          <wd-checkbox v-model="isSeletAllGoods">
+            全选
+          </wd-checkbox>
+        </view>
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <view class="goods mt24rpx">
+          <CollapsePanel :line-height="150">
+            <wd-checkbox-group v-model="selectGoods">
+              <view v-for="item in 10" :key="item" class="mb20rpx">
+                <wd-checkbox :model-value="item">
+                  <view class="w-full flex items-center">
+                    <image :src="`${StaticUrl}/shu.png`" class="h120rpx w120rpx flex-shrink-0" />
+                    <view class="ml20rpx flex-1">
+                      <view class="flex items-center justify-between">
+                        <view class="text-28rpx">
+                          赶海季生鲜大闸蟹
+                        </view>
+                        <view class="text-32rpx text-#FF4D3A font-semibold">
+                          ¥103.95
+                        </view>
+                      </view>
+                      <view class="text-24rpx text-#AAAAAA">
+                        规格:5kg,盒
+                      </view>
+                      <view class="flex items-center justify-between">
+                        <view class="text-24rpx text-#AAAAAA">
+                          单价:¥1.8
+                        </view>
+                        <view>
+                          <wd-input-number />
+                        </view>
+                      </view>
+                    </view>
+                  </view>
+                </wd-checkbox>
+                <view class="mt20rpx h2rpx w-full bg-#F0F0F0" />
+              </view>
+            </wd-checkbox-group>
+          </CollapsePanel>
+        </view>
+      </view>
+      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="flex items-center justify-between">
+          <view class="text-32rpx font-semibold">
+            退款原因
+          </view>
+          <view class="flex items-center text-28rpx" @click="showReson = true">
+            <view class="text-#AAAAAA">
+              {{ resonName }}
+            </view> <wd-icon name="arrow-right" size="18px" color="#aaa" />
+          </view>
+        </view>
+        <view class="mt20rpx rounded-16rpx bg-#F6F6F6 p24rpx">
+          <wd-textarea placeholder="请填写退款原因" show-word-limit :maxlength="200" />
+          <view class="upload mt18rpx">
+            <Zupload v-model:value="fileList" />
+          </view>
+        </view>
+      </view>
+    </view>
+    <Zpopup v-model="showReson">
+      <view class="p24rpx">
+        <view class="w-full text-center text-32rpx font-semibold">
+          选择退款原因
+        </view>
+        <view class="mt20rpx flex items-center rounded-16rpx bg-#f8e3ca px24rpx py12rpx">
+          <wd-icon name="info-circle-filled" size="22px" color="#FF941A" />
+          <view class="ml16rpx text-28rpx">
+            部分退款时,有积分消费的,优先返还积分。
+          </view>
+        </view>
+        <view class="mt20rpx rounded-32rpx bg-white p24rpx">
+          <view class="mb20rpx text-28rpx font-semibold">
+            请选择退款原因 <text class="text-#AAAAAA">
+              (必选)
+            </text>
+          </view>
+          <wd-radio-group v-model="resonId" shape="dot">
+            <wd-radio v-for="item in resonList" :key="item.id" :value="item.id">
+              <view class="w-full text-24rpx">
+                {{ item.name }}
+              </view>
+            </wd-radio>
+          </wd-radio-group>
+        </view>
+      </view>
+      <template #footer>
+        <wd-button block @click="handleSelectReson">
+          确定
+        </wd-button>
+      </template>
+    </Zpopup>
+    <view class="h200rpx" />
+    <view
+      class="ios fixed bottom-0 z-10 box-border w-full w-full rounded-t-32rpx bg-white px32rpx pt-16rpx"
+    >
+      <wd-button block @click="handleSubmit">
+        提交
+      </wd-button>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.page-xsb {
+  :deep() {
+    .goods .wd-checkbox{
+      display: flex;
+      align-items: center;
+      .wd-checkbox__shape{
+        flex-shrink: 0;
+      }
+      .wd-checkbox__label {
+      width:100%;
+      .wd-checkbox__txt{
+        width: 100%;
+      }
+    }
+    }
+    .wd-textarea{
+      background: #F6F6F6 !important;
+      .wd-textarea__value{
+        background: #F6F6F6 !important;
+      }
+      .wd-textarea__count{
+        background: #F6F6F6 !important;
+      }
+    }
+    .upload {
+      .wd-upload__preview{
+        width: 120rpx !important;
+        height: 120rpx !important;
+      }
+      .wd-upload__status-content{
+        overflow: hidden !important;
+        border-radius: 32rpx !important;
+      }
+    }
+  }
+}
+</style>

+ 249 - 0
src/subPack-xsb/my/afterSalesDetail/index.vue

@@ -0,0 +1,249 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'xsb-afterSalesDetail',
+  style: {
+    navigationBarTitleText: '售后详情',
+
+  },
+})
+const activeStep = ref(0)
+</script>
+
+<template>
+  <view class="page-xsb pt20rpx">
+    <wd-card>
+      <view class="py24rpx">
+        <view class="text-32rpx text-#222 font-semibold">
+          待商家审核
+        </view>
+        <view class="mt20rpx text-24rpx text-#AAAAAA">
+          商家将在23小时59分内为您处理,逾期将自动同意
+        </view>
+        <view class="mt24rpx flex items-center justify-between text-28rpx">
+          <view class="text-#222 font-semibold">
+            退款金额
+          </view>
+          <view class="text-#FF4D3A font-semibold">
+            ¥21
+          </view>
+        </view>
+        <view class="mt20rpx text-24rpx text-#AAAAAA">
+          申请通过后,将退回至原账户
+        </view>
+      </view>
+    </wd-card>
+    <view class="mt20rpx">
+      <wd-card>
+        <view class="grid grid-cols-5 py24rpx text-28rpx text-#222">
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-apply.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              取消申请
+            </view>
+          </view>
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-wx.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              联系商家
+            </view>
+          </view>
+        </view>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card>
+        <view class="py24rpx">
+          <view class="mb20rpx text-32rpx font-semibold">
+            退款流程
+          </view>
+          <wd-steps :active="activeStep" vertical dot>
+            <wd-step>
+              <template #title>
+                <view class="text-28rpx font-semibold">
+                  待商家审核
+                </view>
+              </template>
+              <template #description>
+                <view class="mt20rpx text-24rpx text-#AAAAAA">
+                  <view>您的服务单已申请成功,待商家审核</view>
+                  <view class="mt12rpx">
+                    2024-12-13 11:12:30
+                  </view>
+                </view>
+              </template>
+            </wd-step>
+            <wd-step>
+              <template #title>
+                <view class="text-28rpx font-semibold">
+                  申请原因
+                </view>
+              </template>
+              <template #description>
+                <view class="mt20rpx text-24rpx text-#AAAAAA">
+                  <view>不需要</view>
+                  <view class="mt12rpx">
+                    2024-12-13 11:12:30
+                  </view>
+                </view>
+              </template>
+            </wd-step>
+          </wd-steps>
+        </view>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card>
+        <template #title>
+          <view class="flex items-center justify-between text-28rpx font-semibold">
+            <view class="">
+              退款商品
+            </view>
+            <view class="text-#FF4A39">
+              退款金额:¥21
+            </view>
+          </view>
+          <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        </template>
+        <CollapsePanel :line-height="150">
+          <view v-for="item in 5" :key="item" class="mb20rpx w-full flex items-center">
+            <view class="mr20rpx w120rpx flex-shrink-0">
+              <image
+                :src="`${StaticUrl}/shu.png`"
+                class="h120rpx w120rpx"
+              />
+            </view>
+            <view class="flex-1">
+              <view class="w-full flex items-center justify-between font-semibold">
+                <view class="text-28rpx">
+                  赶海季生鲜大闸蟹
+                </view>
+                <view class="text-32rpx text-#FF4D3A">
+                  ¥103.95
+                </view>
+              </view>
+              <view class="text-24rpx text-#AAAAAA">
+                规格:5kg,盒
+              </view>
+              <view class="text-24rpx text-#AAAAAA">
+                ×1
+              </view>
+            </view>
+          </view>
+        </CollapsePanel>
+
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            商品金额
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            配送费(即时配送)
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            积分(1400)
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <template #footer>
+          <view class="flex items-center justify-between">
+            <view class="text-28rpx font-semibold">
+              合计:
+            </view>
+            <view class="flex items-center">
+              <view class="text-24rpx text-#AAAAAA">
+                总计54 共减14
+              </view>
+              <view class="ml8rpx text-28rpx text-#FF4D3A font-semibold">
+                <text class="text-#222">
+                  实付款
+                </text> ¥54.00
+              </view>
+            </view>
+          </view>
+        </template>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card title="订单信息">
+        <view class="pb20rpx">
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              订单编号
+            </view>
+            <view class="flex items-center">
+              <text class="text-#222">
+                1867402054587256856
+              </text>
+              <view class="ml10rpx">
+                <wd-icon name="file-copy" size="22px" />
+              </view>
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              售后编号
+            </view>
+            <view class="flex items-center">
+              <text class="text-#222">
+                1867402054587256856
+              </text>
+              <view class="ml10rpx">
+                <wd-icon name="file-copy" size="22px" />
+              </view>
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              申请时间
+            </view>
+            <view class="text-#222">
+              2024-12-13 11:12:30
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              服务类型
+            </view>
+            <view class="text-#222">
+              仅退款
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              申请原因
+            </view>
+            <view class="text-#222">
+              无
+            </view>
+          </view>
+        </view>
+      </wd-card>
+    </view>
+    <view class="h30rpx" />
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 66 - 0
src/subPack-xsb/my/afterSalesList/index.vue

@@ -0,0 +1,66 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import router from '@/router'
+
+definePage({
+  name: 'xsb-afterSalesList',
+  style: {
+    navigationBarTitleText: '售后列表',
+  },
+})
+</script>
+
+<template>
+  <view class="page-xsb py24rpx">
+    <wd-card v-for="item in 10" :key="item">
+      <view class="py24rpx" @click="router.push({ name: 'xsb-afterSalesDetail' })">
+        <view class="flex items-center justify-between">
+          <view class="text-28rpx text-#AAAAAA">
+            售后编号:2048602564
+          </view>
+          <view class="text-24rpx text-#222">
+            仅退款
+          </view>
+        </view>
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <view class="mt24rpx box-border h176rpx w-full flex items-center justify-between rounded-16rpx bg-#F9F9F9">
+          <view class="box-border h-full w480rpx py28rpx pl20rpx">
+            <scroll-view scroll-x class="h-full w-full whitespace-nowrap">
+              <view class="flex items-center">
+                <view v-for="item in 20" :key="item" class="mr50rpx">
+                  <image
+                    :src="`${StaticUrl}/shu.png`"
+                    class="h120rpx w120rpx"
+                  />
+                </view>
+              </view>
+            </scroll-view>
+          </view>
+          <view class="box-shadow box-border h-full flex-1 flex-shrink-0 px14rpx py40rpx">
+            <view class="text-32rpx text-#FF4D3A font-semibold">
+              ¥13.95
+            </view>
+            <view class="text-center text-28rpx text-#AAAAAA">
+              共5件
+            </view>
+          </view>
+        </view>
+        <view class="mt24rpx rounded-16rpx bg-#F0F0F0 px24rpx py20rpx text-28rpx text-#222">
+          售后取消
+          <text class="text-24rpx text-#AAAAAA">
+            您已主动取消退款申请,如有需要可再次提交
+          </text>
+        </view>
+        <view class="mt20rpx flex items-center justify-end">
+          <wd-button plain block type="info" size="small">
+            再次申请
+          </wd-button>
+        </view>
+      </view>
+    </wd-card>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 131 - 0
src/subPack-xsb/my/index.vue

@@ -0,0 +1,131 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import router from '@/router'
+import xsbTabbar from '@/subPack-xsb/components/xsbTabbar/index.vue'
+
+definePage({
+  name: 'xsb-my',
+  style: {
+    navigationStyle: 'custom',
+    navigationBarTitleText: '星闪豹我的',
+    disableScroll: true,
+  },
+})
+const tabList = ref([
+  { title: '待支付', icon: `${StaticUrl}/1.png`, name: 'xsb-order' },
+  { title: '待收货', icon: `${StaticUrl}/2.png`, name: 'xsb-order' },
+  { title: '已完成', icon: `${StaticUrl}/6.png`, name: 'xsb-order' },
+  { title: '退款售后', icon: `${StaticUrl}/3.png`, name: 'xsb-afterSalesList' },
+])
+</script>
+
+<template>
+  <view class="page-class page-xsb bg-#F9F9F9 dark:bg-[var(--wot-dark-background)]">
+    <wd-navbar
+      title="个人中心" custom-style="background-color: transparent !important;" :bordered="false"
+      safe-area-inset-top fixed :z-index="99"
+    />
+    <view class="header relative h-408rpx rounded-18px">
+      <view class="absolute bottom-100rpx left-0 box-border w-full flex items-center justify-between pl48rpx pr58rpx">
+        <image :src="`${StaticUrl}/9.png`" alt="" class="h100rpx w100rpx" />
+        <view class="text-32rpx font-semibold">
+          请登录后使用完整功能
+        </view>
+        <wd-button custom-class="login-btn">
+          登录
+        </wd-button>
+      </view>
+    </view>
+    <view class="relative z-50 -mt48rpx">
+      <wd-card>
+        <template #title>
+          <view class="flex items-center justify-between">
+            <view class="text-32rpx font-semibold">
+              订单列表
+            </view>
+            <view class="flex items-center">
+              <view class="text-28rpx">
+                查看全部
+              </view>
+              <wd-icon name="arrow-right" size="18px" />
+            </view>
+          </view>
+        </template>
+        <view class="grid grid-cols-4 gap-4">
+          <view v-for="item in tabList" :key="item.title" class="flex flex-col items-center justify-center" @click="router.push({ name: item.name })">
+            <image :src="item.icon" class="h56rpx w56rpx" />
+            <view class="mt20rpx text-24rpx">
+              {{ item.title }}
+            </view>
+          </view>
+        </view>
+        <view class="h20rpx" />
+      </wd-card>
+    </view>
+    <view class="item-cell mt20rpx">
+      <wd-card custom-class="card">
+        <wd-cell-group custom-class="cell-group">
+          <wd-cell title="收货地址" custom-title-class="cell-title" clickable is-link>
+            <template #icon>
+              <image :src="`${StaticUrl}/4.png`" class="h50rpx w50rpx" />
+            </template>
+          </wd-cell>
+          <wd-cell title="联系平台客服" custom-title-class="cell-title" clickable is-link>
+            <template #icon>
+              <image :src="`${StaticUrl}/5.png`" class="h50rpx w50rpx" />
+            </template>
+          </wd-cell>
+        </wd-cell-group>
+      </wd-card>
+    </view>
+    <view class="item-cell mt20rpx">
+      <wd-card custom-class="card">
+        <wd-cell-group custom-class="cell-group">
+          <wd-cell title="积分" custom-title-class="cell-title" clickable is-link>
+            <template #icon>
+              <image :src="`${StaticUrl}/7.png`" class="h50rpx w50rpx" />
+            </template>
+          </wd-cell>
+          <wd-cell title="评价" custom-title-class="cell-title" clickable is-link>
+            <template #icon>
+              <image :src="`${StaticUrl}/8.png`" class="h50rpx w50rpx" />
+            </template>
+          </wd-cell>
+        </wd-cell-group>
+      </wd-card>
+    </view>
+    <xsbTabbar />
+  </view>
+</template>
+
+<style lang="scss" scoped>
+.header {
+ background: linear-gradient( 113deg, #F7FFDC 0%, #E0FF8E 25%, #F2FFCE 51%, #E3FF98 83%, #F6FFD6 100%);
+}
+
+.page-class {
+  :deep() {
+    .login-btn {
+      min-width: 0 !important;
+      width: 180rpx;
+    }
+
+    .cell-title {
+      padding-left: 20rpx;
+    }
+  }
+
+}
+
+.item-cell {
+  :deep() {
+    .card {
+      padding: 0 !important;
+    }
+    .cell-group{
+      overflow: hidden;
+      border-radius: 12rpx;
+    }
+  }
+}
+</style>

+ 150 - 0
src/subPack-xsb/my/order/index.vue

@@ -0,0 +1,150 @@
+<script setup lang="ts">
+import { getRect } from 'wot-design-uni/components/common/util'
+import { StaticUrl } from '@/config'
+import router from '@/router'
+import { handleCommonOrderStatusText, navTabTypeList, orderStatusList } from './order-data'
+
+definePage({
+  name: 'xsb-order',
+  style: {
+    navigationStyle: 'custom',
+    navigationBarTitleText: '星闪豹订单列表',
+    disableScroll: true,
+  },
+})
+const navActiveTab = ref(0)
+const orderStatusActive = ref(0)
+const { statusBarHeight, MenuButtonHeight } = useSysStore()
+const navHeight = ref(87)
+onMounted(() => {
+  getRect('.nav', false).then((rect) => {
+    if (rect.height) {
+      navHeight.value = rect.height
+    }
+  })
+})
+function handleChangeTypeNav(value: number) {
+  navActiveTab.value = value
+}
+function handleChangeStatus(value: number) {
+  orderStatusActive.value = value
+}
+</script>
+
+<template>
+  <view class="page-xsb">
+    <wd-navbar
+      title="订单列表" :bordered="false"
+      :z-index="99"
+
+      safe-area-inset-top placeholder left-arrow fixed
+      @click-left="router.back()"
+    />
+    <view class="nav bg-white px24rpx py18rpx">
+      <view class="flex items-center">
+        <view v-for="item in navTabTypeList" :key="item.value" class="mr64rpx flex flex-col items-center text-32rpx" :class="[navActiveTab == item.value ? 'font-semibold ' : 'text-#AAAAAA']" @click="handleChangeTypeNav(item.value)">
+          {{ item.name }}
+          <view class="mt10rpx bg-[var(--them-color)] transition-all transition-duration-400 ease-in" :class="[navActiveTab == item.value ? 'w40rpx h8rpx rounded-4rpx' : '']" />
+        </view>
+      </view>
+      <view class="mt20rpx flex items-center">
+        <view v-for="item in orderStatusList" :key="item.value" class="mr16rpx rounded-24rpx bg-#F6F6F6 px16rpx py6rpx text-24rpx" :class="[orderStatusActive == item.value ? 'bg-[var(--them-color)] text-white' : '']" @click="handleChangeStatus(item.value)">
+          {{ item.name }}
+        </view>
+      </view>
+    </view>
+    <view :style="{ height: `calc(100vh - ${(statusBarHeight + MenuButtonHeight) * 2}rpx - ${navHeight * 2}rpx)` }">
+      <scroll-view scroll-y class="h-full pt24rpx">
+        <view v-for="item in 20" :key="item" @click="router.push({ name: 'xsb-orderDetaile' })">
+          <wd-card>
+            <template #title>
+              <view class="flex items-center justify-between">
+                <view class="flex items-center">
+                  <image
+                    :src="`${StaticUrl}/order-icon.png`"
+                    class="h36rpx w36rpx"
+                  />
+                  <view class="ml20rpx text-32rpx font-semibold">
+                    海马购官方旗舰店
+                  </view>
+                </view>
+                <view class="text-24rpx text-#FF4D3A">
+                  {{ handleCommonOrderStatusText(item) }}
+                </view>
+              </view>
+              <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+            </template>
+
+            <view>
+              <view class="mb20rpx box-border rounded-16rpx bg-#F9F9F9 p24rpx">
+                <view class="flex items-center">
+                  <image
+                    :src="`${StaticUrl}/order-car.png`"
+                    class="h36rpx w36rpx"
+                  />
+                  <view class="ml20rpx text-28rpx text-#222 font-semibold">
+                    预计10:40前可送达
+                  </view>
+                </view>
+                <view class="mt18rpx">
+                  您的订单预计3月7日 10:40前送达
+                </view>
+                <view class="mt20rpx">
+                  2025-03-26 11:56:07
+                </view>
+              </view>
+              <view class="box-border h176rpx w-full flex items-center justify-between rounded-16rpx bg-#F9F9F9">
+                <view class="box-border h-full w480rpx py28rpx pl20rpx">
+                  <scroll-view scroll-x class="h-full w-full whitespace-nowrap">
+                    <view class="flex items-center">
+                      <view v-for="item in 20" :key="item" class="mr50rpx">
+                        <image
+                          :src="`${StaticUrl}/shu.png`"
+                          class="h120rpx w120rpx"
+                        />
+                      </view>
+                    </view>
+                  </scroll-view>
+                </view>
+                <view class="box-shadow box-border h-full flex-1 flex-shrink-0 px14rpx py40rpx">
+                  <view class="text-32rpx text-#FF4D3A font-semibold">
+                    ¥13.95
+                  </view>
+                  <view class="text-center text-28rpx text-#AAAAAA">
+                    共5件
+                  </view>
+                </view>
+              </view>
+            </view>
+            <template #footer>
+              <view class="flex items-center justify-end">
+                <wd-button size="small" plain type="info">
+                  取消订单
+                </wd-button>
+                <view class="ml20rpx">
+                  <wd-button size="small" plain type="error">
+                    付款
+                  </wd-button>
+                </view>
+              </view>
+            </template>
+          </wd-card>
+        </view>
+        <view class="ios h30rpx" />
+      </scroll-view>
+    </view>
+  </view>
+</template>
+
+<style scoped lang="scss">
+.page-xsb {
+  :deep(){
+    .wd-button.is-plain.is-error{
+      color: #FF4D3A !important;
+    }
+  }
+  .box-shadow {
+    box-shadow: -6rpx 0rpx 6rpx 2rpx rgba(0,0,0,0.04);
+  }
+}
+</style>

+ 39 - 0
src/subPack-xsb/my/order/order-data.ts

@@ -0,0 +1,39 @@
+export const navTabTypeList = [
+  { name: '全部', value: 0 },
+  { name: '配送(外卖)', value: 1 },
+  { name: '快递', value: 2 },
+]
+
+export const orderStatusList = [
+  { name: '待支付', value: 0 },
+  { name: '待收获', value: 1 },
+  { name: '已完成', value: 5 },
+  { name: '已取消', value: 6 },
+]
+
+/**
+ * 订单状态文字统一处理
+ * @param order
+ *
+ */
+export function handleCommonOrderStatusText(order: any) {
+  return order
+}
+
+/**
+ * 统一待支付状态支付按钮逻辑处理
+ * @param order
+ */
+
+export function handleCommonOrderPay(order: any) {
+  return order
+}
+
+/**
+ *  统一取消订单逻辑处理
+ * @param order
+ */
+
+export function handleCommonCancelOrder(order: any) {
+  return order
+}

+ 257 - 0
src/subPack-xsb/my/orderDetaile/index.vue

@@ -0,0 +1,257 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+import router from '@/router'
+
+definePage({
+  name: 'xsb-orderDetaile',
+  style: {
+    navigationBarTitleText: '订单详情',
+  },
+})
+const collapse = ref(false)
+function handleCollapse() {
+  collapse.value = !collapse.value
+}
+</script>
+
+<template>
+  <view class="page-xsb">
+    <view class="px24rpx pt20rpx">
+      <view class="text-36rpx font-semibold">
+        <view>
+          <view>
+            请在 <text class="text-#FF4D3A">
+              14分59秒
+            </text> 内支付
+          </view>
+          <view class="mt20rpx text-28rpx text-#AAAAAA">
+            现在支付:预计10:40-10:55送达
+          </view>
+          <view class="mt20rpx flex items-center">
+            <view class="info-btn mr20rpx w226rpx">
+              <wd-button type="info" block>
+                取消订单1
+              </wd-button>
+            </view>
+            <view class="flex-1">
+              <wd-button block>
+                立即支付¥119
+              </wd-button>
+            </view>
+          </view>
+        </view>
+        <view class="flex items-center" @click="handleCollapse">
+          <view class="mr10rpx">
+            待商家接单
+          </view>
+          <view :class="[collapse ? 'rotate-90' : '']">
+            <wd-icon name="arrow-right" size="22px" />
+          </view>
+        </view>
+      </view>
+    </view>
+    <view class="mt20rpx">
+      <wd-card>
+        <view class="grid grid-cols-5 py24rpx text-28rpx text-#222">
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-del.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              删除订单
+            </view>
+          </view>
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-wx.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              联系商家
+            </view>
+          </view>
+          <view class="flex flex-col items-center" @click="router.push({ name: 'xsb-afterSales' })">
+            <image
+              :src="`${StaticUrl}/orderDetaile-shou.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              申请售后
+            </view>
+          </view>
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-pj.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              评价晒单
+            </view>
+          </view>
+          <view class="flex flex-col items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-bao.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx">
+              再次购买
+            </view>
+          </view>
+        </view>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card>
+        <view class="py28rpx">
+          <view class="flex items-center">
+            <image
+              :src="`${StaticUrl}/orderDetaile-user.png`"
+              class="mr20rpx h40rpx w40rpx"
+            />
+            <view class="text-32rpx text-#222 font-semibold">
+              杨先生 152****4972
+            </view>
+          </view>
+          <view class="mt20rpx text-28rpx text-#AAAAAA">
+            贵州省贵阳市观山湖区富力中心A7座
+          </view>
+        </view>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card>
+        <template #title>
+          <view class="flex items-center">
+            <image
+              :src="`${StaticUrl}/order-icon.png`"
+              class="h36rpx w36rpx"
+            />
+            <view class="ml20rpx text-32rpx font-semibold">
+              中数超市(富力中心店)
+            </view>
+          </view>
+          <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        </template>
+        <CollapsePanel :line-height="150">
+          <view v-for="item in 5" :key="item" class="mb20rpx w-full flex items-center">
+            <view class="mr20rpx w120rpx flex-shrink-0">
+              <image
+                :src="`${StaticUrl}/shu.png`"
+                class="h120rpx w120rpx"
+              />
+            </view>
+            <view class="flex-1">
+              <view class="w-full flex items-center justify-between font-semibold">
+                <view class="text-28rpx">
+                  赶海季生鲜大闸蟹
+                </view>
+                <view class="text-32rpx text-#FF4D3A">
+                  ¥103.95
+                </view>
+              </view>
+              <view class="text-24rpx text-#AAAAAA">
+                规格:5kg,盒
+              </view>
+              <view class="text-24rpx text-#AAAAAA">
+                ×1
+              </view>
+            </view>
+          </view>
+        </CollapsePanel>
+
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            商品金额
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            配送费(即时配送)
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx flex items-center justify-between">
+          <view class="text-28rpx">
+            积分(1400)
+          </view>
+          <view class="text-#FF4A39 font-semibold">
+            ¥54.00
+          </view>
+        </view>
+        <view class="mt24rpx h2rpx w-full bg-#F0F0F0" />
+        <template #footer>
+          <view class="flex items-center justify-end">
+            <view class="text-28rpx">
+              总计233.5 共减2.5
+            </view>
+            <view class="ml20rpx text-28rpx text-#FF4D3A font-semibold">
+              需付款¥54.00
+            </view>
+          </view>
+        </template>
+      </wd-card>
+    </view>
+    <view class="mt20rpx">
+      <wd-card title="订单信息">
+        <view class="pb20rpx">
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              订单编号
+            </view>
+            <view class="flex items-center">
+              <text class="text-#222">
+                1867402054587256856
+              </text>
+              <view class="ml10rpx">
+                <wd-icon name="file-copy" size="22px" />
+              </view>
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              支付方式
+            </view>
+            <view class="text-#222">
+              微信支付
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              下单时间
+            </view>
+            <view class="text-#222">
+              2024-12-13 11:12:30
+            </view>
+          </view>
+          <view class="mb28rpx flex items-center justify-between">
+            <view class="text-28rpx text-#AAAAAA">
+              备注信息
+            </view>
+            <view class="text-#222">
+              无
+            </view>
+          </view>
+        </view>
+      </wd-card>
+    </view>
+    <view class="h30rpx" />
+  </view>
+</template>
+
+<style scoped lang="scss">
+.page-xsb {
+  :deep(){
+    .info-btn .wd-button{
+      background: #fff !important;
+      color: #aaa !important;
+    }
+  }
+}
+</style>

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

@@ -0,0 +1,12 @@
+import { defineStore } from 'pinia'
+
+interface SysState {
+  ScrollDown: boolean
+}
+export const useSysXsbStore = defineStore('system-xsb', {
+  state: (): SysState => ({
+    ScrollDown: false,
+  }),
+  actions: {
+  },
+})

+ 11 - 0
src/subPack-xsb/store-xsb/tabbar.ts

@@ -0,0 +1,11 @@
+import { defineStore } from 'pinia'
+
+interface XsbTabbarState {
+
+}
+export const useXsbTabbarStore = defineStore('XsbTabbarStore', {
+  state: (): XsbTabbarState => ({
+  }),
+  actions: {
+  },
+})

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

@@ -6,7 +6,18 @@
 type _LocationUrl =
   "/pages/index/index" |
   "/pages/cart/index" |
-  "/pages/my/index";
+  "/pages/login/index" |
+  "/pages/my/index" |
+  "/subPack-xsb/cart/index" |
+  "/subPack-xsb/classfiy/index" |
+  "/subPack-xsb/goods/index" |
+  "/subPack-xsb/home/index" |
+  "/subPack-xsb/my/index" |
+  "/subPack-xsb/my/afterSales/index" |
+  "/subPack-xsb/my/afterSalesDetail/index" |
+  "/subPack-xsb/my/afterSalesList/index" |
+  "/subPack-xsb/my/order/index" |
+  "/subPack-xsb/my/orderDetaile/index";
 
 interface NavigateToOptions {
   url: _LocationUrl;

+ 2 - 2
src/utils/index.ts

@@ -11,10 +11,10 @@ export function getCurrentPath() {
 /**
  * 统一跳转小程序方法
  * @param appid
- * @param path
+ *
  */
 export function navCommonMiniProgram(appid: string) {
-  uni.openEmbeddedMiniProgram({
+  uni.navigateToMiniProgram({
     appId: appid,
   })
 }

+ 1 - 2
tsconfig.json

@@ -11,8 +11,7 @@
       "@mini-types/alipay",
       "miniprogram-api-typings",
       "@uni-helper/uni-types",
-      "wot-design-uni/global",
-      "uni-echarts/global"
+      "wot-design-uni/global"
     ],
     "sourceMap": true
   },

+ 12 - 10
vite.config.ts

@@ -1,15 +1,14 @@
 import process from 'node:process'
-import { defineConfig } from 'vite'
 import Uni from '@dcloudio/vite-plugin-uni'
-import UniHelperManifest from '@uni-helper/vite-plugin-uni-manifest'
-import UniHelperPages from '@uni-helper/vite-plugin-uni-pages'
-import UniHelperLayouts from '@uni-helper/vite-plugin-uni-layouts'
 import UniHelperComponents from '@uni-helper/vite-plugin-uni-components'
-import AutoImport from 'unplugin-auto-import/vite'
 import { WotResolver } from '@uni-helper/vite-plugin-uni-components/resolvers'
-import UniKuRoot from '@uni-ku/root'
-import { UniEchartsResolver } from 'uni-echarts/resolver'
+import UniHelperLayouts from '@uni-helper/vite-plugin-uni-layouts'
+import UniHelperManifest from '@uni-helper/vite-plugin-uni-manifest'
+import UniHelperPages from '@uni-helper/vite-plugin-uni-pages'
 import Optimization from '@uni-ku/bundle-optimizer'
+import UniKuRoot from '@uni-ku/root'
+import AutoImport from 'unplugin-auto-import/vite'
+import { defineConfig } from 'vite'
 // https://vitejs.dev/config/
 export default async () => {
   const UnoCSS = (await import('unocss/vite')).default
@@ -24,6 +23,9 @@ export default async () => {
       // https://github.com/uni-helper/vite-plugin-uni-pages
       UniHelperPages({
         dts: 'src/uni-pages.d.ts',
+        subPackages: [
+          'src/subPack-xsb',
+        ],
         /**
          * 排除的页面,相对于 dir 和 subPackages
          * @default []
@@ -34,9 +36,9 @@ export default async () => {
       UniHelperLayouts(),
       // https://github.com/uni-helper/vite-plugin-uni-components
       UniHelperComponents({
-        resolvers: [WotResolver(), UniEchartsResolver()],
+        resolvers: [WotResolver()],
         dts: 'src/components.d.ts',
-        dirs: ['src/components', 'src/business'],
+        dirs: ['src/components'],
         directoryAsNamespace: true,
       }),
       // https://github.com/uni-ku/root
@@ -59,7 +61,7 @@ export default async () => {
           imports: ['usePagination', 'useRequest'],
         }],
         dts: 'src/auto-imports.d.ts',
-        dirs: ['src/composables', 'src/store', 'src/utils', 'src/api'],
+        dirs: ['src/composables', 'src/store', 'src/utils', 'src/api', 'src/subPack-xsb/store-xsb'],
         vueTemplate: true,
       }),
       // https://github.com/antfu/unocss

Some files were not shown because too many files changed in this diff