瀏覽代碼

feat(api): 支持accessId请求头并从H5地址栏读取

- 在API请求实例中增加accessId请求头,条件为accessId存在时添加
- 在配置文件中新增accessId变量,从H5环境地址栏query参数中获取
- 非H5环境accessId默认为空字符串
- 优化请求时缓存处理,GET请求参数自动添加时间戳防止缓存
zhangtao 1 周之前
父節點
當前提交
29e4575696
共有 3 個文件被更改,包括 128 次插入1 次删除
  1. 108 0
      CLAUDE.md
  2. 4 1
      src/api/core/instance.ts
  3. 16 0
      src/config/index.ts

+ 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)

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

@@ -2,7 +2,7 @@ import AdapterUniapp from '@alova/adapter-uniapp'
 import { createAlova } from 'alova'
 import vueHook from 'alova/vue'
 import { handleAlovaError, handleAlovaResponse } from './handlers'
-import { BASE_URL } from '@/config'
+import { BASE_URL, accessId } from '@/config'
 
 export const alovaInstance = createAlova({
   baseURL: BASE_URL,
@@ -15,6 +15,9 @@ export const alovaInstance = createAlova({
     }
     const { token } = useUserStore()
     method.config.headers.Authorization = token || 'Basic c21xamgtYXBwbGV0OjEyMzQ1Ng=='
+    if (accessId) {
+      method.config.headers.accessId = accessId
+    }
     // Add timestamp to prevent caching for GET requests
     if (method.type === 'GET' && CommonUtil.isObj(method.config.params)) {
       method.config.params._t = Date.now()

+ 16 - 0
src/config/index.ts

@@ -59,3 +59,19 @@ function handleEnvVersion() {
  * h5小橘重定向地址
  */
 export const REDIRECT_URL = 'https://smqjh.h5.zswlgz.com/#/subPack-refueling/commonTab/index'
+
+/**
+ * H5 环境从地址栏获取 accessId 参数
+ */
+export const accessId = getAccessId()
+
+function getAccessId(): string {
+  // #ifdef H5
+  const search = window.location.search
+  const params = new URLSearchParams(search)
+  return params.get('accessId') || ''
+  // #endif
+  // #ifndef H5
+  return ''
+  // #endif
+}