346 lines
15 KiB
Markdown
346 lines
15 KiB
Markdown
# 开发准则与规范 (DesignerCEP / Photoshop Plugin)
|
||
|
||
## 1. 项目概述
|
||
|
||
本项目是一个基于 **Vue 3 + Vite + TypeScript** 的 Adobe Photoshop 扩展插件 (CEP) 项目。
|
||
|
||
## 2. 技术栈
|
||
|
||
- **核心框架**: Vue 3 (Composition API + `<script setup>`)
|
||
- **构建工具**: Vite
|
||
- **语言**: TypeScript
|
||
- **UI 组件库**: Arco Design Vue (`@arco-design/web-vue`)
|
||
- **路由**: Vue Router 4
|
||
- **CEP 环境**: Adobe CEP (宿主环境: **Adobe Photoshop**)
|
||
- **HTTP**: Axios / Umi-request
|
||
|
||
---
|
||
|
||
## 3. 开发规范
|
||
|
||
### 3.1 Vue 3 & 代码风格
|
||
|
||
1. **Composition API**:
|
||
|
||
- 必须使用 `<script setup lang="ts">` 语法糖。
|
||
- 优先使用 `ref` 定义基本类型,`reactive` 定义对象类型。
|
||
- 逻辑复用应提取为 **Composables (Hooks)** (`useXxx`),存放于 `src/hooks` 或 `src/composables`。
|
||
|
||
2. **组件 (Components)**:
|
||
|
||
- **单一职责**: 每个组件应只负责一个功能模块。
|
||
- **命名**: 文件名使用 **PascalCase** (如 `userProfile.vue` -> `UserProfile.vue`)。
|
||
- **Props 定义**: 使用 `defineProps<{ ... }>()` 进行类型安全的 Props 定义。
|
||
|
||
3. **TypeScript 类型安全**:
|
||
|
||
- ❌ **严禁使用 `any`**:除非是在不得不对接极度混乱的 legacy 代码时(需加注释说明)。
|
||
- **接口定义**: 数据模型应定义 interface,存放于 `src/types` 或组件同级目录。
|
||
- **CEP 交互**: 与 Photoshop 宿主环境交互时 (CSInterface, JSX 脚本),应注意类型转换和错误处理。
|
||
|
||
4. **样式 (CSS/Less/Sass)**:
|
||
- 使用 **Scoped CSS** (`<style scoped>`) 避免全局因污染。
|
||
- 利用 Arco Design 的 Token 进行样式定制,保持 UI 风格统一。
|
||
|
||
### 3.2 日志管理规范
|
||
|
||
本项目使用统一的全局日志管理工具 (`logger`),禁止直接使用 `console.*` 方法。
|
||
|
||
1. **核心原则**:
|
||
|
||
- ❌ **严禁直接使用 `console.log/warn/error/info/debug`**。
|
||
- ✅ **必须统一使用 `logger` 工具类**,位于 `src/utils/logger.ts`。
|
||
- ✅ **一键控制**:所有日志可通过全局开关统一开启/关闭,便于生产环境清理日志。
|
||
|
||
2. **使用方法**:
|
||
|
||
```typescript
|
||
import { logger } from '@/utils/logger';
|
||
|
||
// 普通日志
|
||
logger.log('用户登录成功');
|
||
|
||
// 信息日志
|
||
logger.info('正在加载数据...');
|
||
|
||
// 警告日志
|
||
logger.warn('Token 即将过期');
|
||
|
||
// 错误日志(始终显示,不受开关控制)
|
||
logger.error('API 请求失败:', error);
|
||
|
||
// 可控制的错误日志
|
||
logger.errorSilent('这个错误只在开启日志时显示');
|
||
|
||
// 调试日志
|
||
logger.debug('调试信息:', data);
|
||
|
||
// 分隔线
|
||
logger.separator(); // 输出 60 个 '='
|
||
logger.separator('-', 40); // 输出 40 个 '-'
|
||
```
|
||
|
||
3. **日志开关控制**:
|
||
|
||
```typescript
|
||
// 开启日志(开发环境)
|
||
logger.enable();
|
||
|
||
// 关闭日志(生产环境)
|
||
logger.disable();
|
||
|
||
// 切换日志状态
|
||
logger.toggle();
|
||
|
||
// 查询当前状态
|
||
console.log(logger.enabled); // true/false
|
||
```
|
||
|
||
4. **浏览器控制台访问**:
|
||
|
||
- 日志工具自动挂载到 `window.logger`,可在浏览器控制台直接操作:
|
||
|
||
```javascript
|
||
// 在 Chrome DevTools 控制台中
|
||
window.logger.enable(); // 开启日志
|
||
window.logger.disable(); // 关闭日志
|
||
window.logger.toggle(); // 切换状态
|
||
```
|
||
|
||
5. **特殊说明**:
|
||
|
||
- **错误日志策略**:
|
||
- `logger.error()` 始终输出,即使日志开关关闭(用于捕获关键错误)。
|
||
- 如需可控的错误日志,使用 `logger.errorSilent()`。
|
||
- **默认状态**: 日志默认为**关闭**状态,需要手动开启。
|
||
- **性能考虑**: 关闭日志后,所有日志调用不会产生任何输出,不影响性能。
|
||
|
||
6. **禁止事项**:
|
||
|
||
- ❌ 禁止在代码中直接使用 `console.log()` 等原生方法。
|
||
- ❌ 禁止删除日志代码(保留代码,通过开关控制)。
|
||
- ❌ 禁止在生产环境中开启日志(避免信息泄露)。
|
||
|
||
### 3.3 Adobe CEP & Photoshop 特有规范
|
||
|
||
1. **CSInterface**: 所有与 Photoshop 的交互必须通过 `CSInterface` 进行。
|
||
2. **Photoshop 脚本 (JSX)**:
|
||
- 宿主脚本(ExtendScript)位于 `/jsx` 目录。
|
||
- 优先使用 **ActionManager (ActionDescriptor/Reference)** 代码(通常更高效),但也支持 DOM 操作 (`app.activeDocument` 等)。
|
||
- **调试**: 使用 **ExtendScript Toolkit** 或 **VSCode ExtendScript Debugger** 调试 `.jsx` 文件。
|
||
3. **事件监听**: 使用 `CSInterface` 监听 Photoshop 事件(如文档切换、选区改变 `com.adobe.PhotoshopJSONCallback`)时,需注意性能开销。
|
||
4. **文件系统**: 利用 Node.js 上下文 (`fs`, `path`) 处理本地文件操作,比 JSX 传参更灵活。
|
||
|
||
### 3.4 目录结构建议 (参考)
|
||
|
||
```
|
||
src/
|
||
├── assets/ # 静态资源
|
||
├── components/ # 通用组件
|
||
├── view/ # 页面视图 (Pages)
|
||
├── router/ # 路由配置
|
||
├── hooks/ # 组合式函数 (Composables)
|
||
├── types/ # TypeScript 类型定义
|
||
├── utils/ # 工具函数 (含 CSInterface 封装)
|
||
├── App.vue
|
||
└── main.ts
|
||
```
|
||
|
||
### 3.5 UI/UX 设计规范 (Photoshop Theme)
|
||
|
||
1. **PS 主题适配 (Native Look)**:
|
||
|
||
- ✅ **必须适配 Photoshop 的 4 种颜色主题**(深黑、深灰、浅灰、白)。
|
||
- ✅ **核心机制**:
|
||
- **获取颜色**: 通过 `new CSInterface().getHostEnvironment().appSkinInfo` 获取宿主环境颜色 (`panelBackgroundColor`)。
|
||
- **监听切换**: 必须监听 `com.adobe.csxs.events.ThemeColorChanged` 事件,实现实时自动切换。
|
||
- **实现参考代码**:
|
||
|
||
```typescript
|
||
const updateTheme = () => {
|
||
const csInterface = new CSInterface();
|
||
const skinInfo = csInterface.getHostEnvironment().appSkinInfo;
|
||
const color = skinInfo.panelBackgroundColor.color;
|
||
// 将 RGB 转换为 CSS 变量或应用到 body
|
||
const bgColor = `rgb(${Math.round(color.red)}, ${Math.round(
|
||
color.green
|
||
)}, ${Math.round(color.blue)})`;
|
||
document.body.style.backgroundColor = bgColor;
|
||
// TODO: 更新 Arco Design 的 Token (如 --color-bg-1)
|
||
};
|
||
|
||
// 初始化运行 + 监听事件
|
||
updateTheme();
|
||
new CSInterface().addEventListener(
|
||
"com.adobe.csxs.events.ThemeColorChanged",
|
||
updateTheme
|
||
);
|
||
```
|
||
|
||
- ❌ 禁止使用固定死颜色,导致在不同主题下看不清文字。
|
||
|
||
2. **样式库选择**:
|
||
|
||
- 虽然 Adobe 官方推荐 **Spectrum** (React),但在 Vue 项目中,建议使用 **Arco Design** 并自定义通过 CSS 变量映射 PS 主题色。
|
||
- **Mac 兼容性**: 如果遇到点击事件无效,尝试 hack: `delete window.PointerEvent` (常见于 CEF 环境兼容问题)。
|
||
|
||
3. **视觉美感 (Aesthetics)**:
|
||
- ✅ **高级感**: 界面设计要精致,拒绝简陋的“工程师审美”。
|
||
- ✅ **微交互**: 按钮、列表项必须有 Hover/Active 状态和过渡动画 (`transition: all 0.2s`)。
|
||
- ✅ **排版**: 使用系统字体或 Inter,保持良好的留白 (Spacing) 和层级感。
|
||
|
||
---
|
||
|
||
## 4. 后端开发规范 (Python / FastAPI)
|
||
|
||
本项目后端采用 **FastAPI** 框架,必须遵循**模块化、组件化**的开发原则。
|
||
|
||
### 4.1 核心原则
|
||
|
||
1. **分层架构**: 严格分离 控制层(API)、业务层(Service) 和 数据模型(Schema/Model)。
|
||
- ❌ **禁止**在 API 路由函数中编写通过复杂的业务逻辑。
|
||
- ✅ 业务逻辑应封装在 `services/` 目录下的服务类中。
|
||
2. **类型安全**: 全面使用 **Pydantic** (`schemas/`) 定义请求和响应模型,利用 Python Type Hints。
|
||
3. **依赖注入**: 使用 FastAPI 的 `Depends` 进行服务注入和权限验证。
|
||
|
||
### 4.2 目录结构规范
|
||
|
||
后端代码位于 `Server/` 目录,内部结构如下:
|
||
|
||
```
|
||
Server/
|
||
├── app/
|
||
│ ├── api/ # 路由层 (Endpoints)
|
||
│ │ └── v1/ # 版本控制
|
||
│ │ ├── auth.py # 认证相关接口
|
||
│ │ └── user.py # 用户相关接口
|
||
│ ├── core/ # 核心配置 (Config, Security, Exceptions)
|
||
│ ├── schemas/ # 数据模型 (Pydantic Models) - 用于请求/响应
|
||
│ ├── services/ # 业务逻辑服务层
|
||
│ ├── models/ # 数据库模型 (SQLAlchemy/Tortoise) - 如需数据库
|
||
│ └── main.py # 程序入口
|
||
├── requirements.txt # 依赖列表
|
||
└── .env # 环境变量
|
||
```
|
||
|
||
### 4.3 编码规范
|
||
|
||
- **路由定义**: 使用 `APIRouter` 分散管理路由,不要全部写在 `main.py`。
|
||
- **错误处理**: 使用 `HTTPException` 抛出标准 HTTP 错误。
|
||
- **配置管理**: 所有配置项(数据库 URL、密钥等)必须从环境变量或 `core/config.py` 读取。
|
||
|
||
### 4.4 错误信息与本地化
|
||
|
||
- **后端接口返回的错误信息必须为中文**,统一由后端产生,不由前端拼接或翻译。
|
||
- 错误示例(`HTTPException.detail` 字段):
|
||
- 登录失败:`用户名或密码错误`(401)
|
||
- 注册失败(密码不一致):`两次输入的密码不一致`(400)
|
||
- 注册失败(用户名占用):`用户名已被注册`(400)
|
||
- 单设备限制:`该账号已在其他设备在线`(403)
|
||
- 用户不存在:`用户不存在`(404)
|
||
- 前端显示层可以自行决定文案风格,但不得修改后端错误语义;建议原样展示或在 UI 上补充说明。
|
||
|
||
### 4.5 登录并发与在线时长
|
||
|
||
- **单设备同时在线限制**:后端基于 `device_id` 限制同账号仅允许一个设备在线;若另一设备尝试登录,返回 403 `该账号已在其他设备在线`。
|
||
- **会话记录**:后端在登录时记录 `login_at`,在登出时记录 `logout_at` 并计算在线时长 `duration_seconds`(秒)。
|
||
- **时长统计接口**:`GET /api/v1/auth/online-time/{username}` 返回该用户历史累计在线时长(秒)与当前活跃会话的实时在线时长(秒)。
|
||
- **前端约定**:登录时必须传入稳定的 `device_id`;登出时调用 `POST /api/v1/auth/logout` 释放会话,保证统计准确。
|
||
|
||
### 4.6 HTTP 接口交互与错误码规范
|
||
|
||
#### 1. 请求方法 (HTTP Methods)
|
||
|
||
- **GET (Get Request)**
|
||
|
||
- **用途**: 仅用于**获取/查询数据**。
|
||
- **特点**: 安全且幂等(多次请求结果一致),参数通常拼接在 URL Query 中。
|
||
- **场景**: 获取用户列表、查询订单详情。
|
||
|
||
- **POST (Post Request)**
|
||
|
||
- **用途**: 用于**创建新资源**、**提交表单**或**执行非幂等操作**。
|
||
- **特点**: 数据放在 Body 中,支持大数据量,安全性高于 GET。
|
||
- **场景**: 用户注册、登录、上传文件、合并图层。
|
||
|
||
- **PUT (Put Request)**
|
||
|
||
- **用途**: 用于**全量更新**资源。
|
||
- **特点**: 幂等操作。通常需要提供被更新资源的全部字段,未提供的字段可能被置空。
|
||
- **场景**: 覆盖保存用户个人信息(包含所有字段)。
|
||
|
||
- **PATCH (Patch Request)**
|
||
|
||
- **用途**: 用于**局部更新**资源。
|
||
- **特点**: 仅发送需要修改的字段,未发送的字段保持原样。
|
||
- **场景**: 仅修改用户的“昵称”或“头像”,而不影响其他信息。
|
||
|
||
- **DELETE (Delete Request)**
|
||
|
||
- **用途**: 用于**删除资源**。
|
||
- **特点**: 幂等操作。
|
||
- **场景**: 删除订单、注销账号。
|
||
|
||
- **OPTIONS (Options Request)**
|
||
|
||
- **用途**: **预检请求 (Pre-flight)**。
|
||
- **特点**: 浏览器在跨域请求 (CORS) 前自动发起,用于询问服务器支持哪些方法和 Header。
|
||
- **场景**: 本地开发环境调用远程 API 时的跨域检查。
|
||
|
||
- **HEAD (Head Request)**
|
||
- **用途**: 获取资源的元信息(Headers),但不返回 Body。
|
||
- **特点**: 速度快,用于检查资源是否存在或是否有更新。
|
||
- **场景**: 检查大文件下载链接是否有效、检查文件最后修改时间。
|
||
|
||
#### 2. 状态码规范 (Status Codes)
|
||
|
||
所有接口应遵循标准 HTTP 状态码,结合业务错误码 (`code`) 使用。
|
||
|
||
| 状态码 | 含义 | 常见场景 |
|
||
| :------ | :-------------------- | :----------------------------------------------------------------------------- |
|
||
| **200** | OK | 请求成功,业务逻辑执行完成。 |
|
||
| **400** | Bad Request | **客户端错误**。通常是参数缺失、格式错误或业务逻辑校验失败(如“密码不一致”)。 |
|
||
| **401** | Unauthorized | **未授权**。Token 无效、过期或未登录。前端应跳转至登录页。 |
|
||
| **403** | Forbidden | **禁止访问**。已登录但权限不足,或账号被在其他设备挤下线。 |
|
||
| **404** | Not Found | 请求的资源(用户、订单等)不存在。 |
|
||
| **500** | Internal Server Error | **服务器内部错误**。代码崩溃或数据库连接失败,需联系后端排查。 |
|
||
|
||
### 4.7 配置管理与代码规模限制
|
||
|
||
1. **统一配置管理**:
|
||
- ❌ **严禁硬编码**:所有路径地址、数据库连接字符串、API 请求地址、密钥等敏感或可变信息,禁止直接写在代码中。
|
||
- ✅ **集中管理**:
|
||
- 后端:必须使用环境变量 (`.env`) 或 `app/core/config.py` 进行管理。
|
||
- 前端/客户端:必须使用 `.env` 文件或专门的 `config.ts` 模块。
|
||
- 工具脚本:必须在脚本头部定义常量或读取外部配置文件。
|
||
|
||
2. **代码规模限制**:
|
||
- ❌ **严禁“巨型文件”**:单个代码文件(`.py`, `.ts`, `.vue` 等)的行数 **不得超过 500 行**。
|
||
- ✅ **拆分重构**:
|
||
- 一旦文件接近 500 行,必须立即进行拆分。
|
||
- 将逻辑提取为独立的 Service、Utility 函数、Composable Hook 或子组件。
|
||
- 保持代码的“高内聚、低耦合”。
|
||
|
||
---
|
||
|
||
## 5. Git 提交规范
|
||
|
||
请遵循 **Conventional Commits** 规范:
|
||
|
||
- `feat`: 新增功能
|
||
- `fix`: 修复 Bug
|
||
- `docs`: 文档变更
|
||
- `style`: 代码格式调整(不影响逻辑)
|
||
- `refactor`: 代码重构
|
||
- `chore`: 构建工具或依赖变更
|
||
|
||
**示例**: `feat: 增加PS图层自动重命名功能`
|
||
|
||
---
|
||
|
||
## 5. 调试与构建
|
||
|
||
- **开发模式**: `npm run dev` (在浏览器预览 UI)
|
||
- **构建**: `npm run build`
|
||
- **CEP 调试**: 在 Photoshop 中加载扩展,访问 `http://localhost:XXXX` 进行 Chrome DevTools 调试 UI。
|