فهرست منبع

Merge remote-tracking branch 'origin/master'

# Conflicts:
#	src/config/index.ts
zouzexu 1 هفته پیش
والد
کامیت
171d887b24
100فایلهای تغییر یافته به همراه12180 افزوده شده و 531 حذف شده
  1. 10 0
      .claude/settings.local.json
  2. 1 0
      .gitignore
  3. 108 0
      CLAUDE.md
  4. 12 2
      manifest.config.ts
  5. 2 0
      package.json
  6. 9 0
      pnpm-lock.yaml
  7. 16 2
      src/App.vue
  8. 2375 0
      src/api/api.type.d.ts
  9. 65 0
      src/api/apiDefinitions.ts
  10. 5 6
      src/api/core/instance.ts
  11. 6075 0
      src/api/globals.d.ts
  12. 2 0
      src/auto-imports.d.ts
  13. 2 0
      src/components.d.ts
  14. 15 0
      src/components/FixedLayout.vue
  15. 15 0
      src/components/PrivacyPopup.vue
  16. 1 10
      src/components/StatusTip.vue
  17. 1 0
      src/components/Zcontact.vue
  18. 14 14
      src/composables/useTabbar.ts
  19. 30 5
      src/config/index.ts
  20. 7 0
      src/env.d.ts
  21. BIN
      src/iconfont/iconfont.ttf
  22. BIN
      src/iconfont/iconfont.woff
  23. BIN
      src/iconfont/iconfont.woff2
  24. 15 0
      src/iconfont/index.css
  25. 6 9
      src/layouts/tabbar.vue
  26. 7 2
      src/manifest.json
  27. 91 1
      src/pages.json
  28. 6 4
      src/pages/cart/index.vue
  29. 3 3
      src/pages/classfiy/index.vue
  30. 106 95
      src/pages/index/index.vue
  31. 168 13
      src/pages/login/index.vue
  32. 17 14
      src/pages/my/index.vue
  33. 1 0
      src/shims.d.ts
  34. BIN
      src/static/tab/cart1.png
  35. BIN
      src/static/tab/cart2.png
  36. BIN
      src/static/tab/class-tab0.png
  37. BIN
      src/static/tab/class-tab1.png
  38. BIN
      src/static/tab/index.png
  39. BIN
      src/static/tab/index1.png
  40. BIN
      src/static/tab/index2.png
  41. BIN
      src/static/tab/my1.png
  42. BIN
      src/static/tab/my2.png
  43. 28 3
      src/store/address.ts
  44. 47 1
      src/store/sys.ts
  45. 94 1
      src/store/user.ts
  46. 11 18
      src/subPack-attractions/attractionsDetail/attractionsDetail.vue
  47. 5 0
      src/subPack-attractions/attractionsOrderPay/attractionsOrderPay.vue
  48. 3 1
      src/subPack-attractions/attractionsReservation/attractionsReservation.vue
  49. 2 2
      src/subPack-attractions/commonTab/components/homeList.vue
  50. 2 5
      src/subPack-attractions/commonTab/index.vue
  51. 10 10
      src/subPack-charge/chargeDetail/chargeDetail.vue
  52. 1 1
      src/subPack-charge/chargeMap/chargeMap.vue
  53. 2 2
      src/subPack-charge/chargeSiteDetail/chargeSiteDetail.vue
  54. 6 0
      src/subPack-charge/chargeVoucher/chargeVoucher.vue
  55. 3 2
      src/subPack-charge/components/charge-tab.vue
  56. 68 57
      src/subPack-charge/index/index.vue
  57. 15 1
      src/subPack-charge/utils/index.ts
  58. 114 10
      src/subPack-common/threePay/index.vue
  59. 72 0
      src/subPack-common/threePayRes/index.vue
  60. 61 4
      src/subPack-common/user-center/index.vue
  61. 6 7
      src/subPack-djk/commonTab/index.vue
  62. 6 0
      src/subPack-djk/confirmOrder/index.vue
  63. 5 0
      src/subPack-djk/orderDetaile/index.vue
  64. 36 39
      src/subPack-film/choose-film/index.vue
  65. 1 2
      src/subPack-film/choose-seat/components/pages/CanvasSeatmap.vue
  66. 16 9
      src/subPack-film/choose-seat/components/pages/canvasOperator.js
  67. 3 1
      src/subPack-film/choose-seat/components/pages/main.js
  68. 6 3
      src/subPack-film/choose-seat/index.vue
  69. 1 1
      src/subPack-film/components/choose-time.vue
  70. 13 11
      src/subPack-film/components/tabbar.vue
  71. 1 1
      src/subPack-film/index/index.vue
  72. 1 1
      src/subPack-film/movie/index.vue
  73. 159 0
      src/subPack-refueling/activityCenter/index.vue
  74. 130 0
      src/subPack-refueling/activityList/index.vue
  75. 106 0
      src/subPack-refueling/commonTab/components/index.vue
  76. 212 0
      src/subPack-refueling/commonTab/components/order.vue
  77. 199 0
      src/subPack-refueling/commonTab/components/voucher.vue
  78. 53 56
      src/subPack-refueling/commonTab/index.vue
  79. 441 0
      src/subPack-refueling/confirmOrder/index.vue
  80. 87 0
      src/subPack-refueling/exchangeFail/index.vue
  81. 130 0
      src/subPack-refueling/exchangeSuccess/index.vue
  82. 32 30
      src/subPack-refueling/orderDetail/index.vue
  83. 170 0
      src/subPack-refueling/paySuccess/index.vue
  84. 216 0
      src/subPack-refueling/refuelDetaile/index.vue
  85. 68 0
      src/subPack-refueling/transition/index.vue
  86. 259 0
      src/subPack-refueling/voucherDetail/index.vue
  87. 5 0
      src/subPack-smqjh/components/djk-order/index.vue
  88. 9 0
      src/subPack-smqjh/components/xsb-orderList/xsb-orderList.vue
  89. 2 2
      src/subPack-smqjh/order/components/OrderRenderer.vue
  90. 2 2
      src/subPack-smqjh/order/index.vue
  91. 5 5
      src/subPack-xsb/commonTab/components/cart.vue
  92. 13 12
      src/subPack-xsb/commonTab/components/classfiy.vue
  93. 11 11
      src/subPack-xsb/commonTab/components/index.vue
  94. 13 15
      src/subPack-xsb/commonTab/components/my.vue
  95. 10 17
      src/subPack-xsb/commonTab/index.vue
  96. 1 1
      src/subPack-xsb/components/goodsItem/index.vue
  97. 12 4
      src/subPack-xsb/confirmOrder/index.vue
  98. 1 1
      src/subPack-xsb/goods/index.vue
  99. 9 2
      src/subPack-xsb/orderDetaile/index.vue
  100. 1 0
      src/types/jz-h5-scanCode.d.ts

+ 10 - 0
.claude/settings.local.json

@@ -0,0 +1,10 @@
+{
+  "permissions": {
+    "allow": [
+      "WebFetch(domain:www.iconfont.cn)",
+      "WebSearch",
+      "Bash(curl -sL \"https://at.alicdn.com/t/c/font_4626013_vwpx4thmin.css\" -o /tmp/iconfont_cdn.css)",
+      "Read(//tmp/**)"
+    ]
+  }
+}

+ 1 - 0
.gitignore

@@ -11,6 +11,7 @@ dist
 node_modules
 async-import.d.ts
 async-component.d.ts
+smqjhh5
 
 # Executables
 *.swf

+ 108 - 0
CLAUDE.md

@@ -0,0 +1,108 @@
+# CLAUDE.md
+
+This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
+
+## Common Commands
+
+```bash
+# Development
+pnpm dev:h5                        # Start dev server for H5 (browser)
+pnpm dev:mp-weixin                 # Start dev server for WeChat Mini Program
+pnpm dev:app                       # Start dev server for native app
+
+# Build
+pnpm build:h5:production           # Build H5 for production
+pnpm build:h5:custom               # Build H5 to dist/smqjhh5
+pnpm build:mp-weixin               # Build for WeChat Mini Program
+
+# Code quality
+pnpm type-check                    # Run TypeScript type checking (vue-tsc --noEmit)
+pnpm lint                          # Run ESLint
+pnpm lint:fix                      # Run ESLint with auto-fix
+
+# API generation (auto-generates src/api/apiDefinitions.ts and src/api/globals.d.ts from OpenAPI spec)
+pnpm alova-gen                     # Run alova gen -f
+
+# Git
+pnpm commit                        # Run commitizen (git-cz) for conventional commits
+```
+
+## Architecture Overview
+
+This is a **uni-app 3.0** cross-platform project (Vue 3.4 + TypeScript) targeting WeChat Mini Program, H5, and native app. The project is "city-gather" (智慧社区/城市生活综合服务平台) — a multi-module city services platform.
+
+### Build & Toolchain
+
+- **Vite** with `@dcloudio/vite-plugin-uni` for cross-platform builds
+- **pnpm** 9.9.0 with Node >= 22
+- **UnoCSS** for utility-first styling (configured via `unocss.config.ts`)
+- **Sass** 1.78.0 as CSS preprocessor
+- **uni-mini-router** for routing (auto-generates routes from pages.json)
+- **@uni-ku/pages-json** for type-safe pages.json generation from the file system
+- **unplugin-auto-import** with auto-imports from: vue, @vueuse/core, pinia, uni-app, uni-mini-router, wot-design-uni, alova/client, plus all `src/composables`, `src/store`, `src/utils`, `src/api`, `src/subPack-xsb/store-xsb`
+
+### API Layer (`src/api/`)
+
+- Powered by **Alova 3.3.4** with `@alova/adapter-uniapp`
+- [src/api/core/instance.ts](src/api/core/instance.ts) creates the Alova instance with:
+  - Auto auth injection (Bearer token or fallback Basic auth)
+  - GET request cache busting via `_t` timestamp
+  - 60s timeout, no response caching
+- [src/api/core/handlers.ts](src/api/core/handlers.ts) handles responses: 401/403 triggers auto-logout; status >= 400 shows toast
+- [src/api/core/middleware.ts](src/api/core/middleware.ts) provides delay-loading and global-loading middleware
+- [src/api/apiDefinitions.ts](src/api/apiDefinitions.ts) is **auto-generated** by `alova-gen` from the backend OpenAPI spec — never edit manually
+- [src/api/createApis.ts](src/api/createApis.ts) creates a global `Apis` proxy object, auto-imported so `Apis.xxx.yyy()` works in any file
+- API types are in [src/api/globals.d.ts](src/api/globals.d.ts) (also auto-generated)
+
+### Routing (`src/router/`)
+
+- `uni-mini-router` generates routes from `pages.json` via `virtual:pages-json`
+- Route guard in [src/router/index.ts](src/router/index.ts) checks `islogin` from pages.json metadata
+- Pages without `islogin: true` are in the white-list; all other pages require authentication (redirects to `smqjh-login`)
+- Special handling for encoded QR-code scan parameters (`q` param)
+
+### State Management (`src/store/`)
+
+- **Pinia** with custom persist plugin ([src/store/persist.ts](src/store/persist.ts)) using `uni.getStorageSync`/`uni.setStorageSync`
+- Key stores: `user` (auth, profiles, addresses, unified payment/order actions), `system` (device info, navigation state), `theme` (follow-system dark/light mode), `cart`
+- Stores in `src/store/` are auto-imported via `unplugin-auto-import`, so `useUserStore()`, `useSysStore()` etc. are available globally without imports
+
+### Page Structure
+
+- **Main package** (5 pages in `src/pages/`): `index` (home), `classfiy`, `cart`, `my`, `login`
+- **10 sub-packages** (lazy-loaded): `subPack-xsb` (supermarket), `subPack-smqjh` (citizen marketplace), `subPack-film`, `subPack-charge` (EV charging), `subPack-attractions`, `subPack-refueling`, `subPack-djk` (health), `subPack-videoRights`, `subPack-common` (shared pages like address, after-sales, user-center, payment results)
+- Each sub-package is defined in `vite.config.ts` under `pagesJson.subPackageDirs`
+
+### Cross-Platform Conditional Compilation
+
+Uses uni-app preprocessor directives extensively:
+```js
+// #ifdef H5         — H5 only
+// #ifdef MP-WEIXIN   — WeChat Mini Program only
+// #ifndef MP-WEIXIN  — Not WeChat Mini Program
+```
+
+### Layout System
+
+- `@uni-helper/vite-plugin-uni-layouts` provides file-based layouts
+- [src/layouts/default.vue](src/layouts/default.vue) is the default layout with `addGlobalClass`, `virtualHost`, `styleIsolation: shared`
+- [src/layouts/tabbar.vue](src/layouts/tabbar.vue) for pages with the bottom tab bar
+
+### UI Framework
+
+- **Wot Design Uni** (`wot-design-uni`) for components (auto-resolved via `WotResolver`)
+- Custom components in `src/components/` are auto-registered via `@uni-helper/vite-plugin-uni-components`
+- Global composables for toast, message, loading (wrappers around uni/wot APIs)
+
+### Config (`src/config/`)
+
+- [src/config/index.ts](src/config/index.ts) dynamically selects `BASE_URL` based on:
+  - **H5**: uses `import.meta.env.MODE` (development → local/test server, production → production API)
+  - **WeChat Mini Program**: uses `uni.getAccountInfoSync().miniProgram.envVersion` (develop/trial/release)
+- Static assets served from Alibaba Cloud OSS (`StaticUrl`)
+
+### Commit Convention
+
+- **Conventional Commits** enforced via commitlint + commitizen
+- Pre-commit hook: `lint-staged` runs ESLint --fix on all files
+- Version releases: `pnpm release-patch`, `pnpm release-minor`, `pnpm release-major` (standard-version)

+ 12 - 2
manifest.config.ts

@@ -86,8 +86,18 @@ export default defineManifestConfig({
     usingComponents: true,
   },
   'h5': {
-    darkmode: true,
-    themeLocation: 'theme.json',
+    // darkmode: true,
+    // themeLocation: 'theme.json',
+    // router: {
+    //   mode: 'history',
+    // },
+    sdkConfigs: {
+      maps: {
+        qqmap: {
+          key: 'JO5BZ-QLVCJ-22OFQ-XNV4U-MHIWV-UCFQB',
+        },
+      },
+    },
   },
   'uniStatistics': {
     enable: false,

+ 2 - 0
package.json

@@ -35,6 +35,7 @@
     "build:custom": "uni build -p",
     "build:h5": "uni build",
     "build:h5:ssr": "uni build --ssr",
+    "build:h5:custom": "uni build -p h5 --outDir dist/smqjhh5",
     "build:h5:development": "uni build --mode development",
     "build:h5:staging": "uni build --mode staging",
     "build:h5:production": "uni build --mode production",
@@ -84,6 +85,7 @@
     "@vueuse/core": "^11.0.3",
     "alova": "^3.3.4",
     "echarts": "^6.0.0",
+    "jz-h5-scancode": "^1.1.0",
     "pinia": "^2.3.1",
     "uqrcodejs": "^4.0.7",
     "vue": "~3.4.38",

+ 9 - 0
pnpm-lock.yaml

@@ -82,6 +82,9 @@ importers:
       echarts:
         specifier: ^6.0.0
         version: 6.0.0
+      jz-h5-scancode:
+        specifier: ^1.1.0
+        version: 1.1.0
       pinia:
         specifier: ^2.3.1
         version: 2.3.1(typescript@5.5.4)(vue@3.4.38(typescript@5.5.4))
@@ -5089,6 +5092,10 @@ packages:
     resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==}
     engines: {'0': node >= 0.2.0}
 
+  jz-h5-scancode@1.1.0:
+    resolution: {integrity: sha512-R/B5G/oU5MgTy/n4gQOj+rgECraY2lFgcF7VprIn+gnXhdO5107IO9lgQata8BvMMnkKuJidM2ZX0fASmQLgqg==}
+    engines: {node: '>=12.0.0'}
+
   keyv@4.5.4:
     resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
 
@@ -13559,6 +13566,8 @@ snapshots:
 
   jsonparse@1.3.1: {}
 
+  jz-h5-scancode@1.1.0: {}
+
   keyv@4.5.4:
     dependencies:
       json-buffer: 3.0.1

+ 16 - 2
src/App.vue

@@ -4,15 +4,29 @@ import useUpdateManager from './composables/useUpdateManager'
 useUpdateManager()
 useSysStore().getSystemData()
 onLaunch(() => { })
+
+// 动态设置主题色 CSS 变量
+// #ifdef H5
+useSysStore().getThirdPartyThemeColor()
+// #endif
+const { themeVars } = storeToRefs(useManualThemeStore())
+const themeColor = computed(() => themeVars.value.colorTheme || '#9ED605')
+watch(themeColor, (val) => {
+  // #ifdef H5
+  document.documentElement.style.setProperty('--them-color', val)
+  // #endif
+}, { immediate: true })
 </script>
 
 <style lang="scss">
+@import '@/iconfont/index.css';
 .page-wraper {
   min-height: calc(100vh - var(--window-top));
   box-sizing: border-box;
   background: #f6f6f6;
+  /* #ifdef MP-WEIXIN */
   --them-color: #9ED605;
-
+  /* #endif */
   .upload {
     .wd-upload__preview {
       width: 120rpx !important;
@@ -40,7 +54,7 @@ onLaunch(() => { })
 }
 
 .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%);
+  background: linear-gradient(179deg, var(--them-color) 0%,  rgba(158, 214, 5, 0) 100%);
 }
 
 /* 隐藏滚动条安卓机会出现滚动条 */

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

@@ -4342,5 +4342,2380 @@ namespace Api {
     useStatus?: number
     [property: string]: any
   }
+  export interface QueryStorePriceRequest {
+  /**
+   * 门店id列表,最多10个
+   */
+    storeIds: string[]
+    /**
+     * 手机号
+     */
+    mobile: string
+    /**
+     * 用户标识
+     */
+    outUserId: string
+    /**
+     * 开放渠道,固定1即可
+     */
+    openChannel: number
+  }
+  export interface QueryStoreDetailRequest {
+  /**
+   * 门店id
+   */
+    storeId: string
+    /**
+     * 纬度
+     */
+    lat: number
+    /**
+     * 经度
+     */
+    lon: number
+    /**
+     * 外部用户id
+     */
+    outUserId?: string
+    /**
+     * 手机号
+     */
+    mobile?: string
+    /**
+     * 开放渠道,固定1即可
+     */
+    openChannel?: number
+  }
+  export interface PromotionInfo {
+  /**
+   * 小桔定义的津贴id
+   */
+    allowanceId?: string
+    /**
+     * 津贴类型,2-枪价券
+     */
+    allowanceType?: number
+  }
+  export interface QueryCalPriceRequest {
+  /**
+   * 门店id
+   */
+    storeId: string
+    /**
+     * 用户设备号,标识用户终端设备,可为空
+     */
+    deviceId?: string
+    /**
+     * 开放渠道,固定1即可
+     */
+    openChannel: number
+    /**
+     * 外部用户id,唯一标识用户,接入方需保证用户粒度唯一性
+     */
+    outUserId: string
+    /**
+     * 手机号
+     */
+    mobile: string
+    /**
+     * 油品名称,如:92#
+     */
+    itemName: string
+    /**
+     * 订单总金额、机显金额,单位分
+     */
+    amount: number
+    /**
+     * 优惠营销信息,非必填,目前只允许单次使用一张优惠券
+     */
+    promotionInfo?: PromotionInfo[]
+  }
+  export interface ItemInfo2 {
+  /**
+   * 油品名称,如:92#
+   */
+    itemName: string
+    /**
+     * 订单总金额、机显金额,单位分
+     */
+    amount: number
+  }
+  export interface PromotionInfo1 {
+  /**
+   * 小桔定义的津贴id
+   */
+    allowanceId?: string
+    /**
+     * 津贴类型,2-枪价券
+     */
+    allowanceType?: number
+  }
+  export interface QueryCalPricesRequest {
+  /**
+   * 门店id
+   */
+    storeId: string
+    /**
+     * 用户设备号,标识用户终端设备,可为空
+     */
+    deviceId?: string
+    /**
+     * 开放渠道,固定1即可
+     */
+    openChannel: number
+    /**
+     * 外部用户id,唯一标识用户,接入方需保证用户粒度唯一性
+     */
+    outUserId: string
+    /**
+     * 手机号
+     */
+    mobile: string
+    /**
+     * 油品、容量信息
+     */
+    itemList: ItemInfo2[]
+    /**
+     * 优惠营销信息,非必填,目前只允许单次使用一张优惠券
+     */
+    promotionInfo?: PromotionInfo1[]
+  }
+  export interface PromotionInfo2 {
+  /**
+   * 小桔定义的津贴id
+   */
+    allowanceId?: string
+    /**
+     * 津贴类型,2-枪价券
+     */
+    allowanceType?: number
+  }
+  export interface QueryNewOrderRequest {
+  /**
+   * 外部用户id,唯一标识用户
+   */
+    outUserId: string
+    /**
+     * 手机号
+     */
+    mobile: string
+    /**
+     * 模糊后手机号,例如135****9872
+     */
+    vagueMobile?: string
+    /**
+     * 外部订单号
+     */
+    outOrderId: string
+    /**
+     * 用户实时纬度
+     */
+    lat: number
+    /**
+     * 用户实时经度
+     */
+    lon: number
+    /**
+     * 门店id
+     */
+    storeId: string
+    /**
+     * 油号id
+     */
+    itemId: number
+    /**
+     * 枪号
+     */
+    gunNo: string
+    /**
+     * 订单总金额,单位分,价格查询接口返回的totalPrice
+     */
+    originalAmount: number
+    /**
+     * 订单支付金额,单位分,价格查询接口返回的realPrice
+     */
+    paymentAmount: number
+    /**
+     * 服务费,单位分,价格查询接口返回的serviceFee
+     */
+    serviceFee: number
+    /**
+     * 加油升数,单位毫升
+     */
+    litre: number
+    /**
+     * 小桔价、折扣价、优惠价,单位分
+     */
+    vipPrice: number
+    /**
+     * 门店价、油枪价、油机价,单位分
+     */
+    storePrice: number
+    /**
+     * 开放渠道,固定1即可
+     */
+    openChannel: number
+    /**
+     * 扩展参数,选填,接入方自定义,订单回调及查询会原样返回
+     */
+    openExtra?: string
+    /**
+     * 优惠营销信息,非必填
+     */
+    promotionInfo?: PromotionInfo2[]
+  }
+  export interface CancelOrderRequest {
+  /**
+   * 外部订单号
+   */
+    outOrderId: string
+    /**
+     * 小桔订单号
+     */
+    orderId: string
+    /**
+     * 外部用户号
+     */
+    outUserId: string
+  }
+  export interface GetPromotionRequest {
+  /**
+   * 手机号
+   */
+    mobile?: string
+    /**
+     * 外部用户id
+     */
+    outUserId?: string
+    /**
+     * 活动id
+     */
+    activityId?: string
+    /**
+     * 外部交易号
+     */
+    tradeNo?: string
+  }
+  export interface QueryOrderPromotionListRequest {
+  /**
+   * 手机号
+   */
+    mobile?: string
+    /**
+     * 外部用户id,唯一标识用户
+     */
+    outUserId?: string
+    /**
+     * 门店id,用于判断是否满足门店使用限制条件
+     */
+    storeId?: string
+    /**
+     * 订单金额,用于判断是否满足满减的条件,单位:分
+     */
+    orderAmount?: number
+    /**
+     * 津贴类型 2.枪价券
+     */
+    allowanceType?: number
+  }
+  export interface QueryUserPromotionListRequest {
+  /**
+   * 手机号
+   */
+    mobile?: string
+    /**
+     * 外部用户id,唯一标识用户
+     */
+    outUserId?: string
+    /**
+     * 津贴类型 2.枪价券
+     */
+    allowanceType?: number
+    /**
+     * 津贴状态 3.已使用、4.已过期、5.未使用
+     */
+    status?: number
+    /**
+     * 页码,从1开始
+     */
+    pageIndex?: number
+    /**
+     * 分页大小
+     */
+    pageSize?: number
+  }
+  export interface MapString {
+    key?: string
+  }
+  export interface XiaojuEncryptedRequest {
+  /**
+   * 应用标识
+   */
+    appKey?: string
+    /**
+     * 加密后的业务数据(AES-128-CBC加密)
+     */
+    data?: string
+    /**
+     * 请求唯一标识
+     */
+    requestId?: string
+    /**
+     * 签名(HMac-MD5,大写)
+     */
+    sig?: string
+    /**
+     * 时间戳(格式:yyyyMMddHHmmss)
+     */
+    timeStamp?: string
+  }
+  export interface GasStationQuery {
+  /**
+   * 页码
+   */
+    pageNum?: number
+    /**
+     * 每页记录数
+     */
+    pageSize?: number
+    /**
+     * 纬度(GCJ-02火星坐标系)
+     * 用户当前纬度
+     */
+    lat?: number
+    /**
+     * 经度(GCJ-02火星坐标系)
+     * 用户当前经度
+     */
+    lon?: number
+    /**
+     * 排序方式:0:价格排序,1:距离优先
+     */
+    sort?: number
+  }
+  export interface DistanceFenceQuery {
+  /**
+   * 用户当前纬度
+   */
+    lat?: number
+    /**
+     * 用户当前经度
+     */
+    lon?: number
+    /**
+     * 下单门店id
+     */
+    storeId?: string
+  }
+  export interface OilOrderPo {
+  /**
+   * 用户实时纬度
+   */
+    lat?: number
+    /**
+     * 用户实时经度
+     */
+    lon?: number
+    /**
+     * 门店id
+     */
+    storeId?: string
+    /**
+     * 油号id
+     */
+    itemId?: number
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 订单总金额,单位分,价格查询接口返回的totalPrice
+     */
+    originalAmount: number
+    /**
+     * 订单支付金额,单位分,价格查询接口返回的realPrice
+     */
+    paymentAmount: number
+    /**
+     * 服务费,单位分,价格查询接口返回的serviceFee
+     */
+    serviceFee?: number
+    /**
+     * 加油升数,单位毫升 价格查询接口返回的promotionAmount
+     */
+    litre?: number
+    /**
+     * 小桔价、折扣价、优惠价,单位分
+     */
+    vipPrice?: number
+    /**
+     * 门店价、油枪价、油机价,单位分
+     */
+    storePrice?: number
+    /**
+     * 发改委价格、国标价,单位分,查询油站站点详细信息接口返回cityPrice
+     */
+    cityPrice?: number
+    /**
+     * 优惠减免金额 价格查询接口返回的promotionAmount
+     */
+    promotionAmount?: number
+    /**
+     * 门店名称 查询油站站点详细信息storeName
+     */
+    storeName?: string
+    /**
+     * 城市 查询油站站点详细信息cityName
+     */
+    cityName?: string
+    /**
+     * 油品名称 查询门店价格itemName
+     */
+    itemName?: string
+    /**
+     * 优惠营销信息,非必填
+     */
+    promotionInfo?: PromotionInfo[]
+  }
+  export interface OmsOrderOilPageQuery {
+  /**
+   * 页码
+   */
+    pageNum?: number
+    /**
+     * 每页记录数
+     */
+    pageSize?: number
+    /**
+     * 订单状态:0全部,1-待支付,2-已支付,6-已退款,9-已取消
+     */
+    status?: number
+  }
+  export interface NotifyOrderInfoRequestDto {
+  /**
+   * 外部用户号(第三方平台UserId)
+   */
+    outUserId?: string
+    /**
+     * 订单号
+     */
+    orderId?: string
+    /**
+     * 门店id
+     */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 城市名称
+     */
+    cityName?: string
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 商品名称(油品名称)
+     */
+    itemName?: string
+    /**
+     * 商品升数
+     */
+    quantity?: string
+    /**
+     * 订单金额(单位:分)
+     */
+    totalMoney?: number
+    /**
+     * 实付金额(单位:分)
+     */
+    realMoney?: number
+    /**
+     * 订单状态:1-待支付,2-已支付,6-已退款,9-已取消
+     */
+    orderStatus?: number
+    /**
+     * 支付时间
+     */
+    payTime?: string
+    /**
+     * 退款时间(未退款时无退款时间)
+     */
+    refundTime?: string
+  }
+  export interface CouponInfoAppVo {
+  /**
+   * id
+   */
+    id?: string
+    /**
+     * 活动id
+     */
+    activityId?: string
+    /**
+     * 活动名称
+     */
+    activityName?: string
+    /**
+     * 优惠类型 1.满减、2.立减
+     */
+    promotionType?: number
+    /**
+     * 门槛(单位(分)) 满减时的需要达到什么金额
+     */
+    amountMoney?: number
+    /**
+     * 面额(单位(分)) 优惠的金额
+     */
+    discountMoney?: number
+    /**
+     * 库存
+     */
+    inventoryTotal?: number
+    /**
+     * 实际库存
+     */
+    inventoryActual?: number
+    /**
+     * 含税采购价(元)
+     */
+    purchasePrice?: number
+    /**
+     * 优惠券开始时间
+     */
+    couponStartTime?: string
+    /**
+     * 优惠券结束时间
+     */
+    couponEndTime?: string
+    /**
+     * 有效期,领取后多少天内有效(单位天)
+     */
+    expirationDate?: number
+    /**
+     * 创建时间
+     */
+    createTime?: string
+    /**
+     * 更新时间
+     */
+    updateTime?: string
+    /**
+     * 标识是否有领取数
+     */
+    receiveSign?: boolean
+    /**
+     * 过期时间
+     */
+    expirationTime?: string
+  }
+  export interface ResultListCouponInfoAppVo {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: CouponInfoAppVo[]
+    msg?: string
+  }
+  export interface CaptchaResult {
+  /**
+   * 验证码唯一标识(用于从Redis获取验证码Code)
+   */
+    captchaId?: string
+    /**
+     * 验证码图片Base64字符串
+     */
+    captchaBase64?: string
+  }
+  export interface ResultCaptchaResult {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CaptchaResult
+    msg?: string
+  }
+  export interface MemberVO {
+  /**
+   * 会员ID
+   */
+    id?: number
+    /**
+     * 会员昵称
+     */
+    nickName?: string
+    /**
+     * 会员头像地址
+     */
+    avatarUrl?: string
+    /**
+     * 会员手机号
+     */
+    mobile?: string
+    /**
+     * 会员余额(单位:分)
+     */
+    balance?: number
+    /**
+     * 所属企业ID
+     */
+    channelId?: number
+    /**
+     * 所属企业名称
+     */
+    channelName?: string
+    /**
+     * 配送费
+     */
+    freightFee?: number
+    /**
+     * 所属企业顶级ID
+     */
+    channelTopId?: number
+  }
+  export interface ResultMemberVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: MemberVO
+    msg?: string
+  }
+  export interface QueryTokenResponse {
+  /**
+   * token,有效期内可复用
+   */
+    accessToken?: string
+    /**
+     * 有效期,单位秒
+     */
+    availableTime?: number
+  }
+  export interface ResultQueryTokenResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryTokenResponse
+    msg?: string
+  }
+  export interface CheckOnPayOrderVO {
+  /**
+   * 小桔H5支付地址
+   */
+    payUrl?: string
+    orderId?: string
+  }
+  export interface ResultCheckOnPayOrderVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CheckOnPayOrderVO
+    msg?: string
+  }
+  export interface ResultBoolean {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: boolean
+    msg?: string
+  }
+  export interface AppMemberCouponVO {
+  /**
+   * id
+   */
+    id?: string
+    /**
+     * 第三方id
+     */
+    allowanceId?: string
+    /**
+     * 门槛(单位(元)) 满减时的需要达到什么金额
+     */
+    amountMoney?: number
+    /**
+     * 面额(单位(元)) 优惠的金额
+     */
+    discountMoney?: number
+    /**
+     * 使用状态:0-未使用 1-已使用 2-已过期
+     */
+    useStatus?: number
+    /**
+     * 锁定状态:0-未锁定/已释放 1-已锁定
+     */
+    lockStatus?: number
+    /**
+     * 锁定的订单ID
+     */
+    lockOrderId?: string
+    /**
+     * 过期时间
+     */
+    expirationTime?: string
+    /**
+     * 订单使用时间
+     */
+    orderCreateTime?: string
+  }
+  export interface DataAppMemberCouponVO {
+    list?: AppMemberCouponVO[]
+    total?: number
+  }
+  export interface PageResultAppMemberCouponVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: DataAppMemberCouponVO
+    /**
+     * 返回处理消息
+     */
+    msg?: string
+  }
+  export interface AppCouponDetailsVO {
+  /**
+   * id
+   */
+    id?: string
+    /**
+     * 门槛(单位(元)) 满减时的需要达到什么金额
+     */
+    amountMoney?: number
+    /**
+     * 第三方的津贴/券id
+     */
+    allowanceId?: string
+    /**
+     * 批次id
+     */
+    batchId?: string
+    /**
+     * 面额(单位(元)) 优惠的金额
+     */
+    discountMoney?: number
+    /**
+     * 使用状态:0-未使用 1-已使用 2-已过期
+     */
+    useStatus?: number
+    /**
+     * 锁定状态:0-未锁定/已释放 1-已锁定
+     */
+    lockStatus?: number
+    /**
+     * 领取时间
+     */
+    getTime?: string
+    /**
+     * 过期时间
+     */
+    expirationTime?: string
+    /**
+     * 订单使用时间
+     */
+    orderPayTime?: string
+    /**
+     * 锁定的订单ID
+     */
+    orderNumber?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 商品名称(油品名称)
+     */
+    itemName?: string
+    /**
+     * 订单金额(单位:分)
+     */
+    totalMoney?: number
+    /**
+     * 实付金额(单位:分)
+     */
+    realMoney?: number
+    /**
+     * 优惠减免金额
+     */
+    promotionAmount?: number
+    /**
+     * 下单时间
+     */
+    orderCreateTime?: string
+  }
+  export interface ResultAppCouponDetailsVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: AppCouponDetailsVO
+    msg?: string
+  }
+  export interface AppCouponOrderOptimalVO {
+  /**
+   * id
+   */
+    id?: string
+    /**
+     * 券Id
+     */
+    allowanceId?: string
+    /**
+     * 订单金额,单位:元
+     */
+    amountMoney?: number
+    /**
+     * 优惠金额,单位:元
+     */
+    discountMoney?: number
+    /**
+     * 优惠类型 1-满减,2-立减
+     */
+    promotionType?: number
+    /**
+     * 状态 1-可用;其他不可用
+     */
+    status?: number
+    /**
+     * 状态描述
+     */
+    statusDesc?: string
+    /**
+     * 限制使用优惠券,true:被限制
+     */
+    restrict?: boolean
+    /**
+     * 结束时间
+     */
+    expirationTime?: string
+  }
+  export interface AppMemberCouponOrderVO {
+    appCouponOrderOptimalVO?: AppCouponOrderOptimalVO
+    /**
+     * 可以用优惠劵
+     */
+    appCouponOrderVOList?: AppCouponOrderOptimalVO[]
+    /**
+     * 不可用优惠劵
+     */
+    appCouponNoOrderVOList?: AppCouponOrderOptimalVO[]
+  }
+  export interface ResultAppMemberCouponOrderVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: AppMemberCouponOrderVO
+    msg?: string
+  }
+  export interface DataCouponInfoAppVo {
+    list?: CouponInfoAppVo[]
+    total?: number
+  }
+  export interface PageResultCouponInfoAppVo {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: DataCouponInfoAppVo
+    /**
+     * 返回处理消息
+     */
+    msg?: string
+  }
+  export interface ResultCouponInfoAppVo {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CouponInfoAppVo
+    msg?: string
+  }
+  export interface CouponExchangeVo {
+  /**
+   * id
+   */
+    id?: string
+    /**
+     * 活动id
+     */
+    activityId?: string
+    /**
+     * 活动名称
+     */
+    activityName?: string
+    /**
+     * 优惠类型 1.满减、2.立减
+     */
+    promotionType?: number
+    /**
+     * 门槛(单位(分)) 满减时的需要达到什么金额
+     */
+    amountMoney?: number
+    /**
+     * 面额(单位(分)) 优惠的金额
+     */
+    discountMoney?: number
+    /**
+     * 积分金额
+     */
+    pointsMoney?: number
+    /**
+     * 总库存
+     */
+    inventoryTotal?: number
+    /**
+     * 实际库存
+     */
+    inventoryActual?: number
+    /**
+     * 优惠券开始时间
+     */
+    couponStartTime?: string
+    /**
+     * 优惠券结束时间
+     */
+    couponEndTime?: string
+    /**
+     * 有效期,领取后多少天内有效(单位天)
+     */
+    expirationDate?: number
+  }
+  export interface ResultCouponExchangeVo {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CouponExchangeVo
+    msg?: string
+  }
+  export interface CouponExchangePointsVo {
+  /**
+   * 抵扣券id
+   */
+    id?: string
+    /**
+     * 活动id
+     */
+    activityId?: string
+    /**
+     * 活动名称
+     */
+    activityName?: string
+    /**
+     * 门槛(单位(分)) 满减时的需要达到什么金额
+     */
+    amountMoney?: number
+    /**
+     * 面额(单位(分)) 优惠的金额
+     */
+    discountMoney?: number
+    /**
+     * 第三方的津贴/券id
+     */
+    allowanceId?: string
+    /**
+     * 批次id
+     */
+    batchId?: string
+    /**
+     * 有效期,领取后多少天内有效(单位天)
+     */
+    expirationDate?: number
+  }
+  export interface ResultCouponExchangePointsVo {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CouponExchangePointsVo
+    msg?: string
+  }
+  export interface Result {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: object
+    msg?: string
+  }
+  export interface TagInfo {
+  /**
+   * 标签类型,目前默认为0
+   */
+    type?: number
+    /**
+     * 标签位置,目前默认为0
+     */
+    location?: number
+    /**
+     * 图形类型,目前默认为0
+     */
+    iconType?: number
+    /**
+     * 标签名称
+     */
+    title?: string
+  }
+  export interface ItemInfo {
+  /**
+   * 油品名称,例如92#
+   */
+    itemName?: string
+    /**
+     * 油品id
+     */
+    itemId?: string
+    /**
+     * 发改委价格、国标价,单位分
+     */
+    cityPrice?: number
+    /**
+     * 门店价、油枪价、油机价,单位分
+     */
+    storePrice?: number
+    /**
+     * 小桔价、折扣价、优惠价,单位分
+     */
+    vipPrice?: number
+    /**
+     * 枪号列表
+     */
+    gunNos?: string[]
+    /**
+     * 优惠活动标签详情列表
+     */
+    tagList?: TagInfo[]
+    /**
+     * 小桔价、折扣价、优惠价,小程序显示的价格
+     */
+    vipPriceShow?: number
+    /**
+     * 发改委价格、国标价,小程序显示的价格
+     */
+    cityPriceShow?: number
+    /**
+     * 门店价、油枪价、油机价,小程序显示的价格
+     */
+    storePriceShow?: number
+  }
+  export interface QueryStorePriceResponse {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 油站禁止使用优惠券,0:禁止使用
+     */
+    allowanceClientScheme?: number
+    /**
+     * 油号信息列表
+     */
+    itemInfoList?: ItemInfo[]
+  }
+  export interface ResultListQueryStorePriceResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: QueryStorePriceResponse[]
+    msg?: string
+  }
+  export interface ItemInfo1 {
+  /**
+   * 油品名称,例如92#
+   */
+    itemName?: string
+    /**
+     * 油品id
+     */
+    itemId?: string
+    /**
+     * 发改委价格、国标价,单位分
+     */
+    cityPrice?: number
+    /**
+     * 门店价、油枪价、油机价,单位分
+     */
+    storePrice?: number
+    /**
+     * 小桔价、折扣价、优惠价,单位分
+     */
+    vipPrice?: number
+    /**
+     * 枪号列表
+     */
+    gunNos?: string[]
+    /**
+     * 优惠活动标签详情列表
+     */
+    tagList?: TagInfo[]
+    /**
+     * 小桔价、折扣价、优惠价,小程序显示的价格
+     */
+    vipPriceShow?: number
+    /**
+     * 发改委价格、国标价,小程序显示的价格
+     */
+    cityPriceShow?: number
+    /**
+     * 门店价、油枪价、油机价,小程序显示的价格
+     */
+    storePriceShow?: number
+  }
+  export interface QueryStoreDetailResponse {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 门店logo
+     */
+    storeLogo?: string
+    /**
+     * 门店图片列表
+     */
+    storePicList?: string[]
+    /**
+     * 城市
+     */
+    cityName?: string
+    /**
+     * 地址
+     */
+    address?: string
+    /**
+     * 经度
+     */
+    lon?: number
+    /**
+     * 纬度
+     */
+    lat?: number
+    /**
+     * 品牌
+     */
+    brandName?: string
+    /**
+     * 用户是否有未支付订单,0-否,1-是
+     */
+    orderInPay?: number
+    /**
+     * 油号信息列表
+     */
+    itemInfoList?: ItemInfo1[]
+  }
+  export interface ResultQueryStoreDetailResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryStoreDetailResponse
+    msg?: string
+  }
+  export interface QueryCalPriceResponse {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 实付金额,单位分
+     */
+    realPrice?: number
+    /**
+     * 订单总金额、机显金额,单位分
+     */
+    totalPrice?: number
+    /**
+     * 服务费,单位分
+     */
+    serviceFee?: number
+    /**
+     * 优惠减免金额,单位分
+     */
+    promotionAmount?: number
+    /**
+     * 加油容量,单位毫升
+     */
+    litre?: number
+    /**
+     * 油品名称,例如92#
+     */
+    itemName?: string
+  }
+  export interface ResultQueryCalPriceResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryCalPriceResponse
+    msg?: string
+  }
+  export interface ItemPrice {
+  /**
+   * 实付金额,单位分
+   */
+    realPrice?: number
+    /**
+     * 订单总金额、机显金额,单位分
+     */
+    totalPrice?: number
+    /**
+     * 服务费,单位分
+     */
+    serviceFee?: number
+    /**
+     * 优惠减免金额,单位分
+     */
+    promotionAmount?: number
+    /**
+     * 加油容量,单位毫升
+     */
+    litre?: number
+    /**
+     * 油品名称,例如92#
+     */
+    itemName?: string
+  }
+  export interface QueryCalPricesResponse {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 价格信息列表
+     */
+    itemList?: ItemPrice[]
+  }
+  export interface ResultQueryCalPricesResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryCalPricesResponse
+    msg?: string
+  }
+  export interface QueryNewOrderResponse {
+  /**
+   * 待支付单号,客户端页面又称tradeId
+   */
+    tradeNo?: string
+    /**
+     * 小桔订单号,客户端页面又称orderId
+     */
+    orderId?: string
+    /**
+     * 小桔H5支付地址
+     */
+    payUrl?: string
+  }
+  export interface ResultQueryNewOrderResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryNewOrderResponse
+    msg?: string
+  }
+  export interface CancelOrderResponse {
+  /**
+   * 取消订单结果:取消订单成功:null;取消订单失败:3001(订单已支付)、3002(订单已支付)、
+   */
+    opStatus?: number
+    /**
+     * 状态
+     */
+    success?: boolean
+    /**
+     * 消息
+     */
+    message?: string
+  }
+  export interface ResultCancelOrderResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: CancelOrderResponse
+    msg?: string
+  }
+  export interface PromotionInfoVo {
+  /**
+   * 津贴/券id
+   */
+    allowanceId?: string
+    /**
+     * 批次id
+     */
+    batchId?: string
+    /**
+     * 状态 1-已使用 2-可使用 5-已过期
+     */
+    status?: number
+  }
+  export interface GetPromotionResponse {
+  /**
+   * 津贴类型 2.枪价券
+   */
+    allowanceType?: number
+    /**
+     * 优惠类型 1.满减、2.立减
+     */
+    promotionType?: number
+    /**
+     * 优惠描述
+     */
+    promotionDesc?: string
+    /**
+     * 订单金额
+     */
+    amount?: number
+    /**
+     * 优惠金额 单位:分
+     */
+    discount?: number
+    /**
+     * 优惠券信息列表
+     */
+    promotionInfo?: PromotionInfoVo[]
+  }
+  export interface ResultListGetPromotionResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: GetPromotionResponse[]
+    msg?: string
+  }
+  export interface QueryOrderPromotionListResponse {
+  /**
+   * 券Id
+   */
+    allowanceId?: string
+    /**
+     * 优惠描述
+     */
+    promotionDesc?: string
+    /**
+     * 订单金额,单位:分
+     */
+    amount?: number
+    /**
+     * 优惠金额,单位:分
+     */
+    discount?: number
+    /**
+     * 优惠类型 1-满减,2-立减
+     */
+    promotionType?: number
+    /**
+     * 状态 1-可用;其他不可用
+     */
+    status?: number
+    /**
+     * 状态描述
+     */
+    statusDesc?: string
+    /**
+     * 限制使用优惠券,true:被限制
+     */
+    restrict?: boolean
+    /**
+     * 可用时间-开始,秒级时间戳
+     */
+    startTimestamp?: string
+    /**
+     * 可用时间-结束,秒级时间戳
+     */
+    endTimestamp?: string
+  }
+  export interface ResultListQueryOrderPromotionListResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: QueryOrderPromotionListResponse[]
+    msg?: string
+  }
+  export interface UserPromotionInfo {
+  /**
+   * 小桔定义的津贴id
+   */
+    allowanceId?: string
+    /**
+     * 优惠描述
+     */
+    promotionDesc?: string
+    /**
+     * 订单金额,单位:分
+     */
+    amount?: number
+    /**
+     * 优惠金额,单位:分
+     */
+    discount?: number
+    /**
+     * 优惠类型 1.满减、2.立减
+     */
+    promotionType?: number
+    /**
+     * 可用时间-开始,秒级时间戳
+     */
+    startTimestamp?: string
+    /**
+     * 可用时间-结束,秒级时间戳
+     */
+    endTimestamp?: string
+    /**
+     * 状态 1.可用;其他不可用
+     */
+    status?: number
+    /**
+     * 状态描述
+     */
+    statusDesc?: string
+  }
+  export interface QueryUserPromotionListResponse {
+  /**
+   * 页码
+   */
+    pageIndex?: number
+    /**
+     * 分页大小
+     */
+    pageSize?: number
+    /**
+     * 总记录数
+     */
+    totalSize?: number
+    /**
+     * 总页数
+     */
+    totalPage?: number
+    /**
+     * 优惠券信息列表
+     */
+    data?: UserPromotionInfo[]
+  }
+  export interface ResultQueryUserPromotionListResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryUserPromotionListResponse
+    msg?: string
+  }
+  export interface ResultString {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    /**
+     * 返回数据对象
+     */
+    data?: string
+    msg?: string
+  }
+  export interface ReceiveGasStationResponse {
+  /**
+   * 接收是否成功
+   */
+    success?: boolean
+    /**
+     * 信息提示
+     */
+    msg?: string
+  }
+  export interface ResultReceiveGasStationResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: ReceiveGasStationResponse
+    msg?: string
+  }
+  export interface NotifyOrderInfoResponse {
+  /**
+   * 接收是否成功:0-不成功,1-成功
+   */
+    state?: number
+    /**
+     * 信息提示
+     */
+    message?: string
+  }
+  export interface ResultNotifyOrderInfoResponse {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: NotifyOrderInfoResponse
+    msg?: string
+  }
+  export interface GasStationDetailVO {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 门店logo
+     */
+    storeLogo?: string
+    /**
+     * 门店图片列表
+     */
+    storePicList?: string[]
+    /**
+     * 城市
+     */
+    cityName?: string
+    /**
+     * 地址
+     */
+    address?: string
+    /**
+     * 经度
+     */
+    lon?: number
+    /**
+     * 纬度
+     */
+    lat?: number
+    /**
+     * 品牌
+     */
+    brandName?: string
+    /**
+     * 用户是否有未支付订单,0-否,1-是
+     */
+    orderInPay?: number
+    /**
+     * 油号信息列表
+     */
+    itemInfoList?: ItemInfo[]
+    /**
+     * 前端距离显示千米
+     */
+    distanceShow?: number
+    /**
+     * 油站禁止使用优惠券
+     */
+    allowanceClientScheme?: boolean
+  }
+  export interface ResultGasStationDetailVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: GasStationDetailVO
+    msg?: string
+  }
+  export interface GasStationVO {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 地址
+     */
+    address?: string
+    /**
+     * 品牌
+     */
+    brandName?: string
+    /**
+     * 小桔价、折扣价、优惠价,单位分
+     */
+    vipPrice?: number
+    /**
+     * 油品名称,例如92#
+     */
+    itemName?: string
+    /**
+     * 距离
+     */
+    distance?: number
+    /**
+     * 前端距离显示千米
+     */
+    distanceShow?: number
+    /**
+     * 纬度(GCJ-02火星坐标系)
+     */
+    lat?: number
+    /**
+     * 经度(GCJ-02火星坐标系)
+     */
+    lon?: number
+    /**
+     * 差值
+     */
+    maxPriceDiff?: number
+    /**
+     * 油站禁止使用优惠券
+     */
+    allowanceClientScheme?: boolean
+  }
+  export interface DataGasStationVO {
+    list?: GasStationVO[]
+    total?: number
+  }
+  export interface PageResultGasStationVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: DataGasStationVO
+    /**
+     * 返回处理消息
+     */
+    msg?: string
+  }
+  export interface DistanceStoreVO {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 品牌
+     */
+    brandName?: string
+    /**
+     * 距离
+     */
+    distance?: number
+    /**
+     * 前端距离显示千米
+     */
+    distanceShow?: number
+    /**
+     * 纬度(GCJ-02火星坐标系)
+     */
+    lat?: number
+    /**
+     * 经度(GCJ-02火星坐标系)
+     */
+    lon?: number
+  }
+  export interface DistanceFenceVO {
+  /**
+   * 是否有更近的油站标识,true弹框提示,false继续下一步
+   */
+    isClosest?: boolean
+    /**
+     * 有更近标识时次集合有两条数据,第一条最近油站,当前下单油站
+     */
+    storeVOS?: DistanceStoreVO[]
+  }
+  export interface ResultDistanceFenceVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: DistanceFenceVO
+    msg?: string
+  }
+  export interface QueryCalPriceVO {
+  /**
+   * 门店id
+   */
+    storeId?: string
+    /**
+     * 实付金额,单位分
+     */
+    realPrice?: number
+    /**
+     * 订单总金额、机显金额,单位分
+     */
+    totalPrice?: number
+    /**
+     * 服务费,单位分
+     */
+    serviceFee?: number
+    /**
+     * 优惠减免金额,单位分
+     */
+    promotionAmount?: number
+    /**
+     * 加油容量,单位毫升
+     */
+    litre?: number
+    /**
+     * 油品名称,例如92#
+     */
+    itemName?: string
+    /**
+     * 实付金额,前端显示
+     */
+    realPriceShow?: number
+    /**
+     * 订单总金额、机显金额,前端显示
+     */
+    totalPriceShow?: number
+    /**
+     * 服务费,前端显示
+     */
+    serviceFeeShow?: number
+    /**
+     * 优惠减免金额,前端显示
+     */
+    promotionAmountShow?: number
+    /**
+     * 加油容量,前端显示
+     */
+    litreShow?: number
+  }
+  export interface ResultQueryCalPriceVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: QueryCalPriceVO
+    msg?: string
+  }
+  export interface OmsOrderOilPageVO {
+  /**
+   * 订购流水号
+   */
+    orderNumber?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 商品名称(油品名称)
+     */
+    itemName?: string
+    /**
+     * 品牌
+     */
+    brandName?: string
+    /**
+     * 实付金额
+     */
+    realMoney?: number
+    /**
+     * 订单金额
+     */
+    totalMoney?: number
+    /**
+     * 订单状态:1-待支付,2-已支付,6-已退款,9-已取消
+     */
+    oilOrderStatus?: number
+    /**
+     * 合作方订单号
+     */
+    thirdOrderId?: string
+    /**
+     * 付款时间
+     */
+    payTime?: string
+    /**
+     * 退款时间
+     */
+    refundTime?: string
+    /**
+     * 下单时间
+     */
+    createTime?: string
+    /**
+     * 取消时间
+     */
+    cancelTime?: string
+    /**
+     * 订单过期时间
+     */
+    expireTime?: string
+    /**
+     * 小桔H5支付地址
+     */
+    payUrl?: string
+    /**
+     * 微信交易号
+     */
+    transactionId?: string
+  }
+  export interface DataOmsOrderOilPageVO {
+    list?: OmsOrderOilPageVO[]
+    total?: number
+  }
+  export interface PageResultOmsOrderOilPageVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: DataOmsOrderOilPageVO
+    /**
+     * 返回处理消息
+     */
+    msg?: string
+  }
+  export interface PayResultInfoVO {
+  /**
+   * 订单金额
+   */
+    totalMoney?: number
+    /**
+     * 平台订单号
+     */
+    orderNumber?: string
+    /**
+     * 三方订单号
+     */
+    thirdOrderId?: string
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 加油量
+     */
+    quantity?: number
+    /**
+     * 品牌名称
+     */
+    brandName?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 油品
+     */
+    itemName?: string
+  }
+  export interface ResultPayResultInfoVO {
+  /**
+   * 返回状态码
+   */
+    code?: string
+    data?: PayResultInfoVO
+    msg?: string
+  }
+  export interface OmsDjkOrderAttach {
+    createTime?: string
+    updateTime?: string
+    /**
+     * 订单号
+     */
+    orderNumber?: string
+    /**
+     * 大健康订单类型 0-正常订单 1-福利订单
+     */
+    djkOrderType?: number
+    /**
+     * 商品id
+     */
+    goodsId?: number
+    /**
+     * 商品图
+     */
+    goodsImg?: string
+    /**
+     * 商品名
+     */
+    goodsName?: string
+    /**
+     * 商品编码
+     */
+    goodsCode?: string
+    /**
+     * 价格
+     */
+    price?: number
+    /**
+     * 商品数量
+     */
+    goodsNum?: number
+    /**
+     * 有效时间(天)
+     */
+    effectiveTime?: number
+    /**
+     * 提前预约时间(天)
+     */
+    advanceBookingTime?: number
+    /**
+     * 活动名称
+     */
+    activityName?: string
+    /**
+     * 客户授权
+     */
+    customerAuthorization?: number
+    /**
+     * 过期时间
+     */
+    expiredTime?: string
+    /**
+     * 核销时间
+     */
+    verificationTime?: string
+    /**
+     * 核销人
+     */
+    verificationPerson?: string
+    /**
+     * 核销门店
+     */
+    verificationShop?: string
+    /**
+     * 退款单号
+     */
+    refundNo?: string
+    /**
+     * 退款原因
+     */
+    refundReason?: string
+    /**
+     * 退款描述
+     */
+    refundDesc?: string
+    /**
+     * 退款图片
+     */
+    refundImg?: string
+    /**
+     * 提交退款时间
+     */
+    submitRefundTime?: string
+    /**
+     * 退款到账时间
+     */
+    refundTime?: string
+    /**
+     * 订单备注
+     */
+    remark?: string
+  }
+  export interface OmsOrderItem {
+  /**
+   * 用户Id
+   */
+    memberId?: number
+    /**
+     * 店铺id
+     */
+    shopId?: number
+    /**
+     * 订单order_number
+     */
+    orderNumber?: string
+    /**
+     * 产品ID
+     */
+    prodId?: number
+    /**
+     * 产品SkuID
+     */
+    skuId?: number
+    /**
+     * 购物车产品个数
+     */
+    prodCount?: number
+    /**
+     * 产品名称
+     */
+    prodName?: string
+    /**
+     * sku名称
+     */
+    skuName?: string
+    /**
+     * 产品主图片路径
+     */
+    pic?: string
+    /**
+     * spec
+     */
+    spec?: string
+    /**
+     * 产品价格
+     */
+    price?: number
+    /**
+     * 商品小计
+     */
+    productTotalAmount?: number
+    /**
+     * 购物时间
+     */
+    recTime?: string
+    /**
+     * 使用积分
+     */
+    useScore?: number
+    /**
+     * 获得积分
+     */
+    gainScore?: number
+  }
+  export interface OmsOrderMovieItem {
+  /**
+   * 订单order_number
+   */
+    orderNumber?: string
+    /**
+     * 座位名称
+     */
+    name?: string
+    /**
+     * 票码
+     */
+    ticketCode?: string
+    /**
+     * 二维码
+     */
+    pic?: string
+    /**
+     * 区域类型(1-普通区域, 2-特殊区域 3-贵宾区)
+     */
+    areaType?: string
+    /**
+     * 使用状态(未使用, :已使用, :已过期)
+     */
+    status?: number
+    /**
+     * 产品价格
+     */
+    price?: number
+    /**
+     * 购物时间
+     */
+    recTime?: string
+  }
+  export interface ChargeOrderPo {
+  /**
+   * 用户ID
+   */
+    memberId?: number
+    /**
+     * 订购流水号
+     */
+    orderNumber?: string
+    /**
+     * 充电订单状态:
+     */
+    status?: number
+    /**
+     * 备注
+     */
+    remarks?: string
+    /**
+     * 充电订单号
+     */
+    chargeOrderNo?: string
+    /**
+     * 开始充电时间
+     */
+    startTime?: string
+    /**
+     * 结束充电时间
+     */
+    endTime?: string
+    /**
+     * 第三方充电站ID
+     */
+    stationId?: string
+    /**
+     * 充电时间:秒
+     */
+    chargeTime?: number
+    /**
+     * 实际充电度数(单位:0.001 kw/h)
+     */
+    totalCharge?: number
+    /**
+     * 平台实际收取金额
+     */
+    realCost?: number
+    /**
+     * 平台总服务费
+     */
+    realServiceCost?: number
+    /**
+     * 预充值金额
+     */
+    preAmt?: number
+    /**
+     * 充电设备接口编码
+     */
+    connectorId?: string
+    chargeOrderId?: string
+    /**
+     * 电站名称
+     */
+    powerStationName?: string
+    /**
+     * 三方电费
+     */
+    totalMoney?: number
+    /**
+     * 充电度数
+     */
+    totalPower?: number
+    /**
+     * 0:用户手动停止充电;1:客户归属地运营商平台停止充电;2:BMS停止充电;3:充电机设备故障;4:连接器断开;其它:自定义
+     */
+    stopMethod?: number
+  }
+  export type Key = object
+  export interface JSONObject {
+    key?: object
+  }
+  export interface OmsDjkOrderLog {
+    createTime?: string
+    updateTime?: string
+    /**
+     * 订单号
+     */
+    orderNumber?: string
+    /**
+     * 操作
+     */
+    operation?: string
+    /**
+     * 操作员
+     */
+    operator?: string
+    /**
+     * 订单备注
+     */
+    remark?: string
+  }
+  export interface OmsVirtualOrderItem {
+    createTime?: string
+    updateTime?: string
+    /**
+     * 订购流水号,关联主订单
+     */
+    orderNumber?: string
+    /**
+     * 用户ID
+     */
+    memberId?: number
+    /**
+     * 渠道ID
+     */
+    channelId?: number
+    /**
+     * 商品编号(本地pms_video_product.product_number)
+     */
+    productNumber?: string
+    /**
+     * 第三方商品编码(pms_video_product.product_id)
+     */
+    productId?: string
+    /**
+     * 商品名称
+     */
+    productName?: string
+    /**
+     * 商品类型:卡密/直充
+     */
+    productType?: string
+    /**
+     * 面值
+     */
+    faceValue?: number
+    /**
+     * 采购价(成本)
+     */
+    purchasePrice?: number
+    /**
+     * 销售价(从pms_video_channel_price获取)
+     */
+    sellPrice?: number
+    /**
+     * 充值账号(直充类)
+     */
+    rechargeAccount?: string
+    /**
+     * 账号类型:1手机号 2QQ号 0其他
+     */
+    accountType?: number
+    /**
+     * 充值状态:0待处理 1处理中 2成功 3失败
+     */
+    rechargeStatus?: number
+    /**
+     * 第三方平台订单号
+     */
+    thirdOrderNo?: string
+    /**
+     * 卡密信息JSON(卡密类商品,需解密)
+     */
+    cardInfo?: string
+    /**
+     * 第三方接口原始返回JSON
+     */
+    thirdResponse?: string
+  }
+  export interface DJKShopInfoVo {
+  /**
+   * 门店id
+   */
+    shopId?: number
+    /**
+     * shop_logo
+     */
+    shopLogo?: string
+    /**
+     * 门店名称
+     */
+    shopName?: string
+    /**
+     * shop_lat
+     */
+    shopLat?: number
+    /**
+     * shop_lng
+     */
+    shopLng?: number
+    /**
+     * tel
+     */
+    tel?: string
+  }
+  export interface OmsOrderOilVO {
+  /**
+   * 小桔订单号
+   */
+    xjOrderId?: string
+    /**
+     * 门店ID
+     */
+    storeId?: string
+    /**
+     * 门店名称
+     */
+    storeName?: string
+    /**
+     * 城市名称
+     */
+    cityName?: string
+    /**
+     * 枪号
+     */
+    gunNo?: string
+    /**
+     * 商品名称(油品名称)
+     */
+    itemName?: string
+    /**
+     * 油号id
+     */
+    itemId?: number
+    /**
+     * 商品升数
+     */
+    quantity?: number
+    /**
+     * 订单金额(单位:分)
+     */
+    totalMoney?: number
+    /**
+     * 实付金额(单位:分)
+     */
+    realMoney?: number
+    /**
+     * 订单状态:1-待支付,2-已支付,6-已退款,9-已取消
+     */
+    orderStatus?: number
+    /**
+     * 支付时间
+     */
+    payTime?: string
+    /**
+     * 退款时间
+     */
+    refundTime?: string
+    /**
+     * 服务费
+     */
+    serviceFee?: number
+    /**
+     * 优惠减免金额
+     */
+    promotionAmount?: number
+    /**
+     * 发改委价格、国标价
+     */
+    cityPrice?: number
+    /**
+     * 门店价、油枪价、油机价
+     */
+    storePrice?: number
+    /**
+     * 品牌名称
+     */
+    brandName?: string
+    /**
+     * 油站地址
+     */
+    address?: string
+    /**
+     * 优惠卷名称
+     */
+    activityName?: string
+    /**
+     * 优惠卷id
+     */
+    allowanceId?: string
+    /**
+     * 小桔H5支付地址
+     */
+    payUrl?: string
+    /**
+     * 小桔价、折扣价、优惠价
+     */
+    vipPrice?: number
+  }
 
 }

+ 65 - 0
src/api/apiDefinitions.ts

@@ -36,6 +36,7 @@ export default {
   'sys.updateUserInfo': ['PUT', '/smqjh-system/app-api/v1/members/{memberId}'],
   'sys.selectZhUser': ['GET', '/smqjh-system/app-api/v1/claim/select'],
   'sys.zhUserReceived': ['POST', '/smqjh-system/app-api/v1/claim/received'],
+  'sys.appAccess': ['GET', '/smqjh-system/app-api/v1/appAccess/{accessId}'],
   'sys.userVipInfo':['GET', '/smqjh-system/app-api/v1/member/current'],
   'sys.giftsList': ['GET', '/smqjh-system/app-api/v1/member/gifts'],
   'sys.giftsReceive': ['POST', '/smqjh-system/app-api/v1/member/gifts/receive'],
@@ -148,4 +149,68 @@ export default {
   'attractions.orderList':['GET','/smqjh-oms/app-api/v1/order/scenic/list'],
   'attractions.orderDetail':['GET','/smqjh-oms/app-api/v1/order/scenic/detail'],
   'attractions.cancelOrder':['POST','/smqjh-oms/app-api/v1/order/scenic/cancel'],
+
+    'app.get_smqjh_system_app_api_membercoupon_page': ['GET', '/smqjh-system/app-api/memberCoupon/page'],
+  'app.get_smqjh_system_app_api_membercoupon_findbyid': ['GET', '/smqjh-system/app-api/memberCoupon/findById'],
+  'app.get_smqjh_system_app_api_membercoupon_findplaceorderlist': [
+    'GET',
+    '/smqjh-system/app-api/memberCoupon/findPlaceOrderList'
+  ],
+  'app.get_smqjh_system_app_api_coupon_page': ['GET', '/smqjh-system/app-api/coupon/page'],
+  'app.get_smqjh_system_app_api_coupon_findbyid': ['GET', '/smqjh-system/app-api/coupon/findById'],
+  'app.get_smqjh_system_app_api_coupon_exchangeinfo': ['GET', '/smqjh-system/app-api/coupon/exchangeInfo'],
+  'app.get_smqjh_system_app_api_coupon_exchangepoints': ['GET', '/smqjh-system/app-api/coupon/exchangePoints'],
+  'app.get_smqjh_system_app_api_coupon_findlist': ['GET', '/smqjh-system/app-api/coupon/findList'],
+  'general.post_smqjh_auth_oauth2_token': ['POST', '/smqjh-auth/oauth2/token'],
+  'general.post_smqjh_auth_api_v1_auth_sms_code': ['POST', '/smqjh-auth/api/v1/auth/sms_code'],
+  'general.get_smqjh_system_app_api_v1_members_me': ['GET', '/smqjh-system/app-api/v1/members/me'],
+  'general.post_smqjh_pms_api_v1_refueling_querytoken': ['POST', '/smqjh-pms/api/v1/refueling/queryToken'],
+  'general.post_smqjh_pms_api_v1_refueling_querystoreprice': ['POST', '/smqjh-pms/api/v1/refueling/queryStorePrice'],
+  'general.post_smqjh_pms_api_v1_refueling_querystoredetail': ['POST', '/smqjh-pms/api/v1/refueling/queryStoreDetail'],
+  'general.post_smqjh_pms_api_v1_refueling_querycalprice': ['POST', '/smqjh-pms/api/v1/refueling/queryCalPrice'],
+  'general.post_smqjh_pms_api_v1_refueling_querycalprices': ['POST', '/smqjh-pms/api/v1/refueling/queryCalPrices'],
+  'general.post_smqjh_pms_api_v1_refueling_queryneworder': ['POST', '/smqjh-pms/api/v1/refueling/queryNewOrder'],
+  'general.post_smqjh_pms_api_v1_refueling_cancelorder': ['POST', '/smqjh-pms/api/v1/refueling/cancelOrder'],
+  'general.post_smqjh_pms_api_v1_refueling_getpromotion': ['POST', '/smqjh-pms/api/v1/refueling/getPromotion'],
+  'general.post_smqjh_pms_api_v1_refueling_queryorderpromotionlist': [
+    'POST',
+    '/smqjh-pms/api/v1/refueling/queryOrderPromotionList'
+  ],
+  'general.post_smqjh_pms_api_v1_refueling_queryuserpromotionlist': [
+    'POST',
+    '/smqjh-pms/api/v1/refueling/queryUserPromotionList'
+  ],
+  'general.post_smqjh_pms_api_v1_refueling_generateqrcode': ['POST', '/smqjh-pms/api/v1/refueling/generateQrCode'],
+  'general.post_smqjh_pms_api_v1_refueling_receivinggasstation': [
+    'POST',
+    '/smqjh-pms/api/v1/refueling/receivingGasStation'
+  ],
+  'general.post_smqjh_pms_api_v1_refueling_notifyorderinfo': ['POST', '/smqjh-pms/api/v1/refueling/notifyOrderInfo'],
+  'general.post_smqjh_pms_app_api_v1_product_oil_savepushproductoil': [
+    'POST',
+    '/smqjh-pms/app-api/v1/product_oil/savePushProductOil'
+  ],
+  'general.post_smqjh_pms_app_api_v1_product_oil_querystoredetail': [
+    'POST',
+    '/smqjh-pms/app-api/v1/product_oil/queryStoreDetail'
+  ],
+  'general.post_smqjh_pms_app_api_v1_product_oil_page': ['POST', '/smqjh-pms/app-api/v1/product_oil/page'],
+  'general.post_smqjh_pms_app_api_v1_product_oil_querydistancefence': [
+    'POST',
+    '/smqjh-pms/app-api/v1/product_oil/queryDistanceFence'
+  ],
+  'general.post_smqjh_pms_app_api_v1_product_oil_querycalprice': [
+    'POST',
+    '/smqjh-pms/app-api/v1/product_oil/queryCalPrice'
+  ],
+  'general.post_smqjh_oms_api_v1_oil_order_createorder': ['POST', '/smqjh-oms/api/v1/oil/order/createOrder'],
+  'general.post_smqjh_oms_api_v1_oil_order_findoilorderpage': ['POST', '/smqjh-oms/api/v1/oil/order/findOilOrderPage'],
+  'general.post_smqjh_oms_api_v1_oil_order_cancel': ['POST', '/smqjh-oms/api/v1/oil/order/cancel'],
+  'general.post_smqjh_oms_api_v1_oil_order_pay': ['POST', '/smqjh-oms/api/v1/oil/order/pay'],
+  'general.post_smqjh_oms_api_v1_oil_order_invoiceorder': ['POST', '/smqjh-oms/api/v1/oil/order/invoiceOrder'],
+  'general.get_smqjh_oms_api_v1_oil_order_payresultinfo': ['GET', '/smqjh-oms/api/v1/oil/order/payResultInfo'],
+  'general.post_smqjh_oms_api_v1_oil_order_refundorder': ['POST', '/smqjh-oms/api/v1/oil/order/refundOrder'],
+  'general.post_smqjh_oms_api_v1_oil_order_findbypayurl': ['POST', '/smqjh-oms/api/v1/oil/order/findByPayUrl'],
+  'general.get_smqjh_oms_api_v1_order_orderinfo': ['GET', '/smqjh-oms/api/v1/order/orderInfo'],
+
 };

+ 5 - 6
src/api/core/instance.ts

@@ -13,12 +13,13 @@ export const alovaInstance = createAlova({
     if (['POST', 'PUT', 'PATCH'].includes(method.type)) {
       method.config.headers['Content-Type'] = 'application/json'
     }
-    // if (['POST', 'PUT', 'PATCH', 'DELETE', 'GET'].includes(method.type)) {
-    //   method.config.headers['X-Tenant-Domain'] = BASE_URL
-    // }
     const { token } = useUserStore()
     method.config.headers.Authorization = token || 'Basic c21xamgtYXBwbGV0OjEyMzQ1Ng=='
-    // Add timestamp to prevent caching for GET requests
+    const { tenantCode } = storeToRefs(useSysStore())
+    const code = tenantCode.value || 'zswl'
+    method.config.headers['X-Tenant-code'] = code
+    console.log(code, 'tenantCode======================')
+
     if (method.type === 'GET' && CommonUtil.isObj(method.config.params)) {
       method.config.params._t = Date.now()
     }
@@ -29,8 +30,6 @@ export const alovaInstance = createAlova({
         `[Alova Request] ${method.type} ${method.url}`,
         method.data || method.config.params,
       )
-      // console.log(`[API Base URL] ${import.meta.env.VITE_API_BASE_URL}`);
-      // console.log(`[Environment] ${import.meta.env.VITE_ENV_NAME}`);
     }
     console.log(
       BASE_URL,

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 6075 - 0
src/api/globals.d.ts


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

@@ -54,6 +54,7 @@ declare global {
   const getCurrentPath: typeof import('./utils/index')['getCurrentPath']
   const getCurrentScope: typeof import('vue')['getCurrentScope']
   const h: typeof import('vue')['h']
+  const hexToRgba: typeof import('./utils/index')['hexToRgba']
   const ignorableWatch: typeof import('@vueuse/core')['ignorableWatch']
   const inject: typeof import('vue')['inject']
   const injectLocal: typeof import('@vueuse/core')['injectLocal']
@@ -421,6 +422,7 @@ declare module 'vue' {
     readonly getCurrentPath: UnwrapRef<typeof import('./utils/index')['getCurrentPath']>
     readonly getCurrentScope: UnwrapRef<typeof import('vue')['getCurrentScope']>
     readonly h: UnwrapRef<typeof import('vue')['h']>
+    readonly hexToRgba: UnwrapRef<typeof import('./utils/index')['hexToRgba']>
     readonly ignorableWatch: UnwrapRef<typeof import('@vueuse/core')['ignorableWatch']>
     readonly inject: UnwrapRef<typeof import('vue')['inject']>
     readonly injectLocal: UnwrapRef<typeof import('@vueuse/core')['injectLocal']>

+ 2 - 0
src/components.d.ts

@@ -8,6 +8,7 @@ export {}
 declare module 'vue' {
   export interface GlobalComponents {
     CollapsePanel: typeof import('./components/CollapsePanel.vue')['default']
+    FixedLayout: typeof import('./components/FixedLayout.vue')['default']
     GlobalLoading: typeof import('./components/GlobalLoading.vue')['default']
     GlobalMessage: typeof import('./components/GlobalMessage.vue')['default']
     GlobalToast: typeof import('./components/GlobalToast.vue')['default']
@@ -48,6 +49,7 @@ declare module 'vue' {
     WdStatusTip: typeof import('wot-design-uni/components/wd-status-tip/wd-status-tip.vue')['default']
     WdStep: typeof import('wot-design-uni/components/wd-step/wd-step.vue')['default']
     WdSteps: typeof import('wot-design-uni/components/wd-steps/wd-steps.vue')['default']
+    WdSticky: typeof import('wot-design-uni/components/wd-sticky/wd-sticky.vue')['default']
     WdSwiper: typeof import('wot-design-uni/components/wd-swiper/wd-swiper.vue')['default']
     WdTab: typeof import('wot-design-uni/components/wd-tab/wd-tab.vue')['default']
     WdTabbar: typeof import('wot-design-uni/components/wd-tabbar/wd-tabbar.vue')['default']

+ 15 - 0
src/components/FixedLayout.vue

@@ -0,0 +1,15 @@
+<script setup lang="ts">
+
+</script>
+
+<template>
+  <view class="ios fixed bottom-0 box-border w-full bg-white px24rpx">
+    <view class="pb20rpx pt10rpx">
+      <slot />
+    </view>
+  </view>
+</template>
+
+<style scoped>
+
+</style>

+ 15 - 0
src/components/PrivacyPopup.vue

@@ -26,6 +26,7 @@ function privacyHandler(resolve: any) {
 }
 
 onBeforeMount(() => {
+  // #ifdef MP-WEIXIN
   // 注册监听
   if (wx.onNeedPrivacyAuthorization) {
     wx.onNeedPrivacyAuthorization((resolve: any) => {
@@ -34,6 +35,7 @@ onBeforeMount(() => {
       }
     })
   }
+  // #endif
 })
 
 /**
@@ -68,7 +70,9 @@ function handleDisagree() {
  * 打开隐私协议
  */
 function openPrivacyContract() {
+  // #ifdef MP-WEIXIN
   wx.openPrivacyContract({})
+  // #endif
 }
 
 /**
@@ -109,6 +113,7 @@ export default {
         <button id="disagree-btn" class="is-block is-round is-medium is-plain wd-privacy-popup__footer-disagree wd-button" @click="handleDisagree">
           拒绝
         </button>
+        <!-- #ifdef MP-WEIXIN -->
         <button
           id="agree-btn"
           class="wd-button is-block is-round is-medium is-primary wd-privacy-popup__footer-agree"
@@ -117,6 +122,16 @@ export default {
         >
           同意
         </button>
+        <!-- #endif -->
+        <!-- #ifndef MP-WEIXIN -->
+        <button
+          id="agree-btn"
+          class="wd-button is-block is-round is-medium is-primary wd-privacy-popup__footer-agree"
+          @click="handleAgree"
+        >
+          同意
+        </button>
+        <!-- #endif -->
       </view>
     </wd-popup>
   </view>

+ 1 - 10
src/components/StatusTip.vue

@@ -1,22 +1,13 @@
 <script setup lang="ts">
 import { statusTipProps } from 'wot-design-uni/components/wd-status-tip/types'
-import { StaticUrl } from '@/config'
 
 const props = defineProps({ ...statusTipProps, image: { type: String, default: '' }, imageSize: { type: String, default: '248rpx' } })
-const imgs = computed(() => {
-  if (props.image)
-    return `${StaticUrl}/${props.image}`
-  return `${StaticUrl}/status-tip.png`
-})
 </script>
 
 <template>
   <wd-status-tip v-bind="props">
     <template #image>
-      <image
-        :style="{ width: imageSize, height: imageSize }"
-        :src="imgs"
-      />
+      <i class="iconfont text-[var(--them-color)]" :style="{ fontSize: imageSize }">&#xe659;</i>
     </template>
   </wd-status-tip>
 </template>

+ 1 - 0
src/components/Zcontact.vue

@@ -13,6 +13,7 @@
   all: unset;
   &::after{
     border: none;
+    width: 0 !important;
   }
 }
 </style>

+ 14 - 14
src/composables/useTabbar.ts

@@ -1,10 +1,3 @@
-import icon3 from '@/static/tab/cart1.png'
-import icon4 from '@/static/tab/cart2.png'
-import icon5 from '@/static/tab/my1.png'
-import icon6 from '@/static/tab/my2.png'
-import class1 from '@/static/tab/class-tab0.png'
-import class2 from '@/static/tab/class-tab1.png'
-
 export interface TabbarItem {
   name: string
   value: number | null
@@ -12,17 +5,26 @@ export interface TabbarItem {
   title: string
   icon2: string
   icon1: string
+  isShow: boolean
 }
 
 const tabbarItems = ref<TabbarItem[]>([
-  { name: 'smqjh-home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
-  { name: 'smqjh-classfiy', value: null, active: false, title: '分类', icon1: class1, icon2: class2 },
-  { name: 'smqjh-cart', value: null, active: false, title: '购物车', icon1: icon3, icon2: icon4 },
-  { name: 'smqjh-my', value: null, active: false, title: '我的', icon1: icon5, icon2: icon6 },
+  { name: 'smqjh-home', value: null, active: true, title: '首页', icon1: '', icon2: '', isShow: true },
+  { name: 'smqjh-classfiy', value: null, active: false, title: '分类', icon1: '', icon2: '', isShow: true },
+  { name: 'smqjh-cart', value: null, active: false, title: '购物车', icon1: '', icon2: '', isShow: true },
+  { name: 'smqjh-my', value: null, active: false, title: '我的', icon1: '', icon2: '', isShow: true },
 ])
 
 export function useTabbar() {
-  const tabbarList = computed(() => tabbarItems.value)
+  const { isOnlineAudit } = storeToRefs(useSysStore())
+  const tabbarList = computed(() => {
+    if (isOnlineAudit.value) {
+      return tabbarItems.value.filter(item => item.name !== 'smqjh-classfiy')
+    }
+    else {
+      return tabbarItems.value
+    }
+  })
 
   const activeTabbar = computed(() => {
     const item = tabbarItems.value.find(item => item.active)
@@ -35,8 +37,6 @@ export function useTabbar() {
   }
 
   const setTabbarItem = (name: string, value: number) => {
-    console.log('设置市民请集合购物车数量===========================')
-
     const tabbarItem = tabbarItems.value.find(item => item.name === name)
     if (tabbarItem) {
       tabbarItem.value = value

+ 30 - 5
src/config/index.ts

@@ -8,11 +8,10 @@ const mapEnvVersion = {
   // develop: 'http://192.168.1.253:8080',
   // develop: 'http://192.168.0.19:8080', // 邓
   // develop: 'http://192.168.1.20:8080', // 黄
-  // develop: 'http://192.168.0.11:8080', // 王
+  // develop: 'http://192.168.0.11:8081', // 王
   // develop: 'http://192.168.1.21:8080', // 田
   // develop: 'http://74949mkfh190.vicp.fun', // 付
   // develop: 'http://47.109.84.152:8081', // 测试代理
-  // develop: 'http://192.168.1.242:8080', // 测试直连
   // develop: 'https://5ed0f7cc.r9.vip.cpolar.cn',
   // develop: 'https://25740642.r3.cpolar.top',
   develop: 'https://smqjh.api.zswlgz.com',
@@ -21,9 +20,10 @@ const mapEnvVersion = {
    */
   // trial: "http://192.168.1.166:8080/jeecg-boot",
   // trial: 'http://192.168.0.157:8080',
-  // trial: 'http://47.109.84.152:8081',
+  trial: 'http://47.109.84.152:8081',
+  // trial: 'http://192.168.0.11:8081', // 王
   // trial: 'http://192.168.1.166:8080,
-  trial: 'https://smqjh.api.zswlgz.com',
+  // trial: 'https://smqjh.api.zswlgz.com',
   /**
    * 正式版
    */
@@ -34,10 +34,35 @@ const mapEnvVersion = {
  * Base URL请求基本url
  */
 export const BASE_URL
-  = mapEnvVersion[uni.getAccountInfoSync().miniProgram.envVersion]
+  = handleEnvVersion()
 
 /**
  * 静态资源服务
  */
 
 export const StaticUrl = 'https://zswl-smqjh.oss-cn-chengdu.aliyuncs.com/static/static'
+
+function handleEnvVersion() {
+  // #ifdef H5
+  const mode = import.meta.env.MODE
+  const h5Server = {
+    development: 'http://47.109.84.152:8081',
+    // development: 'http://192.168.0.157:8080',
+    // development: 'http://192.168.0.11:8081',
+    // development: 'http://192.168.1.21:8080',
+    // development: 'https://smqjh.api.zswlgz.com',
+    // production: 'https://smqjh.api.zswlgz.com',
+    production: 'http://47.109.84.152:8081',
+  }
+  console.log(mode, '==================mode===================')
+  return h5Server[mode as 'development' | 'production']
+  // #endif
+  // #ifdef MP-WEIXIN
+  return mapEnvVersion[uni.getAccountInfoSync().miniProgram.envVersion]
+  // #endif
+}
+
+/**
+ * h5小橘重定向地址
+ */
+export const REDIRECT_URL = 'https://smqjh.h5.zswlgz.com/#/subPack-refueling/commonTab/index'

+ 7 - 0
src/env.d.ts

@@ -1 +1,8 @@
 /// <reference types="vite/client" />
+
+declare module '*.vue' {
+  import type { DefineComponent } from 'vue'
+
+  const component: DefineComponent<Record<string, never>, Record<string, never>, any>
+  export default component
+}

BIN
src/iconfont/iconfont.ttf


BIN
src/iconfont/iconfont.woff


BIN
src/iconfont/iconfont.woff2


+ 15 - 0
src/iconfont/index.css

@@ -0,0 +1,15 @@
+@font-face {
+  font-family: "iconfont"; /* Project id 5175205 */
+  src: url('iconfont.woff2?t=1778556699734') format('woff2'),
+       url('iconfont.woff?t=1778556699734') format('woff'),
+       url('iconfont.ttf?t=1778556699734') format('truetype'),
+       url('iconfont.svg?t=1778556699734#iconfont') format('svg');
+}
+
+.iconfont {
+  font-family: "iconfont" !important;
+  font-size: 16px;
+  font-style: normal;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+}

+ 6 - 9
src/layouts/tabbar.vue

@@ -1,13 +1,9 @@
 <script lang="ts" setup>
-import icon2 from '@/static/tab/index1.png'
-import icon1 from '@/static/tab/index2.png'
-
 const router = useRouter()
 const route = useRoute()
 const { opcity } = storeToRefs(useSysStore())
 
 const { activeTabbar, getTabbarItemValue, setTabbarItemActive, tabbarList } = useTabbar()
-
 function handleTabbarChange({ value }: { value: string }) {
   setTabbarItemActive(value)
   router.pushTab({ name: value })
@@ -55,15 +51,16 @@ export default {
       >
         <template #icon="{ active }">
           <template v-if="index == 0 && !active">
-            <image src="@/static/tab/index.png" class="h44rpx w44rpx" />
+            <i class="iconfont text-44rpx">&#xe629;</i>
           </template>
           <template v-else-if="index == 0 && active">
-            <image v-if="opcity == 1" :src="icon1" class="h76rpx w76rpx" @click="handleClick" />
-            <image v-else :src="icon2" class="h76rpx w76rpx" />
+            <i v-if="opcity == 1" class="iconfont text-76rpx text-[var(--them-color)]" @click="handleClick">&#xe62b;</i>
+            <i v-else class="iconfont text-76rpx text-[var(--them-color)]">&#xe648;</i>
           </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" />
+            <text :class="[active ? 'text-[var(--them-color)]' : '']" class="iconfont text-44rpx">
+              {{ item.icon1 }}
+            </text>
           </template>
         </template>
       </wd-tabbar-item>

+ 7 - 2
src/manifest.json

@@ -84,7 +84,12 @@
   },
   "vueVersion": "3",
   "h5": {
-    "darkmode": true,
-    "themeLocation": "theme.json"
+    "sdkConfigs": {
+      "maps": {
+        "qqmap": {
+          "key": "JO5BZ-QLVCJ-22OFQ-XNV4U-MHIWV-UCFQB"
+        }
+      }
+    }
   }
 }

+ 91 - 1
src/pages.json

@@ -281,6 +281,16 @@
             "navigationBarTitleText": "支付"
           }
         },
+        {
+          "path": "threePayRes/index",
+          "name": "common-threePayRes",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "支付结果",
+            "navigationStyle": "custom",
+            "disableScroll": true
+          }
+        },
         {
           "path": "user-center/index",
           "name": "common-user-center",
@@ -655,6 +665,24 @@
     {
       "root": "subPack-refueling",
       "pages": [
+        {
+          "path": "activityCenter/index",
+          "name": "activityCenter-detail",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "活动详情",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "activityList/index",
+          "name": "activityList",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "活动中心",
+            "navigationStyle": "custom"
+          }
+        },
         {
           "path": "commonTab/index",
           "name": "refueling-tabbar",
@@ -664,7 +692,34 @@
           }
         },
         {
-          "path": "orderDetaile/index",
+          "path": "confirmOrder/index",
+          "name": "confimOrder",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "下单",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "exchangeFail/index",
+          "name": "exchangeFail",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "支付",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "exchangeSuccess/index",
+          "name": "exchangeSuccess",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "支付",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "orderDetail/index",
           "name": "refueling-orderDetail",
           "islogin": true,
           "style": {
@@ -672,6 +727,41 @@
             "navigationStyle": "custom"
           }
         },
+        {
+          "path": "paySuccess/index",
+          "name": "paySuccess",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "支付",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "refuelDetaile/index",
+          "name": "refuelDetaile",
+          "islogin": false,
+          "style": {
+            "navigationBarTitleText": "加油站详情"
+          }
+        },
+        {
+          "path": "transition/index",
+          "name": "transition",
+          "islogin": false,
+          "style": {
+            "navigationBarTitleText": "",
+            "navigationStyle": "custom"
+          }
+        },
+        {
+          "path": "voucherDetail/index",
+          "name": "voucherDetail",
+          "islogin": true,
+          "style": {
+            "navigationBarTitleText": "抵扣券详情",
+            "navigationStyle": "custom"
+          }
+        },
         {
           "path": "webView/index",
           "name": "refueling-webview",

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

@@ -55,7 +55,8 @@ async function handleSelectAddress() {
           <view class="mr-20rpx text-36rpx font-semibold">
             购物车
           </view>
-          <image :src="`${StaticUrl}/location-green.png`" class="h-33.8rpx w-29rpx" />
+          <!-- <image :src="`${StaticUrl}/location-green.png`" class="h-33.8rpx w-29rpx" /> -->
+          <image :src="`${StaticUrl}/location-black.png`" class="h-33.8rpx min-w-28.97rpx w-28.97rpx" />
           <view class="ml-10rpx max-w-280rpx truncate text-32rpx text-[#222] font-semibold">
             {{ smqjhSelectedAddress?.city || '请选择地址' }}
           </view>
@@ -133,7 +134,7 @@ async function handleSelectAddress() {
                     <!-- <wd-input-number v-model="item.num" disable-input @change="handleChangeNum($event, item)" /> -->
                     <view class="flex items-center">
                       <image
-                        :src="` ${StaticUrl}/sub-cart.png`"
+                        :src="`${StaticUrl}/sub-cart.png`"
                         class="h-44rpx w-44rpx"
                         @click.stop="cartStore.cartSubGoods(item)"
                       />
@@ -141,7 +142,7 @@ async function handleSelectAddress() {
                         {{ item.num }}
                       </view>
                       <image
-                        :src="` ${StaticUrl}/add-cart.png`"
+                        :src="`${StaticUrl}/add-cart.png`"
                         class="h-44rpx w-44rpx"
                         @click.stop="cartStore.cartAddGoods(item)"
                       />
@@ -165,7 +166,8 @@ async function handleSelectAddress() {
 
         <view v-if="!cartList.length" class="box-border w-full flex items-center justify-center">
           <view class="mt-220rpx flex flex-col items-center">
-            <image :src="`${StaticUrl}/cart.png`" class="h-110rpx w-110rpx" />
+            <!-- <image :src="`${StaticUrl}/cart.png`" class="h-110rpx w-110rpx" /> -->
+            <i class="iconfont text-110rpx text-[var(--them-color)]">&#xe64d;</i>
             <view class="mb-20rpx mt-20rpx text-24rpx">
               你还没有添加商品哦~
             </view>

+ 3 - 3
src/pages/classfiy/index.vue

@@ -37,14 +37,14 @@ getCategories()
     >
       <template #left>
         <view class="ml10rpx flex items-center" @click.stop="useAddressStore().getMapAddress()">
-          <image :src="`${StaticUrl}/location-green.png`" class="h33.8rpx w29rpx" />
-          <view class="ml10rpx max-w-280rpx truncate text-32rpx text-#222 font-semibold">
+          <!-- <image :src="`${StaticUrl}/location-green.png`" class="h33.8rpx w29rpx" /> -->
+          <image :src="`${StaticUrl}/location-black.png`" class="h-33.8rpx min-w-28.97rpx w-28.97rpx" />          <view class="ml10rpx max-w-280rpx truncate text-32rpx text-#222 font-semibold">
             {{ name }}
           </view>
         </view>
       </template>
     </wd-navbar>
-    <view class="h176rpx bg-#F4FFD1" />
+    <view class="header-linear h176rpx" />
     <view class="wraper">
       <scroll-view class="w200rpx" :scroll-into-view-offset="-150" enable-passive scroll-with-animation scroll-y :scroll-into-view="`id${active}`">
         <view v-for="item in classfiylist" :id="`id${item.id}`" :key="item.id" :class="[item.id == active ? 'bg-white' : '']" class="relative h100rpx flex items-center justify-center whitespace-nowrap text-28rpx">

+ 106 - 95
src/pages/index/index.vue

@@ -18,7 +18,7 @@ definePage({
 const { show } = useGlobalToast()
 
 const addressStore = useAddressStore()
-const { statusBarHeight, MenuButtonHeight, opcity, isOnlineAudit } = storeToRefs(useSysStore())
+const { statusBarHeight, MenuButtonHeight, opcity, isOnlineAudit, thirdPartyLogo } = storeToRefs(useSysStore())
 const { name } = storeToRefs(addressStore)
 const { userInfo, userMemberInfo } = storeToRefs(useUserStore())
 const xsbStore = ref<typeof import('@/subPack-xsb/store-xsb/sys')>()
@@ -97,10 +97,15 @@ function handleClick(name: string) {
     return
   }
   if (name === 'refueling-tabbar') { // 跳转至公众号
+    // #ifdef MP-WEIXIN
     ;(wx as any).openOfficialAccountProfile({
       username: 'gh_6a682fa2ed1d',
     })
+    // #endif
 
+    // #ifdef H5
+    router.push({ name: 'refueling-tabbar' })
+    // #endif
     return
   }
 
@@ -132,26 +137,34 @@ function handleGo() {
   router.push({ name: 'bannerDetaile' })
 }
 function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
-  console.log(e.detail.current, 'e.detail.current')
-
   currentIndex.value = e.detail.current
 }
 function handleJyBanner() {
+  // #ifdef MP-WEIXIN
   wx.openOfficialAccountArticle({
     url: 'https://mp.weixin.qq.com/s/lxpdZ6DUhgqg00AT9klu5Q',
   })
+  // #endif
+  // #ifdef H5
+  window.open('https://mp.weixin.qq.com/s/lxpdZ6DUhgqg00AT9klu5Q')
+  // #endif
 }
 </script>
 
 <template>
   <view class="page-class box-border">
     <wd-navbar
-      title="" :custom-style="`background-color: rgba(158,214,5,${opcity});`" :bordered="false" :z-index="99"
+      title="" :custom-style="`background-color: ${hexToRgba(useManualThemeStore().themeVars.colorTheme as string, opcity)};`" :bordered="false" :z-index="99"
       safe-area-inset-top fixed
     >
       <template #left>
         <view class="relative z-10 h-48rpx w-202rpx w-full opacity-100">
+          <!-- #ifdef MP-WEIXIN -->
           <image class="absolute left-0 top-0 h-48rpx w-202rpx" :src="`${StaticUrl}/logo.png`" />
+          <!-- #endif -->
+          <!-- #ifdef H5 -->
+          <image class="absolute left-0 top-0 h-48rpx w-202rpx" :src="thirdPartyLogo" />
+          <!-- #endif -->
         </view>
       </template>
     </wd-navbar>
@@ -160,14 +173,14 @@ function handleJyBanner() {
       class="header-linear h-320rpx px-24rpx"
       :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
     >
-      <view class="box-border flex items-center">
+      <view class="box-border w-full flex items-center">
         <view class="flex items-center" @click="useAddressStore().getMapAddress()">
           <image :src="`${StaticUrl}/location-black.png`" class="h-33.8rpx min-w-28.97rpx w-28.97rpx" />
           <view class="ml-18rpx max-w-180rpx truncate text-32rpx">
             {{ name }}
           </view>
         </view>
-        <view class="ml-16rpx h-60rpx w-502rpx flex items-center justify-between rounded-40rpx bg-white pr-6rpx">
+        <view class="ml-16rpx h-60rpx flex flex-1 items-center justify-between rounded-40rpx bg-white pr-6rpx">
           <view class="flex items-center pb-14rpx pl-24rpx pt-16rpx">
             <wd-icon name="search" size="14" color="#ccc" />
             <view class="ml-12rpx text-24rpx text-gray">
@@ -205,11 +218,11 @@ function handleJyBanner() {
           <!-- h340rpx -->
           <swiper :duration="300" :style="swiperStyle" class="transition-height" @change="handleChangeSwiper">
             <swiper-item
-              v-for="pageIndex in Math.ceil(navList.filter(i => i.show).length / 8)" :key="pageIndex"
+              v-for="pageIndex in Math.ceil(navList.filter((i: any) => i.show).length / 8)" :key="pageIndex"
             >
               <view class="grid grid-cols-4 gap-12rpx">
                 <template
-                  v-for="item in navList.filter(i => i.show).slice((pageIndex - 1) * 8, pageIndex * 8)"
+                  v-for="item in navList.filter((i: any) => i.show).slice((pageIndex - 1) * 8, pageIndex * 8)"
                   :key="item.icon"
                 >
                   <view
@@ -234,7 +247,7 @@ function handleJyBanner() {
             </swiper-item>
           </swiper>
           <view class="w-full flex items-center justify-center">
-            <view v-for="_pageIndex, index in Math.ceil(navList.filter(i => i.show).length / 8)" :key="index" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentIndex == index ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
+            <view v-for="_pageIndex, index in Math.ceil(navList.filter((i: any) => i.show).length / 8)" :key="index" class="mr14rpx transition-all transition-duration-400 ease-in" :class="[currentIndex == index ? 'rounded-12rpx w-40rpx h12rpx bg-[var(--them-color)]' : 'w12rpx h12rpx rounded-50% bg-#F0F0F0']" />
           </view>
         </wd-skeleton>
       </view>
@@ -252,124 +265,122 @@ function handleJyBanner() {
           :row-col="[[{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }], [{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }]]"
         >
           <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">
-                <view
-                  v-for="item in goodsList" :key="item.id"
-                  class="relative overflow-hidden rounded-16rpx bg-white pb-16rpx"
-                >
-                  <view @click="router.push({ name: 'xsb-goods', params: { id: item.prodId } })">
-                    <view class="relative h-344rpx">
-                      <image :src="item.pic" class="h-344rpx w-344rpx" />
-                      <image
-                        :src="`${StaticUrl}/xsb-shui-index.png`"
-                        class="absolute left-0 top-0 h-344rpx w-344rpx"
-                      />
-                      <view class="absolute bottom-0 left-0 flex items-center text-22rpx">
-                        <view class="rounded-tl-8rpx bg-[#02ECFD] pl-4rpx">
-                          星闪豹
-                        </view>
-                        <!-- <view class="rounded-tr-8rpx bg-[rgba(0,0,0,0.5)] pl8rpx pr4rpx text-white">
+            <view class="w-full columns-2 gap-[10px]">
+              <view
+                v-for="item in goodsList" :key="item.id"
+                class="relative mb-[10px] break-inside-avoid overflow-hidden rounded-16rpx bg-white pb-16rpx"
+              >
+                <view @click="router.push({ name: 'xsb-goods', params: { id: item.prodId } })">
+                  <view class="relative h-344rpx">
+                    <image :src="item.pic" class="h-344rpx w-344rpx" />
+                    <image
+                      :src="`${StaticUrl}/xsb-shui-index.png`"
+                      class="absolute left-0 top-0 h-344rpx w-344rpx"
+                    />
+                    <view class="absolute bottom-0 left-0 flex items-center text-22rpx">
+                      <view class="rounded-tl-8rpx bg-[#02ECFD] pl-4rpx">
+                        星闪豹
+                      </view>
+                      <!-- <view class="rounded-tr-8rpx bg-[rgba(0,0,0,0.5)] pl8rpx pr4rpx text-white">
                       峰10:00-13:00
                     </view> -->
-                      </view>
                     </view>
-                    <view class="mt-16rpx pl-20rpx pr-6rpx">
-                      <view class="flex items-center">
-                        <!-- <view class="rounded-8rpx bg-#FF4D3A px12rpx text-24rpx text-white">
+                  </view>
+                  <view class="mt-16rpx pl-20rpx pr-6rpx">
+                    <view class="flex items-center">
+                      <!-- <view class="rounded-8rpx bg-#FF4D3A px12rpx text-24rpx text-white">
                       补贴
                     </view> -->
-                        <view class="line-clamp-2 text-28rpx font-semibold">
-                          {{ item.prodName }}
-                        </view>
+                      <view class="line-clamp-2 text-28rpx font-semibold">
+                        {{ item.prodName }}
                       </view>
-                      <view v-if="item.isMember" class="mt-20rpx flex items-center gap-16rpx">
-                        <view class="flex items-end text-[#FF4D3A]">
-                          <view class="text-24rpx">
-                            ¥
-                          </view>
-                          <view class="text-36rpx line-height-[36rpx]">
-                            {{ item.memberPrice }}
-                          </view>
-                          <view class="text-24rpx">
-                            元
-                          </view>
-                        </view>
-                        <view class="rounded-8rpx bg-#FF4A39 px-8rpx py-4rpx text-22rpx text-#FFF">
-                          会员价
-                        </view>
-                        <view class="text-24rpx text-#AAA line-through">
-                          ¥{{ item.channelProdPrice }}
-                        </view>
-                      </view>
-                      <view v-else class="mt-20rpx flex items-end text-[#FF4D3A]">
+                    </view>
+                    <view v-if="item.isMember" class="mt-20rpx flex items-center gap-16rpx">
+                      <view class="flex items-end text-[#FF4D3A]">
                         <view class="text-24rpx">
                         </view>
                         <view class="text-36rpx line-height-[36rpx]">
-                          {{ item.channelProdPrice }}
+                          {{ item.memberPrice }}
                         </view>
                         <view class="text-24rpx">
                         </view>
                       </view>
+                      <view class="rounded-8rpx bg-#FF4A39 px-8rpx py-4rpx text-22rpx text-#FFF">
+                        会员价
+                      </view>
+                      <view class="text-24rpx text-#AAA line-through">
+                        ¥{{ item.channelProdPrice }}
+                      </view>
+                    </view>
+                    <view v-else class="mt-20rpx flex items-end text-[#FF4D3A]">
+                      <view class="text-24rpx">
+                        ¥
+                      </view>
+                      <view class="text-36rpx line-height-[36rpx]">
+                        {{ item.channelProdPrice }}
+                      </view>
+                      <view class="text-24rpx">
+                        元
+                      </view>
                     </view>
                   </view>
+                </view>
+                <view
+                  v-if="!item.spuStock"
+                  class="absolute left-0 top-0 z-1 h-full w-full flex items-center justify-center bg-[rgba(255,255,255,0.6)]"
+                >
                   <view
-                    v-if="!item.spuStock"
-                    class="absolute left-0 top-0 z-1 h-full w-full flex items-center justify-center bg-[rgba(255,255,255,0.6)]"
+                    class="h-156rpx w-156rpx flex items-center justify-center rounded-full bg-[rgba(0,0,0,.6)] text-28rpx text-white"
                   >
-                    <view
-                      class="h-156rpx w-156rpx flex items-center justify-center rounded-full bg-[rgba(0,0,0,.6)] text-28rpx text-white"
-                    >
-                      商品已售罄
-                    </view>
+                    商品已售罄
                   </view>
+                </view>
+                <view
+                  v-if="!item.skuList.some((it: any) => it.saleStatus)"
+                  class="absolute left-0 top-0 z-1 h-full w-full flex items-center justify-center bg-[rgba(255,255,255,0.6)]"
+                >
                   <view
-                    v-if="!item.skuList.some((it) => it.saleStatus)"
-                    class="absolute left-0 top-0 z-1 h-full w-full flex items-center justify-center bg-[rgba(255,255,255,0.6)]"
+                    class="h-156rpx w-156rpx flex items-center justify-center rounded-full bg-[rgba(0,0,0,.6)] text-28rpx text-white"
                   >
-                    <view
-                      class="h-156rpx w-156rpx flex items-center justify-center rounded-full bg-[rgba(0,0,0,.6)] text-28rpx text-white"
-                    >
-                      商品不可售
-                    </view>
+                    商品不可售
                   </view>
                 </view>
-              </grid-view>
-            </scroll-view>
+              </view>
+            </view>
           </view>
         </wd-skeleton>
-        <wd-loadmore v-if="goodsList.length > 9" :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="reload" />
-        <wd-overlay :show="showoverlay" @click="showoverlay = false">
-          <view class="mt-280rpx flex items-center justify-center">
-            <view class="relative h-906rpx w-644rpx flex flex-col justify-center text-center" :style="{ backgroundImage: `url(${StaticUrl}/home-overlay-img.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }">
-              <view>
-                <view class="text-80rpx text-#FF1B51 font-600">
-                  ¥200
-                </view>
-                <view class="text-28rpx font-800">
-                  现金抵扣券
-                </view>
+      </view>
+      <wd-loadmore v-if="goodsList.length > 9" :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="reload" />
+      <wd-overlay :show="showoverlay" @click="showoverlay = false">
+        <view class="mt-280rpx flex items-center justify-center">
+          <view class="relative h-906rpx w-644rpx flex flex-col justify-center text-center" :style="{ backgroundImage: `url(${StaticUrl}/home-overlay-img.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }">
+            <view>
+              <view class="text-80rpx text-#FF1B51 font-600">
+                ¥200
               </view>
-              <view class="absolute bottom-110rpx left-42% text-60rpx text-#FF1B51 font-bold" @click="getZhUserReceived">
-                
+              <view class="text-28rpx font-800">
+                现金抵扣券
               </view>
             </view>
+            <view class="absolute bottom-110rpx left-42% text-60rpx text-#FF1B51 font-bold" @click="getZhUserReceived">
+              领
+            </view>
           </view>
-        </wd-overlay>
-        <wd-overlay :show="showoverlay2 && userMemberInfo.isFirstLogin" @click="showoverlay2 = false">
-          <view class="mt-280rpx flex items-center justify-center">
-            <view class="relative h-906rpx w-644rpx flex flex-col items-center justify-center text-center" :style="{ backgroundImage: `url(${StaticUrl}/vip-index-popup.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }">
-              <view class="absolute top-120rpx w-406rpx border-[1rpx_solid_#FFFFFF] rounded-50rpx border-solid px-30rpx py-8rpx text-center text-24rpx text-#FFF">
-                您的会员权益已生效有效期至{{ userMemberInfo.expireTime }}
-              </view>
-              <image :src="`${StaticUrl}/vip-index-check.png`" class="absolute top-690rpx h-84rpx w-372rpx" @click="router.push({ name: 'smqjh-user-vip' })" />
-              <image :src="`${StaticUrl}/vip-index-shopping.png`" class="absolute top-800rpx h-84rpx w-288rpx" @click="router.push({ name: 'xsb-homeTabbar' })" />
+        </view>
+      </wd-overlay>
+      <wd-overlay :show="showoverlay2 && userMemberInfo.isFirstLogin" @click="showoverlay2 = false">
+        <view class="mt-280rpx flex items-center justify-center">
+          <view class="relative h-906rpx w-644rpx flex flex-col items-center justify-center text-center" :style="{ backgroundImage: `url(${StaticUrl}/vip-index-popup.png)`, backgroundSize: 'cover', backgroundPosition: 'center' }">
+            <view class="absolute top-120rpx w-406rpx border-[1rpx_solid_#FFFFFF] rounded-50rpx border-solid px-30rpx py-8rpx text-center text-24rpx text-#FFF">
+              您的会员权益已生效有效期至{{ userMemberInfo.expireTime }}
             </view>
+            <image :src="`${StaticUrl}/vip-index-check.png`" class="absolute top-690rpx h-84rpx w-372rpx" @click="router.push({ name: 'smqjh-user-vip' })" />
+            <image :src="`${StaticUrl}/vip-index-shopping.png`" class="absolute top-800rpx h-84rpx w-288rpx" @click="router.push({ name: 'xsb-homeTabbar' })" />
           </view>
-        </wd-overlay>
-      </view>
+        </view>
+      </wd-overlay>
     </view>
   </view>
 </template>

+ 168 - 13
src/pages/login/index.vue

@@ -8,15 +8,90 @@ definePage({
   islogin: false,
   style: {
     navigationBarTitleText: '市民请集合',
+    navigationStyle: 'custom',
   },
 })
 const { token, redirectName } = storeToRefs(useUserStore())
+const { thirdPartyName, thirdPartyLogo, tenantCode } = storeToRefs(useSysStore())
 const { data, send } = useRequest((code, phoneCode) => Apis.sys.auth({ params: {
   grant_type: 'wechat',
   code,
   phoneCode,
+  tenantCode: 'zswl',
 } }), { middleware: createGlobalLoadingMiddleware({ loadingText: '手机号授权登录中' }), immediate: false })
 const tabList = ['/pages/my/index', '/pages/index/index', '/pages/cart/index', '/pages/classfiy/index']
+// 表单数据
+const phone = ref('')
+const code = ref('')
+// 验证码倒计时
+const countdown = ref(0)
+const isSending = ref(false)
+onMounted(() => {
+  console.log(redirectName.value, '==================================')
+})
+// 发送验证码
+async function handleSendCode() {
+  if (!phone.value) {
+    useGlobalToast().show('请输入手机号')
+
+    return
+  }
+  if (!/^1[3-9]\d{9}$/.test(phone.value)) {
+    useGlobalToast().show('请输入正确的手机号')
+    return
+  }
+  if (isSending.value)
+    return
+
+  isSending.value = true
+  countdown.value = 60
+
+  const timer = setInterval(() => {
+    countdown.value--
+    if (countdown.value <= 0) {
+      clearInterval(timer)
+      isSending.value = false
+    }
+  }, 1000)
+
+  // TODO: 调用发送验证码接口
+  await Apis.general.post_smqjh_auth_api_v1_auth_sms_code({ params: { mobile: phone.value, tenantCode: tenantCode.value } })
+  useGlobalToast().show('验证码已发送')
+}
+
+// 登录
+async function handleLogin() {
+  if (!phone.value) {
+    useGlobalToast().show('请输入手机号')
+    return
+  }
+  if (!code.value) {
+    useGlobalToast().show('请输入验证码')
+    return
+  }
+  uni.showLoading({ mask: true })
+  try {
+    const res = await Apis.general.post_smqjh_auth_oauth2_token({ params: { grant_type: 'sms_code', mobile: phone.value, code: code.value, tenantCode: tenantCode.value } })
+    token.value = `Bearer ${res.data.access_token}`
+    useUserStore().getUserInfo()
+    uni.hideLoading()
+    useGlobalToast().show('登录成功')
+    setTimeout(() => {
+      const path = redirectName.value || '/pages/index/index'
+      if (tabList.includes(path)) {
+        router.pushTab({ path })
+      }
+      else {
+        router.replace({ path })
+      }
+    }, 1000)
+  }
+  catch {
+    token.value = ''
+    uni.hideLoading()
+    useGlobalToast().show('登录失败')
+  }
+}
 async function handleGetPhone(e: UniHelper.ButtonOnGetphonenumberDetail) {
   console.log(e, '手机号')
   uni.showLoading({ mask: true })
@@ -26,8 +101,8 @@ async function handleGetPhone(e: UniHelper.ButtonOnGetphonenumberDetail) {
       uni.hideLoading()
       await send(res.code, e.code)
       token.value = `Bearer ${data.value.data.access_token}`
-      useGlobalToast().show({ msg: '登录成功' })
       useUserStore().getUserInfo()
+      useGlobalToast().show({ msg: '登录成功' })
 
       setTimeout(() => {
         if (tabList.includes(redirectName.value)) {
@@ -46,29 +121,106 @@ function goBack() {
   uni.switchTab({
     url: '/pages/index/index',
   })
+  useTabbar().setTabbarItemActive('smqjh-home')
 }
 </script>
 
 <template>
-  <view class="header px24rpx">
-    <view class="pt150rpx">
-      <view class="w-full flex items-center justify-center">
+  <view>
+    <!-- #ifdef MP-WEIXIN -->
+    <view class="header px24rpx">
+      <wd-navbar
+        title="市民请集合" custom-style="background-color:transparent !important" :bordered="false" :z-index="99"
+
+        safe-area-inset-top placeholder fixed
+      />
+      <view class="pt150rpx">
+        <view class="w-full flex items-center justify-center">
+          <image
+            :src="`${StaticUrl}/smqjh-logo.png`"
+            class="h120rpx w120rpx"
+          />
+        </view>
+        <view class="mt50rpx">
+          <wd-button block size="large" open-type="getPhoneNumber" @getphonenumber="handleGetPhone">
+            手机号快捷登录
+          </wd-button>
+          <view class="mt40rpx">
+            <wd-button block size="large" type="info" @click="goBack">
+              暂不登录
+            </wd-button>
+          </view>
+        </view>
+      </view>
+    </view>
+
+    <!-- #endif -->
+    <!-- #ifdef H5 -->
+    <view class="login-page min-h-100vh px48rpx">
+      <wd-navbar
+        :title="thirdPartyName" custom-style="background-color:transparent !important" :bordered="false" :z-index="99"
+
+        safe-area-inset-top placeholder fixed
+      />
+      <view class="w-full flex items-center justify-center pt40rpx">
         <image
-          :src="`${StaticUrl}/smqjh-logo.png`"
+          :src="`${thirdPartyLogo}`"
           class="h120rpx w120rpx"
         />
       </view>
-      <view class="mt50rpx">
-        <wd-button block size="large" open-type="getPhoneNumber" @getphonenumber="handleGetPhone">
-          手机号快捷登录
-        </wd-button>
-        <view class="mt40rpx">
-          <wd-button block size="large" type="info" @click="goBack">
-            暂不登录
-          </wd-button>
+      <!-- 表单区域 -->
+      <view class="pt242rpx">
+        <!-- 手机号 -->
+        <view class="mb48rpx">
+          <view class="mb24rpx text-32rpx text-#333 font-medium">
+            手机号
+          </view>
+          <view class="h96rpx flex items-center rounded-48rpx bg-#E5E8D8 px32rpx">
+            <input
+              v-model="phone"
+              type="number"
+              :maxlength="11"
+              placeholder="请输入手机号"
+              placeholder-class="text-#999"
+              class="flex-1 text-32rpx"
+            >
+          </view>
+        </view>
+
+        <!-- 验证码 -->
+        <view class="mb64rpx">
+          <view class="mb24rpx text-32rpx text-#333 font-medium">
+            验证码
+          </view>
+          <view class="h96rpx flex items-center rounded-48rpx bg-#E5E8D8 px32rpx">
+            <input
+              v-model="code"
+              type="tel"
+              :maxlength="4"
+              placeholder="请输入验证码"
+              placeholder-class="text-#999"
+              class="flex-1 text-32rpx"
+            >
+            <view
+              class="ml20rpx flex-shrink-0 text-28rpx"
+              :class="[isSending ? 'text-#999' : 'text-[var(--them-color)]']"
+              @click="handleSendCode"
+            >
+              {{ isSending ? `${countdown}秒后重新发送` : '获取验证码' }}
+            </view>
+          </view>
         </view>
+
+        <!-- 登录按钮 -->
+        <wd-button block size="large" @click="handleLogin">
+          登录
+        </wd-button>
+        <!-- <view class="mt20rpx text-center text-#999">
+          请使用市民请集合小程序账号进行登录
+        </view> -->
       </view>
     </view>
+    <!-- #endif -->
   </view>
 </template>
 
@@ -76,4 +228,7 @@ function goBack() {
 .header{
   height: calc(100vh - var(--window-top));
 }
+.login-page {
+background: linear-gradient( 181deg, var(--them-color) 0%, #F9F9F9 100%);
+}
 </style>

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

@@ -13,10 +13,10 @@ definePage({
   },
 })
 const tabList = ref([
-  { title: '待支付', icon: `${StaticUrl}/1.png`, name: 'smqjh-order', status: 'paddingPay' },
-  { title: '进行中', icon: `${StaticUrl}/2.png`, name: 'smqjh-order', status: 'ing' },
-  { title: '已完成', icon: `${StaticUrl}/6.png`, name: 'smqjh-order', status: 'completed' },
-  { title: '退款售后', icon: `${StaticUrl}/3.png`, name: 'common-afterSalesList', status: '' },
+  { title: '待支付', icon: ``, name: 'smqjh-order', status: 'paddingPay' },
+  { title: '进行中', icon: ``, name: 'smqjh-order', status: 'ing' },
+  { title: '已完成', icon: ``, name: 'smqjh-order', status: 'completed' },
+  { title: '退款售后', icon: ``, name: 'common-afterSalesList', status: '' },
 ])
 onMounted(() => {
   useUserStore().getUserInfo()
@@ -27,11 +27,15 @@ function handleLoginOut() {
     title: '提示',
     msg: '确定要退出登录吗?',
     success: async () => {
-      useUserStore().$reset()
+      await useUserStore().$reset()
       useSmqjhCartStore().$reset()
       useAddressStore().$reset()
       useTabbar().setTabbarItem('smqjh-cart', 0)
-      router.replace({ name: 'smqjh-login' })
+      uni.showLoading({ mask: true })
+      setTimeout(() => {
+        uni.hideLoading()
+        router.replace({ name: 'smqjh-login' })
+      }, 1000)
     },
   })
 }
@@ -46,10 +50,11 @@ function handleGo(item: { name: string, status: string }) {
       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="relative h-408rpx rounded-[18px]" :style="{ background: `linear-gradient( 180deg, var(--them-color) 0%, rgba(255,255,255,0) 100%)` }">
       <view class="absolute bottom-100rpx left-0 box-border w-full flex items-center justify-between pl-48rpx pr-58rpx">
         <template v-if="!token">
-          <image :src="`${StaticUrl}/9.png`" alt="" class="h-100rpx w-100rpx" />
+          <!-- <image :src="`${StaticUrl}/9.png`" alt="" class="h-100rpx w-100rpx" /> -->
+          <i class="iconfont text-100rpx text-[var(--them-color)]">&#xe654;</i>
           <view class="text-32rpx font-semibold">
             请登录后使用完整功能
           </view>
@@ -70,7 +75,7 @@ function handleGo(item: { name: string, status: string }) {
               <view class="text-32rpx font-semibold">
                 {{ userInfo.nickName }}
               </view>
-              <view class="mt-12rpx rounded-8rpx bg-white px-12rpx py-4rpx text-24rpx text-[var(--them-color)] opacity-70">
+              <view class="mt-12rpx w-fit rounded-8rpx bg-white px-12rpx py-4rpx text-24rpx text-[var(--them-color)] opacity-70">
                 {{ userInfo.channelName }}
               </view>
             </view>
@@ -104,7 +109,9 @@ function handleGo(item: { name: string, status: string }) {
         </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="handleGo(item)">
-            <image :src="item.icon" class="h-56rpx w-56rpx" />
+            <i class="iconfont text-56rpx text-[var(--them-color)]">
+              {{ item.icon }}
+            </i>
             <view class="mt-20rpx text-24rpx">
               {{ item.title }}
             </view>
@@ -164,10 +171,6 @@ function handleGo(item: { name: string, status: string }) {
 </template>
 
 <style lang="scss" scoped>
-.header {
- background: linear-gradient( 113deg, #F7FFDC 0%, #E0FF8E 25%, #F2FFCE 51%, #E3FF98 83%, #F6FFD6 100%);
-}
-
 .page-class {
   height: calc(100vh - var(--window-top) - 150rpx);
   :deep() {

+ 1 - 0
src/shims.d.ts

@@ -12,3 +12,4 @@ declare module '*.vue' {
   const component: Vue.ComponentOptions<Vue>
   export default component
 }
+declare module 'jz-h5-scanCode';

BIN
src/static/tab/cart1.png


BIN
src/static/tab/cart2.png


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


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


BIN
src/static/tab/index.png


BIN
src/static/tab/index1.png


BIN
src/static/tab/index2.png


BIN
src/static/tab/my1.png


BIN
src/static/tab/my2.png


+ 28 - 3
src/store/address.ts

@@ -26,9 +26,10 @@ export const useAddressStore = defineStore('address', {
     city: '',
   }),
   actions: {
-  // 获取地理位置的函数
+    // 获取地理位置的函数
     getLocation() {
       uni.showLoading({ mask: true })
+      // #ifdef MP-WEIXIN
       // 1. 检查当前授权状态
       uni.getSetting({
         success: (res) => {
@@ -49,6 +50,11 @@ export const useAddressStore = defineStore('address', {
           }
         },
       })
+      // #endif
+      // #ifndef MP-WEIXIN
+      // H5 无授权流程,直接获取定位
+      this.fetchActualLocation()
+      // #endif
     },
 
     // 实际获取位置的方法
@@ -61,31 +67,41 @@ export const useAddressStore = defineStore('address', {
           console.log('位置获取成功', res)
           this.Location.latitude = res.latitude
           this.Location.longitude = res.longitude
+          // #ifndef MP-WEIXIN
+          uni.hideLoading()
+          // #endif
         },
         fail: (err) => {
           console.log(err, '获取位置失败')
+          // #ifdef MP-WEIXIN
           if (err.errMsg === 'getLocation:fail system permission denied') {
             useGlobalToast().show('手机定位权限未打开,请手动在设置里面打开定位')
           }
           else {
             useGlobalToast().show(`获取定位失败:${err.errMsg}`)
           }
+          // #endif
+          // #ifndef MP-WEIXIN
+          uni.hideLoading()
+          this.showAuthGuide()
+          // #endif
         },
       })
     },
 
     // 显示授权引导
     showAuthGuide() {
+      // #ifdef MP-WEIXIN
       uni.showModal({
         title: '需要位置权限',
         content: '请开启位置授权以使用完整功能',
         confirmText: '去设置',
         success: (res) => {
           if (res.confirm) {
-            // 4. 用户点击确认后打开设置页
+            // 用户点击确认后打开设置页
             wx.openSetting({
               success: (settingRes) => {
-                // 5. 检查用户是否在设置页中开启了授权
+                // 检查用户是否在设置页中开启了授权
                 if (settingRes.authSetting['scope.userLocation']) {
                   this.fetchActualLocation()
                 }
@@ -97,6 +113,15 @@ export const useAddressStore = defineStore('address', {
           }
         },
       })
+      // #endif
+      // #ifndef MP-WEIXIN
+      uni.showModal({
+        title: '需要位置权限',
+        content: '您的浏览器定位权限未开启,请点击地址栏左侧的锁形图标,将"位置"权限设置为"允许"后刷新页面重试',
+        showCancel: false,
+        confirmText: '我知道了',
+      })
+      // #endif
     },
     getMapAddress() {
       uni.chooseLocation({

+ 47 - 1
src/store/sys.ts

@@ -36,7 +36,19 @@ interface SysState {
    * 如果是组件模式加tabbar,从订单详情返回订单列表页面需要刷新,监听此字段刷新页面
    */
   refreshOrderList: boolean
+  /**
+   * 第三方名称
+   */
+  thirdPartyName: string
+  /**
+   * 三方logo
+   */
+  thirdPartyLogo: string
 
+  /**
+   * 租户代码
+   */
+  tenantCode: string
 }
 export const useSysStore = defineStore('system', {
   state: (): SysState => ({
@@ -48,13 +60,21 @@ export const useSysStore = defineStore('system', {
     opcity: 0,
     isOnlineAudit: true,
     refreshOrderList: false,
+    thirdPartyName: '',
+    thirdPartyLogo: '',
+    tenantCode: '',
   }),
   actions: {
     getSystemData() {
       const { statusBarHeight } = uni.getSystemInfoSync()
+      // #ifdef MP-WEIXIN
       const { height } = uni.getMenuButtonBoundingClientRect()
-      this.statusBarHeight = Number(statusBarHeight)
       this.MenuButtonHeight = height
+      // #endif
+      // #ifndef MP-WEIXIN
+      this.MenuButtonHeight = 0
+      // #endif
+      this.statusBarHeight = Number(statusBarHeight)
     },
     /**
      *
@@ -93,6 +113,32 @@ export const useSysStore = defineStore('system', {
         })
       })
     },
+    /**
+     * 获取第三方主题色
+     */
+    async getThirdPartyThemeColor() {
+      if (this.tenantCode)
+        return
+      const accessId = this.getAccessIdFromPath() || 'ch_003'
+      try {
+        const res = await Apis.sys.appAccess({ pathParams: { accessId } })
+        this.thirdPartyName = res.data.accessName
+        this.thirdPartyLogo = res.data.logoUrl
+        this.tenantCode = res.data.tenantCode
+        useManualThemeStore().setCurrentThemeColor({ name: '三方主题色', value: 'blue', primary: res.data.themeMainColor })
+      }
+      catch {
+        useGlobalToast().show('渠道有问题!,请联系管理员')
+      }
+    },
+
+    getAccessIdFromPath() {
+      const pathname = window.location.pathname || ''
+      console.log(pathname, '============pathname============')
+      const [accessId] = pathname.split('/').filter(Boolean)
+      console.log(accessId, '============accessId============')
+      return accessId || ''
+    },
 
   },
 })

+ 94 - 1
src/store/user.ts

@@ -1,6 +1,6 @@
 import { defineStore } from 'pinia'
 import { dayjs } from 'wot-design-uni'
-import { StaticUrl } from '@/config'
+import { REDIRECT_URL, StaticUrl } from '@/config'
 import router from '@/router'
 import type { wxpay } from '@/api/globals'
 
@@ -474,5 +474,98 @@ export const useUserStore = defineStore('user', {
         }).finally(() => uni.hideLoading())
       })
     },
+    /**
+     *
+     * @param _item 兑换的券 加油
+     */
+    async handleExchange(_item: any) {
+      uni.showLoading({ mask: true })
+      try {
+        const res = await Apis.app.get_smqjh_system_app_api_coupon_exchangepoints({ params: { couponId: _item.id } })
+        uni.hideLoading()
+        // 兑换成功,跳转成功页
+        router.push({
+          name: 'exchangeSuccess',
+          params: {
+            couponId: res.data?.id || _item.id,
+            batchNo: res.data?.batchId || '',
+            expireDays: res.data?.expirationDate || _item.expirationDate,
+            discountMoney: res.data?.discountMoney || _item.discountMoney,
+            amountMoney: res.data?.amountMoney || _item.amountMoney,
+          },
+        })
+      }
+      catch (error: any) {
+        console.log(error)
+
+        uni.hideLoading()
+        // 兑换失败,跳转失败页
+        router.push({
+          name: 'exchangeFail',
+          params: {
+            failReason: error?.message || '兑换失败,请稍后重试',
+          },
+        })
+      }
+    },
+    /**
+     * 拉起小橘支付
+     * @param path
+     */
+    handleCommonPath(path: string) {
+      uni.showLoading({ mask: true })
+      const url = REDIRECT_URL
+      window.location.href = `${path}&redirectUrl=${url}`
+      uni.hideLoading()
+    },
+    async handleCommonGoXiaoJuPay(orderNumber: string) {
+      try {
+        const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_findbypayurl({ params: { orderNumber } })
+        this.handleCommonPath(res.data as string)
+      }
+      catch (error) {
+        console.log(error)
+        useGlobalToast().show('获取支付信息失败')
+      }
+    },
+    /**
+     * 加油统一取消订单
+     * @param orderNumber
+     * @returns
+     */
+    async handleCommonCancelOrderJY(orderNumber: string) {
+      try {
+        const res = await Apis.xsb.cancelOrder({ data: { orderNo: orderNumber } })
+        return res
+      }
+      catch (error) {
+        console.log(error)
+        useGlobalToast().show('取消订单失败')
+      }
+    },
+    /**
+     * h5专属。小程序不可调用
+     * h5第三方统一拉起微信支付跳转路径及参数
+     * @param orderNumber
+     */
+    handleCommonWechatPay(orderNumber: string) {
+      // #ifdef H5
+      uni.showLoading({ mask: true })
+      const query = {
+        orderNumber,
+        phone: String(this.userInfo.mobile),
+        tenantCode: useSysStore().tenantCode,
+      }
+      const queryString = Object.entries(query)
+        .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
+        .join('&')
+      const path = 'subPack-common/threePay/index'
+      // const env = 'develop'
+      const env = 'trial'
+      // const env = 'release'
+      window.location.href = `weixin://dl/business/?appid=wx43b5b906cc30ed0b&path=${path}&query=${encodeURIComponent(queryString)}&env_version=${env}`
+      uni.hideLoading()
+      // #endif
+    },
   },
 })

+ 11 - 18
src/subPack-attractions/attractionsDetail/attractionsDetail.vue

@@ -126,7 +126,7 @@ async function handleMonthChange(e: { year: number, month: number }) {
   <view class="min-h-screen bg-#F5F5F5">
     <wd-navbar
       title="景区门票"
-      :custom-style="`background-color: rgba(226, 255, 145, ${opcity})`"
+      :custom-style="`background-color: ${hexToRgba(useManualThemeStore().themeVars.colorTheme as string, opcity)};`"
       :bordered="false"
       :z-index="9999"
       safe-area-inset-top
@@ -233,13 +233,14 @@ async function handleMonthChange(e: { year: number, month: number }) {
       class="fixed bottom-0 left-0 z-100 box-border w-full flex items-center justify-between border-t border-#eee bg-white px24rpx py16rpx"
       :style="{ paddingBottom: `${(Number(statusBarHeight) || 44) - 20}px` }"
     >
-      <view class="flex items-center border-t-#EEEEEE">
-        <view class="relative mr-40rpx flex flex-col items-center">
-          <button open-type="contact" class="zbutton" />
-          <wd-icon name="service" size="24px" color="#666" />
-          <text class="text-22rpx text-#666">
-            客服
-          </text>
+      <view class="flex flex-1 items-center justify-between border-t-#EEEEEE pr20rpx">
+        <view class="zbutton">
+          <Zcontact>
+            <wd-icon name="service" size="24px" color="#666" />
+            <view class="text-20rpx text-#666">
+              客服
+            </view>
+          </Zcontact>
         </view>
         <view class="flex flex-col items-center" @click="handleOrder">
           <wd-icon name="list" size="22px" color="#666" />
@@ -249,7 +250,7 @@ async function handleMonthChange(e: { year: number, month: number }) {
         </view>
       </view>
       <view
-        class="h80rpx w-400rpx flex items-center justify-center rounded-40rpx bg-#9ED605 px80rpx text-28rpx text-#FFF font-semibold"
+        class="h80rpx w-400rpx flex items-center justify-center rounded-40rpx bg-[var(--them-color)] px80rpx text-28rpx text-#FFF font-semibold"
         @click="handleBook"
       >
         立即预定
@@ -259,13 +260,5 @@ async function handleMonthChange(e: { year: number, month: number }) {
 </template>
 
 <style lang="scss" scoped>
-.zbutton{
-  all: unset;
-  width: 70rpx;
-  height: 70rpx;
-  position: absolute;
-  &::after{
-    border: none;
-  }
-}
+
 </style>

+ 5 - 0
src/subPack-attractions/attractionsOrderPay/attractionsOrderPay.vue

@@ -29,6 +29,7 @@ async function getPayPreview() {
 }
 
 async function submitPay() {
+  // #ifdef MP-WEIXIN
   const res = await useUserStore().handleCommonPayMent(orderNo.value)
   if (res.payType !== 1) {
     try {
@@ -42,6 +43,10 @@ async function submitPay() {
   else {
     router.replace({ name: 'attractions-order-detail', params: { orderNo: String(payPreviewInfo.value?.orderNumber), ispay: 'true' } })
   }
+  // #endif
+  // #ifdef H5
+  useUserStore().handleCommonWechatPay(orderNo.value)
+  // #endif
 }
 </script>
 

+ 3 - 1
src/subPack-attractions/attractionsReservation/attractionsReservation.vue

@@ -333,9 +333,11 @@ async function handleSubmit() {
             {{ formattedDate }}
           </view>
         </view>
+        <view class="h120rpx" />
       </view>
     </Zpopup>
   </view>
 </template>
 
-<style lang="scss" scoped></style>
+<style lang="scss" scoped>
+</style>

+ 2 - 2
src/subPack-attractions/commonTab/components/homeList.vue

@@ -53,7 +53,7 @@ function handleClear() {
   <view class="attractions-home-page">
     <wd-navbar
       title="景区门票"
-      :custom-style="`background-color: rgba(226, 255, 145, ${opcity})`"
+      :custom-style="`background-color: ${hexToRgba(useManualThemeStore().themeVars.colorTheme as string, opcity)};`"
       :bordered="false"
       :z-index="9999"
       safe-area-inset-top
@@ -119,7 +119,7 @@ function handleClear() {
             </view>
           </wd-skeleton>
         </scroll-view>
-        <wd-loadmore :state="state" :loading-props="{ color: '#9ED605', size: 20 }" @reload="reload" />
+        <wd-loadmore :state="state" :loading-props="{ color: useManualThemeStore().themeVars.colorTheme, size: 20 }" @reload="reload" />
       </view>
     </view>
   </view>

+ 2 - 5
src/subPack-attractions/commonTab/index.vue

@@ -1,7 +1,6 @@
 <script setup lang="ts">
 import homeList from './components/homeList.vue'
 import orderList from './components/orderList.vue'
-import { StaticUrl } from '@/config'
 
 const tabbar = ref(0)
 const { opcity } = storeToRefs(useSysStore())
@@ -36,14 +35,12 @@ onPageScroll((e) => {
       <wd-tabbar v-model="tabbar" safe-area-inset-bottom placeholder fixed :bordered="false" :z-index="99999">
         <wd-tabbar-item title="列表" icon="goods">
           <template #icon>
-            <image v-if="tabbar === 0" class="h-40rpx w-40rpx" :src="`${StaticUrl}/attractions-selHome-tabbar.png`" />
-            <image v-else class="h-40rpx w-40rpx" :src="`${StaticUrl}/attractions-home-tabbar.png`" />
+            <i class="iconfont text-44rpx" :class="[tabbar === 0 ? 'text-[var(--them-color)]' : '']">&#xe63a;</i>
           </template>
         </wd-tabbar-item>
         <wd-tabbar-item title="订单记录" icon="list">
           <template #icon>
-            <image v-if="tabbar === 1" class="h-40rpx w-40rpx" :src="`${StaticUrl}/attractions-selOrder-tabbar.png`" />
-            <image v-else class="h-40rpx w-40rpx" :src="`${StaticUrl}/attractions-order-tabbar.png`" />
+            <i class="iconfont text-44rpx" :class="[tabbar === 1 ? 'text-[var(--them-color)]' : '']">&#xe645;</i>
           </template>
         </wd-tabbar-item>
       </wd-tabbar>

+ 10 - 10
src/subPack-charge/chargeDetail/chargeDetail.vue

@@ -61,7 +61,7 @@ function switchTab(tab: string) {
 // 计算样式的方法
 function getTabStyle(tab: string) {
   return activeTab.value === tab
-    ? { background: '#9ED605', color: '#FFF' }
+    ? { background: 'var(--them-color)', color: '#FFF' }
     : {}
 }
 async function getDeviceInfo(connectorCode: string) {
@@ -92,9 +92,9 @@ async function scanCode() {
 </script>
 
 <template>
-  <view class="charge-detail-page min-h-screen bg-[linear-gradient(90deg,#F1FECC_0%,#EAFEFA_100%)]">
+  <view class="charge-detail-page min-h-screen bg-[linear-gradient(181deg,var(--them-color)_0%,#F5F7FB_100%)]">
     <wd-navbar
-      title="充电详情" custom-style="background: linear-gradient(90deg, #F1FECC 0%, #EAFEFA 100%);"
+      title="充电详情" custom-style="background: var(--them-color);"
       :bordered="false" :z-index="999" safe-area-inset-top left-arrow fixed @click-left="router.back()"
     />
     <view :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }" />
@@ -104,7 +104,7 @@ async function scanCode() {
           <view class="text-32rpx font-bold">
             {{ priceDetail?.stationName }}
           </view>
-          <view class="mt-16rpx text-24rpx text-#AAA">
+          <view class="mt-16rpx text-24rpx text-#fff">
             {{ priceDetail?.tips || '--' }}
           </view>
         </view>
@@ -114,7 +114,7 @@ async function scanCode() {
       </view>
       <view class="items-centerrounded-16rpx mt-20rpx flex bg-#FFF p-20rpx">
         <view class="w-230rpx text-center">
-          <view class="text-32rpx text-#9ED605 font-bold">
+          <view class="text-32rpx text-[var(--them-color)] font-bold">
             {{ connectorsDetail?.idleCount }}
           </view>
           <view class="text-24rpx font-500">
@@ -123,7 +123,7 @@ async function scanCode() {
         </view>
         <view class="h-76rpx w-2rpx bg-#F0F0F0" />
         <view class="w-230rpx text-center">
-          <view class="text-32rpx text-#9ED605 font-bold">
+          <view class="text-32rpx text-[var(--them-color)] font-bold">
             {{ connectorsDetail?.occupiedCount }}
           </view>
           <view class="text-24rpx font-500">
@@ -132,7 +132,7 @@ async function scanCode() {
         </view>
         <view class="h-76rpx w-2rpx bg-#F0F0F0" />
         <view class="w-230rpx text-center">
-          <view class="text-32rpx text-#9ED605 font-bold">
+          <view class="text-32rpx text-[var(--them-color)] font-bold">
             {{ connectorsDetail?.offlineCount }}
           </view>
           <view class="text-24rpx font-500">
@@ -160,7 +160,7 @@ async function scanCode() {
         <view
           v-for="item in priceDetail?.priceList" :key="item.timePeriod"
           class="mt-20rpx rounded-16rpx bg-#FFF p-24rpx"
-          :style="{ border: item.currentPeriod ? '2rpx solid #9ED605' : '' }"
+          :style="{ border: item.currentPeriod ? '2rpx solid var(--them-color)' : '' }"
         >
           <view class="relative flex items-center justify-between">
             <view class="flex items-center gap-20rpx">
@@ -175,7 +175,7 @@ async function scanCode() {
             </view>
             <view
               v-if="item.currentPeriod"
-              class="absolute h-40rpx w-152rpx rounded-[0_16rpx_0_16rpx] bg-[linear-gradient(99deg,#D2F670_0%,#9ED605_100%)] text-center text-28rpx text-#FFF font-600 -right-24rpx -top-24rpx"
+              class="absolute h-40rpx w-152rpx rounded-[0_16rpx_0_16rpx] bg-[linear-gradient(181deg,var(--them-color)_0%,#F5F7FB_100%)] text-center text-28rpx text-#FFF font-600 -right-24rpx -top-24rpx"
             >
               当前时段
             </view>
@@ -229,7 +229,7 @@ async function scanCode() {
     </view>
     <view class="h-180rpx" />
     <view
-      class="fixed bottom-66rpx left-24rpx h-100rpx w-702rpx rounded-16rpx bg-[linear-gradient(90deg,#DBFC81_0%,#9ED605_100%)] text-center text-28rpx font-800 line-height-[100rpx] shadow-[inset_0rpx_6rpx_20rpx_2rpx_#FFFFFF]"
+      class="fixed bottom-66rpx left-24rpx h-100rpx w-702rpx rounded-16rpx bg-[var(--them-color)] text-center text-28rpx font-800 line-height-[100rpx] shadow-[inset_0rpx_6rpx_20rpx_2rpx_#FFFFFF]"
       @click="scanCode"
     >
       扫码充电

+ 1 - 1
src/subPack-charge/chargeMap/chargeMap.vue

@@ -72,7 +72,7 @@ function openMarkerTap(item: any) {
       <view class="absolute left-0 top-0 z-0 h-full w-full">
         <map
           style="width: 100%;height: 100vh;" :longitude="Location.longitude || 113.264435"
-          :latitude="Location.latitude || 23.129163" :markers="markersData" @markertap.stop="openMarkerTap"
+          :latitude="Location.latitude || 23.129163" :markers="markersData" @markertap="openMarkerTap"
         />
       </view>
       <transition name="slide-up">

+ 2 - 2
src/subPack-charge/chargeSiteDetail/chargeSiteDetail.vue

@@ -319,7 +319,7 @@ async function scanCode() {
 }
 
 .select-item-active {
-  background: #9ED605;
+  background: var(--them-color);
   box-shadow: inset 0rpx 20rpx 40rpx 2rpx rgba(100, 255, 218, 0.26);
   border-radius: 0rpx 16rpx 0rpx 16rpx;
   font-weight: bold;
@@ -329,7 +329,7 @@ async function scanCode() {
 .scan-qrcode {
   width: 220rpx;
   height: 100rpx;
-  background: linear-gradient(90deg, #DBFC81 0%, #9ED605 100%);
+  background: var(--them-color);
   box-shadow: inset 0rpx 6rpx 20rpx 2rpx #FFFFFF;
   border-radius: 16rpx;
   font-weight: 800;

+ 6 - 0
src/subPack-charge/chargeVoucher/chargeVoucher.vue

@@ -74,6 +74,7 @@ async function submitPay() {
       await uni.showToast({ title: '下单失败', icon: 'none' })
       return
     }
+    // #ifdef MP-WEIXIN
     const payRes = await Apis.charge.wxJsApiPay({
       data: {
         orderNumber,
@@ -82,6 +83,11 @@ async function submitPay() {
     uni.hideLoading()
     await useUserStore().getWxCommonPayment(payRes.data)
     await useUserStore().paySuccess('charge-buy-a-ticket-list', 'subPack-charge/chargeBuyaTicketList/chargeBuyaTicketList')
+    // #endif
+    // #ifdef H5
+    uni.hideLoading()
+    useUserStore().handleCommonWechatPay(orderNumber)
+    // #endif
   }
   catch (error) {
     uni.hideLoading()

+ 3 - 2
src/subPack-charge/components/charge-tab.vue

@@ -1,6 +1,5 @@
 <script lang="ts" setup>
 import { ScanCodeUtil } from '../utils/index'
-import { StaticUrl } from '@/config'
 import router from '@/router'
 
 async function getDeviceInfo(connectorCode: string) {
@@ -16,6 +15,7 @@ async function getDeviceInfo(connectorCode: string) {
 }
 
 async function scanCode() {
+  await useUserStore().checkLogin()
   try {
     const connectorCode = await ScanCodeUtil.scanAndGetConnectorCode()
     if (!connectorCode) {
@@ -35,7 +35,8 @@ async function scanCode() {
   <view class="charge-footer">
     <view class="ios flex items-center justify-center pb-20rpx -mt-26rpx">
       <view class="img-box" @click="scanCode">
-        <image class="h-120rpx w-120rpx" :src="`${StaticUrl}/charge-qrCode.png`" />
+        <!-- <image class="h-120rpx w-120rpx" :src="`${StaticUrl}/charge-qrCode.png`" /> -->
+        <i class="iconfont text-120rpx text-[var(--them-color)]">&#xe646;</i>
       </view>
     </view>
   </view>

+ 68 - 57
src/subPack-charge/index/index.vue

@@ -24,7 +24,7 @@ const filterOptions = [
   { key: 2, label: '空闲最多', widthClass: '' },
   { key: 3, label: '电费最低', widthClass: '' },
 ]
-
+const { themeVars } = storeToRefs(useManualThemeStore())
 /**
  * 获取充电站列表
  */
@@ -127,9 +127,9 @@ function refund() {
 </script>
 
 <template>
-  <view class="min-h-screen from-[#E2FF91] to-[rgba(158,214,5,0)] bg-gradient-to-b">
+  <view class="min-h-screen" :style="{ backgroundImage: `linear-gradient(to bottom, ${themeVars.colorTheme}, ${hexToRgba(themeVars.colorTheme as string, 0)})` }">
     <wd-navbar
-      title="" :custom-style="`background-color: rgba(226, 255, 145, ${opcity})`" :bordered="false"
+      title="" :custom-style="`background-color: ${hexToRgba(themeVars.colorTheme as string, opcity)};`" :bordered="false"
       :z-index="99" safe-area-inset-top left-arrow fixed @click-left="router.back()"
     >
       <template #left>
@@ -154,10 +154,10 @@ function refund() {
               <view class="text-32rpx text-#2B303A font-bold">
                 {{ userInfo?.nickName || '暂未登录' }}
               </view>
-              <view v-if="!token" class="text-24rpx text-#9ED605" @click="router.replace({ name: 'smqjh-login' })">
+              <view v-if="!token" class="text-24rpx" @click="router.replace({ name: 'smqjh-login' })">
                 授权登录
               </view>
-              <view v-else class="rounded-8rpx bg-#E9FFAC px12rpx py4rpx text-24rpx text-#9ED605">
+              <view v-else class="rounded-8rpx bg-[var(--them-color)] px12rpx py4rpx text-24rpx text-#fff">
                 {{ userInfo.channelName }}
               </view>
             </view>
@@ -170,17 +170,16 @@ function refund() {
           <view class="relative flex items-center justify-between">
             <view class="flex items-center gap-16rpx">
               <view class="h-40rpx w-40rpx">
-                <image
-                  class="h-40rpx w-40rpx"
-                  :src="`${StaticUrl}/charge-mine-wallet.png`"
-                  mode="scaleToFill"
-                />
+                <image class="h-40rpx w-40rpx" :src="`${StaticUrl}/charge-mine-wallet.png`" mode="scaleToFill" />
               </view>
               <view class="text-32rpx font-bold">
                 我的钱包
               </view>
             </view>
-            <view class="absolute right-[-24rpx] h-44rpx w-120rpx rounded-[22rpx_0_0_22rpx] bg-#9ED605 text-center text-28rpx text-#FFF line-height-[44rpx]" @click="refund">
+            <view
+              class="absolute right-[-24rpx] h-44rpx w-120rpx rounded-[22rpx_0_0_22rpx] bg-[var(--them-color)] text-center text-28rpx text-#FFF line-height-[44rpx]"
+              @click="refund"
+            >
               退还
             </view>
           </view>
@@ -189,16 +188,16 @@ function refund() {
               <view class="text-28rpx">
                 企业积分
               </view>
-              <view class="mt-16rpx text-40rpx text-#9ED605 font-bold">
+              <view class="mt-16rpx text-40rpx text-[var(--them-color)] font-bold">
                 {{ userAccountInfo?.availablePoints || '0.00' }}
               </view>
             </view>
-            <view class="h-92rpx w-2rpx bg-#9ED605" />
+            <view class="h-92rpx w-2rpx bg-[var(--them-color)]" />
             <view class="text-center">
               <view class="text-28rpx">
                 平台券
               </view>
-              <view class="mt-16rpx text-40rpx text-#9ED605 font-bold">
+              <view class="mt-16rpx text-40rpx text-[var(--them-color)] font-bold">
                 <text class="text-24rpx">
                 </text>{{ userAccountInfo?.couponBalance || '0.00' }}
@@ -223,14 +222,13 @@ function refund() {
             </view>
           </view>
           <view class="h-100rpx w-100rpx">
-            <image
-              class="h-100rpx w-100rpx"
-              :src="`${StaticUrl}/charge-mine-order.png`"
-              mode="scaleToFill"
-            />
+            <image class="h-100rpx w-100rpx" :src="`${StaticUrl}/charge-mine-order.png`" mode="scaleToFill" />
           </view>
         </view>
-        <view class="flex items-center gap-18rpx rounded-16rpx bg-#FFF px-24rpx py-28rpx" @click="router.push({ name: 'charge-voucher', params: { couponBalance: userAccountInfo?.couponBalance } })">
+        <view
+          class="flex items-center gap-18rpx rounded-16rpx bg-#FFF px-24rpx py-28rpx"
+          @click="router.push({ name: 'charge-voucher', params: { couponBalance: userAccountInfo?.couponBalance } })"
+        >
           <view>
             <view class="flex items-center gap-16rpx">
               <text class="text-32rpx font-bold">
@@ -245,11 +243,7 @@ function refund() {
             </view>
           </view>
           <view class="h-100rpx w-100rpx">
-            <image
-              class="h-100rpx w-100rpx"
-              :src="`${StaticUrl}/charge-mine-voucher.png`"
-              mode="scaleToFill"
-            />
+            <image class="h-100rpx w-100rpx" :src="`${StaticUrl}/charge-mine-voucher.png`" mode="scaleToFill" />
           </view>
         </view>
       </view>
@@ -258,49 +252,63 @@ function refund() {
           我的车辆
         </view>
         <!-- 无车辆时显示添加提示 -->
-        <view v-if="!defaultVehicle" class="flex items-center gap-10rpx" @click="router.push({ name: 'charge-plate-list' })">
+        <view
+          v-if="!defaultVehicle" class="flex items-center gap-10rpx"
+          @click="router.push({ name: 'charge-plate-list' })"
+        >
           <view class="text-26rpx">
             添加车辆,享更多权益
           </view>
-          <view class="h-50rpx w-50rpx rounded-50% bg-[linear-gradient(90deg,#DBFC81_0%,#9ED605_100%)] text-center text-30rpx text-#FFF font-bold line-height-[50rpx]">
+          <view
+            class="h-50rpx w-50rpx rounded-50% bg-[linear-gradient(90deg,#DBFC81_0%,#9ED605_100%)] text-center text-30rpx text-#FFF font-bold line-height-[50rpx]"
+          >
             +
           </view>
         </view>
         <!-- 有车辆时显示车牌和管理入口 -->
-        <view v-else class="flex items-center gap-50rpx text-26rpx text-#9ED605" @click="router.push({ name: 'charge-plate-list' })">
+        <view
+          v-else class="flex items-center gap-50rpx text-26rpx text-[var(--them-color)]"
+          @click="router.push({ name: 'charge-plate-list' })"
+        >
           <view>{{ defaultVehicle.licensePlate }}</view>
           <view>管理>></view>
         </view>
       </view>
       <view class="mt-24rpx flex items-center gap-20rpx">
         <view
-          v-for="option in filterOptions"
-          :key="option.key"
+          v-for="option in filterOptions" :key="option.key"
           class="select-item h-60rpx w-152rpx text-28rpx line-height-[60rpx]" :class="[
             option.widthClass,
             { 'select-item-active': activeFilter === option.key },
-          ]"
-          @click="handleFilterClick(option.key)"
+          ]" @click="handleFilterClick(option.key)"
         >
           {{ option.label }}
         </view>
       </view>
       <view :class="[loading ? 'pt-24rpx' : '']">
-        <wd-skeleton theme="paragraph" animation="gradient" :loading="loading" :row-col="[{ height: '100px', width: '100%' }, { height: '100px', width: '100%' }, { height: '100px', width: '100%' }]">
-          <view v-for="item in stationList" :key="item.stationId" class="relative mt-24rpx rounded-16rpx bg-#FFFFFF p-24rpx" @click="router.push({ name: 'charge-site-detail', params: { stationId: String(item.stationId) } })">
-            <image
-              class="absolute right-0 top-0 h-52rpx w-186rpx"
-              :src="`${StaticUrl}/charge-firm-tag.png`"
-            />
+        <wd-skeleton
+          theme="paragraph" animation="gradient" :loading="loading"
+          :row-col="[{ height: '100px', width: '100%' }, { height: '100px', width: '100%' }, { height: '100px', width: '100%' }]"
+        >
+          <view
+            v-for="item in stationList" :key="item.stationId"
+            class="relative mt-24rpx rounded-16rpx bg-#FFFFFF p-24rpx"
+            @click="router.push({ name: 'charge-site-detail', params: { stationId: String(item.stationId) } })"
+          >
+            <image class="absolute right-0 top-0 h-52rpx w-186rpx" :src="`${StaticUrl}/charge-firm-tag.png`" />
             <view class="text-32rpx text-#2B303A font-bold">
               {{ item.stationName }}
             </view>
             <view class="mt-20rpx text-24rpx text-#aaa">
               {{ item.tips || '暂无提示' }}
             </view>
-            <view class="mt-24rpx flex items-center rounded-16rpx bg-[linear-gradient(90deg,rgba(170,255,235,0.3)_0%,rgba(175,247,252,0.2)_43.57%,rgba(139,232,252,0)_100%)] p-20rpx">
+            <view
+              class="mt-24rpx flex items-center rounded-16rpx bg-[linear-gradient(90deg,rgba(170,255,235,0.3)_0%,rgba(175,247,252,0.2)_43.57%,rgba(139,232,252,0)_100%)] p-20rpx"
+            >
               <view class="flex items-center gap-16rpx">
-                <view class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#4FEF86_0%,#00AA3A_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]">
+                <view
+                  class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#4FEF86_0%,#00AA3A_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]"
+                >
                 </view>
                 <view class="flex items-center">
@@ -310,7 +318,9 @@ function refund() {
                 </view>
               </view>
               <view class="ml-40rpx flex items-center gap-16rpx">
-                <view class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#8EB1FF_0%,#3071FF_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]">
+                <view
+                  class="h-40rpx w-40rpx rounded-8rpx bg-[linear-gradient(180deg,#8EB1FF_0%,#3071FF_100%)] text-center text-28rpx text-#FFF font-bold line-height-[40rpx]"
+                >
                 </view>
                 <view class="flex items-center">
@@ -319,7 +329,9 @@ function refund() {
                   </text>
                 </view>
               </view>
-              <view class="ml-150rpx h-44rpx w-148rpx flex items-center border-2rpx border-#3EB6F8 rounded-34rpx border-solid line-height-[44rpx]">
+              <view
+                class="ml-150rpx h-44rpx w-148rpx flex items-center border-2rpx border-#3EB6F8 rounded-34rpx border-solid line-height-[44rpx]"
+              >
                 <view class="w-44rpx rounded-[34rpx_0rpx_0rpx_34rpx] bg-#3EB6F8 text-center">
                   <wd-icon name="location" size="16px" color="#FFF" />
                 </view>
@@ -338,10 +350,7 @@ function refund() {
                     元/度
                   </text>
                 </view>
-                <image
-                  class="absolute h-60rpx w-365rpx -top-30rpx"
-                  :src="`${StaticUrl}/to-charge-tag.png`"
-                />
+                <image class="absolute h-60rpx w-365rpx -top-30rpx" :src="`${StaticUrl}/to-charge-tag.png`" />
               </view>
               <view class="text-24rpx text-#2B303A">
                 {{ item.peakValue }}:{{ item.peakTime }}
@@ -364,17 +373,19 @@ function refund() {
   padding: 24rpx;
   margin-top: 24rpx;
 }
-.select-item{
-background: #FFFFFF;
-border-radius: 16rpx;
-color: #2B303A;
-text-align: center;
+
+.select-item {
+  background: #FFFFFF;
+  border-radius: 16rpx;
+  color: #2B303A;
+  text-align: center;
 }
-.select-item-active{
-background: #9ED605;
-box-shadow: inset 0rpx 20rpx 40rpx 2rpx rgba(100,255,218,0.26);
-border-radius: 0rpx 16rpx 0rpx 16rpx;
-font-weight: bold;
-color: #FFFFFF;
+
+.select-item-active {
+  background: var(--them-color);
+  box-shadow: inset 0rpx 20rpx 40rpx 2rpx rgba(100, 255, 218, 0.26);
+  border-radius: 0rpx 16rpx 0rpx 16rpx;
+  font-weight: bold;
+  color: #FFFFFF;
 }
 </style>

+ 15 - 1
src/subPack-charge/utils/index.ts

@@ -1,10 +1,14 @@
+// #ifdef H5
+import jzH5ScanCode from 'jz-h5-scanCode/js/index.js'
+// #endif
+
 /**
  * @param statusName 去掉括号及括号内的内容
  */
+
 export function formatStatusName(statusName: string) {
   return statusName.replace(/\([^)]*\)/g, '')
 }
-
 /**
  * 统一充电订单状态处理
  * @param order
@@ -82,6 +86,7 @@ export class ScanCodeUtil {
    */
   static scan(opts: any = {}) {
     return new Promise((resolve, reject) => {
+      // #ifdef MP-WEIXIN
       uni.scanCode(
         Object.assign(
           {},
@@ -92,6 +97,14 @@ export class ScanCodeUtil {
           opts,
         ),
       )
+      // #endif
+      // #ifdef H5
+      jzH5ScanCode.scanCode({
+        ...opts,
+        success: (res: any) => resolve(res),
+        fail: reject,
+      })
+      // #endif
     })
   }
 
@@ -135,6 +148,7 @@ export class ScanCodeUtil {
     }
     catch (error) {
       console.error('扫码或解析失败:', error)
+      useGlobalToast().show(`扫码或解析失败:${error}`)
       throw error
     }
   }

+ 114 - 10
src/subPack-common/threePay/index.vue

@@ -1,39 +1,143 @@
 <script setup lang="ts">
 import type { wxpay } from '@/api/globals'
+import router from '@/router'
 
-definePage({ name: 'smqjh-threePay', islogin: false, style: { navigationBarTitleText: '支付' } })
+definePage({ name: 'smqjh-threePay', islogin: false, style: { navigationBarTitleText: '支付', navigationStyle: 'custom' } })
 
+const { token } = storeToRefs(useUserStore())
+const { tenantCode } = storeToRefs(useSysStore())
 const orderNumber = ref()
 onLoad((options: any) => {
   orderNumber.value = options.orderNumber
-  handlePay()
+  tenantCode.value = options.tenantCode
+  token.value = ''
+  handleLogin(options.phone)
+  console.log(options, '============options=======')
 })
 const priceInfo = ref<wxpay>()
+function handleLogin(phoneCode: string) {
+  uni.showLoading({ mask: true })
+  uni.login({
+    provider: 'weixin',
+    success: async (res) => {
+      const data = await Apis.sys.auth({
+        params: {
+          grant_type: 'wechat',
+          code: res.code,
+          phoneCode,
+        },
+      })
+      console.log(data, '============data=======')
+
+      token.value = `Bearer ${data.data.access_token}`
+      useUserStore().getUserInfo()
+      handlePay()
+    },
+    complete: () => {
+      uni.hideLoading()
+    },
+  })
+}
+
 async function handlePay() {
   const res = await useUserStore().handleCommonPayMent(orderNumber.value)
   priceInfo.value = res
+  console.log(priceInfo.value, '=========================')
 }
 async function handleGoPay() {
   if (priceInfo.value?.payType !== 1) {
     try {
       await useUserStore().getWxCommonPayment(priceInfo.value as wxpay)
+      router.push({ name: 'common-threePayRes', params: { price: String(priceInfo.value?.price), type: '1' } })
     }
-    catch {
+    catch (error: any) {
+      console.log(error, '=========================')
+
+      router.push({ name: 'common-threePayRes', params: { price: String(priceInfo.value?.price), type: '0', error: error.errMsg } })
       // console.log(111)
-      useGlobalToast().show({ msg: '支付失败!请重试' })
     }
   }
 }
+
+// 倒计时:15分钟 = 900秒
+const COUNTDOWN_SECONDS = 15 * 60
+const countdown = ref(COUNTDOWN_SECONDS)
+const countdownTimer = ref<ReturnType<typeof setInterval> | null>(null)
+
+// 模块级变量:记录倒计时结束的时间戳,离页后回来可继续
+// 页面卸载(onUnload)时重置,保证下次进入是全新的15分钟
+let endTimestamp: number | null = null
+
+// 格式化为 MM:SS
+const countdownText = computed(() => {
+  const m = Math.floor(countdown.value / 60).toString().padStart(2, '0')
+  const s = (countdown.value % 60).toString().padStart(2, '0')
+  return `${m}:${s}`
+})
+
+function updateCountdown() {
+  if (!endTimestamp)
+    return
+  const remaining = Math.max(0, Math.ceil((endTimestamp - Date.now()) / 1000))
+  countdown.value = remaining
+  if (remaining <= 0) {
+    stopCountdown()
+    // TODO: 倒计时结束后的跳转逻辑
+    router.push({ name: 'common-threePayRes', params: { price: String(priceInfo.value?.price), type: '0' } })
+  }
+}
+
+function startCountdown() {
+  // 首次进入:初始化结束时间戳
+  if (!endTimestamp) {
+    endTimestamp = Date.now() + COUNTDOWN_SECONDS * 1000
+  }
+  // 立即同步一次剩余时间(防止回来时短暂显示旧值)
+  updateCountdown()
+  stopCountdown()
+  countdownTimer.value = setInterval(updateCountdown, 1000)
+}
+
+function stopCountdown() {
+  if (countdownTimer.value) {
+    clearInterval(countdownTimer.value)
+    countdownTimer.value = null
+  }
+}
+
+// 页面显示时启动/恢复倒计时(含首次进入和从其他页面返回)
+onShow(() => {
+  startCountdown()
+})
+
+// 离开页面时暂停定时器,但保留 endTimestamp
+onHide(() => {
+  stopCountdown()
+})
+
+// 页面卸载时清理,下次进入重新开始
+onUnload(() => {
+  stopCountdown()
+  endTimestamp = null
+})
 </script>
 
 <template>
-  <view class="px20rpx pt20rpx">
-    <view class="mb20rpx text-center text-48rpx text-#FF4A39">
-      ¥{{ priceInfo?.price }}
+  <view>
+    <wd-navbar title="支付" :bordered="false" :z-index="99" safe-area-inset-top placeholder fixed />
+    <view v-if="priceInfo" class="px20rpx pt20rpx">
+      <view class="text-center text-48rpx text-#FF4A39">
+        ¥{{ (priceInfo?.price / 100).toFixed(2) }}
+      </view>
+      <view class="mb20rpx mt24rpx text-center text-26rpx text-[#999]">
+        支付剩余时间:<text class="text-[#FF4A39] font-semibold">
+          {{ countdownText }}
+        </text>
+      </view>
+      <wd-button block @click="handleGoPay">
+        确认支付
+      </wd-button>
     </view>
-    <wd-button block @click="handleGoPay">
-      确认支付
-    </wd-button>
   </view>
 </template>
 

+ 72 - 0
src/subPack-common/threePayRes/index.vue

@@ -0,0 +1,72 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'common-threePayRes',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付结果',
+    navigationStyle: 'custom',
+    disableScroll: true,
+  },
+})
+const price = ref()
+const type = ref(0) // 1支付成功,0支付失败
+const error = ref('支付超时')
+
+onLoad((options: any) => {
+  price.value = options.price
+  if (options.error) {
+    error.value = options.error
+  }
+  type.value = Number(options.type)
+})
+function handleClose() {
+  // 关闭当前小程序
+  uni.exitMiniProgram()
+}
+</script>
+
+<template>
+  <view class="pages">
+    <wd-navbar
+      title="支付结果" custom-style="background-color:transparent !important" :bordered="false" :z-index="99"
+
+      safe-area-inset-top left-arrow fixed
+      @click-left="handleClose"
+    />
+    <view class="header-line h406rpx" />
+    <view class="-mt200rpx">
+      <view class="flex flex-col items-center">
+        <image
+          :src="`${StaticUrl}/revalue-success.png`"
+          class="h200rpx w200rpx"
+        />
+        <view class="mt20rpx text-32rpx font-semibold">
+          {{ type === 1 ? '支付成功' : '支付失败' }}
+        </view>
+        <view v-if="type == 0" class="mt20rpx text-24rpx text-#AAAAAA">
+          失败原因:{{ error }}
+        </view>
+        <view v-else class="mt20rpx text-24rpx text-#AAAAAA">
+          实付金额:<text class="text-32rpx text-#FF4A39">
+            ¥{{ (price / 100).toFixed(2) }}
+          </text>
+        </view>
+        <view class="mt60rpx flex items-center">
+          <wd-button block size="large" @click="handleClose">
+            <text class="text-32rpx font-semibold">
+              关闭页面
+            </text>
+          </wd-button>
+        </view>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style scoped>
+.header-line{
+  background: linear-gradient( 179deg, rgba(190,255,13,0.4) 0%, rgba(220,255,125,0.2) 49%, rgba(158,214,5,0) 100%);
+}
+</style>

+ 61 - 4
src/subPack-common/user-center/index.vue

@@ -1,5 +1,6 @@
 <script setup lang="ts">
 import router from '@/router'
+import { BASE_URL } from '@/config'
 
 definePage({
   name: 'common-user-center',
@@ -9,11 +10,62 @@ definePage({
   },
 })
 const { userInfo, getUserAvatar } = storeToRefs(useUserStore())
+
+async function uploadAvatar(filePath: string) {
+  uni.showLoading({ title: '上传中...', mask: true })
+  try {
+    const { token } = useUserStore()
+    const uploadRes = await new Promise<UniApp.UploadFileSuccessCallbackResult>((resolve, reject) => {
+      uni.uploadFile({
+        url: `${BASE_URL}/smqjh-system/api/v1/files`,
+        filePath,
+        name: 'file',
+        header: {
+          authorization: token || 'Basic c21xamgtYXBwbGV0OjEyMzQ1Ng==',
+        },
+        success: resolve,
+        fail: reject,
+      })
+    })
+    const data = JSON.parse(uploadRes.data)
+    const url = data?.data?.url || data?.url
+    if (!url) {
+      useGlobalToast().show({ msg: '上传失败' })
+      return
+    }
+    await useUserStore().updataUserInfo({ ...userInfo.value, avatarUrl: url })
+  }
+  finally {
+    uni.hideLoading()
+  }
+}
+
 async function handleChooseAvatar(e: UniHelper.ButtonOnChooseavatarEvent) {
-  const res = await Apis.sys.uploadFile({ data: { filePath: e.avatarUrl, name: 'file' }, fileType: 'image', requestType: 'upload', headers: {
-    'Content-Type': 'multipart/form-data',
-  } })
-  useUserStore().updataUserInfo({ ...userInfo.value, avatarUrl: res.url })
+  await uploadAvatar(e.avatarUrl)
+}
+
+function chooseImage() {
+  return new Promise<UniApp.ChooseImageSuccessCallbackResult>((resolve, reject) => {
+    uni.chooseImage({
+      count: 1,
+      sizeType: ['compressed'],
+      sourceType: ['album', 'camera'],
+      success: resolve,
+      fail: reject,
+    })
+  })
+}
+
+async function handleUplaod() {
+  // #ifdef H5
+  const res = await chooseImage()
+  const filePath = res.tempFilePaths?.[0]
+  console.log(filePath, '======================')
+  if (!filePath) {
+    return
+  }
+  await uploadAvatar(filePath)
+  // #endif
 }
 </script>
 
@@ -23,7 +75,12 @@ async function handleChooseAvatar(e: UniHelper.ButtonOnChooseavatarEvent) {
       <view class="flex items-center justify-between">
         <view>头像</view>
         <view class="h60rpx w60rpx">
+          <!-- #ifdef MP-WEIXIN -->
           <wd-button :icon="getUserAvatar" type="icon" open-type="chooseAvatar" @chooseavatar="handleChooseAvatar" />
+          <!-- #endif -->
+          <!-- #ifdef H5 -->
+          <wd-button :icon="getUserAvatar" type="icon" @click="handleUplaod" />
+          <!-- #endif -->
         </view>
       </view>
       <view class="mt26rpx flex items-center justify-between" @click="router.push({ name: 'common-nickName' })">

+ 6 - 7
src/subPack-djk/commonTab/index.vue

@@ -27,9 +27,9 @@ onMounted(() => {
   refreshOrderList.value = false
 })
 const tabbarItems = ref([
-  { name: 'djk-home', value: null, active: true, title: '首页', icon1: `${StaticUrl}/djk-idx0.png`, icon2: `${StaticUrl}/djk-idx1.png` },
-  { name: 'djk-fl', value: null, active: false, title: '福利中心', icon1: `${StaticUrl}/djk-fl0.png`, icon2: `${StaticUrl}/djk-fl1.png` },
-  { name: 'djk-order', value: null, active: false, title: '订单', icon1: `${StaticUrl}/djk-order0.png`, icon2: `${StaticUrl}/djk-order1.png` },
+  { name: 'djk-home', value: null, active: true, title: '首页', icon: '' },
+  { name: 'djk-fl', value: null, active: false, title: '福利中心', icon: '' },
+  { name: 'djk-order', value: null, active: false, title: '订单', icon: '' },
 ])
 const tabbarName = ref('djk-home')
 const welfare = ref<Api.DjkWelfareVO>()
@@ -75,14 +75,13 @@ getData()
       >
         <template #icon="{ active }">
           <template v-if="index == 0 && !active">
-            <image :src="item.icon1" class="h44rpx w44rpx" />
+            <i class="iconfont text-44rpx">&#xe644;</i>
           </template>
           <template v-else-if="index == 0 && active">
-            <image :src="item.icon2" class="h74rpx w74rpx" />
+            <i class="iconfont text-76rpx text-[var(--them-color)]">&#xe637;</i>
           </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" />
+            <i :class="[active ? 'text-[var(--them-color)]' : '']" class="iconfont text-44rpx">{{ item.icon }}</i>
           </template>
         </template>
       </wd-tabbar-item>

+ 6 - 0
src/subPack-djk/confirmOrder/index.vue

@@ -36,6 +36,7 @@ async function handlePay() {
   isPay.value = true
   try {
     const data = await Apis.djk.addDJKOrder({ data: { shopId: orderInfo.value.shopId, channelId: useUserStore().userInfo.channelId, phone: phone.value, goodsId: orderInfo.value.id, goodsNum: 1, customerAuthorization: boolToNumber(isAllow.value) } })
+    // #ifdef MP-WEIXIN
     const res = await useUserStore().handleCommonPayMent(data.data)
     if (res.payType !== 1) {
       try {
@@ -49,6 +50,11 @@ async function handlePay() {
     else {
       await useUserStore().paySuccess('djk-homeTabbar', 'subPack-djk/commonTab/index')
     }
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(data.data)
+    isPay.value = false
+    // #endif
   }
   catch (error) {
     console.log('error', error)

+ 5 - 0
src/subPack-djk/orderDetaile/index.vue

@@ -34,8 +34,13 @@ async function handleCancel() {
 async function handlePay() {
   const res = await useUserStore().handleCommonPayMent(String(unref(orderInfo)?.orderNumber))
   if (res.payType !== 1) {
+    // #ifdef MP-WEIXIN
     await useUserStore().getWxCommonPayment(res)
     getDetail(String(unref(orderInfo)?.orderNumber))
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(String(unref(orderInfo)?.orderNumber))
+    // #endif
   }
   else {
     getDetail(String(unref(orderInfo)?.orderNumber))

+ 36 - 39
src/subPack-film/choose-film/index.vue

@@ -2,7 +2,6 @@
 import { ref, watch } from 'vue'
 import selectTime from '../components/choose-time.vue'
 import { timeFormat } from '../utils/index'
-import { StaticUrl } from '@/config'
 
 interface brand {
   id: number
@@ -191,28 +190,25 @@ onLoad((options) => {
           <view class="choose-item-title">
             全城
           </view>
-          <image
-            class="icon" :src="StaticUrl + (active == 0 ? '/film-choose-active.png' : '/film-choose.png')"
-            mode="scaleToFill"
-          />
+          <view class="iconfont ml10rpx text-30rpx" :class="[active == 0 ? 'text-[var(--them-color)]' : '']">
+            &#xe656;
+          </view>
         </view>
         <view class="choose-item" :class="[active == 1 ? 'active' : '']" @click="handleChoose(1)">
           <view class="choose-item-title">
             品牌
           </view>
-          <image
-            class="icon" :src="StaticUrl + (active == 1 ? '/film-choose-active.png' : '/film-choose.png')"
-            mode="scaleToFill"
-          />
+          <view class="iconfont ml10rpx text-30rpx" :class="[active == 1 ? 'text-[var(--them-color)]' : '']">
+            &#xe656;
+          </view>
         </view>
         <view class="choose-item" :class="[active == 2 ? 'active' : '']" @click="handleChoose(2)">
           <view class="choose-item-title">
             特色
           </view>
-          <image
-            class="icon" :src="StaticUrl + (active == 2 ? '/film-choose-active.png' : '/film-choose.png')"
-            mode="scaleToFill"
-          />
+          <view class="iconfont ml10rpx text-30rpx" :class="[active == 2 ? 'text-[var(--them-color)]' : '']">
+            &#xe656;
+          </view>
         </view>
       </view>
     </view>
@@ -264,28 +260,25 @@ onLoad((options) => {
             <view class="choose-item-title">
               全城
             </view>
-            <image
-              class="icon" :src="StaticUrl + (active == 0 ? '/film-choose-active.png' : '/film-choose.png')"
-              mode="scaleToFill"
-            />
+            <view class="iconfont ml10rpx text-30rpx" :class="[active == 0 ? 'text-[var(--them-color)]' : '']">
+              &#xe656;
+            </view>
           </view>
           <view class="choose-item" :class="[active == 1 ? 'active' : '']" @click="handleChoose(1)">
             <view class="choose-item-title">
               品牌
             </view>
-            <image
-              class="icon" :src="StaticUrl + (active == 1 ? '/film-choose-active.png' : '/film-choose.png')"
-              mode="scaleToFill"
-            />
+            <view class="iconfont ml10rpx text-30rpx" :class="[active == 1 ? 'text-[var(--them-color)]' : '']">
+              &#xe656;
+            </view>
           </view>
           <view class="choose-item" :class="[active == 2 ? 'active' : '']" @click="handleChoose(2)">
             <view class="choose-item-title">
               特色
             </view>
-            <image
-              class="icon" :src="StaticUrl + (active == 2 ? '/film-choose-active.png' : '/film-choose.png')"
-              mode="scaleToFill"
-            />
+            <view class="iconfont ml10rpx text-30rpx" :class="[active == 2 ? 'text-[var(--them-color)]' : '']">
+              &#xe656;
+            </view>
           </view>
         </view>
         <view v-if="active == 0" class="choose-box">
@@ -302,10 +295,13 @@ onLoad((options) => {
               <view class="name">
                 全城
               </view>
-              <image
+              <!-- <image
                 v-if="query.districtId === ''" class="icon" :src="`${StaticUrl}/film-choose-icon.png`"
                 mode="scaleToFill"
-              />
+              /> -->
+              <view v-if="query.districtId === ''" class="iconfont ml10rpx text-30rpx text-[var(--them-color)]">
+                &#xe657;
+              </view>
             </view>
             <view
               v-for="(item, index) in cityList[currentCity].districts" :key="index" class="choose-item"
@@ -314,10 +310,13 @@ onLoad((options) => {
               <view class="name" :class="[query.districtId == item.districtId ? 'active' : '']">
                 {{ item.districtName }}
               </view>
-              <image
+              <!-- <image
                 v-if="query.districtId == item.districtId" class="icon" :src="`${StaticUrl}/film-choose-icon.png`"
                 mode="scaleToFill"
-              />
+              /> -->
+              <view v-if="query.districtId == item.districtId" class="iconfont ml10rpx text-30rpx text-[var(--them-color)]">
+                &#xe657;
+              </view>
             </view>
           </view>
         </view>
@@ -327,19 +326,17 @@ onLoad((options) => {
               <view class="name">
                 全部
               </view>
-              <image
-                v-if="query.brandId === ''" class="icon" :src="`${StaticUrl}/film-choose-icon.png`"
-                mode="scaleToFill"
-              />
+              <view v-if="query.brandId === ''" class="iconfont ml10rpx text-30rpx text-[var(--them-color)]">
+                &#xe657;
+              </view>
             </view>
             <view v-for="(item, index) in brandList" :key="index" class="choose-item" @click="choose(item.brandId)">
               <view class="name" :class="[query.brandId == item.brandId ? 'active' : '']">
                 {{ item.brandName }}
               </view>
-              <image
-                v-if="query.brandId == item.brandId" class="icon" :src="`${StaticUrl}/film-choose-icon.png`"
-                mode="scaleToFill"
-              />
+              <view v-if="query.brandId == item.brandId" class="iconfont ml10rpx text-30rpx text-[var(--them-color)]">
+                &#xe657;
+              </view>
             </view>
           </view>
         </view>
@@ -510,7 +507,7 @@ onLoad((options) => {
       }
       &.active{
         .choose-item-title{
-          color: #9ED605;
+          color: var(--them-color);
         }
       }
     }
@@ -603,7 +600,7 @@ onLoad((options) => {
         }
       }
       .name.active{
-          color: #9ED605;
+          color: var(--them-color);
       }
     }
   }

+ 1 - 2
src/subPack-film/choose-seat/components/pages/CanvasSeatmap.vue

@@ -25,8 +25,6 @@ export default {
     async init({ seatList, options }) {
       this.seatList = seatList
       this.options = options
-      console.log(options)
-
       // #ifdef MP-WEIXIN || H5 || MP-ALIPAY
       this.onCanvasReady()
       // #endif
@@ -48,6 +46,7 @@ export default {
         canvas.height = canvasHeight * pixelRatio
         ctx.scale(pixelRatio, pixelRatio)
         // #endif
+
         this.seatmapInstance = new Seatmap({
           canvas,
           seatList,

+ 16 - 9
src/subPack-film/choose-seat/components/pages/canvasOperator.js

@@ -5,15 +5,23 @@ export default class CanvasOperator {
 
   /* ---------- RAF 封装 ---------- */
   raf(cb) {
-    // #ifdef MP-WEIXIN || MP-ALIPAY
-    return this.canvas.requestAnimationFrame(cb)
-    // #endif
+    if (typeof this.canvas.requestAnimationFrame === 'function') {
+      return this.canvas.requestAnimationFrame(cb)
+    }
+    if (typeof requestAnimationFrame === 'function') {
+      return requestAnimationFrame(cb)
+    }
+    return setTimeout(cb, 16)
   }
 
   cancelRaf(id) {
-    // #ifdef MP-WEIXIN || MP-ALIPAY
-    return this.canvas.cancelAnimationFrame(id)
-    // #endif
+    if (typeof this.canvas.cancelAnimationFrame === 'function') {
+      return this.canvas.cancelAnimationFrame(id)
+    }
+    if (typeof cancelAnimationFrame === 'function') {
+      return cancelAnimationFrame(id)
+    }
+    return clearTimeout(id)
   }
 
   /* ---------- 图片加载 ---------- */
@@ -25,10 +33,9 @@ export default class CanvasOperator {
     if (typeof Image !== 'undefined') {
       img = new Image()
     }
-    // if (typeof wx !== 'undefined') {
-    //   filePath = `/${filePath}` // 微信环境下添加前缀/
-    // }
+    // #ifndef H5
     img.crossOrigin = 'anonymous'
+    // #endif
     return new Promise((resolve, reject) => {
       img.src = filePath
       img.onload = () => resolve(img)

+ 3 - 1
src/subPack-film/choose-seat/components/pages/main.js

@@ -160,7 +160,9 @@ export default class seatmap {
     const { canvasX, canvasY } = this.calc.clientToCanvas({ x, y, panX, panY })
 
     const seat = this.seatList.find((item) => {
-      const { points: { startX, startY, endX, endY } } = item
+      if (!item.points)
+        return false
+      const { startX, startY, endX, endY } = item.points
       return (canvasX >= startX && canvasX <= endX && canvasY >= startY && canvasY <= endY)
     })
     if (!seat || ![AVAILABLE, SELECTED].includes(seat[STATUS_NAME])) {

+ 6 - 3
src/subPack-film/choose-seat/index.vue

@@ -250,8 +250,11 @@ async function getData(sessionId: string, movieId: string, cinemaId: string): Pr
         seatType,
         seatName: seat.seatName,
         seatId: seat.originSeatID,
-        columnId: seat.colId,
-        rowId: item.rowsId,
+        columnId: seat.colNum,
+        rowId: item.rowsNum,
+        // columnId: i,
+        // rowId: index,
+
         areaId: seat.areaId,
         marketPrice,
         ticketPrice: price,
@@ -262,7 +265,6 @@ async function getData(sessionId: string, movieId: string, cinemaId: string): Pr
   }
 
   console.log(2222, areaList.value)
-
   // 赋值座位图配置项(严格符合 SeatmapOptions 接口)
   options.value = {
     title: '',
@@ -340,6 +342,7 @@ function onError(e: { message: string }): void {
  */
 function onSeatTap(event: SeatTapEvent): void {
   chooseSeatList.value = event.chooseSeatList
+  console.log('chooseSeatList', event)
   console.log('zuoshsjd', chooseSeatList.value)
   // 遍历已选座位列表,累加价格(严格类型访问)
   let price = 0

+ 1 - 1
src/subPack-film/components/choose-time.vue

@@ -56,7 +56,7 @@ function handleTab(val: string) {
           transform: translateX(-50%);
           width: 28rpx;
           height: 6rpx;
-          background: #9ED605;
+          background: var(--them-color);
           border-radius: 4rpx 4rpx 4rpx 4rpx;
         }
       }

+ 13 - 11
src/subPack-film/components/tabbar.vue

@@ -1,5 +1,4 @@
 <script setup lang="ts">
-import { StaticUrl } from '@/config'
 import router from '@/router'
 
 defineProps({
@@ -10,9 +9,9 @@ defineProps({
 })
 
 const tabList = reactive([
-  { title: '首页', src: `${StaticUrl}/film-home.png`, activeSrc: `${StaticUrl}/film-active-home.png`, path: 'film-index' },
-  { title: '电影/影院', src: `${StaticUrl}/film-movie.png`, activeSrc: `${StaticUrl}/film-active-movie.png`, path: 'film-movie' },
-  { title: '订单', src: `${StaticUrl}/film-order.png`, activeSrc: `${StaticUrl}/film-active-order.png`, path: 'film-order' },
+  { title: '首页', icon: '', path: 'film-index' },
+  { title: '电影/影院', icon: '', path: 'film-movie' },
+  { title: '订单', icon: '', path: 'film-order' },
 ])
 
 function handleItem(name: string) {
@@ -21,11 +20,13 @@ function handleItem(name: string) {
 </script>
 
 <template>
-  <view class="tabbar">
-    <view v-for="(item, index) in tabList" :key="index" class="item" @click="handleItem(item.path)">
-      <image class="img" :src="active == index ? item.activeSrc : item.src" mode="aspectFill" />
-      <view class="title" :class="[active == index ? 'active' : '']">
-        {{ item.title }}
+  <view>
+    <view class="tabbar">
+      <view v-for="(item, index) in tabList" :key="index" class="item pt20rpx" @click="handleItem(item.path)">
+        <i class="iconfont text-44rpx" :class="[active == index ? 'text-[var(--them-color)]' : '']">{{ item.icon }}</i>
+        <view class="title" :class="[active == index ? 'active' : '']">
+          {{ item.title }}
+        </view>
       </view>
     </view>
   </view>
@@ -34,13 +35,14 @@ function handleItem(name: string) {
 <style lang="scss" scoped>
 .tabbar{
     display: flex;
-    justify-content: space-around;
-    width: 750rpx;
+    justify-content: space-between;
+    width: 100%;
     height: 166rpx;
     background: #FFFFFF;
     box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(0, 0, 0, 0.09);
     border-radius: 32rpx 32rpx 0rpx 0rpx;
     position: fixed;
+    box-sizing: border-box;
     bottom: 0;
     left: 0;
     z-index: 99999;

+ 1 - 1
src/subPack-film/index/index.vue

@@ -134,7 +134,7 @@ onMounted(() => {
             height: 44rpx;
             line-height: 44rpx;
             text-align: center;
-            background: #9ED605;
+            background: var(--them-color);
             border-radius: 26rpx 26rpx 26rpx 26rpx;
             font-size: 28rpx;
             color: #FFFFFF;

+ 1 - 1
src/subPack-film/movie/index.vue

@@ -451,7 +451,7 @@ onMounted(() => {
           height: 52rpx;
           line-height: 52rpx;
           text-align: center;
-          background: #9ED605;
+          background: var(--them-color);
           border-radius: 26rpx 26rpx 26rpx 26rpx;
           font-size: 28rpx;
           color: #FFFFFF;

+ 159 - 0
src/subPack-refueling/activityCenter/index.vue

@@ -0,0 +1,159 @@
+<script setup lang="ts">
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'activityCenter-detail',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '活动详情',
+    navigationStyle: 'custom',
+  },
+})
+
+const couponInfo = ref<Api.CouponInfoAppVo>()
+
+const { send } = useRequest(couponId => Apis.app.get_smqjh_system_app_api_coupon_findbyid({ params: { couponId } }), {
+  immediate: false,
+}).onSuccess((res) => {
+  couponInfo.value = res.data.data
+})
+
+onLoad((options: any) => {
+  send(options.id)
+})
+
+// 抵扣信息文案
+const discountText = computed(() => {
+  if (!couponInfo.value)
+    return ''
+  const discount = (couponInfo.value.discountMoney || 0)
+  const amount = (couponInfo.value.amountMoney || 0)
+  return `抵扣${discount}元(满${amount}元可用)`
+})
+
+// 活动状态
+const activityStatus = computed(() => {
+  if (!couponInfo.value)
+    return ''
+  const now = Date.now()
+  const start = couponInfo.value.couponStartTime ? new Date(couponInfo.value.couponStartTime).getTime() : 0
+  const end = couponInfo.value.couponEndTime ? new Date(couponInfo.value.couponEndTime).getTime() : 0
+
+  if (start && now < start)
+    return '未开始'
+  if (end && now > end)
+    return '已结束'
+  return '进行中'
+})
+
+// 活动规则
+const rules = computed(() => [
+  {
+    title: '1.抵扣券',
+    items: [discountText.value],
+  },
+  {
+    title: '2.使用限制',
+    items: ['每单限用1张', '不可与其他优惠同享'],
+  },
+  {
+    title: '3.使用油站',
+    items: ['全部合作油站', '部分油站不可用'],
+  },
+  {
+    title: '4.有效期',
+    items: [`领取后${couponInfo.value?.expirationDate || 7}天内有效`],
+  },
+])
+
+// 领取活动
+function handleClaim() {
+  useUserStore().handleExchange(couponInfo.value)
+}
+</script>
+
+<template>
+  <view v-if="couponInfo" class="activity-page pt20rpx">
+    <!-- 活动卡片 -->
+    <view class="mx24rpx overflow-hidden rounded-16rpx">
+      <view class="pages-bg flex items-center justify-between px24rpx py28rpx">
+        <view>
+          <view class="text-32rpx text-#333 font-semibold">
+            {{ couponInfo.activityName }}
+          </view>
+          <view class="mt12rpx text-28rpx">
+            {{ discountText }}
+          </view>
+        </view>
+        <image
+          :src="`${StaticUrl}/smqjh-jy-center.png`"
+          class="h156rpx w156rpx"
+        />
+      </view>
+    </view>
+
+    <!-- 活动状态信息 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+      <view class="flex items-center text-28rpx">
+        <view class="text-#666">
+          活动状态:
+        </view>
+        <view class="text-#333">
+          {{ activityStatus }}
+        </view>
+      </view>
+      <view class="mt20rpx flex items-center text-28rpx">
+        <view class="text-#666">
+          活动ID:
+        </view>
+        <view class="text-#333">
+          {{ couponInfo.activityId }}
+        </view>
+      </view>
+      <view class="mt20rpx flex items-center text-28rpx">
+        <view class="text-#666">
+          剩余库存:
+        </view>
+        <view class="text-#333">
+          {{ couponInfo.inventoryActual }}张
+        </view>
+      </view>
+    </view>
+
+    <!-- 活动规则 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+      <view class="text-32rpx text-#333 font-semibold">
+        活动规则
+      </view>
+      <view v-for="(rule, index) in rules" :key="index" class="mt24rpx">
+        <view class="text-28rpx text-#333 font-medium">
+          {{ rule.title }}
+        </view>
+        <view v-for="(item, idx) in rule.items" :key="idx" class="mt12rpx text-26rpx text-#666">
+          {{ item }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部占位 -->
+    <view class="h200rpx" />
+    <FixedLayout>
+      <wd-button
+        block
+        size="large"
+        :disabled="couponInfo?.receiveSign || activityStatus !== '进行中'"
+        @click="handleClaim"
+      >
+        {{ couponInfo?.receiveSign ? '已领取' : '立即领取' }}
+      </wd-button>
+    </FixedLayout>
+  </view>
+
+  <!-- 底部固定按钮 -->
+</template>
+
+<style lang="scss" scoped>
+.pages-bg{
+  background: linear-gradient( 180deg, #FFDCDC 0%, #FFFFFF 100%);
+}
+</style>

+ 130 - 0
src/subPack-refueling/activityList/index.vue

@@ -0,0 +1,130 @@
+<script setup lang="ts">
+import router from '@/router'
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'activityList',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '活动中心',
+    navigationStyle: 'custom',
+  },
+})
+const showModel = ref(false)
+const clickItem = ref<Api.CouponInfoAppVo>()
+const { data, isLastPage, page, send } = usePagination((pageNum, pageSize) => Apis.app.get_smqjh_system_app_api_coupon_page({ params: {
+  pageNum,
+  pageSize,
+} }), {
+  initialPage: 1,
+  initialPageSize: 10,
+  data: res => res.data?.list,
+  append: true,
+  immediate: false,
+})
+onShow(() => {
+  data.value = []
+  send()
+},
+)
+
+// 查看详情
+function handleViewDetail(item: any) {
+  router.push({
+    name: 'activityCenter-detail',
+    params: { id: item.id },
+  })
+}
+
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
+function handleExchange(item: Api.CouponInfoAppVo) {
+  showModel.value = true
+  clickItem.value = item
+}
+</script>
+
+<template>
+  <view class="activity-list-page px24rpx pt20rpx">
+    <!-- 活动卡片列表 -->
+    <view
+      v-for="item in data"
+      :key="item.id"
+      class="activity-card mb24rpx overflow-hidden rounded-16rpx bg-white"
+    >
+      <view class="page-box flex flex-1 items-start justify-between px24rpx py28rpx">
+        <view class="flex-1">
+          <!-- 标题 -->
+          <view class="text-32rpx font-semibold">
+            {{ item.activityName }}
+          </view>
+          <!-- 抵扣信息 -->
+          <view class="mt16rpx text-28rpx text-#333">
+            抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
+          </view>
+          <!-- 有效期 -->
+          <view class="mt12rpx text-26rpx text-#666">
+            有效期:{{ item.expirationTime ? item.expirationTime : `领取过后${item.expirationDate}天有效` }}
+          </view>
+          <!-- 已领取数量 -->
+          <view class="mt12rpx text-26rpx text-#666">
+            已领取:{{ Number(item.inventoryTotal) - Number(item.inventoryActual) }} / {{ item.inventoryTotal }}
+          </view>
+          <!-- 状态 -->
+          <view v-if="item.receiveSign" class="mt12rpx text-26rpx text-#666">
+            状态:已领取
+          </view>
+        </view>
+
+        <!-- 右侧礼包图片 -->
+        <image
+          :src="`${StaticUrl}/smqjh-jy-center.png`"
+          class="ml20rpx h212rpx w212rpx flex-shrink-0"
+        />
+      </view>
+
+      <!-- 底部按钮 -->
+      <view class="flex justify-center pb28rpx">
+        <wd-button
+          v-if="!item.receiveSign"
+          size="small"
+          custom-class="exchange-btn"
+          @click="handleExchange(item)"
+        >
+          积分兑换
+        </wd-button>
+        <wd-button
+          v-else
+          size="small"
+          plain
+          custom-class="detail-btn"
+          @click="handleViewDetail(item)"
+        >
+          查看详情
+        </wd-button>
+      </view>
+    </view>
+    <StatusTip v-if="!data.length" tip="暂无活动" />
+    <IntegralPopup v-model="showModel" :coupon-id="String(clickItem?.id)" />
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.exchange-btn) {
+  min-width: 180rpx !important;
+  border-radius: 32rpx !important;
+}
+
+:deep(.detail-btn) {
+  min-width: 180rpx !important;
+  border-radius: 32rpx !important;
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+}
+.page-box{
+  background: linear-gradient( 180deg, #FFDCDC 0%, #FFF8F8 36.01%, #FFFFFF 100%);
+}
+</style>

+ 106 - 0
src/subPack-refueling/commonTab/components/index.vue

@@ -0,0 +1,106 @@
+<script setup lang="ts">
+import router from '@/router'
+import { StaticUrl } from '@/config'
+
+const tabList = ref([
+  { label: '距离优先', value: 1 },
+  { label: '价格从低到高', value: 0 },
+])
+const currentTab = ref(1)
+const { data, send, isLastPage, page, reload } = usePagination((pageNum, pageSize) =>
+  Apis.general.post_smqjh_pms_app_api_v1_product_oil_page(
+    { data: { pageNum, pageSize, lat: useAddressStore().Location.latitude, lon: useAddressStore().Location.longitude, sort: currentTab.value } },
+  ), {
+  initialPage: 1,
+  initialPageSize: 10,
+  immediate: false,
+  data: res => res.data?.list,
+  append: true,
+})
+
+function handleView(_item: any) {
+  router.push({
+    name: 'refuelDetaile',
+    params: { id: _item.storeId },
+  })
+}
+
+onLoad((_options: any) => {
+
+})
+onMounted(async () => {
+  await useAddressStore().getLocation()
+  send()
+  // #ifdef H5
+  // 解析浏览器 URL 参数,处理第三方支付回调
+  const urlParams = new URLSearchParams(window.location.search)
+  const payStatus = urlParams.get('payStatus')
+  const outerOrderId = urlParams.get('outerOrderId') || ''
+  if (payStatus !== null) {
+    router.push({ name: 'transition', params: { payStatus, outerOrderId } })
+  }
+  // #endif
+})
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
+watch(() => currentTab.value, () => {
+  reload()
+})
+</script>
+
+<template>
+  <view>
+    <view class="box-border px24rpx py20px">
+      <wd-sticky :offset-top="0">
+        <view class="z9 box-border box-border w95vw flex items-center overflow-hidden bg-#f6f6f6 pb20rpx pt20rpx">
+          <view v-for="item in tabList" :key="item.value" class="mr28rpx rounded-24rpx px16rpx py8rpx text-24rpx" :class="[currentTab === item.value ? 'bg-[var(--them-color)] text-white ' : 'bg-white']" @click="currentTab = item.value">
+            {{ item.label }}
+          </view>
+        </view>
+      </wd-sticky>
+      <view v-for="item in data" :key="item.storeId" class="relative mb20rpx box-border rounded-16rpx bg-white p24rpx" @click="handleView(item)">
+        <view class="flex items-center justify-between">
+          <view class="text-36rpx font-semibold">
+            {{ item.storeName }}
+          </view>
+          <view class="flex items-center text-24rpx">
+            <image :src="`${StaticUrl}/smqjh-jy-dh.png`" class="mr3 h18.34rpx w18.34rpx" />  {{ item.distanceShow }}km
+          </view>
+        </view>
+        <view class="mt20rpx text-#aaa">
+          {{ item.address }}
+        </view>
+        <view class="mt20rpx flex items-center justify-between">
+          <view v-if="item.allowanceClientScheme" class="flex items-center rounded-8rpx bg-#E6E6E6 px12rpx py8rpx">
+            <view class="text-22rpx text-#AAAAAA">
+              不支持优惠券
+            </view>
+          </view>
+          <view class="flex items-end">
+            <view class="text-28rpx">
+              {{ item.itemName }}
+            </view>
+            <view class="mx8rpx ml12rpx flex items-end text-#ff4d3a">
+              特惠价 <view class="font-semibold">
+                <text class="text-20rpx">
+                  ¥
+                </text> <text class="text-36rpx">
+                  {{ item.vipPrice }}/L
+                </text>
+              </view>
+            </view>
+          </view>
+        </view>
+      <!-- <image :src="`${staticUrl}/smqjh-jy-cz.png`" class="absolute left-0 top-0 h80rpx w234rpx" /> -->
+      </view>
+    </view>
+    <image
+      :src="`${StaticUrl}/smqjh-jy-dkj.png`"
+      class="fixed bottom-524rpx right-24rpx h114rpx w124rpx"
+      @click="router.push({ name: 'activityList' })"
+    />
+  </view>
+</template>

+ 212 - 0
src/subPack-refueling/commonTab/components/order.vue

@@ -0,0 +1,212 @@
+<script setup lang="ts">
+import router from '@/router'
+// Tab 列表
+const tabList = ref([
+  { label: '全部', value: 0 },
+  { label: '待支付', value: 1 },
+  { label: '已支付', value: 2 },
+  { label: '已退款', value: 6 },
+])
+const currentTab = ref(0)
+
+// 分页请求
+const { data, isLastPage, page, reload } = usePagination(
+  (pageNum, pageSize) => Apis.general.post_smqjh_oms_api_v1_oil_order_findoilorderpage({
+    data: { pageNum, pageSize, status: currentTab.value },
+  }),
+  {
+    initialPage: 1,
+    initialPageSize: 10,
+    immediate: false,
+    data: res => res.data?.list,
+    append: true,
+  },
+)
+
+// 切换 Tab
+function handleTabChange(value: number) {
+  currentTab.value = value
+  page.value = 1
+  reload()
+}
+
+// 订单状态映射
+const statusMap = new Map([
+  [1, '待支付'],
+  [2, '已支付'],
+  [6, '已退款'],
+  [9, '已取消'],
+])
+
+// 获取状态文字
+function getStatusText(status?: number) {
+  return statusMap.get(status as number) || ''
+}
+
+// 计算倒计时剩余毫秒数(30分钟)
+function getCountdownTime(expireTime?: string): number {
+  if (!expireTime)
+    return 0
+  const expire = new Date(expireTime).getTime()
+  const remaining = expire - Date.now()
+  return remaining > 0 ? remaining : 0
+}
+
+// 取消订单
+async function handleCancelOrder(item: Api.xsbOrderList) {
+  await useUserStore().handleCommonCancelOrder(item)
+  reload()
+}
+
+// 付款(占位)
+function handlePay(_item: Api.OmsOrderOilPageVO) {
+  useUserStore().handleCommonPath(_item.payUrl as string)
+}
+
+// 申请开票(占位)
+async function handleInvoice(_item: Api.OmsOrderOilPageVO) {
+  // useGlobalToast().show('功能开发中')
+  uni.showLoading({ mask: true })
+  try {
+    const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_invoiceorder({ params: { orderId: _item.orderNumber as string } })
+    window.location.href = res.data as string
+  }
+  catch (error) {
+    console.log(error)
+    // useGlobalToast().show('获取支付信息失败')
+  }
+  finally {
+    uni.hideLoading()
+  }
+}
+
+onShow(() => {
+  reload()
+})
+
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
+</script>
+
+<template>
+  <view class="min-h-100vh bg-#f5f5f5">
+    <!-- Tab 切换 -->
+    <view class="sticky top-0 z-10 flex items-center justify-around bg-white px24rpx">
+      <view
+        v-for="item in tabList"
+        :key="item.value"
+        class="py24rpx text-28rpx"
+        :class="[currentTab === item.value ? 'text-[var(--them-color)] font-semibold border-b-4rpx border-[var(--them-color)]' : 'text-#666']"
+        @click="handleTabChange(item.value)"
+      >
+        {{ item.label }}
+      </view>
+    </view>
+
+    <!-- 订单列表 -->
+    <view class="px24rpx pt20rpx">
+      <view
+        v-for="item in data"
+        :key="item.orderNumber"
+        class="mb20rpx rounded-16rpx bg-white px24rpx py28rpx"
+      >
+        <view @click="router.push({ name: 'orderDetail', params: { orderNo: item.orderNumber as string } })">
+          <!-- 头部:油站名称 + 状态 -->
+          <view class="flex justify-between">
+            <view class="text-30rpx font-semibold">
+              {{ item.brandName ? `${item.brandName}·` : '' }}{{ item.storeName }}
+            </view>
+            <!-- 待支付状态显示倒计时 -->
+            <view v-if="item.oilOrderStatus === 1" class="w300rpx flex items-center justify-end text-24rpx text-#1890ff">
+              待支付(<wd-count-down :time="getCountdownTime(item.expireTime)" format="还剩mm:ss" />)
+            </view>
+            <view v-else class="text-24rpx text-#666">
+              {{ getStatusText(item.oilOrderStatus) }}
+            </view>
+          </view>
+
+          <!-- 油号 | 油枪 -->
+          <view class="mt16rpx text-26rpx text-#999">
+            {{ item.itemName }} | {{ item.gunNo }}号枪
+          </view>
+
+          <!-- 订单金额 -->
+          <view class="mt12rpx text-26rpx text-#999">
+            订单金额:<text class="text-#333">
+              ¥{{ item.totalMoney }}
+            </text>
+          </view>
+
+          <!-- 根据状态显示不同金额 -->
+          <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
+            需付金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
+          <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
+            实付金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
+          <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
+            退款金额:<text class="text-#333">
+              ¥{{ item.realMoney }}
+            </text>
+          </view>
+
+          <!-- 根据状态显示不同时间 -->
+          <view v-if="item.oilOrderStatus === 1" class="mt12rpx text-26rpx text-#999">
+            下单时间:{{ item.createTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 2" class="mt12rpx text-26rpx text-#999">
+            支付时间:{{ item.payTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 6" class="mt12rpx text-26rpx text-#999">
+            退款时间:{{ item.refundTime }}
+          </view>
+          <view v-else-if="item.oilOrderStatus === 9" class="mt12rpx text-26rpx text-#999">
+            取消时间:{{ item.cancelTime }}
+          </view>
+
+          <!-- 已支付显示合作方订单号 -->
+          <view v-if="item.oilOrderStatus === 2 && item.thirdOrderId" class="mt12rpx text-26rpx text-#999">
+            合作方订单号:{{ item.thirdOrderId }}
+          </view>
+        </view>
+        <!-- 操作按钮 -->
+        <view v-if="item.oilOrderStatus === 1" class="mt20rpx flex items-center justify-end gap-20rpx">
+          <wd-button plain size="small" custom-class="action-btn" @click="handleCancelOrder(item)">
+            取消订单
+          </wd-button>
+          <wd-button plain size="small" custom-class="action-btn" @click="handlePay(item)">
+            付款
+          </wd-button>
+        </view>
+        <view v-else-if="item.oilOrderStatus === 2" class="mt20rpx flex items-center justify-end">
+          <wd-button plain size="small" custom-class="action-btn" @click="handleInvoice(item)">
+            申请开票
+          </wd-button>
+        </view>
+      </view>
+
+      <!-- 空状态 -->
+      <view v-if="data && data.length === 0" class="flex flex-col items-center pt100rpx">
+        <StatusTip tip="暂无订单" />
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.action-btn) {
+  border-color: #333 !important;
+  color: #333 !important;
+  border-radius: 32rpx !important;
+}
+:deep(.wd-count-down){
+  color: #1890ff !important;
+}
+</style>

+ 199 - 0
src/subPack-refueling/commonTab/components/voucher.vue

@@ -0,0 +1,199 @@
+<script setup lang="ts">
+import router from '@/router'
+
+import { StaticUrl } from '@/config'
+// Tab 列表
+const tabList = ref([
+  { label: '可用', value: 2 },
+  { label: '已使用', value: 1 },
+  { label: '已过期', value: 5 },
+])
+const currentTab = ref(2)
+
+// 状态映射
+const statusMap = new Map([
+  [2, '可用'],
+  [1, '已使用'],
+  [5, '已过期'],
+])
+
+// 分页请求
+const { data, isLastPage, page, reload } = usePagination(
+  (pageNum, pageSize) => Apis.app.get_smqjh_system_app_api_membercoupon_page({
+    params: { pageNum, pageSize, useStatus: currentTab.value },
+  }),
+  {
+    initialPage: 1,
+    initialPageSize: 10,
+    immediate: false,
+    data: res => res.data?.list,
+    append: true,
+  },
+)
+
+// 切换 Tab
+function handleTabChange(value: number) {
+  currentTab.value = value
+  page.value = 1
+  reload()
+}
+
+function handleUse(_item: Api.AppMemberCouponVO) {
+  router.pushTab({ name: 'home' })
+  useTabbar().setTabbarItemActive('home')
+}
+
+// 取消订单(占位)
+async function handleCancelOrder(_item: Api.AppMemberCouponVO) {
+  // useGlobalToast().show('功能开发中')
+  await useUserStore().handleCommonCancelOrderJY(_item.lockOrderId as string)
+  reload()
+}
+
+// 付款(占位)
+function handlePay(_item: Api.AppMemberCouponVO) {
+  // useGlobalToast().show('功能开发中')
+  useUserStore().handleCommonGoXiaoJuPay(_item.lockOrderId as string)
+}
+
+// 计算倒计时剩余毫秒数
+function getCountdownTime(orderCreateTime?: string): number {
+  if (!orderCreateTime)
+    return 0
+  const createTime = new Date(orderCreateTime).getTime()
+  const expireTime = createTime + 15 * 60 * 1000 // 假设15分钟支付有效期
+  const remaining = expireTime - Date.now()
+  return remaining > 0 ? remaining : 0
+}
+
+onShow(() => {
+  page.value = 1
+  reload()
+})
+
+onReachBottom(() => {
+  if (!isLastPage.value) {
+    page.value++
+  }
+})
+</script>
+
+<template>
+  <view class="min-h-100vh bg-#f5f5f5">
+    <!-- Tab 切换 -->
+    <view class="sticky top-0 z-10 flex items-center justify-between bg-white px24rpx">
+      <view
+        v-for="item in tabList"
+        :key="item.value"
+        class="py24rpx text-28rpx"
+        :class="[currentTab === item.value ? 'text-[var(--them-color)] font-semibold border-b-4rpx border-[var(--them-color)]' : 'text-#666']"
+        @click="handleTabChange(item.value)"
+      >
+        {{ item.label }}
+      </view>
+    </view>
+
+    <!-- 券列表 -->
+    <view class="px24rpx pt20rpx">
+      <view
+        v-for="item in data"
+        :key="item.id"
+        class="mb20rpx rounded-16rpx bg-white px24rpx py28rpx"
+      >
+        <view @click="router.push({ name: 'voucherDetail', params: { id: item.id as string } })">
+          <!-- 券信息头部 -->
+          <view class="flex items-center justify-between">
+            <view class="flex items-center">
+              <image
+                :src="`${StaticUrl}/smqjh-reful-juan.png`"
+                class="mr12rpx h32rpx w32rpx"
+              />
+              <view class="text-30rpx font-semibold">
+                抵扣{{ item.discountMoney }}元(满{{ item.amountMoney }}元可用)
+              </view>
+            </view>
+            <!-- 待支付倒计时 -->
+            <view v-if="item.lockStatus === 1 && currentTab === 2" class="flex items-center text-24rpx text-#1890ff">
+              待支付(<wd-count-down :time="getCountdownTime(item.orderCreateTime)" format="还剩mm:ss" />)
+            </view>
+          </view>
+
+          <!-- 券详情 -->
+          <view class="mt16rpx text-26rpx text-#999">
+            适用:全部合作油站
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            有效期至:{{ item.expirationTime }}
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            可抵扣:<text class="text-#ff4d3a">
+              ¥{{ item.discountMoney }}
+            </text>
+          </view>
+          <view class="mt12rpx text-26rpx text-#999">
+            状态:{{ statusMap.get(item.useStatus as number) || '' }}
+          </view>
+        </view>
+
+        <!-- 操作按钮区域 -->
+        <view v-if="currentTab === 2" class="mt20rpx">
+          <!-- 未被锁定 - 显示去使用 -->
+          <view v-if="item.lockStatus !== 1" class="flex justify-end">
+            <wd-button size="small" plain custom-class="use-btn" @click="handleUse(item)">
+              去使用
+            </wd-button>
+          </view>
+
+          <!-- 被锁定 - 显示订单信息和操作 -->
+          <view v-else>
+            <view class="flex items-center text-26rpx text-#1890ff">
+              <wd-icon name="info-circle" size="28rpx" color="#1890ff" class="mr8rpx" />
+              当前订单未支付,券被占用
+            </view>
+            <view class="mt16rpx flex items-center justify-between">
+              <view class="text-26rpx text-#999">
+                订单号:{{ item.lockOrderId }}
+              </view>
+              <view class="flex items-center gap-16rpx">
+                <wd-button size="small" plain custom-class="cancel-btn" @click="handleCancelOrder(item)">
+                  取消订单
+                </wd-button>
+                <wd-button size="small" plain custom-class="pay-btn" @click="handlePay(item)">
+                  付款
+                </wd-button>
+              </view>
+            </view>
+          </view>
+        </view>
+      </view>
+
+      <!-- 空状态 -->
+      <view v-if="data && data.length === 0" class="flex flex-col items-center pt100rpx">
+        <StatusTip tip="暂无抵扣券" />
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.use-btn) {
+  border-color: #333 !important;
+  color: #333 !important;
+  border-radius: 32rpx !important;
+}
+
+:deep(.cancel-btn) {
+  border-color: #999 !important;
+  color: #999 !important;
+  border-radius: 32rpx !important;
+}
+
+:deep(.pay-btn) {
+  border-color: #333 !important;
+  color: #333 !important;
+  border-radius: 32rpx !important;
+}
+:deep(.wd-count-down){
+  color: #1890ff !important;
+}
+</style>

+ 53 - 56
src/subPack-refueling/commonTab/index.vue

@@ -1,4 +1,8 @@
 <script setup lang="ts">
+import order from './components/order.vue'
+import voucher from './components/voucher.vue'
+import index from './components/index.vue'
+
 definePage({
   name: 'refueling-tabbar',
   islogin: false,
@@ -6,70 +10,63 @@ definePage({
     navigationBarTitleText: '加油',
   },
 })
-
-onMounted(() => {
-  console.log('触发加载')
-  getPayQrcode()
+interface TabbarItem {
+  name: string
+  value: number | null
+  active: boolean
+  title: string
+  icon: string
+}
+const tabbarItems = ref<TabbarItem[]>([
+  { name: 'home', value: null, active: true, title: '首页', icon: '' },
+  { name: 'voucher', value: null, active: false, title: '优惠券', icon: '' },
+  { name: 'order', value: null, active: false, title: '订单', icon: '' },
+])
+const tabbarList = computed(() => tabbarItems.value)
+const activeTabbar = computed(() => {
+  const item = tabbarItems.value.find(item => item.active)
+  return item || tabbarItems.value[0]
 })
-
-function refuelingPay() {
-  console.log('触发跳转')
-  // router.push({ name: 'refueling-webview' })
-  // wx.openOfficialAccountArticle({
-  //   url: 'https://smqjh.admin.zswlgz.com/test.html', // 此处填写公众号的原始 ID
-  //   success: (res) => {
-  //   },
-  //   fail: (res) => {
-  //     console.log(res, 'err')
-  //   },
-  // })
-  uni.navigateToMiniProgram({
-    appId: 'wx0d252f6ed9755862', // 滴滴加油小程序appId
-    path: 'packageA/pages/open-energy-pay/index?orderId=&tradeId=&appId=wx43b5b906cc30ed0b&path=/pages/index/index&envVersion=小程序回跳环境', // 滴滴加油收银台页面地址,需要拼接orderId和tradeId
-    envVersion: 'release', // 固定release
-  })
+function getTabbarItemValue(name: string) {
+  const item = tabbarItems.value.find(item => item.name === name)
+  return item && item.value ? item.value : null
 }
-
-const payQrCode = ref('')
-async function getPayQrcode() {
-  const res = await Apis.refueling.getPayCode({
-    data: {
-      content: 'https://static.am.xiaojukeji.com/cf-terminal/oil/thanos-fe-oil/pages/open-energy-h5-pay/index.html?orderId=3521815091021431239&tradeId=20260226b3dd729612c482ab35c26879ca59118a10560142',
-    },
+function setTabbarItemActive(name: string) {
+  tabbarItems.value.forEach((item) => {
+    if (item.name === name) {
+      item.active = true
+    }
+    else {
+      item.active = false
+    }
   })
-  payQrCode.value = res.data
 }
-function testClick() {
-  uni.previewImage({
-    // 需要预览的图片链接列表
-    urls: [payQrCode.value],
-    // 当前显示图片的链接
-    current: payQrCode.value,
-    // 图片指示器样式
-    indicator: 'default',
-    // 是否可循环预览
-    loop: false,
-    showmenu: true,
-    // 长按图片显示操作菜单
-    longPressActions: {
-      itemList: ['发送给朋友', '保存到相册', '识别图中二维码'],
-    },
-    success: (res) => {
-      console.log('previewImage res', res)
-    },
-    fail: (err) => {
-      console.log('previewImage err', err)
-    },
-  })
+function handleTabbarChange({ value }: { value: string }) {
+  setTabbarItemActive(value)
 }
+onMounted(() => {
+  console.log('触发加载')
+})
 </script>
 
 <template>
-  <view class="">
-    <wd-button @click="refuelingPay">
-      加油充值
-    </wd-button>
-    <image :src="payQrCode" @click="testClick" />
+  <view>
+    <order v-if="activeTabbar.name === 'order'" />
+    <voucher v-if="activeTabbar.name === 'voucher'" />
+    <index v-if="activeTabbar.name === 'home'" />
+    <wd-tabbar
+      :model-value="activeTabbar.name" safe-area-inset-bottom bordered fixed
+      @change="handleTabbarChange"
+    >
+      <wd-tabbar-item
+        v-for="(item, index) in tabbarList" :key="index" :name="item.name"
+        :value="getTabbarItemValue(item.name)" :title="item.title"
+      >
+        <template #icon="{ active }">
+          <i class="iconfont text-44rpx" :class="[active ? 'text-[var(--them-color)]' : '']">{{ item.icon }}</i>
+        </template>
+      </wd-tabbar-item>
+    </wd-tabbar>
   </view>
 </template>
 

+ 441 - 0
src/subPack-refueling/confirmOrder/index.vue

@@ -0,0 +1,441 @@
+<script setup lang="ts">
+import router from '@/router'
+
+definePage({ name: 'confimOrder', islogin: true, style: { navigationBarTitleText: '下单', navigationStyle: 'custom' } })
+const showModel = ref(false)
+const refuelNumber = ref()
+const refuelGun = ref()
+const showModelJf = ref(false)
+const selectDk = ref()
+const storeDetail = ref<Api.GasStationDetailVO>()
+const isSelect = ref(false)
+const refuelMoney = ref(null)
+const { Location } = storeToRefs(useAddressStore())
+const ThreePrice = ref<Api.QueryCalPriceResponse>()
+const dkList = ref<Api.AppMemberCouponOrderVO>()
+const isSeletDk = ref(false)
+onLoad(async (options: any) => {
+  await getData(options.storeId)
+})
+
+async function getData(storeId: string) {
+  const res = await Apis.general.post_smqjh_pms_app_api_v1_product_oil_querystoredetail({ data: { storeId, lat: Location.value.latitude, lon: Location.value.longitude } })
+  storeDetail.value = res.data
+  refuelNumber.value = res.data?.itemInfoList ? res.data?.itemInfoList[0].itemId : null
+}
+
+const refuelGunList = computed(() => {
+  return storeDetail.value?.itemInfoList ? storeDetail.value?.itemInfoList.find(item => item.itemId === refuelNumber.value)?.gunNos : []
+})
+const priceData = computed(() => {
+  return storeDetail.value?.itemInfoList ? storeDetail.value?.itemInfoList.find(item => item.itemId === refuelNumber.value) : null
+})
+async function handlePay() {
+  if (!selectDk.value) {
+    return useGlobalToast().show('如需不使用优惠卷,请选择暂不使用优惠卷')
+  }
+  if (!ThreePrice.value) {
+    return useGlobalToast().show('第三方价格计算失败')
+  }
+  if (!refuelGun.value) {
+    return useGlobalToast().show('请选择油枪')
+  }
+  if (!refuelMoney.value) {
+    return useGlobalToast().show('请输入加油金额')
+  }
+  goPay()
+  console.log('handlePay')
+}
+async function handleBlur() {
+  if (Number(refuelMoney.value) < 10) {
+    return useGlobalToast().show('最小金额为10元')
+  }
+  if (!storeDetail.value)
+    return
+  if (!storeDetail.value.allowanceClientScheme) {
+    const res = await Apis.app.get_smqjh_system_app_api_membercoupon_findplaceorderlist({
+      params: {
+        storeId: storeDetail.value?.storeId,
+        orderAmount: Number(refuelMoney.value) * 100,
+      },
+    })
+
+    dkList.value = res.data
+    if (dkList.value?.appCouponOrderOptimalVO != null) {
+      selectDk.value = dkList.value?.appCouponOrderOptimalVO?.allowanceId
+      isSeletDk.value = true
+      getMoney()
+    }
+    else {
+      selectDk.value = null
+      isSeletDk.value = false
+      ThreePrice.value = undefined
+    }
+  }
+}
+async function getMoney() {
+  if (!storeDetail.value)
+    return
+  const nams = storeDetail.value?.itemInfoList?.find(item => item.itemId === refuelNumber.value)?.itemName
+  const { data } = await Apis.general.post_smqjh_pms_app_api_v1_product_oil_querycalprice({ data: {
+    storeId: storeDetail.value?.storeId as string,
+    itemName: nams as string,
+    amount: Number(refuelMoney.value) * 100,
+    openChannel: 1,
+    outUserId: '',
+    mobile: '',
+    promotionInfo: selectDk.value === 'nodk' ? [] : [{ allowanceId: selectDk.value }],
+  } })
+  ThreePrice.value = data
+}
+async function goPay() {
+  uni.showLoading({ mask: true })
+  try {
+    const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_createorder({ data: {
+      lat: Location.value.latitude,
+      lon: Location.value.longitude,
+      itemId: refuelNumber.value,
+      gunNo: refuelGun.value,
+      originalAmount: Number(ThreePrice.value?.totalPrice),
+      paymentAmount: Number(ThreePrice.value?.realPrice),
+      promotionAmount: Number(ThreePrice.value?.promotionAmount),
+      litre: Number(ThreePrice.value?.litre),
+      serviceFee: Number(ThreePrice.value?.serviceFee),
+      totalPrice: Number(ThreePrice.value?.totalPrice),
+      vipPrice: Number(priceData.value?.vipPrice),
+      cityPrice: Number(priceData.value?.cityPrice),
+      storePrice: Number(priceData.value?.storePrice),
+      storeId: storeDetail.value?.storeId,
+      itemName: priceData.value?.itemName,
+      promotionInfo: selectDk.value === 'nodk' ? [] : [{ allowanceId: selectDk.value }],
+    } })
+    console.log(res, '===============================================支付')
+    // #ifdef H5
+    useUserStore().handleCommonPath(res.data as string)
+    // #endif
+    uni.hideLoading()
+  }
+  catch {
+    uni.hideLoading()
+  }
+}
+function handleSelectDk() {
+  console.log(selectDk.value, '==============')
+  if (selectDk.value === 'nodk') {
+    return '不使用抵扣券'
+  }
+  if (dkList.value?.appCouponOrderOptimalVO?.allowanceId === selectDk.value) {
+    return `${getSelectDkInfo()?.discountMoney}元`
+  }
+  else {
+    return `${getSelectDkInfo()?.discountMoney}元`
+  }
+}
+function getSelectDkInfo() {
+  if (dkList.value?.appCouponOrderOptimalVO?.allowanceId === selectDk.value) {
+    return dkList.value?.appCouponOrderOptimalVO
+  }
+  return dkList.value?.appCouponOrderVOList?.find(item => item.allowanceId === selectDk.value)
+}
+</script>
+
+<template>
+  <view v-if="storeDetail">
+    <view class="p24rpx">
+      <view class="rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="text-36rpx font-semibold">
+          {{ storeDetail?.storeName }}
+        </view>
+        <view class="mt20rpx text-#aaa">
+          {{ storeDetail?.address }}
+        </view>
+        <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+        <view class="flex items-center justify-between">
+          <view class="text-#ff4d3a font-semibold">
+            平台价
+          </view>
+          <view class="text-#aaa">
+            门店价:¥{{ priceData?.storePriceShow || 0 }}/L
+          </view>
+        </view>
+        <view class="mt16rpx flex items-center justify-between">
+          <view class="text-32rpx text-#ff4d3a font-semibold">
+            ¥{{ priceData?.vipPriceShow || 0 }}/L
+          </view>
+          <view class="text-#aaa">
+            国标价:¥{{ priceData?.cityPriceShow || 0 }}/L
+          </view>
+        </view>
+      </view>
+      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="text-28rpx font-semibold">
+          选择油号/油枪
+        </view>
+        <view class="mt24rpx flex items-center" @click="showModel = true">
+          <view class="relative w47% rounded-8rpx px24rpx py20rpx" :class="[refuelNumber ? 'bg-#F6FFDF border border-#9ED605 border-solid text-#9ED605' : 'bg-#F9F9F9']">
+            <view class="text-center text-28rpx font-semibold">
+              {{ refuelNumber ? storeDetail.itemInfoList?.find(item => item.itemId === refuelNumber)?.itemName : '请选择油号' }}
+            </view>
+            <view class="absolute right-24rpx top-50% h32rpx w32rpx -transform-translate-y-50%">
+              <wd-icon name="arrow-down" size="32rpx" />
+            </view>
+          </view>
+          <view class="relative ml18rpx w47% rounded-8rpx px24rpx py20rpx" :class="[isSelect && refuelGun ? 'bg-#F6FFDF border border-#9ED605 border-solid text-#9ED605' : 'bg-#F9F9F9']">
+            <view class="text-center text-28rpx font-semibold">
+              {{ isSelect && refuelGun ? refuelGun : '请选择油枪' }}
+            </view>
+            <view class="absolute right-24rpx top-50% h32rpx w32rpx -transform-translate-y-50%">
+              <wd-icon name="arrow-down" size="32rpx" />
+            </view>
+          </view>
+        </view>
+      </view>
+      <view class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="text-28rpx font-semibold">
+          加油金额
+        </view>
+        <view class="mt20rpx bg-#F9F9F9 px24rpx py20rpx">
+          <input v-model="refuelMoney" type="number" class="w-full" placeholder="请输入加油金额,优惠价格计算" @blur="handleBlur">
+        </view>
+        <view class="mt20rpx text-#ff4d3a">
+          最小金额10元
+        </view>
+      </view>
+      <view v-if="refuelMoney" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="flex items-center">
+          <view class="mr20rpx text-28rpx font-semibold">
+            抵扣券
+          </view>
+          <wd-button v-if="!storeDetail.allowanceClientScheme" size="small" @click="router.push({ name: 'activityList' })">
+            去兑换
+          </wd-button>
+        </view>
+        <view class="mt24rpx flex items-center justify-between rounded-8rpx bg-#F9F9F9 px24rpx py20rpx" @click="showModelJf = true && !storeDetail.allowanceClientScheme">
+          <view class="text-28rpx text-#aaa">
+            {{ storeDetail.allowanceClientScheme ? '该加油站不可使用抵扣券' : isSeletDk && selectDk ? handleSelectDk() : '暂无抵扣券' }}
+          </view>
+          <wd-icon name="arrow-down" size="32rpx" color="#aaa" />
+        </view>
+        <template v-if="selectDk !== 'nodk' && isSeletDk">
+          <view class="mt16rpx">
+            已选:满{{ getSelectDkInfo()?.amountMoney }}元可抵扣{{ getSelectDkInfo()?.discountMoney }}元 {{ dkList?.appCouponOrderOptimalVO?.allowanceId === selectDk ? '(最优)' : '' }}
+          </view>
+          <view class="mt16rpx">
+            抵扣金额:-¥{{ getSelectDkInfo()?.discountMoney }}
+          </view>
+        </template>
+        <template v-if="selectDk && ThreePrice && refuelMoney">
+          <view class="mb20rpx mt24rpx text-32rpx font-semibold">
+            价格明细
+          </view>
+          <view class="flex items-center justify-between text-28rpx">
+            <view class="text-#aaa">
+              加油金额
+            </view>
+            <view>¥{{ refuelMoney || 0 }}</view>
+          </view>
+          <view class="mt20rpx flex items-center justify-between text-28rpx">
+            <view class="text-#aaa">
+              抵扣券
+            </view>
+            <view>-¥{{ getSelectDkInfo()?.discountMoney || 0 }}</view>
+          </view>
+          <view class="mt20rpx flex items-center justify-between text-28rpx">
+            <view class="text-#aaa">
+              服务费
+            </view>
+            <view>+¥{{ ThreePrice.serviceFee ? ThreePrice.serviceFee / 100 : 0 }}</view>
+          </view>
+
+          <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+          <view class="flex items-center justify-between text-28rpx">
+            <view class="text-#aaa">
+              实付金额
+            </view>
+            <view class="text-#ff4d3a font-semibold">
+              ¥{{ ThreePrice?.realPrice ? ThreePrice?.realPrice / 100 : 0 }}
+            </view>
+          </view>
+        </template>
+      </view>
+    </view>
+    <view class="h200rpx" />
+    <Zpopup v-model="showModel" bg="#fff">
+      <view class="px24rpx py28rpx">
+        <view class="text-center text-32rpx font-semibold">
+          选择油号油枪
+        </view>
+        <view class="mb20rpx text-32rpx font-semibold">
+          油号
+        </view>
+        <wd-radio-group v-model="refuelNumber" shape="button">
+          <view class="flex flex-wrap items-center gap-20rpx">
+            <wd-radio v-for="item in storeDetail?.itemInfoList" :key="item.itemId" :value="String(item.itemId)">
+              {{ item.itemName }}
+            </wd-radio>
+          </view>
+        </wd-radio-group>
+        <view v-if="refuelGunList" class="mb20rpx mt20rpx text-32rpx font-semibold">
+          油枪
+        </view>
+        <wd-radio-group v-model="refuelGun" shape="button">
+          <scroll-view scroll-y class="h400rpx pb40rpx">
+            <view class="grid grid-cols-5 gap-20rpx">
+              <view v-for="item in refuelGunList" :key="item">
+                <wd-radio :value="String(item)">
+                  {{ item }}
+                </wd-radio>
+              </view>
+            </view>
+          </scroll-view>
+        </wd-radio-group>
+      </view>
+      <template #footer>
+        <view class="text-center text-28rpx text-#ff4d3a">
+          请与加油员确认油枪号
+        </view>
+        <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+        <wd-button block size="large" @click="showModel = false, isSelect = true">
+          确认
+        </wd-button>
+      </template>
+    </Zpopup>
+    <Zpopup v-model="showModelJf" bg="#fff">
+      <view class="px24rpx py28rpx">
+        <view class="mb24rpx text-center text-32rpx font-semibold">
+          选择抵扣券
+        </view>
+        <wd-radio-group v-model="selectDk" shape="dot">
+          <view class="flex items-center justify-between">
+            <view class="text-28rpx">
+              不使用抵扣券
+            </view>
+            <wd-radio value="nodk" />
+          </view>
+          <view v-if="dkList?.appCouponOrderOptimalVO" class="mt24rpx">
+            <view class="text-28rpx">
+              自动推荐
+            </view>
+            <view class="relative mt20rpx box-border h144rpx flex items-center justify-between rounded-16rpx bg-[rgba(255,77,58,0.1)] px28rpx py24rpx">
+              <view class="flex-1">
+                <view class="flex items-center">
+                  <view class="text-40rpx text-#ff4d3a font-semibold">
+                    <text class="text-24rpx">
+                      ¥
+                    </text> {{ dkList.appCouponOrderOptimalVO.discountMoney }}
+                  </view>
+                  <view class="ml20rpx text-32rpx font-semibold">
+                    {{ dkList.appCouponOrderOptimalVO.amountMoney ? `满${dkList.appCouponOrderOptimalVO.amountMoney}元可用` : '无使用门槛' }}
+                  </view>
+                </view>
+                <view class="mt24rpx flex items-center text-#aaa">
+                  <view class="text-center text-20rpx">
+                    可抵扣
+                  </view>
+                  <view class="ml20rpx text-24rpx font-semibold">
+                    有效期:{{ dkList.appCouponOrderOptimalVO.expirationTime }}
+                  </view>
+                </view>
+              </view>
+              <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#FF4D3A border-l-dashed">
+                <wd-radio :value="dkList.appCouponOrderOptimalVO.allowanceId as string" />
+              </view>
+              <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
+              <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
+            </view>
+          </view>
+          <scroll-view scroll-y class="h600rpx pb40rpx">
+            <view v-if="dkList?.appCouponOrderVOList" class="mt24rpx">
+              <view class="text-28rpx">
+                其他可用券
+              </view>
+              <view v-for="item in dkList.appCouponOrderVOList" :key="item.allowanceId" class="relative mt20rpx box-border h144rpx flex items-center justify-between rounded-16rpx bg-[rgba(255,77,58,0.1)] px28rpx py24rpx">
+                <view class="flex-1">
+                  <view class="flex items-center">
+                    <view class="text-40rpx text-#ff4d3a font-semibold">
+                      <text class="text-24rpx">
+                        ¥
+                      </text> {{ item.discountMoney }}
+                    </view>
+                    <view class="ml20rpx text-32rpx font-semibold">
+                      {{ item.amountMoney ? `满${item.amountMoney}元可用` : '无使用门槛' }}
+                    </view>
+                  </view>
+                  <view class="mt24rpx flex items-center text-#aaa">
+                    <view class="text-center text-20rpx">
+                      可抵扣
+                    </view>
+                    <view class="ml20rpx text-24rpx font-semibold">
+                      有效期:{{ item.expirationTime }}
+                    </view>
+                  </view>
+                </view>
+                <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#FF4D3A border-l-dashed">
+                  <wd-radio :value="item.allowanceId as string" />
+                </view>
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
+              </view>
+            </view>
+            <view v-if="dkList?.appCouponNoOrderVOList" class="mt24rpx">
+              <view class="text-28rpx">
+                不可用
+              </view>
+              <view v-for="item in dkList.appCouponNoOrderVOList" :key="item.allowanceId" class="relative mt20rpx box-border h144rpx flex items-center justify-between rounded-16rpx bg-[#E6E6E6] px28rpx py24rpx">
+                <view class="flex-1">
+                  <view class="flex items-center">
+                    <view class="text-40rpx text-#AAAAAA font-semibold">
+                      <text class="text-24rpx">
+                        ¥
+                      </text> {{ item.discountMoney }}
+                    </view>
+                    <view class="ml20rpx text-32rpx text-#646464 font-semibold">
+                      {{ item.amountMoney ? `满${item.amountMoney}元可用` : '无使用门槛' }}
+                    </view>
+                  </view>
+                  <view class="mt24rpx flex items-center text-#aaa">
+                    <view class="text-center text-20rpx">
+                      可抵扣
+                    </view>
+                    <view class="ml20rpx text-24rpx font-semibold">
+                      有效期:{{ item.expirationTime }}
+                    </view>
+                  </view>
+                </view>
+                <view class="h-full w134rpx flex items-center justify-center border-l-2rpx border-l-#AAAAAA border-l-dashed">
+                  <wd-radio :value="item.allowanceId as string" disabled />
+                </view>
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -top-10rpx" />
+                <view class="absolute right-150rpx h30rpx w30rpx rounded-full bg-white -bottom-10rpx" />
+              </view>
+            </view>
+          </scroll-view>
+        </wd-radio-group>
+      </view>
+      <template #footer>
+        <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+        <wd-button block size="large" @click="showModelJf = false, isSeletDk = true, getMoney()">
+          确认选择
+        </wd-button>
+      </template>
+    </Zpopup>
+    <FixedLayout>
+      <view :class="[selectDk && ThreePrice && refuelMoney && 'justify-between flex items-center']">
+        <view v-if="selectDk && ThreePrice && refuelMoney" class="text-32rpx text-#FF4A39 font-semibold">
+          <text class="text-24rpx">
+            ¥
+          </text><text>{{ ThreePrice?.realPrice ? ThreePrice?.realPrice / 100 : 0 }}</text>
+        </view>
+        <wd-button block size="large" @click="handlePay">
+          立即支付
+        </wd-button>
+      </view>
+    </FixedLayout>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.wd-radio){
+  margin-top: 0 !important;
+}
+</style>

+ 87 - 0
src/subPack-refueling/exchangeFail/index.vue

@@ -0,0 +1,87 @@
+<script setup lang="ts">
+import router from '@/router'
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'exchangeFail',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付',
+    navigationStyle: 'custom',
+  },
+})
+
+// 页面参数
+const failReason = ref('')
+
+onLoad((options: any) => {
+  failReason.value = options.failReason || '活动太火爆,优惠券已领完'
+})
+
+// 联系客服
+function handleContact() {
+  // TODO: 联系客服功能
+  useGlobalToast().show('客服功能开发中')
+}
+
+// 查看其他活动
+function handleViewActivity() {
+  router.back()
+}
+</script>
+
+<template>
+  <view class="min-h-100vh flex flex-col bg-#f5f5f5">
+    <!-- 失败图标区域 -->
+    <view class="flex flex-1 flex-col items-center justify-center">
+      <!-- 虚线边框容器 -->
+      <image
+        :src="`${StaticUrl}/smqjh-reful-pay-error.png`"
+        class="h200rpx w200rpx"
+      />
+
+      <!-- 失败文字 -->
+      <view class="text-32rpx font-semibold">
+        抱歉,领取失败
+      </view>
+
+      <!-- 失败原因 -->
+      <view class="mt20rpx text-28rpx text-#666">
+        失败原因:{{ failReason }}
+      </view>
+
+      <!-- 按钮区域 -->
+      <view class="mt60rpx flex items-center justify-center gap-32rpx px48rpx">
+        <wd-button
+          plain
+          size="large"
+          custom-class="contact-btn"
+          @click="handleContact"
+        >
+          联系客服
+        </wd-button>
+        <wd-button
+          size="large"
+          custom-class="activity-btn"
+          @click="handleViewActivity"
+        >
+          查看其他活动
+        </wd-button>
+      </view>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.contact-btn) {
+  min-width: 200rpx !important;
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+  border-radius: 48rpx !important;
+}
+
+:deep(.activity-btn) {
+  min-width: 200rpx !important;
+  border-radius: 48rpx !important;
+}
+</style>

+ 130 - 0
src/subPack-refueling/exchangeSuccess/index.vue

@@ -0,0 +1,130 @@
+<script setup lang="ts">
+import router from '@/router'
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'exchangeSuccess',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付',
+    navigationStyle: 'custom',
+  },
+})
+
+// 页面参数
+const couponId = ref('')
+const batchNo = ref('')
+const expireDays = ref('')
+const discountMoney = ref(0)
+const amountMoney = ref(0)
+
+onLoad((options: any) => {
+  couponId.value = options.couponId || ''
+  batchNo.value = options.batchNo || ''
+  expireDays.value = options.expireDays || ''
+  discountMoney.value = Number(options.discountMoney) || 0
+  amountMoney.value = Number(options.amountMoney) || 0
+})
+
+// 查看抵扣券
+function handleViewVoucher() {
+  router.pushTab({ name: 'voucher' })
+  useTabbar().setTabbarItemActive('voucher')
+}
+
+// 立即使用
+function handleUseNow() {
+  // TODO: 跳转到使用页面
+  router.pushTab({ name: 'home' })
+  useTabbar().setTabbarItemActive('home')
+}
+</script>
+
+<template>
+  <view class="min-h-100vh bg-#f5f5f5">
+    <!-- 成功图标 -->
+    <view class="flex flex-col items-center pt60rpx">
+      <view class="h80rpx w80rpx flex items-center justify-center rounded-full bg-#9ED605">
+        <wd-icon name="check" size="48rpx" color="#fff" />
+      </view>
+      <view class="mt20rpx text-32rpx text-#9ED605 font-semibold">
+        兑换成功
+      </view>
+    </view>
+
+    <!-- 抵扣券信息卡片 -->
+    <view class="mx24rpx mt40rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="flex items-center">
+        <view class="mr10rpx h30rpx w30rpx">
+          <image
+            class="h-full w-full"
+            :src="`${StaticUrl}/smqjh-reful-juan.png`"
+          />
+        </view>
+        <view class="text-30rpx font-semibold">
+          抵扣{{ discountMoney }}元(满{{ amountMoney }}可用)
+        </view>
+      </view>
+      <view class="mt16rpx text-26rpx text-#999">
+        优惠券已放入"我的抵扣券"
+      </view>
+    </view>
+
+    <!-- 券详情卡片 -->
+    <view class="mx24rpx mt24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="text-28rpx text-#333">
+        券ID:{{ couponId }}
+      </view>
+      <view class="mt20rpx text-28rpx text-#333">
+        批次号:{{ batchNo }}
+      </view>
+      <view class="mt20rpx text-28rpx text-#333">
+        有效期:{{ expireDays }}天
+      </view>
+    </view>
+
+    <!-- 温馨提示卡片 -->
+    <view class="mx24rpx mt24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-28rpx font-semibold">
+        温馨提示:
+      </view>
+      <view class="text-26rpx text-#666 leading-44rpx">
+        <view>·每单限用1张优惠券</view>
+        <view class="mt8rpx">
+          ·系统会自动选择最优优惠
+        </view>
+        <view class="mt8rpx">
+          ·不支持油站无法使用
+        </view>
+      </view>
+    </view>
+    <view class="mt28rpx flex items-center justify-between gap20rpx px124rpx">
+      <wd-button
+
+        plain block
+        size="large"
+        custom-class="flex-1 view-btn"
+        @click="handleViewVoucher"
+      >
+        查看抵扣券
+      </wd-button>
+      <wd-button
+        block
+        size="large"
+        custom-class="flex-1"
+        @click="handleUseNow"
+      >
+        立即使用
+      </wd-button>
+    </view>
+    <!-- 占位 -->
+    <view class="h200rpx" />
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.view-btn) {
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+}
+</style>

+ 32 - 30
src/subPack-refueling/orderDetaile/index.vue → src/subPack-refueling/orderDetail/index.vue

@@ -13,6 +13,7 @@ definePage({
 const orderNo = ref('')
 const orderInfo = ref<Api.xsbOrderList>()
 const oilInfo = computed<Api.OmsOrderOilVO | undefined>(() => orderInfo.value?.omsOrderOilVO)
+
 // 状态映射
 const statusMap = new Map([
   [1, '待支付'],
@@ -22,7 +23,7 @@ const statusMap = new Map([
 ])
 
 const { send } = useRequest(
-  (no: string) => Apis.xsb.orderInfo({ data: { orderNo: no } }),
+  (no: string) => Apis.general.get_smqjh_oms_api_v1_order_orderinfo({ params: { orderNo: no } }),
   { immediate: false },
 ).onSuccess((res) => {
   orderInfo.value = res.data.data
@@ -57,32 +58,28 @@ function handleCopy(text?: string) {
 }
 
 // 取消订单(占位)
-// async function handleCancelOrder() {
-//   await useUserStore().handleCommonCancelOrder(orderInfo.value?.orderNumber as string)
-//   send(orderNo.value)
-// }
+async function handleCancelOrder() {
+  await useUserStore().handleCommonCancelOrderJY(orderInfo.value?.orderNumber as string)
+  send(orderNo.value)
+}
 
 // 立即支付(占位)
-// function handlePay() {
-//   useUserStore().handleCommonPath(oilInfo.value?.payUrl as string)
-// }
+function handlePay() {
+  useUserStore().handleCommonPath(oilInfo.value?.payUrl as string)
+}
 
 // 跳转首页
-// function handleGoHome() {
-//   router.pushTab({ name: 'home' })
-//   useTabbar().setTabbarItemActive('home')
-// }
+function handleGoHome() {
+  router.pushTab({ name: 'home' })
+  useTabbar().setTabbarItemActive('home')
+}
 // function handleContact() {
-//   window.location.href = `weixin://dl/business/?appid=wx43b5b906cc30ed0b&path=subPack-xsb/orderDetaile/index&query=${orderInfo.value?.orderNumber}&env_version=release`
+//   useUserStore().handleCommonMiniProgram(orderInfo.value?.orderNumber as string)
 // }
 </script>
 
 <template>
-  <wd-navbar
-    title="订单详情" :bordered="false" :z-index="99" safe-area-inset-top left-arrow placeholder fixed
-    @click-left="router.back()"
-  />
-  <view v-if="orderInfo && oilInfo" class="bg-#f5f5f5 pb200rpx pt20rpx">
+  <view v-if="orderInfo && oilInfo" class="min-h-100vh bg-#f5f5f5 pb200rpx pt20rpx">
     <!-- 订单状态头部 -->
     <view class="mx24rpx rounded-16rpx bg-white px28rpx py32rpx">
       <view class="mb16rpx text-32rpx font-semibold">
@@ -94,29 +91,27 @@ function handleCopy(text?: string) {
         <view class="mb20rpx flex items-center text-26rpx text-#FF4A39">
           剩余支付时间:<wd-count-down :time="getCountdownTime()" format="mm分ss秒" />
         </view>
-        <!-- <view class="flex items-center gap-24rpx">
+        <view class="flex items-center gap-24rpx">
           <wd-button plain custom-class="flex-1 cancel-btn" @click="handleCancelOrder">
             取消订单
           </wd-button>
           <wd-button custom-class="flex-1" @click="handlePay">
             立即支付 ¥{{ oilInfo.realMoney }}
           </wd-button>
-        </view> -->
+        </view>
       </template>
 
       <!-- 已退款 - 联系客服 -->
-      <template v-else-if="orderInfo.oilOrderStatus === 6 || orderInfo.oilOrderStatus === 2">
-        <view class="flex items-center gap-48rpx">
+      <!-- <template v-else-if="orderInfo.oilOrderStatus === 6 || orderInfo.oilOrderStatus === 2">
+        <view class="flex items-center gap-48rpx" @click="handleContact">
           <view class="flex flex-col items-center">
             <wd-icon name="chat" size="48rpx" color="#333" />
-            <Zcontact>
-              <view class="mt-40rpx text-28rpx">
-                联系客服
-              </view>
-            </Zcontact>
+            <text class="mt8rpx text-24rpx">
+              联系客服
+            </text>
           </view>
         </view>
-      </template>
+      </template> -->
 
       <!-- 已取消 - 取消原因 -->
       <template v-else-if="orderInfo.oilOrderStatus === 9">
@@ -175,10 +170,10 @@ function handleCopy(text?: string) {
         用户信息
       </view>
       <view class="text-26rpx text-#666 leading-48rpx">
-        <view>用户手机:{{ orderInfo.memberMobile || '-' }}</view>
+        <view>用户手机:{{ orderInfo.consigneeMobile || '-' }}</view>
         <view>外部用户ID:{{ orderInfo.memberId || '-' }}</view>
         <view>下单时间:{{ orderInfo.createTime || '-' }}</view>
-        <view>支付时间:{{ oilInfo.payTime || '-' }}</view>
+        <view>支付时间:{{ orderInfo.payTime || '-' }}</view>
       </view>
     </view>
 
@@ -263,6 +258,13 @@ function handleCopy(text?: string) {
         <view>开票方式:线上自助开票</view>
       </view>
     </view>
+
+    <!-- 底部按钮(已取消状态) -->
+    <FixedLayout v-if="orderInfo.oilOrderStatus === 9">
+      <wd-button block size="large" @click="handleGoHome">
+        再去逛逛
+      </wd-button>
+    </FixedLayout>
   </view>
 </template>
 

+ 170 - 0
src/subPack-refueling/paySuccess/index.vue

@@ -0,0 +1,170 @@
+<script setup lang="ts">
+definePage({
+  name: 'paySuccess',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '支付',
+    navigationStyle: 'custom',
+  },
+})
+
+const outerOrderId = ref('')
+const orderInfo = ref<Api.PayResultInfoVO>()
+const payTime = ref('')
+
+const { send } = useRequest(
+  (orderId: string) => Apis.general.get_smqjh_oms_api_v1_oil_order_payresultinfo({ params: { orderId } }),
+  { immediate: false },
+).onSuccess((res) => {
+  orderInfo.value = res.data.data
+})
+
+onLoad((options: any) => {
+  outerOrderId.value = options.outerOrderId || ''
+  // 记录支付时间
+  const now = new Date()
+  payTime.value = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
+
+  if (outerOrderId.value) {
+    send(outerOrderId.value)
+  }
+})
+
+// 申请开票(占位)
+async function handleInvoice() {
+  // useGlobalToast().show('功能开发中')
+  uni.showLoading({ mask: true })
+  try {
+    const res = await Apis.general.post_smqjh_oms_api_v1_oil_order_invoiceorder({ params: { orderId: orderInfo.value?.orderNumber as string } })
+    window.location.href = res.data as string
+  }
+  catch (error) {
+    console.log(error)
+    // useGlobalToast().show('获取支付信息失败')
+  }
+  finally {
+    uni.hideLoading()
+  }
+}
+
+// 查看订单
+function handleViewOrder() {
+  uni.switchTab({ url: '/pages/order/index' })
+}
+
+// 返回首页
+function handleBackHome() {
+  uni.switchTab({ url: '/pages/index/index' })
+}
+</script>
+
+<template>
+  <view class="min-h-100vh bg-#f5f5f5">
+    <!-- 成功状态 -->
+    <view class="flex items-center justify-center py32rpx">
+      <view class="mr12rpx h40rpx w40rpx flex items-center justify-center rounded-full bg-#9ED605">
+        <wd-icon name="check" size="24rpx" color="#fff" />
+      </view>
+      <view class="text-32rpx text-#9ED605 font-semibold">
+        支付成功
+      </view>
+    </view>
+
+    <!-- 订单金额卡片 -->
+    <view class="mx24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="flex items-center justify-between">
+        <view class="text-28rpx text-#333">
+          订单金额
+        </view>
+        <view class="text-32rpx text-#ff4d3a font-semibold">
+          ¥{{ orderInfo?.totalMoney }}
+        </view>
+      </view>
+      <view class="mt20rpx flex items-center justify-between">
+        <view class="text-28rpx text-#333">
+          支付时间
+        </view>
+        <view class="text-28rpx text-#666">
+          {{ payTime }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 订单信息卡片 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb24rpx text-30rpx font-semibold">
+        订单信息
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          平台订单号
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.orderNumber || '-' }}
+        </view>
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          小桔订单号
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.thirdOrderId || outerOrderId || '-' }}
+        </view>
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          油站
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.storeName || '-' }}
+        </view>
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          油号
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.itemName || '-' }}
+        </view>
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          油枪
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.gunNo ? `${orderInfo.gunNo}号枪` : '-' }}
+        </view>
+      </view>
+      <view class="flex items-center justify-between py16rpx">
+        <view class="text-28rpx text-#999">
+          加油量
+        </view>
+        <view class="text-28rpx text-#333">
+          {{ orderInfo?.quantity ? `${orderInfo.quantity}L` : '-' }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 底部按钮 -->
+    <view class="mt48rpx flex items-center justify-center gap-24rpx px48rpx">
+      <wd-button plain size="medium" custom-class="action-btn" @click="handleInvoice">
+        申请开票
+      </wd-button>
+      <wd-button plain size="medium" custom-class="action-btn" @click="handleViewOrder">
+        查看订单
+      </wd-button>
+      <wd-button plain size="medium" custom-class="action-btn" @click="handleBackHome">
+        返回首页
+      </wd-button>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.action-btn) {
+  border-color: #333 !important;
+  color: #333 !important;
+  border-radius: 32rpx !important;
+  min-width: 160rpx !important;
+}
+</style>

+ 216 - 0
src/subPack-refueling/refuelDetaile/index.vue

@@ -0,0 +1,216 @@
+<script setup lang="ts">
+import router from '@/router'
+import { StaticUrl } from '@/config'
+
+definePage({ name: 'refuelDetaile', islogin: false, style: { navigationBarTitleText: '加油站详情' } })
+const showModel = ref(false)
+const storeDetail = ref<Api.GasStationDetailVO>()
+const dklist = ref<Api.CouponInfoAppVo[]>([])
+const clickItem = ref<Api.CouponInfoAppVo>()
+const showModelReful = ref(false)
+const storeVOList = ref<Api.DistanceStoreVO[]>([])
+const { Location } = storeToRefs(useAddressStore())
+onLoad(async (options: any) => {
+  await getData(options.id)
+})
+
+async function getData(storeId: string) {
+  const res = await Apis.general.post_smqjh_pms_app_api_v1_product_oil_querystoredetail({ data: { storeId, lat: Location.value.latitude, lon: Location.value.longitude } })
+  storeDetail.value = res.data
+  const { data } = await Apis.app.get_smqjh_system_app_api_coupon_findlist()
+  dklist.value = data || []
+}
+function handleShowMap() {
+  console.log('show map')
+  uni.openLocation({
+    latitude: Number(Location.value.latitude),
+    longitude: Number(Location.value.longitude),
+    success() {
+      console.log('success')
+    },
+  })
+}
+function handleExchange(item: Api.CouponInfoAppVo) {
+  console.log('exchange', item)
+  if (item.receiveSign)
+    return
+  if ((Number(item.inventoryActual)) === 0) {
+    useGlobalMessage().show('兑换失败,已被抢光')
+    return
+  }
+  clickItem.value = item
+  showModel.value = true
+}
+// function handleKf() {
+//   useUserStore().handleCommonWx('pages/my/index', '')
+// }
+async function handlePay() {
+  if (Number(storeDetail.value?.distanceShow) > 1) {
+    useGlobalMessage().confirm({
+      title: '提示',
+      msg: '您距离加油站过远,请在油站附近下单',
+      confirmButtonText: '确认',
+      cancelButtonText: '取消',
+    })
+  }
+  else {
+    const { data } = await Apis.general.post_smqjh_pms_app_api_v1_product_oil_querydistancefence({ data: { lat: Location.value.latitude, lon: Location.value.longitude, storeId: storeDetail.value?.storeId } })
+    if (data?.isClosest) {
+      showModelReful.value = true
+      storeVOList.value = data.storeVOS as Api.DistanceStoreVO[]
+    }
+    else {
+      router.push({ name: 'confimOrder', params: { storeId: String(storeDetail.value?.storeId) } })
+    }
+  }
+}
+function handleSelectStore(item: Api.DistanceStoreVO) {
+  if (item.storeId === storeDetail.value?.storeId)
+    return
+  router.replace({ name: 'refuelDetaile', params: { id: String(item.storeId) } })
+}
+</script>
+
+<template>
+  <template v-if="storeDetail">
+    <view class="p24rpx">
+      <view class="h336rpx">
+        <wd-swiper :list="storeDetail.storePicList" height="336rpx" />
+      </view>
+      <view class="mt20rpx h160rpx flex items-center justify-between rounded-16rpx bg-white bg-cover bg-center px24rpx" :style="{ backgroundImage: `url(${StaticUrl}/djk-shop-nav-bg.png)` }">
+        <view>
+          <view class="flex items-center text-36rpx font-semibold">
+            {{ storeDetail.storeName }}
+          </view>
+          <view class="mt20rpx text-#aaa">
+            {{ storeDetail.address }}
+          </view>
+        </view>
+        <view class="flex flex-shrink-0 items-center">
+          <view class="mr40rpx flex flex-col items-center justify-center" @click="handleShowMap">
+            <image
+              :src="`${StaticUrl}/djk-shop-dh.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx text-28rpx">
+              导航
+            </view>
+          </view>
+          <!-- <view class="flex flex-col items-center justify-center" @click="handleKf">
+            <image
+              :src="`${StaticUrl}/smqjh-jy-kf.png`"
+              class="h40rpx w40rpx"
+            />
+            <view class="mt20rpx text-28rpx">
+              客服
+            </view>
+          </view> -->
+        </view>
+      </view>
+      <view v-if="dklist" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="flex items-center">
+          <template v-if="!storeDetail.allowanceClientScheme">
+            <wd-icon name="check-circle-filled" size="22px" color="#52C41A" />
+            <view class="ml20rpx text-28rpx font-semibold">
+              本站可用抵扣券
+            </view>
+          </template>
+          <template v-else>
+            <wd-icon name="close-circle-filled" size="22px" color="#FF4D3A" />
+            <view class="ml20rpx text-28rpx font-semibold">
+              本站暂无抵扣券
+            </view>
+          </template>
+        </view>
+        <view v-if="!storeDetail.allowanceClientScheme" class="mt24rpx flex overflow-x-scroll">
+          <view v-for="item in dklist" :key="item.id" :class="[Number(item.inventoryActual) === 0 || item.receiveSign ? 'bg-#F0F0F0' : 'jf-box']" class="mr16rpx flex-shrink-0 rounded-16rpx p20rpx">
+            <view class="text-center text-36rpx font-semibold" :class="[Number(item.inventoryActual) === 0 || item.receiveSign ? 'text-#aaa' : 'text-#FF4D3A']">
+              <text class="text-20rpx">
+                ¥
+              </text> {{ item.discountMoney }}
+            </view>
+            <view class="my8rpx text-center" :class="[Number(item.inventoryActual) === 0 || item.receiveSign ? 'text-#aaa' : '']">
+              {{ item.amountMoney && item.amountMoney > 0 ? `满${item.amountMoney}减${item.discountMoney}` : `无门槛使用` }}
+            </view>
+            <view class="rounded-26rpx px24rpx py6rpx text-center" :class="[Number(item.inventoryActual) === 0 || item.receiveSign ? 'bg-#E6E6E6 text-#aaa' : 'bg-#FF4A39 text-white']" @click="handleExchange(item)">
+              {{ !item.receiveSign ? Number(item.inventoryActual) === 0 ? '已兑完' : '积分兑换' : '已兑换' }}
+            </view>
+          </view>
+        </view>
+      </view>
+      <view v-for="item in storeDetail.itemInfoList" :key="item.itemId" class="mt20rpx rounded-16rpx bg-white px24rpx py28rpx">
+        <view class="flex items-center justify-between">
+          <view class="text-32rpx font-semibold">
+            {{ item.itemName }}
+          </view>
+          <view class="text-36rpx text-#FF4D3A">
+            <text class="text-20rpx">
+              平台价:
+            </text> ¥{{ item.vipPriceShow }}/L
+          </view>
+        </view>
+        <view class="text-end text-#aaa">
+          国标价:¥{{ item.cityPriceShow }}/L 门店价:¥{{ item.storePriceShow }}L
+        </view>
+        <!-- <view class="mt18rpx text-#aaa">
+          (加油满200原可享前10升优惠价格)
+        </view> -->
+        <view class="mt20rpx">
+          枪号:{{ item.gunNos?.join(', ') }}
+        </view>
+      </view>
+      <view class="h200rpx" />
+    </view>
+    <FixedLayout>
+      <wd-button block size="large" @click="handlePay">
+        立即加油
+      </wd-button>
+    </FixedLayout>
+    <IntegralPopup v-model="showModel" :coupon-id="String(clickItem?.id)" />
+  </template>
+  <Zpopup v-model="showModelReful" bg="#fff">
+    <view class="px24rpx py28rpx">
+      <view class="mb24rpx text-center text-32rpx font-semibold">
+        请确认
+      </view>
+      <view class="text-28rpx">
+        您当前位置最近的油站是
+      </view>
+    </view>
+    <scroll-view v-if="storeDetail" scroll-y class="h600rpx">
+      <view v-for="item in storeVOList" :key="item.storeId" class="px24rpx" @click="handleSelectStore(item)">
+        <view v-if="item.storeId === storeDetail?.storeId" class="mb20rpx mt14rpx text-28rpx text-#333333">
+          您确定在
+        </view>
+        <view class="text-32rpx text-#333333 font-semibold">
+          ({{ item.storeName }}) {{ item.storeId === storeDetail?.storeId ? '下单吗' : '' }}
+        </view>
+
+        <view class="mt20rpx text-28rpx">
+          距离 {{ item.distance }} km
+        </view>
+      </view>
+    </scroll-view>
+    <template #footer>
+      <view class="my24rpx h2rpx w-full bg-#F0F0F0" />
+      <view class="w-full flex items-center justify-between pb20rpx">
+        <view class="w-45%">
+          <wd-button type="info" block size="large" @click="showModelReful = false">
+            取消
+          </wd-button>
+        </view>
+        <view class="w-45%">
+          <wd-button block size="large" @click="router.push({ name: 'confimOrder', params: { storeId: String(storeDetail?.storeId) } }), showModelReful = false">
+            继续
+          </wd-button>
+        </view>
+      </view>
+    </template>
+  </Zpopup>
+</template>
+
+<style lang="scss" scoped>
+.jf-box{
+  background: linear-gradient( 180deg, #FFC2BC 0%, rgba(255,238,238,0.16) 57.27%, #FFEFEF 100%);
+}
+</style>

+ 68 - 0
src/subPack-refueling/transition/index.vue

@@ -0,0 +1,68 @@
+<script setup lang="ts">
+import router from '@/router'
+
+definePage({
+  name: 'transition',
+  islogin: false,
+  style: {
+    navigationBarTitleText: '',
+    navigationStyle: 'custom',
+  },
+})
+
+const orderNo = ref('')
+const orderInfo = ref<Api.xsbOrderList>()
+const countdownTime = ref(3000) // 3秒倒计时
+
+// 倒计时结束后查询订单
+async function handleCountdownFinish() {
+  if (!orderNo.value) {
+    goToOrderList()
+    return
+  }
+
+  try {
+    const res = await Apis.general.get_smqjh_oms_api_v1_order_orderinfo({
+      params: { orderNo: orderNo.value },
+    })
+    orderInfo.value = res.data
+
+    // 有订单数据则跳转支付成功页
+    if (orderInfo.value?.orderNumber) {
+      router.replace({
+        name: 'paySuccess',
+        params: { outerOrderId: orderNo.value },
+      })
+    }
+    else {
+      goToOrderList()
+    }
+  }
+  catch {
+    goToOrderList()
+  }
+}
+
+function goToOrderList() {
+  router.pushTab({ name: 'order' })
+  useTabbar().setTabbarItemActive('order')
+}
+
+onLoad((options: any) => {
+  orderNo.value = options.outerOrderId || ''
+})
+</script>
+
+<template>
+  <view class="min-h-100vh flex flex-col items-center justify-center bg-#f5f5f5">
+    <view class="text-32rpx text-#333">
+      正在处理中,请稍候...
+    </view>
+    <view class="mt24rpx flex items-center text-28rpx text-#999">
+      <wd-count-down :time="countdownTime" format="ss" @finish="handleCountdownFinish" />
+      <text>秒后跳转</text>
+    </view>
+  </view>
+</template>
+
+<style lang="scss" scoped></style>

+ 259 - 0
src/subPack-refueling/voucherDetail/index.vue

@@ -0,0 +1,259 @@
+<script setup lang="ts">
+import router from '@/router'
+
+import { StaticUrl } from '@/config'
+
+definePage({
+  name: 'voucherDetail',
+  islogin: true,
+  style: {
+    navigationBarTitleText: '抵扣券详情',
+    navigationStyle: 'custom',
+  },
+})
+const couponId = ref('')
+const couponInfo = ref<Api.AppCouponDetailsVO>()
+
+// 状态映射
+const statusMap = new Map([
+  [2, '可用'],
+  [1, '已使用'],
+  [5, '已过期'],
+  [7, '无效'],
+])
+
+const { send } = useRequest(
+  (id: string) => Apis.app.get_smqjh_system_app_api_membercoupon_findbyid({ params: { id } }),
+  { immediate: false },
+).onSuccess((res) => {
+  couponInfo.value = res.data.data
+})
+
+onLoad((options: any) => {
+  couponId.value = options.id || ''
+  if (couponId.value) {
+    send(couponId.value)
+  }
+})
+
+// 计算剩余天数
+const remainingDays = computed(() => {
+  if (!couponInfo.value?.expirationTime)
+    return ''
+  const expire = new Date(couponInfo.value.expirationTime).getTime()
+  const now = Date.now()
+  const diff = expire - now
+  if (diff <= 0)
+    return '已过期'
+  const days = Math.floor(diff / (1000 * 60 * 60 * 24))
+  const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60))
+  return `${days}天${hours}小时`
+})
+
+// 计算支付倒计时
+function getCountdownTime(orderCreateTime?: string): number {
+  if (!orderCreateTime)
+    return 0
+  const createTime = new Date(orderCreateTime).getTime()
+  const expireTime = createTime + 30 * 60 * 1000 // 30分钟
+  const remaining = expireTime - Date.now()
+  return remaining > 0 ? remaining : 0
+}
+
+// 去使用
+function handleUse() {
+  router.pushTab({ name: 'home' })
+  useTabbar().setTabbarItemActive('home')
+}
+
+// 查看订单详情
+function handleViewOrder() {
+  router.pushTab({ name: 'order' })
+  useTabbar().setTabbarItemActive('order')
+}
+
+// 取消订单(占位)
+async function handleCancelOrder() {
+  // useGlobalToast().show('功能开发中')
+  await useUserStore().handleCommonCancelOrderJY(couponInfo.value?.orderNumber as string)
+  send(couponId.value)
+}
+
+// 付款(占位)
+function handlePay() {
+  // useGlobalToast().show('功能开发中')
+  useUserStore().handleCommonGoXiaoJuPay(couponInfo.value?.orderNumber as string)
+}
+</script>
+
+<template>
+  <view v-if="couponInfo" class="min-h-100vh bg-#f5f5f5 pb200rpx pt20rpx">
+    <!-- 顶部券信息 -->
+    <view class="mx24rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="flex items-center">
+        <image :src="`${StaticUrl}/smqjh-reful-juan.png`" class="mr12rpx h32rpx w32rpx" />
+        <view class="text-30rpx font-semibold">
+          抵扣{{ couponInfo.discountMoney }}元(满{{ couponInfo.amountMoney }}可用)
+        </view>
+      </view>
+    </view>
+
+    <!-- 券信息卡片 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        券信息
+      </view>
+      <view class="text-26rpx text-#666 leading-48rpx">
+        <view>券ID:{{ couponInfo.allowanceId || couponInfo.id }}</view>
+        <view>批次号:{{ couponInfo.batchId || '-' }}</view>
+        <view>状态:{{ couponInfo.lockStatus === 1 ? '已冻结' : statusMap.get(couponInfo.useStatus as number) || '-' }}</view>
+        <view>面值:¥{{ couponInfo.discountMoney }}</view>
+      </view>
+    </view>
+
+    <!-- 有效期卡片 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        有效期
+      </view>
+      <view class="text-26rpx text-#666 leading-48rpx">
+        <view>开始:{{ couponInfo.getTime || '-' }}</view>
+        <view>结束:{{ couponInfo.expirationTime || '-' }}</view>
+        <view v-if="couponInfo.useStatus === 1">
+          使用:{{ couponInfo.orderPayTime || '-' }}
+        </view>
+        <view v-else>
+          剩余:{{ remainingDays }}
+        </view>
+      </view>
+    </view>
+
+    <!-- 使用记录(已使用状态) -->
+    <view v-if="couponInfo.useStatus === 1" class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        使用记录
+      </view>
+      <view class="text-26rpx text-#666 leading-48rpx">
+        <view>订单号:{{ couponInfo.orderNumber || '-' }}</view>
+        <view>油站:{{ couponInfo.storeName || '-' }}</view>
+        <view>油号:{{ couponInfo.itemName || '-' }}</view>
+        <view>枪号:{{ couponInfo.gunNo ? `${couponInfo.gunNo}号枪` : '-' }}</view>
+        <view>订单金额:¥{{ couponInfo.totalMoney ? (couponInfo.totalMoney) : 0 }}</view>
+        <view>抵扣金额:¥{{ couponInfo.discountMoney }}</view>
+        <view>实付金额:¥{{ couponInfo.realMoney ? (couponInfo.realMoney) : 0 }}</view>
+      </view>
+    </view>
+
+    <!-- 冻结信息(已冻结状态) -->
+    <view v-if="couponInfo.lockStatus === 1 && couponInfo.useStatus === 2" class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        冻结信息
+      </view>
+      <view class="mb16rpx flex items-center text-26rpx text-#ff4d3a">
+        <wd-icon name="info-circle" size="28rpx" color="#ff4d3a" class="mr8rpx" />
+        当前券被订单占用
+      </view>
+      <view class="text-26rpx text-#666 leading-48rpx">
+        <view>订单号:{{ couponInfo.orderNumber || '-' }}</view>
+        <view>下单时间:{{ couponInfo.orderCreateTime || '-' }}</view>
+        <view class="flex items-center">
+          支付剩余时间:<wd-count-down :time="getCountdownTime(couponInfo.orderCreateTime)" format="mm分ss秒" />
+        </view>
+        <view>订单金额:¥{{ couponInfo.totalMoney ? (couponInfo.totalMoney) : 0 }}</view>
+        <view>抵扣金额:¥{{ couponInfo.discountMoney }}</view>
+      </view>
+    </view>
+
+    <!-- 无效原因(无效状态) -->
+    <view v-if="couponInfo.useStatus === 7" class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        无效原因
+      </view>
+      <view class="mb16rpx flex items-center text-26rpx text-#ff4d3a">
+        <wd-icon name="info-circle" size="28rpx" color="#ff4d3a" class="mr8rpx" />
+        此券无法使用
+      </view>
+      <view class="text-26rpx text-#666">
+        原因:油站已下线
+      </view>
+    </view>
+
+    <!-- 使用规则卡片 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        使用规则
+      </view>
+      <view class="text-26rpx text-#666 leading-44rpx">
+        <view>·订单满{{ couponInfo.amountMoney }}元可用</view>
+        <view>·抵扣金额:{{ couponInfo.discountMoney }}元</view>
+        <view>·每单限用1张,不与其他优惠同享</view>
+        <view>·使用全部合作油站</view>
+        <view>·不支持部分特殊油站</view>
+      </view>
+    </view>
+
+    <!-- 状态说明卡片 -->
+    <view class="mx24rpx mt20rpx rounded-16rpx bg-white px28rpx py32rpx">
+      <view class="mb20rpx text-30rpx font-semibold">
+        状态说明
+      </view>
+      <view class="text-26rpx text-#666">
+        <template v-if="couponInfo.lockStatus === 1 && couponInfo.useStatus === 2">
+          此券已被当前订单占用,如需使用其他抵扣券,请先取消订单或完成支付
+        </template>
+        <template v-else-if="couponInfo.useStatus === 2">
+          当前状态正常,可在下单时使用
+        </template>
+        <template v-else-if="couponInfo.useStatus === 1">
+          此抵扣券已使用,您可以在活动期间关注新抵扣券
+        </template>
+        <template v-else-if="couponInfo.useStatus === 7">
+          此抵扣券因合作变动无法使用,您可以联系客服处理。
+        </template>
+        <template v-else>
+          此券当前不可用
+        </template>
+      </view>
+    </view>
+
+    <!-- 底部按钮 -->
+    <FixedLayout>
+      <!-- 可用状态 -->
+      <wd-button
+        v-if="couponInfo.useStatus === 2 && couponInfo.lockStatus !== 1"
+        block
+        size="large"
+        @click="handleUse"
+      >
+        去使用
+      </wd-button>
+
+      <!-- 已使用状态 -->
+      <wd-button
+        v-else-if="couponInfo.useStatus === 1"
+        block
+        size="large"
+        @click="handleViewOrder"
+      >
+        查看订单详情
+      </wd-button>
+
+      <!-- 已冻结状态 -->
+      <view v-else-if="couponInfo.lockStatus === 1 && couponInfo.useStatus === 2" class="flex items-center gap-24rpx">
+        <wd-button plain block size="large" custom-class="flex-1 cancel-btn" @click="handleCancelOrder">
+          取消订单
+        </wd-button>
+        <wd-button block size="large" custom-class="flex-1" @click="handlePay">
+          付款
+        </wd-button>
+      </view>
+    </FixedLayout>
+  </view>
+</template>
+
+<style lang="scss" scoped>
+:deep(.cancel-btn) {
+  border-color: var(--them-color) !important;
+  color: var(--them-color) !important;
+}
+</style>

+ 5 - 0
src/subPack-smqjh/components/djk-order/index.vue

@@ -17,8 +17,13 @@ async function handleCancel(order: Api.xsbOrderList) {
 async function handlePay(orderNumber: string) {
   const res = await useUserStore().handleCommonPayMent?.(orderNumber)
   if (res?.payType !== 1 && res) {
+    // #ifdef MP-WEIXIN
     await useUserStore().getWxCommonPayment(res)
     _emit('refresh')
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(orderNumber)
+    // #endif
   }
   else {
     _emit('refresh')

+ 9 - 0
src/subPack-smqjh/components/xsb-orderList/xsb-orderList.vue

@@ -12,7 +12,9 @@ const _emit = defineEmits<{
 const NodeList = ref<Api.DeliveryNode[]>([])
 const showNode = ref(false)
 
+// #ifdef MP-WEIXIN
 const plugins = requirePlugin('logisticsPlugin')
+// #endif
 async function handleCancel(order: Api.xsbOrderList) {
   await useUserStore().handleCommonCancelOrder?.(order)
   _emit('refresh')
@@ -21,8 +23,13 @@ async function handleCancel(order: Api.xsbOrderList) {
 async function handlePay(orderNumber: string) {
   const res = await useUserStore().handleCommonPayMent?.(orderNumber)
   if (res?.payType !== 1 && res) {
+    // #ifdef MP-WEIXIN
     await useUserStore().getWxCommonPayment(res)
     _emit('refresh')
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(orderNumber)
+    // #endif
   }
   else {
     _emit('refresh')
@@ -64,9 +71,11 @@ async function handleLogistics(_order: Api.xsbOrderList) {
       uni.hideLoading()
       const jsData = JSON.parse(res.data)
       if (jsData.errmsg === 'ok') {
+        // #ifdef MP-WEIXIN
         plugins.openWaybillTracking({
           waybillToken: jsData.waybill_token,
         })
+        // #endif
       }
     }
     catch {

+ 2 - 2
src/subPack-smqjh/order/components/OrderRenderer.vue

@@ -19,7 +19,7 @@ defineEmits<{
 </script>
 
 <template>
-  <block>
+  <view>
     <xsbList
       v-if="orderList.businessType === 'XSB' || orderList.businessType === 'all'" :order="orderList"
       @refresh="$emit('refresh')"
@@ -39,5 +39,5 @@ defineEmits<{
       v-else-if="orderList.businessType === 'JDMP' || orderList.businessType === 'all'" :order="orderList"
       @refresh="$emit('refresh')"
     />
-  </block>
+  </view>
 </template>

+ 2 - 2
src/subPack-smqjh/order/index.vue

@@ -138,7 +138,7 @@ function handleRefresh() {
       </view>
     </view>
     <view class="p-24rpx">
-      <templat v-if="skelet">
+      <template v-if="skelet">
         <view v-for="item in 10" :key="item" class="mb20rpx rounded-16rpx bg-white p24rpx">
           <wd-skeleton
             animation="gradient"
@@ -178,7 +178,7 @@ function handleRefresh() {
             :row-col="[{ width: '100%', height: '60rpx' }]"
           />
         </view>
-      </templat>
+      </template>
       <view v-else>
         <template v-for="item in orderList" :key="item.orderNumber">
           <OrderRenderer

+ 5 - 5
src/subPack-xsb/commonTab/components/cart.vue

@@ -36,8 +36,8 @@ onMounted(async () => {
     <view class="-mt220rpx">
       <view class="content px24rpx">
         <view v-if="cartList.length" class="mb20rpx flex items-center justify-end">
-          <view class="text-24rpx text-[#AAAAAA]" @click="cartStore.cartDeleteGoods">
-            <wd-icon name="delete" size="24rpx" /> 清空购物车
+          <view class="text-24rpx text-[#fff]" @click="cartStore.cartDeleteGoods">
+            <wd-icon name="delete" size="24rpx" color="#fff" /> 清空购物车
           </view>
         </view>
         <scroll-view scroll-y class="content">
@@ -98,7 +98,7 @@ onMounted(async () => {
                       <!-- <wd-input-number v-model="item.num" disable-input @change="handleChangeNum($event, item)" /> -->
                       <view class="flex items-center">
                         <image
-                          :src="` ${StaticUrl}/sub-cart.png`"
+                          :src="`${StaticUrl}/sub-cart.png`"
                           class="h44rpx w44rpx"
                           @click.stop="cartStore.cartSubGoods(item)"
                         />
@@ -106,7 +106,7 @@ onMounted(async () => {
                           {{ item.num }}
                         </view>
                         <image
-                          :src="` ${StaticUrl}/add-cart.png`"
+                          :src="`${StaticUrl}/add-cart.png`"
                           class="h44rpx w44rpx"
                           @click.stop="cartStore.cartAddGoods(item)"
                         />
@@ -130,7 +130,7 @@ onMounted(async () => {
 
           <view v-if="!cartList.length" 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" />
+              <i class="iconfont text-110rpx text-[var(--them-color)]">&#xe64d;</i>
               <view class="mb20rpx mt20rpx text-24rpx">
                 你还没有添加商品哦~
               </view>

+ 13 - 12
src/subPack-xsb/commonTab/components/classfiy.vue

@@ -238,6 +238,9 @@ async function handleSubCart(event: WechatMiniprogram.TouchEvent, item: Api.xsbC
 }
 
 onMounted(async () => {
+  if (token.value) {
+    await getCartCategorList()
+  }
   if (!topNavActive.value || !leftActive.value) {
     const firstWithChildren = props.categoryList?.find(it => it.children && it.children.length > 0)
     if (firstWithChildren) {
@@ -259,12 +262,8 @@ onMounted(async () => {
       topScrollView.value = topNavActive.value
     })
   }
-  console.log(topNavActive.value, '  ==', props.categoryList)
 
   getCartBox()
-  if (token.value) {
-    await getCartCategorList()
-  }
 })
 
 function getCartBox() {
@@ -402,7 +401,7 @@ export default {
 <template>
   <view class="page-xsb">
     <wd-navbar
-      title="" custom-style="background-color:#F4FFD1" :bordered="false" :z-index="9999" safe-area-inset-top
+      title="" :custom-style="`background-color: ${hexToRgba(useManualThemeStore().themeVars.colorTheme as string, 0)};`" :bordered="false" :z-index="9999" safe-area-inset-top
       fixed
     >
       <template #left>
@@ -430,7 +429,7 @@ export default {
       </template>
     </wd-navbar>
     <view
-      class="h162rpx flex items-center justify-between bg-#F4FFD1 pl24rpx"
+      class="header-linear h162rpx flex items-center justify-between pl24rpx"
       :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
     >
       <scroll-view
@@ -475,7 +474,7 @@ export default {
       </view>
       <wd-popup v-model="show" :z-index="9998" position="top" custom-style="border-radius:32rpx;">
         <view
-          class="box-border bg-#F4FFD1 p24rpx"
+          class="header-linear box-border p24rpx"
           :style="{ paddingTop: `${(Number(statusBarHeight) || 44) + MenuButtonHeight + 12}px` }"
         >
           <view class="mb24rpx mt24rpx text-28rpx font-semibold">
@@ -592,16 +591,18 @@ export default {
                       </view>
                       <view v-if="!item.num">
                         <view v-if="item.spuStock" @click.stop="handleAddCart($event, item)">
-                          <image :src="`${StaticUrl}/cart-yes.png`" class="h52rpx w52rpx" />
+                          <!-- <image :src="`${StaticUrl}/cart-yes.png`" class="h52rpx w52rpx" /> -->
+                          <i class="iconfont text-52rpx text-[var(--them-color)]">&#xe64c;</i>
                         </view>
                         <view v-else>
-                          <image :src="`${StaticUrl}/cart-no.png`" class="h52rpx w52rpx" />
+                          <!-- <image :src="`${StaticUrl}/cart-no.png`" class="h52rpx w52rpx" /> -->
+                          <i class="iconfont text-52rpx text-#ccc">&#xe64c;</i>
                         </view>
                       </view>
                       <view v-else>
                         <view class="flex items-center">
                           <image
-                            :src="` ${StaticUrl}/sub-cart.png`" class="h44rpx w44rpx"
+                            :src="`${StaticUrl}/sub-cart.png`" class="h44rpx w44rpx"
                             @click.stop="handleSubCart($event, item)"
                           />
                           <view
@@ -610,7 +611,7 @@ export default {
                             {{ item.num }}
                           </view>
                           <image
-                            :src="` ${StaticUrl}/add-cart.png`" class="h44rpx w44rpx"
+                            :src="`${StaticUrl}/add-cart.png`" class="h44rpx w44rpx"
                             @click.stop="handleAddCart($event, item)"
                           />
                         </view>
@@ -893,7 +894,7 @@ export default {
 
 <style scoped lang="scss">
 .right-nav {
-  background: linear-gradient(180deg, #FAFFEC 0%, #F6FFDE 11%, #E7FFA5 100%);
+  background: linear-gradient( 139deg, #FAFFEC 0%, var(--them-color) 100%);
   box-shadow: -10rpx 0rpx 12rpx 2rpx rgba(0, 0, 0, 0.07);
 }
 

+ 11 - 11
src/subPack-xsb/commonTab/components/index.vue

@@ -90,7 +90,7 @@ function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
   <view class="page-xsb">
     <wd-navbar
       title=""
-      :custom-style="`background-color: rgba(158,214,5,${opcity});`"
+      :custom-style="`background-color: ${hexToRgba(useManualThemeStore().themeVars.colorTheme as string, opcity)};`"
       :bordered="false" :z-index="99" safe-area-inset-top left-arrow fixed @click-left="router.back()"
     >
       <template #left>
@@ -119,7 +119,7 @@ function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
               <wd-icon name="search" size="14" color="#ccc" />
               <view class="search ml12rpx h-full w-full overflow-hidden">
                 <wd-notice-bar
-                  :text="hotText.map((it) => it.searchName)" custom-class="notice-bar" color="#ccc"
+                  :text="hotText.map((it: Api.xsbSearchTerm) => it.searchName)" custom-class="notice-bar" color="#ccc"
                   background-color="#fff" direction="vertical"
                 />
               </view>
@@ -244,12 +244,12 @@ function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
             <view class="h40rpx flex items-center">
               <view v-for="item, idx in navList" :key="idx" class="relative mr44rpx" @click="handleChangeNav(idx)">
                 <image v-if="idx == 2" :src="`${StaticUrl}/chaozhi.png`" class="relative z-2 h-29.06rpx w-105.34rpx" />
-                <text
+                <view
                   v-show="idx != 2" class="relative z-2 text-32rpx"
                   :class="[navActive == idx ? 'text-36rpx font-semibold' : '']"
                 >
                   {{ item.title }}
-                </text>
+                </view>
                 <view
                   v-show="navActive == idx"
                   class="nav-line absolute bottom-0rpx left-50% z-1 h18rpx w80rpx rounded-10rpx -translate-x-50%"
@@ -261,8 +261,8 @@ function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
         <view class="mt20rpx">
           <wd-skeleton theme="image" animation="gradient" :loading="loading" :row-col="[[{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }], [{ height: '568rpx', width: '344rpx' }, { height: '568rpx', width: '344rpx' }]]">
             <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">
+              <view class="w-full columns-2 gap-[10px]">
+                <view class="mb-[10px] break-inside-avoid">
                   <wd-swiper
                     :autoplay="false" :list="[
                       `${StaticUrl}/xsb-swiper1.png`,
@@ -271,11 +271,11 @@ function handleChangeSwiper(e: UniHelper.SwiperOnChangeEvent) {
                     :indicator="{ type: 'dots-bar' }"
                     @click="useGlobalToast().show('敬请期待 !')"
                   />
-                  <view v-for="it in goodsList" :key="it.id">
-                    <itemGoods :item-goods="it" />
-                  </view>
-                </grid-view>
-              </scroll-view>
+                </view>
+                <view v-for="it in goodsList" :key="it.id" class="mb-[10px] break-inside-avoid">
+                  <itemGoods :item-goods="it" />
+                </view>
+              </view>
             </view>
           </wd-skeleton>
         </view>

+ 13 - 15
src/subPack-xsb/commonTab/components/my.vue

@@ -3,10 +3,10 @@ import { StaticUrl } from '@/config'
 import router from '@/router'
 
 const tabList = ref([
-  { title: '待支付', icon: `${StaticUrl}/1.png`, name: 'xsb-order', status: 'paddingPay' },
-  { title: '进行中', icon: `${StaticUrl}/2.png`, name: 'xsb-order', status: 'ing' },
-  { title: '已完成', icon: `${StaticUrl}/6.png`, name: 'xsb-order', status: 'completed' },
-  { title: '退款售后', icon: `${StaticUrl}/3.png`, name: 'common-afterSalesList', status: '' },
+  { title: '待支付', icon: ``, name: 'xsb-order', status: 'paddingPay' },
+  { title: '进行中', icon: ``, name: 'xsb-order', status: 'ing' },
+  { title: '已完成', icon: ``, name: 'xsb-order', status: 'completed' },
+  { title: '退款售后', icon: ``, name: 'common-afterSalesList', status: '' },
 ])
 
 const { token, userInfo, getUserAvatar } = storeToRefs(useUserStore())
@@ -26,10 +26,11 @@ function handleGo(item: { name: string, status: string }) {
       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="relative h-408rpx rounded-18px" :style="{ background: `linear-gradient( 180deg, var(--them-color) 0%, rgba(255,255,255,0) 100%)` }">
       <view class="absolute bottom-100rpx left-0 box-border w-full flex items-center justify-between pl48rpx pr58rpx">
         <template v-if="!token">
-          <image :src="`${StaticUrl}/9.png`" alt="" class="h100rpx w100rpx" />
+          <!-- <image :src="`${StaticUrl}/9.png`" alt="" class="h100rpx w100rpx" /> -->
+          <i class="iconfont text-100rpx text-[var(--them-color)]">&#xe654;</i>
           <view class="text-32rpx font-semibold">
             请登录后使用完整功能
           </view>
@@ -44,16 +45,13 @@ function handleGo(item: { name: string, status: string }) {
               <view class="text-32rpx font-semibold">
                 {{ userInfo.nickName }}
               </view>
-              <view class="mt12rpx rounded-8rpx bg-white px12rpx py4rpx text-24rpx text-[var(--them-color)] opacity-70">
+              <view class="mt12rpx w-fit rounded-8rpx bg-white px12rpx py4rpx text-24rpx text-[var(--them-color)] opacity-70">
                 {{ userInfo.channelName }}
               </view>
             </view>
           </view>
           <view class="flex flex-col items-center" @click="router.push({ name: 'common-user-center' })">
-            <image
-              :src="`${StaticUrl}/user-setting.png`"
-              class="h48rpx w48rpx"
-            />
+            <wd-icon name="setting" size="22px" color="var(--them-color)" />
             <view class="mt12rpx text-24rpx text-[var(--them-color)]">
               账户设置
             </view>
@@ -78,7 +76,9 @@ function handleGo(item: { name: string, status: string }) {
         </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="handleGo(item)">
-            <image :src="item.icon" class="h56rpx w56rpx" />
+            <i class="iconfont text-56rpx text-[var(--them-color)]">
+              {{ item.icon }}
+            </i>
             <view class="mt20rpx text-24rpx">
               {{ item.title }}
             </view>
@@ -133,7 +133,5 @@ function handleGo(item: { name: string, status: string }) {
 </template>
 
 <style lang="scss" scoped>
-.header {
- background: linear-gradient( 113deg, #F7FFDC 0%, #E0FF8E 25%, #F2FFCE 51%, #E3FF98 83%, #F6FFD6 100%);
-}
+
 </style>

+ 10 - 17
src/subPack-xsb/commonTab/index.vue

@@ -4,14 +4,6 @@ import indexHome from './components/index.vue'
 import cart from './components/cart.vue'
 import classfiy from './components/classfiy.vue'
 import my from './components/my.vue'
-import icon2 from '@/static/tab/index1.png'
-import icon1 from '@/static/tab/index2.png'
-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'
 
 definePage({
   name: 'xsb-homeTabbar',
@@ -44,10 +36,10 @@ const { data: goodsList, isLastPage, page, error, reload, refresh } = usePaginat
   immediate: false,
 })
 const tabbarItems = ref([
-  { name: 'xsb-home', value: null, active: true, title: '首页', icon1: '', icon2: '' },
-  { name: 'xsb-classfiy', value: null, active: false, title: '分类', icon1: class1, icon2: class2 },
-  { name: 'xsb-cart', value: null, active: false, title: '购物车', icon1: icon3, icon2: icon4 },
-  { name: 'xsb-my', value: null, active: false, title: '我的', icon1: icon5, icon2: icon6 },
+  { name: 'xsb-home', value: null, active: true, title: '首页', icon1: '' },
+  { name: 'xsb-classfiy', value: null, active: false, title: '分类', icon1: '' },
+  { name: 'xsb-cart', value: null, active: false, title: '购物车', icon1: '' },
+  { name: 'xsb-my', value: null, active: false, title: '我的', icon1: '' },
 ])
 const tabbarName = ref('xsb-home')
 const swiperList = ref<Api.xsbAdvertInfo[]>([])
@@ -201,15 +193,16 @@ async function queryPopupConfig() {
       >
         <template #icon="{ active }">
           <template v-if="index == 0 && !active">
-            <image src="@/static/tab/index.png" class="h44rpx w44rpx" />
+            <i class="iconfont text-44rpx">&#xe629;</i>
           </template>
           <template v-else-if="index == 0 && active">
-            <image v-if="opcity == 1" :src="icon1" class="h74rpx w74rpx" @click="handleClick" />
-            <image v-else :src="icon2" class="h74rpx w74rpx" />
+            <i v-if="opcity == 1" class="iconfont text-76rpx text-[var(--them-color)]" @click="handleClick">&#xe62b;</i>
+            <i v-else class="iconfont text-76rpx text-[var(--them-color)]">&#xe648;</i>
           </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" />
+            <text :class="[active ? 'text-[var(--them-color)]' : '']" class="iconfont text-44rpx">
+              {{ item.icon1 }}
+            </text>
           </template>
         </template>
       </wd-tabbar-item>

+ 1 - 1
src/subPack-xsb/components/goodsItem/index.vue

@@ -58,7 +58,7 @@ defineProps<{ itemGoods: Api.xsbCategoryProductList }>()
               </view>
             </view>
           </view>
-          <image :src="`${StaticUrl}/cart-yes.png`" class="h52rpx w52rpx" />
+          <i class="iconfont text-52rpx text-[var(--them-color)]">&#xe64c;</i>
         </view>
       </view>
     </view>

+ 12 - 4
src/subPack-xsb/confirmOrder/index.vue

@@ -275,6 +275,7 @@ async function handlePay() {
           }
         : undefined,
     )
+    // #ifdef MP-WEIXIN
     const res = await useUserStore().handleCommonPayMent(orderNumber)
     console.log(orderInfo.value, '=====订单信息')
     await useUserStore().clearCart(orderInfo.value.skuList)
@@ -291,6 +292,13 @@ async function handlePay() {
     else {
       await useUserStore().paySuccess('xsb-order', 'subPack-xsb/commonTab/index')
     }
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(orderNumber)
+    isPay.value = false
+    await useUserStore().clearCart(orderInfo.value.skuList)
+    totalProduct.value = null
+    // #endif
   }
   catch {
     isPay.value = false
@@ -349,7 +357,7 @@ async function handlePay() {
           <view v-if="shopDistanceText" class="mb-20rpx text-24rpx text-#AAAAAA">
             {{ shopDistanceText }}
           </view>
-          <wd-icon name="location" size="22px" color="#9ED605" />
+          <wd-icon name="location" size="22px" color="var(--them-color)" />
         </view>
       </view>
       <view>
@@ -501,14 +509,14 @@ async function handlePay() {
           <view class="mb-24rpx flex items-center">
             <view
               class="mr-16rpx flex-1 rounded-full py-18rpx text-center text-28rpx"
-              :class="couponTabActive === 0 ? 'bg-[#9ED605] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
+              :class="couponTabActive === 0 ? 'bg-[var(--them-color)] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
               @click="couponTabActive = 0"
             >
               可用券({{ availableCoupons.length }})
             </view>
             <view
               class="flex-1 rounded-full py-18rpx text-center text-28rpx"
-              :class="couponTabActive === 1 ? 'bg-[#9ED605] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
+              :class="couponTabActive === 1 ? 'bg-[var(--them-color)] text-white font-semibold' : 'bg-[#F0F0F0] text-[#666]'"
               @click="couponTabActive = 1"
             >
               不可用券({{ unavailableCoupons.length }})
@@ -565,7 +573,7 @@ async function handlePay() {
         </view>
       </template>
     </Zpopup>
-    <view class="ios footer fixed bottom-0 left-0 z-1000 box-border w-full rounded-t-16rpx bg-white px24rpx">
+    <view class="ios footer fixed bottom-0 left-0 z-10 box-border w-full rounded-t-16rpx bg-white px24rpx">
       <view class="box-border w-full flex items-center justify-between py20rpx">
         <view v-if="isMemberGiftOrder" class="flex items-center">
           <text class="mr-8rpx rounded-8rpx bg-#FF4D3A px-12rpx py-4rpx text-22rpx text-#FFF">

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

@@ -174,7 +174,7 @@ function handleClick() {
           </view>
         </template>
       </wd-swiper>
-      <view class="header view-0 relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
+      <view class="view-0 header relative z-3 rounded-t-32rpx px24rpx pt24rpx -mt30rpx">
         <view class="flex items-center justify-between">
           <view v-if="goodsInfo?.isMember" class="flex items-end text-#FF4D3A font-semibold">
             <view class="text-24rpx">

+ 9 - 2
src/subPack-xsb/orderDetaile/index.vue

@@ -2,8 +2,9 @@
 import type { MapMarker, MapPolyline } from '@uni-helper/uni-types'
 import { StaticUrl } from '@/config'
 import router from '@/router'
-
+// #ifdef MP-WEIXIN
 const plugins = requirePlugin('logisticsPlugin')
+// #endif
 const { statusBarHeight, MenuButtonHeight } = storeToRefs(useSysStore())
 const { userInfo } = storeToRefs(useUserStore())
 definePage({
@@ -79,8 +80,13 @@ async function handleCancel() {
 async function handlePay() {
   const res = await useUserStore().handleCommonPayMent(String(unref(orderInfo)?.orderNumber))
   if (res.payType !== 1) {
+    // #ifdef MP-WEIXIN
     await useUserStore().getWxCommonPayment(res)
     getDetail(String(unref(orderInfo)?.orderNumber))
+    // #endif
+    // #ifdef H5
+    useUserStore().handleCommonWechatPay(String(unref(orderInfo)?.orderNumber))
+    // #endif
   }
   else {
     getDetail(String(unref(orderInfo)?.orderNumber))
@@ -427,7 +433,8 @@ function handleRefundDetail(item: any) {
       </view>
       <view v-if="orderInfo?.dvyType === 3" class="mt-20rpx rounded-16rpx bg-white p-24rpx">
         <view class="flex items-center">
-          <image :src="`${StaticUrl}/orderDetaile-user.png`" class="mr-20rpx h-40rpx w-40rpx" />
+          <i class="iconfont text-40rpx text-[var(--them-color)]">&#xe654;</i>
+          <!-- <image :src="`${StaticUrl}/orderDetaile-user.png`" class="mr-20rpx h-40rpx w-40rpx" /> -->
           <view class="text-32rpx text-[#222] font-semibold">
             {{ orderInfo?.consigneeName }} {{ orderInfo?.consigneeMobile }}
           </view>

+ 1 - 0
src/types/jz-h5-scanCode.d.ts

@@ -0,0 +1 @@
+declare module 'jz-h5-scanCode/js/index.js';

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است