# 存储管理 API
**本文引用的文件**
- [TsStorage.js](file://src/utils/TsStorage.js)
- [TsCommon.js](file://src/utils/TsCommon.js)
- [TsCrypto.js](file://src/utils/TsCrypto.js)
- [TsSM4.js](file://src/utils/TsSM4.js)
- [TsGlobalConfig.js](file://src/utils/TsGlobalConfig.js)
- [index.js](file://index.js)
- [README.md](file://README.md)
- [package.json](file://package.json)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖关系分析](#依赖关系分析)
7. [性能与可靠性](#性能与可靠性)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)
## 简介
本文件为“存储管理”模块的完整 API 参考文档,聚焦于基于 localStorage 的数据持久化能力,并结合加密工具链实现敏感数据的安全存储。内容涵盖:
- 接口规范:方法签名、参数类型、返回值结构与典型用法
- 数据持久化机制:localStorage 的键值存取、默认值回退策略
- 用户 token 管理:专用的 token 保存与读取
- 加密开关控制:通过全局配置与布尔开关控制是否对请求体进行加密
- 序列化与反序列化:统一采用 JSON 序列化/反序列化,支持复杂对象
- 错误处理与兼容性:解析失败的兜底、浏览器环境差异处理
- 最佳实践:数据迁移与备份建议
## 项目结构
该工具包通过入口文件聚合导出各子模块,存储管理位于 utils/TsStorage.js,配合通用工具 TsCommon.js 提供 JSON 解析兜底,以及加密工具链(TsCrypto.js + TsSM4.js)用于请求体加密。
```mermaid
graph TB
entry["index.js
入口聚合导出"] --> storage["TsStorage.js
存储模块"]
entry --> common["TsCommon.js
通用工具"]
entry --> crypto["TsCrypto.js
加密器"]
entry --> sm4["TsSM4.js
SM4 实现"]
entry --> gconf["TsGlobalConfig.js
全局配置"]
entry --> httpu["TsHttpUtil.js
HTTP 工具外部模块"]
storage --> common
crypto --> sm4
crypto --> gconf
```
图表来源
- [index.js:1-16](file://index.js#L1-L16)
- [TsStorage.js:1-55](file://src/utils/TsStorage.js#L1-L55)
- [TsCommon.js:1-98](file://src/utils/TsCommon.js#L1-L98)
- [TsCrypto.js:1-34](file://src/utils/TsCrypto.js#L1-L34)
- [TsSM4.js:1-456](file://src/utils/TsSM4.js#L1-L456)
- [TsGlobalConfig.js:1-34](file://src/utils/TsGlobalConfig.js#L1-L34)
章节来源
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:1-24](file://package.json#L1-L24)
## 核心组件
- 存储模块(TsStorage):提供通用的保存/读取接口,以及用户 token 和加密开关的专用接口。
- 通用工具(TsCommon):提供 JSON 解析兜底函数,确保从 localStorage 读取时的健壮性。
- 加密工具(TsCrypto + TsSM4):基于 SM4 算法的加密封装,支持 ECB 模式与 base64 输出。
- 全局配置(TsGlobalConfig):提供 base64Key 等配置项,供加密模块初始化使用。
章节来源
- [TsStorage.js:1-55](file://src/utils/TsStorage.js#L1-L55)
- [TsCommon.js:29-44](file://src/utils/TsCommon.js#L29-L44)
- [TsCrypto.js:5-34](file://src/utils/TsCrypto.js#L5-L34)
- [TsSM4.js:96-156](file://src/utils/TsSM4.js#L96-L156)
- [TsGlobalConfig.js:19-33](file://src/utils/TsGlobalConfig.js#L19-L33)
## 架构总览
存储模块围绕 localStorage 构建,所有数据以 JSON 字符串形式保存,读取时进行 JSON 解析并提供默认值兜底。加密开关通过布尔值控制是否对请求体进行加密,加密密钥来自全局配置。
```mermaid
sequenceDiagram
participant App as "应用"
participant Storage as "TsStorage"
participant Local as "localStorage"
participant Common as "TsCommon"
participant Crypto as "TsCrypto"
participant SM4 as "TsSM4"
participant GConf as "TsGlobalConfig"
App->>Storage : save(key, value)
Storage->>Local : setItem(key, JSON.stringify({data : value}))
Local-->>Storage : ok
App->>Storage : get(key, def?)
Storage->>Local : getItem(key)
Local-->>Storage : 字符串或null
Storage->>Common : parseJSON(字符串, {data : def})
Common-->>Storage : 对象或默认值
Storage-->>App : 返回 data 字段
App->>Storage : saveEncryptBody(true/false)
App->>Storage : getEncryptBody()
App->>Crypto : encrypt(body) 或 decrypt(cipher)
Crypto->>GConf : getConfig().base64Key
Crypto->>SM4 : encrypt()/decrypt()
SM4-->>Crypto : 密文/明文
Crypto-->>App : 返回结果
```
图表来源
- [TsStorage.js:26-43](file://src/utils/TsStorage.js#L26-L43)
- [TsCommon.js:34-44](file://src/utils/TsCommon.js#L34-L44)
- [TsCrypto.js:19-30](file://src/utils/TsCrypto.js#L19-L30)
- [TsSM4.js:338-452](file://src/utils/TsSM4.js#L338-L452)
- [TsGlobalConfig.js:19-29](file://src/utils/TsGlobalConfig.js#L19-L29)
## 详细组件分析
### 存储模块 API 规范
- 方法概览
- save(key, value)
- 参数
- key: 字符串,存储键名
- value: 任意可 JSON 序列化对象或原始值
- 返回值:无(写入 localStorage)
- 行为:将 value 包装为 {data: value} 并 JSON 序列化后写入 localStorage
- get(key, def="")
- 参数
- key: 字符串,存储键名
- def: 可选,默认值,当读取失败或空时返回
- 返回值:任意类型(由 JSON 反序列化后的 data 字段决定)
- 行为:从 localStorage 读取字符串,使用 parseJSON 解析并返回 data 字段;失败或不存在则返回 def
- saveUserToken(token)
- 参数
- token: 字符串或可序列化对象
- 返回值:无
- 行为:内部调用 save("token", token),键固定为 "token"
- getUserToken()
- 参数:无
- 返回值:字符串
- 行为:内部调用 get("token"),默认空字符串
- saveEncryptBody(bool=true)
- 参数
- bool: 布尔值,true 表示启用加密
- 返回值:无
- 行为:保存布尔开关到键 "encrypt_body"
- getEncryptBody()
- 参数:无
- 返回值:布尔值
- 行为:读取 "encrypt_body",默认 true
- 使用示例(路径引用)
- 保存对象并读取
- [TsStorage.js:31-43](file://src/utils/TsStorage.js#L31-L43)
- [README.md:28-41](file://README.md#L28-L41)
- 保存用户 token
- [TsStorage.js:9-15](file://src/utils/TsStorage.js#L9-L15)
- 设置/获取加密开关
- [TsStorage.js:17-23](file://src/utils/TsStorage.js#L17-L23)
- 数据序列化与反序列化
- 写入:统一使用 JSON.stringify({data: value}),保证读取时有 data 字段
- 读取:使用 parseJSON 将字符串解析为对象,若失败或为空则返回默认对象 {data: def}
- 类型支持:任何可 JSON 序列化的类型均可保存;读取后按原类型返回
- 错误处理
- get 中的 parseJSON 失败时返回默认值,避免抛错
- getUserToken 默认空字符串,避免未设置 token 时的异常
- 浏览器兼容性
- localStorage 在现代浏览器中广泛支持;在隐私模式或禁用 localStorage 的情况下可能不可用
- 建议在生产环境中增加 try/catch 包裹并降级处理
章节来源
- [TsStorage.js:26-54](file://src/utils/TsStorage.js#L26-L54)
- [TsCommon.js:34-44](file://src/utils/TsCommon.js#L34-L44)
- [README.md:28-41](file://README.md#L28-L41)
### 加密模块与加密开关
- 加密开关
- 通过 saveEncryptBody/getEncryptBody 控制是否对请求体进行加密
- 默认开启(true),可在业务层根据需要关闭
- 加密实现
- TsCrypto 基于 SM4 算法,ECB 模式,输出 base64
- 初始化时从 TsGlobalConfig 获取 base64Key,并转换为 16 字节密钥缓冲区
- 支持 encrypt(content) 与 decrypt(base64) 两个核心方法
- 关键流程图(加密/解密)
```mermaid
flowchart TD
Start(["开始"]) --> GetCfg["读取全局配置
base64Key"]
GetCfg --> InitSM4["初始化 SM4
ECB 模式, base64 输出"]
InitSM4 --> Encrypt{"是否加密?"}
Encrypt --> |是| DoEnc["encrypt(content)"]
Encrypt --> |否| Skip["跳过加密"]
DoEnc --> OutEnc["返回 base64 密文"]
Skip --> OutPlain["返回明文"]
OutEnc --> End(["结束"])
OutPlain --> End
```
图表来源
- [TsCrypto.js:7-13](file://src/utils/TsCrypto.js#L7-L13)
- [TsSM4.js:338-387](file://src/utils/TsSM4.js#L338-L387)
- [TsGlobalConfig.js:19-29](file://src/utils/TsGlobalConfig.js#L19-L29)
章节来源
- [TsCrypto.js:5-34](file://src/utils/TsCrypto.js#L5-L34)
- [TsSM4.js:96-156](file://src/utils/TsSM4.js#L96-L156)
- [TsGlobalConfig.js:19-33](file://src/utils/TsGlobalConfig.js#L19-L33)
### 入口导出与集成
- 入口文件 index.js 将各模块聚合导出,便于统一引入
- README.md 展示了存储模块的基本用法与加密开关的配置思路
章节来源
- [index.js:1-16](file://index.js#L1-L16)
- [README.md:28-41](file://README.md#L28-L41)
## 依赖关系分析
- TsStorage 依赖 TsCommon 的 JSON 解析兜底
- TsCrypto 依赖 TsSM4 与 TsGlobalConfig
- index.js 统一导出各模块,README.md 提供使用示例
```mermaid
graph LR
Storage["TsStorage"] --> Common["TsCommon"]
Crypto["TsCrypto"] --> SM4["TsSM4"]
Crypto --> GConf["TsGlobalConfig"]
Entry["index.js"] --> Storage
Entry --> Common
Entry --> Crypto
Entry --> SM4
Entry --> GConf
```
图表来源
- [TsStorage.js:1](file://src/utils/TsStorage.js#L1)
- [TsCommon.js:1](file://src/utils/TsCommon.js#L1)
- [TsCrypto.js:1-3](file://src/utils/TsCrypto.js#L1-L3)
- [TsSM4.js:1](file://src/utils/TsSM4.js#L1)
- [TsGlobalConfig.js:1-3](file://src/utils/TsGlobalConfig.js#L1-L3)
- [index.js:1-16](file://index.js#L1-L16)
章节来源
- [index.js:1-16](file://index.js#L1-L16)
- [package.json:19-22](file://package.json#L19-L22)
## 性能与可靠性
- 性能特性
- localStorage 为同步 API,适合小规模轻量数据;大对象频繁序列化/反序列化会带来开销
- 建议仅保存必要数据,避免超大对象
- 可靠性
- get 中的 parseJSON 提供失败兜底,降低异常传播风险
- 建议在业务层增加 try/catch 并记录错误日志
- 安全性
- 本地存储非加密,敏感数据建议仅在传输阶段加密(请求体加密)
- 密钥管理需遵循最小暴露原则,避免硬编码
[本节为通用指导,不直接分析具体文件]
## 故障排查指南
- 读取不到数据
- 检查键名是否一致;确认是否使用 save 保存而非直接 setItem
- 若数据为空,get 会返回默认值;检查 def 参数是否被覆盖
- JSON 解析失败
- parseJSON 会在异常时返回默认对象;检查存储值是否为合法 JSON
- token 为空
- getUserToken 默认返回空字符串;确认是否已调用 saveUserToken 保存
- 加密异常
- 确认 TsGlobalConfig 中 base64Key 配置正确且可转换为 16 字节
- 确认加密开关状态(saveEncryptBody/getEncryptBody)
章节来源
- [TsStorage.js:13-23](file://src/utils/TsStorage.js#L13-L23)
- [TsCommon.js:34-44](file://src/utils/TsCommon.js#L34-L44)
- [TsCrypto.js:7-13](file://src/utils/TsCrypto.js#L7-L13)
- [TsGlobalConfig.js:19-29](file://src/utils/TsGlobalConfig.js#L19-L29)
## 结论
存储管理模块提供了简洁可靠的 localStorage 访问接口,并通过 JSON 序列化/反序列化保障复杂对象的持久化。结合加密开关与 SM4 加密工具,可在传输阶段保护敏感数据。建议在生产环境中增强错误处理与降级策略,并遵循最小暴露原则管理密钥。
[本节为总结性内容,不直接分析具体文件]
## 附录
### API 一览表
- 通用存取
- save(key, value): 保存任意可序列化对象
- get(key, def=""): 读取并返回 data 字段,失败或空时返回默认值
- 用户 token
- saveUserToken(token): 保存 token
- getUserToken(): 读取 token,默认空字符串
- 加密开关
- saveEncryptBody(bool=true): 设置加密开关
- getEncryptBody(): 读取加密开关,默认 true
章节来源
- [TsStorage.js:26-54](file://src/utils/TsStorage.js#L26-L54)
### 数据迁移与备份最佳实践
- 迁移策略
- 新版本字段变更时,读取旧键并迁移至新键,再删除旧键
- 迁移前先备份当前 localStorage 快照
- 备份建议
- 定期导出关键键集合的 JSON 文本,离线保存
- 对敏感键(如 token)单独加密备份
- 清理与安全
- 定期清理过期键,避免累积膨胀
- 对外发布前移除调试用键或敏感键
[本节为通用指导,不直接分析具体文件]