Commit 4612dd33 by chunhong.mu

docs(root): 更新架构文档,新增 qqqf-mp 理想架构和 @common/sdk 说明

parent 3e37df57
Showing with 232 additions and 13 deletions
......@@ -6,9 +6,12 @@
common-web/
├── common/ # 公共代码库(跨项目复用)
│ ├── utils/ # 纯工具函数、常量、类型定义
│ └── vue-kit/ # Vue 相关代码(组件、组合式函数、指令)
│ ├── vue-kit/ # Vue 相关代码(组件、组合式函数、指令)
│ └── sdk/ # 统一业务平台 SDK 封装(uniplat-sdk + HTTP 适配)
├── packages/ # 具体项目
│ └── official-site-web/ # 官网项目
│ ├── official-site-web/ # 官网项目(Nuxt 3 SSR)
│ ├── partner-mp/ # 合伙人小程序(UniApp)
│ └── qqqf-mp/ # 亲亲企服小程序(UniApp,理想架构模板)
├── scripts/ # 构建脚本(不参与 lint/format)
├── .husky/ # Git 钩子
├── .vscode/ # VS Code 配置
......@@ -151,6 +154,66 @@ common/vue-kit/src/
---
### 3.3 `@common/sdk` — 统一业务平台 SDK 封装
**存放内容**
- uniplat-sdk 的封装与扩展
- 小程序 HTTP 适配器(uni.request → axios 接口)
- Token 管理、图片处理等通用 SDK 能力
**目录结构**
```
common/sdk/src/
├── index.ts # 统一导出
├── sdk-core.ts # SDK 核心类(SdkCore)
├── sdk-types.ts # SDK 类型定义
├── http/
│ └── adapter.ts # uni.request 适配器(适配 axios 接口)
├── auth/
│ ├── auth-handlers.ts # 认证处理器
│ └── token-manager.ts # Token 管理
└── utils/
└── image-builder.ts # 图片 URL 构建工具
```
**核心导出**
| 导出项 | 说明 |
|--------|------|
| `SdkCore` | SDK 核心类,提供 domainService 请求、Token 解码等 |
| `uniAdapter` | uni.request 适配器,用于小程序环境 |
| `PassportTokenController` | Token 控制器 |
| `decodeToken` | JWT Token 解码工具 |
| `buildImage` / `buildFilePath` | 图片/文件 URL 构建 |
**SDK 调用方式**
```typescript
// 业务 API 文件中直接使用
import { sdk } from "./http"
export async function getAccountInfo() {
return await sdk.core
.domainService("welfare_bean", "reward_account_api", "account_info")
.request("get", {})
.then((r: any) => r as AccountInfo)
.catch((err: any) => {
console.log(`err: ${err}`)
return {} as AccountInfo
})
}
```
**边界条件**
- ✅ 可以放:uniplat-sdk 封装、HTTP 适配、Token 管理
- ❌ 不能放:业务强相关的逻辑(如登录流程、页面跳转)
- ❌ 不能放:Vue 相关代码(应放 `@common/vue-kit`
---
## 四、packages 项目规范
### 4.1 Nuxt 项目目录结构(SSR 项目,如官网)
......@@ -204,7 +267,123 @@ packages/admin-web/
└── tsconfig.json
```
### 4.3 UniApp 小程序项目目录结构(如 partner-mp)
### 4.3 UniApp 小程序项目目录结构(理想架构,如 qqqf-mp)
```
packages/qqqf-mp/
├── src/
│ ├── pages/ # 页面(路由入口)
│ │ └── home/
│ │ └── index.vue # 首页
│ ├── components/ # 组件(公共 UI 组件)
│ │ └── index.ts # 统一导出
│ ├── composables/ # 组合式函数(复用逻辑)
│ │ └── index.ts # 统一导出
│ ├── api/ # API 层(SDK 初始化 + HTTP 调用)
│ │ ├── http.ts # SDK 初始化,导出 sdk 实例
│ │ └── home.ts # 业务接口(使用 sdk.core.domainService().request())
│ ├── services/ # 服务层(业务逻辑编排)
│ │ └── index.ts # 统一导出
│ ├── stores/ # 状态管理(Pinia)
│ ├── utils/ # 工具函数(项目私有)
│ │ └── index.ts # 统一导出
│ ├── config/ # 项目配置(纯配置文件)
│ │ └── index.ts # 环境配置、常量、白名单、CoreEnvir
│ ├── App.vue # 根组件
│ ├── main.ts # 入口文件
│ ├── manifest.json # UniApp 应用配置
│ └── pages.json # 页面路由配置
├── .env.development # 开发环境
├── .env.test # 测试环境
├── .env.staging # 预发环境
├── .env.production # 生产环境
├── vite.config.ts
├── package.json
└── tsconfig.json
```
**关键架构说明**
| 目录 | 职责 | 说明 |
|------|------|------|
| `config/index.ts` | 纯配置文件 | 环境配置、常量、白名单、CoreEnvir 工具类 |
| `api/http.ts` | SDK 初始化 | 继承 SdkCore,传入 config,导出 sdk 实例 |
| `api/xxx.ts` | 业务接口 | 使用 `sdk.core.domainService().request()` 调用 |
| `services/` | 业务逻辑编排 | 组合多个 API,操作 store,处理复杂流程 |
| `composables/` | 组合式函数 | 复用逻辑(如 useAuth、useLoading) |
| `components/` | 公共组件 | 跨页面复用的 UI 组件 |
| `utils/` | 工具函数 | 项目私有工具(格式化、校验等) |
| `stores/` | 状态管理 | Pinia store,按业务模块拆分 |
**SDK 调用标准模式**
```typescript
// api/http.ts - SDK 初始化
import { SdkCore } from "@common/sdk"
import { config } from "@/config"
class Sdk extends SdkCore {
constructor() {
super(config)
}
}
const sdk = new Sdk()
export { sdk }
```
```typescript
// api/home.ts - 业务接口
import { sdk } from "./http"
export async function fetchHomeData() {
return await sdk.core
.domainService("qqqf", "api", "getHomeData")
.request("get", {})
.then((r: any) => r as HomeData)
.catch((err: any) => {
console.log(`err: ${err}`)
return {} as HomeData
})
}
```
**开发脚本**
```bash
# 开发(默认微信小程序)
pnpm dev:project --project=qqqf-mp
# 构建(默认微信小程序)
pnpm build:project --project=qqqf-mp
# 指定环境
pnpm build:project --project=qqqf-mp --env=production
```
**平台支持**
| 脚本 | 说明 |
|------|------|
| `pnpm dev` | 开发微信小程序(默认) |
| `pnpm dev:mp-alipay` | 开发支付宝小程序 |
| `pnpm dev:h5` | 开发 H5 |
| `pnpm build` | 构建微信小程序(默认) |
| `pnpm build:mp-alipay` | 构建支付宝小程序 |
| `pnpm build:h5` | 构建 H5 |
**环境模式**
| 模式 | 对应文件 | 说明 |
|------|---------|------|
| 默认 | `.env.development` | 开发环境 |
| `--mode test` | `.env.test` | 测试环境 |
| `--mode staging` | `.env.staging` | 预发环境 |
| `--mode production` | `.env.production` | 生产环境 |
### 4.4 UniApp 小程序项目目录结构(partner-mp,历史架构)
> ⚠️ partner-mp 为历史架构,新项目建议参照 qqqf-mp 理想架构
```
packages/partner-mp/
......@@ -216,13 +395,9 @@ packages/partner-mp/
│ ├── composables/ # 组合式函数
│ ├── api/ # API 层(HTTP 调用)
│ ├── services/ # 服务层(业务逻辑编排)
│ ├── store/ # 状态管理(Pinia)
│ ├── stores/ # 状态管理(Pinia)
│ ├── utils/ # 工具函数
│ ├── config/ # 项目配置
│ ├── constants/ # 常量定义
│ ├── modules/ # 业务模块
│ ├── controllers/ # 控制器
│ ├── model/ # 数据模型
│ ├── App.vue
│ ├── main.ts
│ ├── manifest.json # UniApp 应用配置
......@@ -267,7 +442,7 @@ pnpm build:project --project=partner-mp
| `--mode staging` | `.env.staging` | 预发环境 |
| `--mode production` | `.env.production` | 生产环境 |
### 4.4 项目内各层职责
### 4.5 项目内各层职责
| 目录 | 职责 | 示例 |
| -------------- | ------------------------ | --------------------------------- |
......@@ -284,18 +459,57 @@ pnpm build:project --project=partner-mp
| `middleware/` | Nuxt 中间件 | 鉴权中间件 |
| `plugins/` | Nuxt 插件 | 全局插件注册 |
### 4.4 `api/` 与 `services/` 职责划分
### 4.6 `api/` 与 `services/` 职责划分
**`api/` — 统一请求方法封装层**
核心职责是**封装统一的 HTTP 请求方法**,按模块导出接口。
**UniApp 小程序项目(SDK 模式)**
- `http.ts`:继承 SdkCore,传入 config,导出 sdk 实例
- `xxx.ts`:只导出业务接口函数,调用 `sdk.core.domainService().request()` 方法
- 不包含业务逻辑,不操作 store,不跳转路由
```typescript
// api/http.ts — SDK 初始化(UniApp 小程序)
import { SdkCore } from "@common/sdk"
import { config } from "@/config"
class Sdk extends SdkCore {
constructor() {
super(config)
}
}
const sdk = new Sdk()
export { sdk }
```
```typescript
// api/user.ts — 业务接口函数(UniApp 小程序)
import { sdk } from "./http"
export function getUserInfo() {
return sdk.core
.domainService("welfare_v2", "smart_app_api", "user_info")
.request("get", {})
.then((r: any) => r as UserInfo)
.catch((err: any) => {
console.log(`err: ${err}`)
return {} as UserInfo
})
}
```
**Web 项目(axios 模式)**
- `request.ts`:创建 axios 实例 + 拦截器 + 导出统一请求方法(get、post、put、delete)
- `xxx.ts`:只导出业务接口函数,调用 `request` 方法
- 不包含业务逻辑,不操作 store,不跳转路由
```typescript
// api/request.ts — 统一请求方法封装
// api/request.ts — 统一请求方法封装(Web 项目)
import axios from 'axios'
const request = axios.create({
......@@ -327,7 +541,7 @@ export { request }
```
```typescript
// api/user.ts — 业务接口函数
// api/user.ts — 业务接口函数(Web 项目)
import { request } from './request'
export function getUserInfo() {
......@@ -359,7 +573,7 @@ export async function handleLoginRedirect() {
}
```
### 4.5 代码放置决策树
### 4.7 代码放置决策树
```
新代码应该放哪里?
......@@ -369,12 +583,17 @@ export async function handleLoginRedirect() {
│ │ ├─ 是 → @common/vue-kit/
│ │ └─ 否 → @common/utils/
│ │
│ ├─ 是 → 是否是 SDK/HTTP 相关?
│ │ └─ 是 → @common/sdk/
│ │
│ └─ 否 → 放在当前项目 packages/xxx/
│ │
│ ├─ 是页面? → pages/
│ ├─ 是 UI 组件? → components/
│ ├─ 是复用逻辑? → composables/
│ ├─ 是 HTTP 调用? → api/
│ │ ├─ UniApp 项目 → http.ts (SDK 初始化) + xxx.ts (业务接口)
│ │ └─ Web 项目 → request.ts (axios 封装) + xxx.ts (业务接口)
│ ├─ 是业务逻辑编排? → services/
│ ├─ 是状态管理? → stores/
│ ├─ 是路由配置? → router/(纯 Vue3 项目)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment