Files
2026-04-21 14:58:48 +08:00

360 lines
10 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Agent 行为准则 & JKCQProjectV2 iOS 开发规范
---
## 一、Agent 行为准则
### 0. 语言强制
- 强制使用简体中文进行所有交互(代码除外)。
### 1. 抽象设计确认
- 涉及抽象设计、架构调整或新功能模块时,必须先用文字或 Mermaid 图对齐设计思路。
- 必须等待用户确认方案后,才能开始编写代码。
### 2. 任务清单确认
- 执行任何实质性任务前,必须先列出详细的任务清单。
- 必须等待用户明确回复(如"好的"、"开始")后,才能进入执行阶段。
### 3. 分步执行与确认
- 代码量较大或逻辑复杂的任务,禁止一次性完成。
- 拆分为多个步骤,每步完成后汇报进度并询问"是否可以进行下一步?"。
### 4. 所有修改必须确认
- 对代码库的任何修改(新建文件、修改文件、删除文件、执行 pod install 等)前,必须先描述变更内容。
- 必须等待用户明确回复"确认"或"同意"后,才能执行。
### 5. 代码注释语言规范
- 所有注释使用简体中文。
- 标识符(变量名、函数名、类名)仍使用英文。
---
## 二、项目技术规范
### 技术栈
- **主语言**: Swift(混编 Objective-CSwift 为主)
- **UI 框架**: UIKit
- **架构模式**: MVC + BasicModule 基础设施层
- **包管理**: CocoaPods,使用 `.xcworkspace` 打开项目
- **最低系统版本**: iOS 13.0
- **布局**: SnapKit(主要)+ frame
- **网络**: Moya + Alamofire
- **图片加载**: Kingfisher
- **主题**: SwiftTheme
---
## 三、项目目录结构
```
JKCQProjectV2/
├── BasicModule/ # 基础设施层(非业务)
│ ├── Base/ # 基类(MktViewController、MktNavigatonController
│ ├── Network/ # 网络层(RequestManager、RequestTarget、NetworkParser
│ ├── Extension/ # Swift 扩展
│ ├── Util/ # 工具类(ThemeManager、Foundation.swift
│ ├── Helper/ # POP 动画 & 自定义辅助类
│ ├── CacheKit/ # 缓存工具
│ └── Configuration/ # APIKey 等配置(敏感,勿外传)
├── Class/ # 业务模块
│ ├── Home/ # 首页(应用)
│ ├── Dangan/ # 档案(健康记录)
│ ├── AI/ # AI 助手
│ ├── Knowledge/ # 知识库
│ ├── Mine/ # 我的(用户中心)
│ ├── Market/ # 市场/产品(未在主 TabBar)
│ ├── Message/ # 消息(TUI IM 集成)
│ └── Login/ # 登录模块
├── Resources/
│ └── Themes/ # 主题配置(blue/red/green/purple.plist
└── JKCQProjectV2-Bridging-Header.h
```
新增业务模块按以下结构组织:
```
Class/ModuleName/
├── ViewController/ # 视图控制器
├── View/ # 自定义视图
└── Model/ # 数据模型(Codable struct
```
---
## 四、命名规范
**类名(PascalCase):**
- 基类及核心组件使用 `Mkt` 前缀,如 `MktViewController``MktNavigatonController`
- 业务类按模块语义命名,如 `HomeViewController``DanganHomeViewController`
- 数据模型用 `Model` 后缀,如 `BannerModel``MarketProductModel`
**文件组织:**
- 扩展文件:`Extension+Feature.swift`,如 `Extension+UIView.swift`
- 模型文件:放在对应模块的 `Model/` 子目录
**方法名(camelCase):**
```swift
func setupUI()
func updateThemeUI()
func loadData(page: Int)
```
**常量:**
```swift
// Swift 常量用 camelCase
let defaultPageSize = 20
// OC 宏用大写
JPScaleValue(16)
```
---
## 五、代码组织
```swift
// MARK: - Life Cycle
// MARK: - Setup
// MARK: - Network
// MARK: - Actions
// MARK: - ThemeProtocol / Theme
// MARK: - UITableViewDataSource
// MARK: - UITableViewDelegate
```
---
## 六、网络层规范
### 发起请求
项目网络层统一使用 `RequestTarget` + `RequestManager`,通过 Moya 封装:
```swift
// GET 请求(带分页参数)
RequestTarget.get("/api/v1/list", query: ["page": 1, "size": 20])
.sendParsed(showHUD: true, type: [ItemModel].self) { success, data, msg in
guard success, let items = data else { return }
self.items = items
self.tableView.reloadData()
}
// POST 请求
RequestTarget.post("/api/v1/submit", body: ["key": "value"])
.sendParsed(showHUD: true, type: ResultModel.self) { success, data, msg in
if success {
Mkt.makeToast("提交成功")
}
}
// 文件上传
RequestTarget.upload("/api/v1/upload", files: [fileData], names: ["file"])
.sendParsed(showHUD: true, type: UploadResult.self) { success, data, msg in
// ...
}
```
### 响应码说明
| 响应码 | 含义 |
|--------|------|
| `0000` / `200` | 请求成功 |
| `4001` | Token 过期,自动跳转登录 |
| `-888` | 网络不可用 |
| `-999` | 请求超时 |
| `-666` | 服务器异常 |
### 数据模型结构
```swift
// 服务端统一响应结构
struct Response<T: Codable> {
var retCode: String // 响应码
var retMsg: String // 响应信息
var retData: T? // 业务数据
}
// 数据模型使用 Codable struct
struct ItemModel: Codable {
var id: String
var name: String
var createdAt: String?
}
```
### 注意事项
- API 地址统一定义在 `BasicModule/Configuration/APIKey.swift`,禁止在业务代码中硬编码 URL
- SDK Key / Secret 统一放 `APIKey.swift`,禁止散落在业务文件
- 网络回调默认在主线程,可直接操作 UI
---
## 七、主题系统
项目支持 4 套主题(blue / red / green / purple),配置文件在 `Resources/Themes/*.plist`
### 初始化(AppDelegate
```swift
AppThemeManager.shared.setup()
```
### 切换主题
```swift
AppThemeManager.shared.switchTheme(to: .blue)
```
### 在视图中应用主题
```swift
override func viewDidLoad() {
super.viewDidLoad()
setupTheme()
}
private func setupTheme() {
updateThemeUI()
observeThemeChanges { [weak self] in
self?.updateThemeUI()
}
}
private func updateThemeUI() {
// 使用 ThemeKey 绑定(推荐,自动响应主题切换)
view.theme_backgroundColor = ThemeKey.backgroundColor
titleLabel.theme_textColor = ThemeKey.textColor
navBar.theme_backgroundColor = ThemeKey.navBarColor
}
```
### 常用 ThemeKey
```swift
ThemeKey.primaryColor // 主色调
ThemeKey.backgroundColor // 页面背景色
ThemeKey.textColor // 正文文字色
ThemeKey.navBarColor // 导航栏背景色
ThemeKey.navBarTextColor // 导航栏文字色
ThemeKey.buttonBgColor // 按钮背景色
ThemeKey.tabBarSelectedColor // TabBar 选中色
```
---
## 八、常用工具速查
### Mkt 全局结构体(`BasicModule/Util/Foundation.swift`
```swift
Mkt.appName // App 名称
Mkt.isDebug // 是否 Debug 模式
Mkt.isDevice // 真机 vs 模拟器
Mkt.screenWidth // 屏幕宽度
Mkt.screenHeight // 屏幕高度
Mkt.safe_top // 安全区上边距
Mkt.safe_bottom // 安全区下边距
Mkt.topBarHeight // 导航栏 + 安全区高度
Mkt.keyWindow // 当前活跃 UIWindow
Mkt.makeToast("提示") // Toast 提示
Mkt.jsonToModel() // JSON ↔ Codable 模型转换
```
### 日志(DEBUG 模式有效)
```swift
dlog("请求参数: \(params)") // 带文件名/函数名/行号自动输出
```
### JPConstant.h 宏(OC 层,通过 Bridging Header 可用)
```objc
JPScaleValue(16) // 按屏幕宽度等比缩放数值(基准 375pt)
JPScaleFont(14) // 等比缩放字体
JPRGBColor(r, g, b) // RGB 0-255 创建颜色
JPStringEqual(a, b) // 安全字符串比较
```
### 用户管理
```swift
UserManager.shared.isLoggedIn // 是否已登录
UserManager.shared.currentUser // 当前用户信息(UserInfo?
UserManager.shared.token // 当前 Token
```
---
## 九、UI 布局规范
**优先使用 SnapKit**
```swift
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.left.right.equalToSuperview().inset(20)
make.height.equalTo(JPScaleValue(44))
}
```
**屏幕适配统一用 `JPScaleValue()`**
```swift
// 设计稿 375pt 基准,所有固定尺寸都过 JPScaleValue
let itemHeight = JPScaleValue(80)
let fontSize = JPScaleFont(14)
```
**UIView 扩展(`Extension+UIView.swift`)常用方法:**
```swift
view.setCornerRadius(8) // 圆角
view.setShadow(color: .black, opacity: 0.1) // 阴影
view.addGradient(colors: [.blue, .cyan]) // 渐变
```
---
## 十、内存管理
Block / 闭包内防循环引用,统一使用 `[weak self]`
```swift
RequestTarget.get("/api/list")
.sendParsed(type: [Item].self) { [weak self] success, data, msg in
guard let self = self else { return }
self.items = data ?? []
self.tableView.reloadData()
}
```
---
## 十一、各模块职责
| 模块 | 路径 | 职责 |
|------|------|------|
| **Home** | `Class/Home/` | 首页 Dashboard、Banner、应用入口 |
| **Dangan** | `Class/Dangan/` | 健康档案、体检记录 |
| **AI** | `Class/AI/` | AI 健康助手对话 |
| **Knowledge** | `Class/Knowledge/` | 健康知识库、文章 |
| **Mine** | `Class/Mine/` | 用户中心、设置、个人信息 |
| **Market** | `Class/Market/` | 产品/服务目录(不在主 TabBar) |
| **Message** | `Class/Message/` | IM 消息列表(TUIKit 集成) |
| **Login** | `Class/Login/` | 登录、注册、忘记密码 |
| **BasicModule/Network** | — | 全局网络请求封装,禁止绕过 |
| **BasicModule/Base** | — | 所有 VC 的基类,提供主题/导航能力 |
---
## 十二、禁止事项
- 禁止将 API Key、SDK AppID 等敏感信息硬编码在业务文件中(统一放 `APIKey.swift`
- 禁止在主线程执行网络请求、数据库读写、文件 IO 等耗时操作
- 禁止绕过 `RequestTarget` / `RequestManager` 直接使用 Alamofire 发起请求
- 禁止在未通知用户的情况下引入新的 Pod 依赖
- 禁止修改 `BasicModule/Base/` 中的基类,除非经用户明确确认
- 禁止在 Swift Extension 中添加存储属性(使用 AssociatedObject 或重构为子类)
- 禁止未经确认自行切换主题或修改 `Resources/Themes/*.plist`