miragehttp
v1.1.75
Published
`miragehttp` 是一个基于 `Vue 3 + TypeScript + Vite` 构建的前端 SDK,用于统一封装 Mirage 系列系统的数据访问、登录、上传与多业务模块调用能力。
Readme
miragehttp
miragehttp 是一个基于 Vue 3 + TypeScript + Vite 构建的前端 SDK,用于统一封装 Mirage 系列系统的数据访问、登录、上传与多业务模块调用能力。
当前仓库同时包含两部分内容:
- SDK 源码与打包入口
- 本地开发调试页面与测试代码
安装
npm install miragehttp镜像地址:
快速开始
1. 初始化 SDK
import { Project } from 'miragehttp';
const sdk = new Project({
url: 'http://127.0.0.1:8011',
pid: 'SYKFGLCC',
ver: 'v2',
});初始化参数说明:
url:后端服务地址pid:项目编号,用于匹配模块与appidver:接口版本,支持v1和v2
功能导览
介绍文档按功能阅读时,建议按下面顺序理解:
- 登录功能
get主推调用post主推调用- 其他调用
- 上传功能
- 子系统调用描述
- 工具功能
2. 登录功能
登录相关能力集中在 sdk.User 上:
适用场景:
- 账号密码登录
- RSA 公钥加密登录
- 手机号验证码登录
- 主动退出并清理登录态
推荐入口:
sdk.User.login()sdk.User.loginMM()sdk.User.loginByPhone()sdk.User.loginOut()
备用入口:
UserInfo:读取已登录用户信息AuthEventBus:监听认证状态变化
这些配套能力也属于稳定公开 API,可直接从包根入口导入:
import { UserInfo, AuthEventBus, configureRuntimeEnv, withRuntimeEnv } from 'miragehttp';const result = await sdk.User.login('SID001', 'admin', '123456');常用方法:
login():账号密码登录loginMM():RSA 公钥加密登录,默认会先自动获取公钥;旧的手动传publicKey方式仍兼容loginByPhone():手机号验证码登录loginOut():清除 SDK 登录态,并通过AuthEventBus派发logout事件
运行时适配:
- 浏览器环境默认无需额外配置
- 如果在
SSR、Node 测试、微前端沙箱或自定义宿主里使用 SDK,可通过configureRuntimeEnv()主动注入window/document/localStorage - 如果只想在某一段逻辑或测试用例中临时覆盖运行时 provider,优先使用
withRuntimeEnv(),回调结束后会自动恢复 - 推荐只从
miragehttp根入口导入这组能力,不要从src/...内部路径直接引用
import { configureRuntimeEnv } from 'miragehttp';
configureRuntimeEnv({
localStorage: myStorage,
document: myDocumentLike,
window: myWindowLike,
});await withRuntimeEnv(
{
localStorage: myScopedStorage,
},
async () => {
// 仅当前作用域内生效
},
);完整可复制示例可直接参考:examples/runtime-env.ts
3. get 主推调用
对于新接入项目和 AI 编程场景,查询默认优先使用 sdk.get():
适用场景:
- 当前模块的普通列表查询
- 详情查询
- 树形查询
- 统计查询
- 还不确定该使用哪个查询别名方法时
推荐入口:
sdk.get()
备用入口:
sdk.Data.getListData()sdk.Data.getSingleData()sdk.Data.getTreeData()sdk.Data.getStatisticsData()sdk.Data.getPageData()
const list = await sdk.get({
XDLMSID: '1001',
XDLMPage: 1,
XDLMPageSize: 20,
});说明:
sdk.get()是默认读操作入口- 内部会委托给
Data.queryData() - 当参数命中特殊规则时,内部仍会自动切换到
POST - 适合作为“不确定具体别名方法时”的统一查询入口
迁移对照:
| 旧入口 | 推荐入口 | 说明 |
| --- | --- | --- |
| sdk.Data.GetData(actionData, headers?) | sdk.get(actionData, headers?) | 默认查询统一走顶层入口 |
| sdk.Data.getListData() | sdk.get() | 列表查询也优先收口到统一入口 |
| sdk.Data.getSingleData() | sdk.get() | 单条查询场景也可先用统一入口 |
4. post 主推调用
提交默认优先使用 sdk.post():
适用场景:
- 当前模块的新增
- 当前模块的更新
- 当前模块的删除
- 不确定具体别名方法时的统一写操作
推荐入口:
sdk.post()
备用入口:
sdk.Data.AddSingleData()sdk.Data.AddBatchData()sdk.Data.updateData()sdk.Data.updateBatchData()sdk.Data.delData()
const saved = await sdk.post({
XDLMCID: '6000',
XDLMID: 'ROW001',
XDLMName: '更新后的名称',
});说明:
sdk.post()是默认写操作入口- 内部会委托给
Data.submitData() - 适用于新增、修改、删除和大多数写操作
- 新代码优先使用它,而不是直接写旧入口
迁移对照:
| 旧入口 | 推荐入口 | 说明 |
| --- | --- | --- |
| sdk.Data.PostData(actionData, headers?) | sdk.post(actionData, headers?) | 默认写操作统一走顶层入口 |
| sdk.Data.AddSingleData() | sdk.post() | 新增单条也优先走统一入口 |
| sdk.Data.updateData() | sdk.post() | 更新场景优先统一收口 |
| sdk.Data.delData() | sdk.post() | 删除场景优先统一收口 |
5. 其他调用
当你已经明确知道业务语义,或者接口明确要求提交格式时,可以使用更明确的方法。
适用场景:
- 业务语义已经很明确
- 接口要求显式 JSON 提交
- 接口要求原始字符串报文
- 扩展查询需要单独标识
推荐入口:
sdk.Data.getExtendedData()sdk.Data.postForm()sdk.Data.postJson()sdk.Data.postRaw()
备用入口:
getListData()getSingleData()updateData()AddSingleData()
查询类别名:
getListData():列表查询getSingleData():单条查询getTreeData():树形查询getStatisticsData():统计查询getPageData():分页查询getExtendedData():扩展查询新入口
写操作别名:
AddSingleData():新增单条AddBatchData():批量新增updateData():更新单条updateBatchData():批量更新delData():删除
显式提交方式:
await sdk.Data.postForm({
XDLMCID: '5000',
XDLMSID: '1001',
XDLMName: '表单提交',
});
await sdk.Data.postJson({
XDLMSID: '1001',
XDLMName: 'JSON 提交',
});
await sdk.Data.postRaw(
'/custom/raw',
JSON.stringify({ raw: true }),
{ 'Content-Type': 'application/json;charset=utf-8' },
);兼容说明:
GetData()、PostData()、PostRawData()、getExtendAPI()仍可继续使用- 新接入项目、示例代码和 AI 生成代码优先使用
sdk.get()/sdk.post()与显式新方法 - 旧的
PostData(..., true)仅作为兼容层保留;明确需要 JSON 或原始报文时,优先改用sdk.Data.postJson()/sdk.Data.postRaw() - 迁移对照请查看
doc/旧入口迁移对照表.md
迁移对照:
| 旧入口 | 推荐入口 | 说明 |
| --- | --- | --- |
| sdk.Data.getExtendAPI(mActionType, actionData, headers?) | sdk.Data.getExtendedData(actionData, headers?) | 去掉历史 mActionType 语义,入口更清晰 |
| sdk.Data.PostRawData(url, headers, data) | sdk.Data.postRaw(url, data, headers?) | 参数顺序更直观,减少误传风险 |
| sdk.Data.PostData() | sdk.post() / sdk.Data.postForm() / sdk.Data.postJson() | 默认写操作优先顶层统一入口;表单提交用 postForm(),PostData(..., true) 只按兼容层理解 |
6. 上传功能
普通上传示例:
适用场景:
- 普通文件上传
- 多文件顺序上传
- 大文件上传
- 分片上传
- 分片合并
推荐入口:
createUploadFormData()createAutoChunkUploadFormData()sdk.uploadFile()sdk.uploadFiles()sdk.uploadLargeFile()sdk.uploadFilesWithOptions()
兼容旧接口 / 备用入口:
sdk.Data.uploadFile()sdk.Data.uploadFiles()sdk.Data.uploadFilesSequential()createChunkUploadFormData()createChunkMergeFormData()sdk.Data.uploadFile2()sdk.Data.uploadFile005()sdk.Data.uploadFile006()
import { createUploadFormData, type IUploadResponse } from 'miragehttp';
const formData = createUploadFormData({
xmbh: 'XM001',
file,
});
const result = await sdk.uploadFile<IUploadResponse>(formData, (progress) => {
console.log('upload progress:', progress);
});
console.log(result.data?.url);多文件顺序上传推荐写法:
import type { IUploadProgressDetail, IUploadResponse } from 'miragehttp';
const files = [
new File(['demo-1'], 'demo-1.txt', { type: 'text/plain' }),
new File(['demo-2'], 'demo-2.txt', { type: 'text/plain' }),
];
const controller = new AbortController();
const results = await sdk.uploadFilesWithOptions<IUploadResponse>(
files,
{ xmbh: 'XM001' },
(progress) => {
console.log('multi upload progress:', progress);
},
{},
{
signal: controller.signal,
onProgressDetail: (detail: IUploadProgressDetail) => {
console.log(detail.fileIndex, detail.fileName, detail.overallProgress);
},
},
);
console.log(results[0]?.data?.url);自动分片上传推荐写法:
import type { IAutoChunkUploadOptions, IChunkUploadResponse } from 'miragehttp';
const largeUploadOptions: IAutoChunkUploadOptions = {
chunkSize: 5 * 1024 * 1024,
chunkThreshold: 5 * 1024 * 1024,
userid: 'USER001',
};
const largeUploadResult = await sdk.uploadLargeFileWithOptions<IChunkUploadResponse>(
formData,
(progress) => {
console.log('large upload progress:', progress);
},
{},
largeUploadOptions,
);
console.log(largeUploadResult.data?.url);分片上传推荐写法:
import { createAutoChunkUploadFormData, type IChunkUploadResponse } from 'miragehttp';
const chunkFormData = createAutoChunkUploadFormData({
xmbh: 'XM001',
file,
chunk: 1,
chunks: 8,
userid: 'USER001',
});
await sdk.Data.uploadFile2<IChunkUploadResponse>(chunkFormData);分片与扩展上传:
uploadFiles():顶层多文件顺序上传默认入口uploadFilesWithOptions():顶层多文件上传增强入口,支持取消与详细进度uploadLargeFile():顶层自动分片上传入口,小文件自动回落普通上传uploadFilesSequential():多文件顺序上传显式入口,返回每个文件的结果数组uploadFile2():常用分片上传入口,最后一片自动合并uploadFile005():底层分片上传,兼容旧接口保留,已标记弃用uploadFile006():底层分片合并,兼容旧接口保留,已标记弃用
兼容旧接口说明:
- 新代码默认不要优先生成
uploadFile005()/uploadFile006() - 只有维护存量项目、或者必须完全复刻历史底层协议时再使用它们
- 如果只是常规分片上传,优先改用
uploadFile2() - 如果是大文件自动切片,优先改用
uploadLargeFile()
迁移对照:
| 旧入口 | 推荐入口 | 说明 |
| --- | --- | --- |
| sdk.Data.uploadFile005() | sdk.Data.uploadFile2() | 常用分片上传已支持最后一片自动合并 |
| sdk.Data.uploadFile006() | 不再单独调用 | 仅兼容旧协议保留;常规分片上传无需手动合并 |
| createChunkUploadFormData() | createAutoChunkUploadFormData() | 常用分片场景自动补 uploadtype/guid/name |
| sdk.Data.uploadFilesSequential() | sdk.uploadFiles() / sdk.uploadFilesWithOptions() | 顶层入口更适合作为新代码默认写法 |
调用前请确认是否已传入必要参数;其中 sdk.Data.uploadFile2() 常用分片上传至少应包含 chunk、chunks、guid、xmbh、userid、name,最后一片上传完成后会自动合并,不需要再额外调用合并接口。新接入优先使用 createUploadFormData() / createAutoChunkUploadFormData() / createChunkMergeFormData() 获取类型校验;其中 createAutoChunkUploadFormData() 会自动补 uploadtype=1、自动生成 guid,并优先从 File.name 推导 name。普通上传与多文件上传优先使用 sdk.uploadFile() / sdk.uploadFiles() / sdk.uploadFilesWithOptions(),内部会自动按顺序逐个上传,避免一次请求携带多个文件导致的兼容问题;进度回调统一返回 0-100 百分比,如需文件级详细进度请结合 IUploadProgressDetail / onProgressDetail。大文件场景优先使用 sdk.uploadLargeFile() / sdk.uploadLargeFileWithOptions();超过阈值时会自动切片并复用 uploadFile2() 的“最后一片自动合并”语义,如无法从登录态读取用户信息,请通过 IAutoChunkUploadOptions.userid 显式传入。对于 uploadFile2() / uploadLargeFile(),推荐把返回泛型声明成 IChunkUploadResponse;SDK 会自动补充 chunkMeta.guid/chunk/chunks/fileName/userid/isLastChunk/mergeCompleted,其中 merged 仅作为兼容别名保留。
7. 子系统调用描述
system 通过懒加载方式提供多个业务模块实例,可按模块编号直接访问:
适用场景:
- 在同一个 SDK 实例里切换到其他业务模块
- 访问
defaultModules中登记的子系统 - 跨子系统查询、扩展查询和写操作
推荐入口:
sdk.system.<PID>.<method>()
备用入口:
sdk.Data.<method>():仅用于当前初始化模块sdk.get()/sdk.post():仅用于当前初始化模块的统一入口
await sdk.system.SYBK.getListData({
XDLMSID: '1001',
});记忆规则:
sdk.Data:当前初始化pid对应模块的数据入口sdk.system.<PID>:按需访问其他业务模块defaultModules中维护了大量可直接通过sdk.system.<PID>访问的子系统
常见示例:
await sdk.system.SYKYGL.getListData({
XDLMSID: '1001',
});
await sdk.system.SYBK.getExtendedData({
XDLMSID: '1111',
XDLMTID: '9701',
});
await sdk.system.SYXMZHGL.postForm({
XDLMCID: '5000',
XDLMSID: '1001',
XDLMName: '测试数据',
});如果你需要查看有哪些子系统、如何跨子系统调用、以及 sdk.Data 和 sdk.system.<PID> 的区别,请阅读 doc/子系统调用指南.md。
8. 工具功能
除业务接口外,SDK 还提供一些工具能力:
适用场景:
- 生成时间戳与随机串
- 发起简单 JSON 请求
- 读写 Cookie 与 LocalStorage
- 处理认证状态通知
- 请求缓存控制
推荐入口:
sdk.toolboxToolBoxCacheRequestCacheAuthEventBusUserInfo
备用入口:
UserInfo:读取登录用户信息AdvancedApi:访问底层兼容能力sdk.toolbox.curDateTime():获取时间戳字符串sdk.toolbox.RndNum(n):生成随机数字串sdk.toolbox.getTimeAndRandom():生成时间戳加随机数ToolBox.getJSON():发起简单异步 JSON 请求,推荐配合await使用Cache:Cookie 与 LocalStorage 读写AuthEventBus:认证状态事件通知RequestCache:请求缓存控制
版本说明
v1
- 使用传统
ashx接口 - GET/POST 入口统一走旧接口风格
v2
- 使用 REST 风格接口
- 查询、提交、上传分别走独立端点
SDK 会根据初始化时传入的 ver 自动切换端点配置。
公开能力概览
当前 SDK 主要公开以下能力:
Project:SDK 主入口System:业务子模块容器DebugLogger:调试日志工具AuthEventBus:认证事件总线RequestCache:请求缓存ToolBox:通用工具方法Cache:Cookie 与 LocalStorage 工具
稳定公共 API 与高级 API
从当前版本开始,导出面按“稳定公共 API”和“高级兼容 API”做了分层组织:
- 稳定公共 API:面向大多数业务接入方,优先推荐直接从
miragehttp使用 - 高级兼容 API:面向需要底层控制能力的场景,推荐通过
AdvancedApi命名空间访问
如果你希望在包依赖层面进一步收清边界,也可以直接使用子路径导入:
示例:
import { Project, AdvancedApi } from 'miragehttp';
const sdk = new Project({
url: 'http://127.0.0.1:8011',
pid: 'SYKFGLCC',
ver: 'v2',
});
AdvancedApi.setParentOrigin('https://your-app.example.com');import { Project } from 'miragehttp/public';
import { setParentOrigin } from 'miragehttp/advanced';
const sdk = new Project({ url: 'http://127.0.0.1:8011', pid: 'SYKFGLCC', ver: 'v2' });
setParentOrigin('https://your-app.example.com');说明:
- 现有直接导出的底层类仍然保留,以兼容旧代码
- 新接入如果需要使用底层能力,更建议从
AdvancedApi进入 - 若团队希望通过 import 路径显式区分推荐层与高级层,可优先使用
miragehttp/public与miragehttp/advanced - 后续版本若继续收敛导出边界,将优先围绕这两层结构演进
本地开发
安装依赖
npm install启动开发环境
npm run dev开发模式会启动本地测试页面,入口为 src/main.ts,用于手工调试 SDK 行为。
构建 SDK
npm run build构建产物输出到 dist/,包含:
miragehttp.es.jsmiragehttp.umd.js- 对应类型声明文件
运行测试
npm run test运行静态检查
npm run lint运行类型检查
npm run typecheck运行统一质量检查
npm run check生成 API 文档
npm run jsdoc3当前 API 文档使用 TypeDoc 生成,输出到 doc/doc-page/,入口文件为 doc/doc-page/index.html。
文档首页摘要来自 doc/jsdoc-home.md,主入口与导出面来自 src/index.ts。
如需本地预览生成后的文档页面,可执行:
npm run docs:serveAI 接入指南
如果你要把本 SDK 提供给其他使用 AI 编程的开发人员,优先让他们阅读:
doc/AI使用指南.mddoc/子系统调用指南.mddoc/兼容式API演进计划.mddoc/旧入口迁移对照表.mddoc/智能体提示词模板.mdexamples/get.tsexamples/login.tsexamples/post.tsexamples/system.tsexamples/tools.tsexamples/runtime-env.tsexamples/upload.tsexamples/compat-methods.tsexamples/sdk-template.ts- 优先记住
sdk.get()/sdk.post()两个入口 - 上传优先记住
createUploadFormData()、createAutoChunkUploadFormData()、sdk.uploadFile()和sdk.uploadFiles()
本地质量检查建议顺序
在提交代码前,建议至少执行以下命令:
npm run checkCI 检查
仓库已提供 GitHub Actions 工作流:
- 路径:
.github/workflows/ci.yml - 内容:自动执行
lint、test、build - 本地可先执行:
npm run check - 触发方式:
push、pull_request、手动触发
如果后续仓库托管到 GitHub,可直接启用这套基础质量检查流程。
环境变量
开发和生产环境通过 .env.* 管理配置,当前主要使用:
VITE_APP_BASE_URL:开发代理目标地址VITE_APP_VER:默认接口版本VITE_APP_DEBUG:调试开关
注意事项
关于登录态
- SDK 会在登录成功后写入部分 Cookie 与 LocalStorage
- 认证失效时会通过事件总线和
postMessage通知宿主页面 - 跨源 iframe 场景建议显式配置父窗口
origin
关于安全
Secret模块中的前端加密仅适用于兼容性存储和数据混淆- 前端硬编码密钥不能作为真正的安全边界
- 真正敏感的数据保护应由后端负责
目录概览
src/
base/ 基础类
config/ 端点与模块注册配置
modules/ 登录、加密等业务模块
types/ 公共类型定义
utils/ 请求层、缓存、项目装配等核心能力
main.ts 开发调试入口
index.ts SDK 发布入口
tests/ 单元测试
doc/ 项目文档后续建议
当前项目更适合采用以下演进路线:
- 先补文档与关键测试
- 再拆分
DataClass与模块注册配置 - 最后推进 lint、CI 与依赖升级
相关文档
- 架构与优化建议:
doc/项目优化方案.md - 依赖升级路线:
doc/依赖升级计划.md - AI 接入指南:
doc/AI使用指南.md - 子系统调用说明:
doc/子系统调用指南.md - 兼容式 API 演进:
doc/兼容式API演进计划.md - 旧入口迁移对照:
doc/旧入口迁移对照表.md - 智能体提示词模板:
doc/智能体提示词模板.md Vitest 4迁移预案:doc/vitest4迁移预案.md- SDK API 文档:
doc/doc-page/index.html
