# chanjs/common/index.js 模块文档
## 概述
`chanjs/common/index.js` 是 `chanjs` 框架的通用工具模块出口文件，聚合了 API 响应处理、分类操作、状态码、邮件、页面处理、短信、通用工具等多个子模块的核心方法/常量，提供统一的导出入口，简化模块引用流程。

## 导出内容总览
该文件通过 ES6 导出语法，批量导出以下子模块的核心成员：

| 导出来源文件 | 导出成员 | 功能分类 |
|--------------|----------|----------|
| `./api.js` | `success`, `fail`, `error` | API 响应格式化 |
| `./category.js` | `getChildrenId` | 分类数据处理 |
| `./code.js` | `CODE` | 业务状态码常量 |
| `./email.js` | `sendMail`, `genRegEmailHtml`, `genResetPasswordEmail` | 邮件发送与模板生成 |
| `./pages.js` | `pages`, `getHtmlFilesSync` | 页面/HTML 文件处理 |
| `./sms.js` | `createSmsClient` | 短信客户端创建 |
| `./utils.js` | `filterBody`, `pc`, `filterImgFromStr` | 通用工具函数 |

## 详细导出成员说明
### 1. 来自 `./api.js`：API 响应格式化
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `success` | 函数 | 生成「成功」类型的 API 响应数据（如包含 `code: 200`、`data`、`msg` 等字段） |
| `fail` | 函数 | 生成「业务失败」类型的 API 响应数据（如包含 `code: 非200`、`msg` 等字段，适用于参数错误、业务逻辑失败等场景） |
| `error` | 函数 | 生成「系统错误」类型的 API 响应数据（如包含 `code: 500`、`msg` 等字段，适用于服务器内部异常场景） |

**使用示例**：
```javascript
import { success, fail } from 'chanjs/common';

// 接口返回成功响应
export const getUser = (req, res) => {
  res.json(success({ name: '张三' }, '获取用户信息成功'));
};

// 接口返回业务失败响应
export const login = (req, res) => {
  res.json(fail('用户名或密码错误', 401));
};
```

### 2. 来自 `./category.js`：分类数据处理
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `getChildrenId` | 函数 | 根据分类 ID，递归获取该分类下所有子分类的 ID 集合（适用于树形结构分类场景，如商品分类、栏目分类） |

**使用示例**：
```javascript
import { getChildrenId } from 'chanjs/common';

// 假设分类数据为树形结构
const categoryList = [
  { id: 1, name: '数码', children: [{ id: 11, name: '手机' }, { id: 12, name: '电脑' }] },
  { id: 2, name: '服饰' }
];
// 获取分类1下所有子分类ID
const childrenIds = getChildrenId(categoryList, 1);
console.log(childrenIds); // [11, 12]
```

### 3. 来自 `./code.js`：业务状态码常量
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `CODE` | 对象 | 聚合了项目中所有业务状态码的常量对象（如 `CODE.SUCCESS = 200`、`CODE.PARAM_ERROR = 400`、`CODE.LOGIN_EXPIRE = 401` 等），统一管理状态码，避免硬编码 |

**使用示例**：
```javascript
import { CODE, fail } from 'chanjs/common';

export const submitForm = (req, res) => {
  if (!req.body.name) {
    // 使用统一状态码返回失败响应
    return res.json(fail('姓名不能为空', CODE.PARAM_ERROR));
  }
  // 业务逻辑处理...
};
```

### 4. 来自 `./email.js`：邮件发送与模板生成
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `sendMail` | 函数 | 封装邮件发送逻辑，接收收件人、邮件标题、邮件内容等参数，调用底层邮件服务发送邮件 |
| `genRegEmailHtml` | 函数 | 生成「用户注册验证」的邮件 HTML 模板（包含验证链接/验证码等动态内容） |
| `genResetPasswordEmail` | 函数 | 生成「密码重置」的邮件 HTML 模板（包含重置链接/验证码等动态内容） |

**使用示例**：
```javascript
import { sendMail, genRegEmailHtml } from 'chanjs/common';

// 发送注册验证邮件
const sendRegEmail = async (toEmail, verifyCode) => {
  const html = genRegEmailHtml(verifyCode);
  await sendMail({
    to: toEmail,
    subject: '【XX平台】注册验证',
    html
  });
};
```

### 5. 来自 `./pages.js`：页面/HTML 文件处理
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `pages` | 对象/函数 | 页面相关配置/工具（如页面路由映射、页面模板配置等，具体需结合子模块实现） |
| `getHtmlFilesSync` | 函数 | 同步读取指定目录下所有 HTML 文件的路径/内容，返回文件列表（适用于静态页面生成、模板扫描等场景） |

**使用示例**：
```javascript
import { getHtmlFilesSync } from 'chanjs/common';

// 获取指定目录下所有HTML文件
const htmlFiles = getHtmlFilesSync('./src/pages');
console.log(htmlFiles); // ['./src/pages/index.html', './src/pages/about.html']
```

### 6. 来自 `./sms.js`：短信客户端创建
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `createSmsClient` | 函数 | 创建并返回短信服务客户端实例（封装了短信服务商 SDK，如阿里云短信、腾讯云短信等），支持配置密钥、签名等参数 |

**使用示例**：
```javascript
import { createSmsClient } from 'chanjs/common';

// 创建短信客户端
const smsClient = createSmsClient({
  accessKeyId: 'your-access-key',
  accessKeySecret: 'your-access-secret',
  signName: 'XX平台'
});

// 发送短信验证码
smsClient.sendSms({
  phoneNumbers: '13800138000',
  templateCode: 'SMS_123456789',
  templateParam: { code: '668899' }
});
```

### 7. 来自 `./utils.js`：通用工具函数
| 成员名 | 类型 | 说明 |
|--------|------|------|
| `filterBody` | 函数 | 过滤请求体（req.body）中的敏感字段/空值字段，返回清洗后的对象（适用于接口入参校验，避免无效/敏感数据传入业务层） |
| `pc` | 函数/对象 | 设备判断工具，通常用于检测请求是否来自 PC 端（如返回 `true/false`，或包含 `isPc`、`isMobile` 等方法） |
| `filterImgFromStr` | 函数 | 从字符串（如 HTML 文本、富文本内容）中提取所有图片 URL，返回图片链接数组 |

**使用示例**：
```javascript
import { filterBody, pc, filterImgFromStr } from 'chanjs/common';

// 过滤请求体空值
const cleanBody = filterBody(req.body, ['name', 'age']); // 仅保留name、age字段，且过滤空值

// 判断是否为PC端请求
if (pc(req.headers['user-agent'])) {
  console.log('PC端访问');
}

// 提取富文本中的图片
const content = '<p>测试<img src="https://example.com/1.jpg">内容<img src="https://example.com/2.jpg"></p>';
const imgUrls = filterImgFromStr(content);
console.log(imgUrls); // ['https://example.com/1.jpg', 'https://example.com/2.jpg']
```

## 引用方式
### 方式1：按需导入（推荐）
```javascript
import { success, CODE, filterBody } from 'chanjs/common';
```

### 方式2：批量导入
```javascript
import * as common from 'chanjs/common';

// 使用时通过 common.xxx 访问
common.success(data, '操作成功');
common.filterBody(req.body);
```

## 注意事项
1. 该文件仅为「导出入口」，无实际业务逻辑，所有功能的具体实现均在对应的子模块（`api.js`/`category.js` 等）中；
2. 若需修改/扩展功能，需修改对应的子模块文件，而非直接修改 `index.js`；
3. 导入时确保子模块文件路径正确，避免因路径变更导致导入失败。