Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
穆春红
/
frontend-hub
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
4612dd33
authored
Jun 23, 2026
by
chunhong.mu
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
docs(root): 更新架构文档,新增 qqqf-mp 理想架构和 @common/sdk 说明
parent
3e37df57
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
232 additions
and
13 deletions
ARCHITECTURE.md
ARCHITECTURE.md
View file @
4612dd33
...
...
@@ -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)
│ ├── store
s/
# 状态管理(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 项目)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment