Files
docsys-skill/docsys/README.md
T
Cheney 8ae1694b6d feat: DocSystem (MxsDoc) 文件操作 skill
从公司 DocSystem / MxsDoc V2.02.71 逆向出 HTTP 接口,封装为零依赖 Python CLI,
让 AI 可以完全通过命令行操作文档系统的文件系统。

功能:
- 浏览:ls / tree / repos / auth
- 读写:mkdir(-p) / touch / upload / download / cat
- 变更:rename / rm / mv / cp
- 检索:search(文件名 + 正文)

要点:
- 不指定仓库时默认操作「研发管理配置库」(id=2);首个位置参数以 / 开头时自动判定为路径
- 凭证不入库,从 ~/.docsys/config.json 或环境变量读取
- 会话 cookie 缓存于 ~/.docsys/session.json,过期自动重登
2026-10-20 15:50:57 +08:00

8.7 KiB
Raw Blame History

DocSystem(MxsDoc)HTTP 接口文档

目标系统:MxsDoc / DocSystem V2.02.71 地址:http://172.1.4.31:8100/DocSystem 前端入口:/DocSystem/web/index.html → projects.html → project.html?vid=<仓库ID>

本文档由前端 JS 逆向 + 逐接口实测得出,用于支撑 scripts/docsys.py。


通用约定

  • 全部接口为 POST,表单编码 application/x-www-form-urlencoded; charset=UTF-8 (仅 uploadDoc.do 为 multipart/form-data)。
  • 必须带请求头 X-Requested-With: XMLHttpRequest。
  • 会话靠 Cookie 维持:JSESSIONID、dstoken(= base64(密码))、dsuser(= 用户名)。 rememberMe=1 时服务端下发 dstoken/dsuser 用于自动登录。
  • 响应统一 JSON:{"status":"ok"|"fail","data":...,"msgInfo":"...","msgData":...}。 少数接口(如 getDocContent.do)返回纯文本。
  • 节点类型:type=1 文件,type=2 目录。
  • 时间字段为毫秒时间戳。

鉴权

POST User/login.do

参数 说明
userName 邮箱或手机号
pwd 密码经 base64 编码后的字符串(标准 base64,非 URL-safe)
rememberMe 1 记住登录,0 不记住

成功返回 data 为用户对象(id/name/realName/role/…)。

POST User/logout.do

无参数。

POST User/getLoginUser.do

无参数,返回当前登录用户。可用于探测会话是否有效。


仓库

POST Repos/getReposList.do

无参数。返回 data 为仓库数组: {id, name, info, type, verCtrl, path, owner, ...}

实测可见仓库:

id 名称 说明
1 意见与反馈 当前账号可新增/编辑,不可删除/下载
2 研发管理配置库 CLI 默认仓库(DEFAULT_REPO_NAME),基本只读,部分目录可下载
5 常用工具 只读
6 临时仓库 无访问权限

约定:scripts/docsys.py 中若省略仓库参数,默认操作 id=2「研发管理配置库」。 判定规则:第一个位置参数以 / 或 ./ 开头则视为路径(仓库取默认),否则视为仓库 id/名称。

POST Repos/getDocSysConfig.do

无参数,返回系统配置(如 defaultReposStorePath)。


目录列举

POST Repos/getSubDocList.do

参数 说明
vid 仓库 id
docId 目录 docId(实测服务端不使用,仅随请求透传)
path 目录路径,仓库根为 "",其余以 / 结尾
name 目录名。服务端取 path + name 作为目标目录
sort 排序方式,0 名称
needLockState 1
shareId 可传空

关键结论:目标目录 = path + name。传 path="a/"、name="" 与 path=""、name="a" 等价;但传 path="a/" 且 name="a" 会变成 a/a 从而返回空。

返回 data 为节点数组,节点字段: docId, pid, path, name, type, level, size, checkSum, createTime, latestEditTime, latestEditorName, creatorName, localRootPath, reposPath, ...

其中 path 是节点所在目录的路径,节点完整路径 = path + name。


权限

POST Repos/getUserDocAuth.do

参数 说明
docId 目录 docId,仓库根为 0
reposId 仓库 id
path 目录自身路径
name 目录名

返回 data:{access, addEn, editEn, deleteEn, downloadEn, isAdmin, uploadSize, ...}

实测(账号 qian.huang@sunyard.com,仓库 1):

access=1  addEn=1  editEn=1  deleteEn=0  downloadEn=0  isAdmin=0

注意:rename / move 在服务端按"删除 + 新增"鉴权,因此即使 addEn=1, deleteEn=0 时重命名和移动同样会被拒绝,报错为「您没有该目录的删除权限」。

权限是逐目录授予的,不是仓库级

同一个仓库里不同目录的权限可以完全不同。实测:

仓库 / 目录 access addEn editEn deleteEn downloadEn
2 研发管理配置库 /(根) 1 0 0 0 0
2 /Sunyard/Docs/开发流程 1 0 0 0 1
2 /Sunyard/Dev/产品/系统研发/工具 1 1 1 1 1
1 意见与反馈 /(根) 1 1 1 0 0

所以不能凭仓库名推断权限,写操作前务必先查 getUserDocAuth。


写操作

POST Doc/addDoc.do(新建文件 / 目录)

参数 说明
reposId 仓库 id
type 1 文件,2 目录
pid 父目录 docId,仓库根为 0
path 父目录完整路径 + /,仓库根为 ""
name 新节点名
content 文本文件内容;建目录传空

返回 data 为新节点,msgData 为 isNewNode。

⚠️ 实测:content 被服务端忽略。 即使传了内容,建出来也是 0 字节空文件 (响应 size=0,随后 getDocContent 读不到任何内容)。 要创建带内容的文件必须改用 Doc/uploadDoc.do(CLI 的 touch 已自动走这条路)。

POST Doc/renameDoc.do

参数 说明
reposId 仓库 id
docId 节点 docId
pid 父目录 docId
type 节点类型
level 节点层级
path 节点自身所在目录路径
name 原名
dstName 新名

POST Doc/deleteDoc.do

参数 说明
reposId 仓库 id
docId 节点 docId
pid 父目录 docId
path 节点自身所在目录路径
name 节点名

删除目录时为递归删除。

POST Doc/moveDoc.do

参数 说明
reposId 仓库 id
docId 节点 docId
type 节点类型
srcLevel 源层级
dstLevel 目标层级(父目录 level + 1;移到仓库根为 0)
srcPid 源父目录 docId
dstPid 目标父目录 docId,仓库根为 0
srcPath 源目录路径
srcName 源名
dstPath 目标父目录完整路径 + /,仓库根为 ""
dstName 目标名(可与源名不同,即改名 + 移动)

POST Doc/copyDoc.do

参数同 moveDoc。


上传 / 下载

POST Doc/uploadDoc.do(multipart/form-data)

字段 说明
reposId 仓库 id
path 目标目录完整路径 + /
name 远端文件名
size 文件字节数
checkSum 文件 MD5
uploadFile 文件内容(文件域)
commitMsg 提交说明,可空
dirPath 文件夹上传标记,可空

大文件走分片:chunkNum / cutSize / chunkIndex / chunkSize / chunkHash / combineDisabled=1,分片全部传完再调 Doc/combineChunks.do。

POST Doc/downloadDocPrepare.do

参数 说明
reposId, docId, pid, path, name 目标节点
downloadType 1 单文件
downloadList 可空

返回 data:{path, name, targetPath, targetName},msgData 为 deleteFlag。 若 msgData == 5 表示目录正在打包,用 data.id 轮询 Doc/queryDownloadPrepareTask.do(参数 taskId),每 2 秒一次,直到 msgData == 6。

GET Doc/downloadDoc.do?...

查询串:vid, path, name, targetPath, targetName, deleteFlag, encryptEn=1(值需 URL 编码)。

实测:直接调 Doc/getDocFileLink.do 拿到的链接指向 tmp/History/rdata/<commitId>/... 历史目录,该文件通常不存在,会返回 500。必须走 downloadDocPrepare 流程。


读取 / 搜索

POST Doc/searchDoc.do

参数 说明
searchWord 关键词
sort 0
reposId 仓库 id
path 限定目录范围,全库传 ""

返回 data 为命中项,hitType:1 文件名命中,3 正文命中; content 为正文的 base64 编码;dataEx 为命中总数。

POST Doc/getDocContent.do

参数 说明
reposId, docId, pid, path, name 目标文件

返回纯文本,响应以 ok 开头,后面才是文件正文,解析时须去掉前两个字符。

POST Doc/getDoc.do

参数 说明
reposId, docId, pid, path, name 目标节点
docType 0 不读取正文和备注

返回节点元信息。


已探明但未使用的接口

  • Doc/lockDoc.do / Doc/unlockDoc.do — 文件锁定
  • Doc/executeDoc.do、Doc/refreshDoc.do
  • Doc/checkChunkUploaded.do、Doc/combineChunks.do、Doc/getMaxThreadCount.do — 分片上传
  • Doc/getDocFileLink.do、Doc/getZipDocFileLink.do — 预览/下载链接(下载场景不可靠,见上)
  • Bussiness/getDocOfficeLink.do、Bussiness/getDocCadLink.do — 在线预览
  • Bussiness/addDocShare.do、Doc/getDocShare.do — 分享
  • Doc/querySystemLog.do — 操作日志
  • Repos/getReposInitMenu.do — 目录树初始化菜单