Files
senmesh-zc/backend/AGENTS.md
KodouWZF 47273ae3fd init: 信创文件安全传输系统内外网本地 Docker 部署
包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套
compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。

说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者
明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT
密钥;上生产前需替换。
2026-11-02 10:59:03 +08:00

7.4 KiB
Raw Blame History

AGENTS.md — s-file(alita-bjy-uygur)编码代理指南

信创文件传输/网盘后端服务:内网与外网之间做文件安全传输("内穿外/外传内"),附带个人网盘、分享、机构与用户管理、通知等能力。单 Maven 模块,Spring Boot 可执行 jar,Docker 部署(src/main/resources/Dockerfile)。

技术栈(务必匹配,勿升级)

  • Java 8 + Spring Boot 2.4.2(父 POM 管理)
  • ORM:MyBatis-Plus 3.4.0(注解/BaseMapper)+ 自研 com.senmesh.tkmybatis 封装 + PageHelper 1.4.6 + 自定义分页拦截器
  • 数据库:达梦 DM8(信创主力,另有 MySQL/PG 驱动),Druid 连接池,SQL 需多库兼容
  • 安全:Spring Security + 自研 JWT(com.senmesh.security),Redisson 分布式锁,RabbitMQ
  • 文档:springfox swagger2 2.7.0;Lombok + MapStruct 1.2.0

常用命令

# 编译(需 JDK 8,例如本机 Zulu 1.8)
export JAVA_HOME=/Users/leijiaping/Library/Java/JavaVirtualMachines/azul-1.8.0_452/Contents/Home
mvn compile -DskipTests

# 测试目录基本为空(仅 PwdTest),项目无自动化测试,验证靠编译 + 自查

已知依赖问题(重要):商业依赖 e-iceblue:spire.pdf:3.7.4 在阿里云/e-iceblue 官方仓库均不存在(官方仓库只有 9.x+)。本地仓库 ~/.m2/repository/e-iceblue/spire.pdf/3.7.4/ 现已安装一个手工编译级 stub jar(仅为 PdfUtils.java 引用的类签名生成),使 mvn package 可以通过;代价是运行 PDF 盖章功能(PdfUtils.pdfStampPerPage)会失败。正式发布前需从公司私服获取真实 jar 覆盖。全量快速编译验证可跳过 PdfUtils.java(详见下方命令)。

mvn dependency:build-classpath -Dmdep.outputFile=/tmp/cp.txt   # 需联网
$JAVA_HOME/bin/javac -encoding UTF-8 -cp "$(cat /tmp/cp.txt)" \
  -sourcepath src/main/java -d /tmp/v \
  $(find src/main/java -name "*.java" ! -name "PdfUtils.java")

包结构地图(com.senmesh)

包 职责
usercenter 用户中心:user(用户/机构用户/注销)、org、authority(角色/权限)、notice(通知)、auth 等,子模块按「controller/service/impl/dto/entity/dao/mapper(XML)/constant/enums」分目录
sfile 文件业务:UserFile(上传/传输/分享记录,核心表 x_user_file)、TransferUserFile、ShareUserFile、TransferFileMonitorJob(定时扫描传输目录)
component/file 物理文件上传组件(xs_file_record、/file/upload、FileProperties)
common AlitaResult、PageQueryDTO、BaseEntity、UserContextHolder、异常体系
security JWT 过滤器、登录、UserInfoDTO
frame/redis Redisson 封装:RedissonUtils、@AutoUnLock、LockDTO
mybatis / mybatisplus / tkmybatis 分页拦截器、@MapperScan、MyMapper<T> 基类
mq、codesetting、config 等 其他支撑模块

注意:源码树里有同包覆写的框架类(org/springframework/...、com/senmesh/swagger),改动前先确认是否为刻意覆写,不要删除。

新增一个接口的标准动作

  1. DTO:查询 DTO 继承 PageQueryDTO<XxxDTO>(自带 pageNo/pageSize/needPage/pageResult);出参 DTO 继承 BaseDTO(用 @SuperBuilder);时间字段统一 Date + @DateTimeFormat + @JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")。
  2. Entity:继承 BaseEntity(带机构的继承 OrgBaseEntity),@TableName 注解,逻辑删除字段 deleted。
  3. Mapper:接口继承 MyMapper<T>(已有 saveEntity/updateEntitySelective/getById/deleteEntity,自动填充 createBy/updateBy),放 **/dao/;自定义 SQL 的 XML 放同名 java 源码目录的 mapper/ 下(pom 已配置打包 java 目录下 **/*.xml),XML 中参数一律 @Param("param") + param.xxx 引用。
  4. Service:接口 + impl。权限校验用命令式断言(项目无 @PreAuthorize):
    • 平台超管:Assert.isTrue(UserContextHolder.isSuperior(), "当前用户无操作权限"),注意字段拼写就是 supeiror(历史笔误,勿"修复")
    • 机构管理员:UserContextHolder.isAdministrator();平台机构:checkPlatformOrg()
  5. Controller:返回一律 AlitaResult<T>(AlitaResult.success(data));@Api(tags=...) + @ApiOperation;分页接口返回 AlitaResult<Page<T>>,模式:Service 把 queryDTO 传给 mapper 即自动分页,Controller 返回 queryDTO.getPageResult()。查询类用 GET + query 参数绑定,操作类用 POST + @Validated @RequestBody。
  6. URL 前缀有语义:anon/** 匿名(清单在配置 security.anonymous)、unac/** 已登录未激活可用、authed/** 已实名;普通前缀 = 登录即可。

关键业务概念

  • 用户(uc_user):status 1待激活/2已激活/3已注销 + enabled 启用开关 + 逻辑删除 deleted,三者独立。登录侧实时校验 enabled=TRUE and status!=3,禁用/注销后用户下次请求即失效。注销有两套:自助申请流(UserCancelService,uc_user_cancel 表)与管理员直接注销(user/admin_cancel)。同一手机号可对应多个账号(企业+个人)。
  • 机构:xs_org(parent_id 树)+ uc_org_user 中间表(含 administrator 标志,一个用户可在多个机构,登录时选定 orgId)。用户表没有 org_id。平台机构固定 orgId=1(CommonConstants.PLATFORM_ORG_ID)。
  • 文件记录(x_user_file):上传/发送/接收/分享全在这一张表,靠 root_type 区分:1普通(上传)、2内穿外、3外传内、4我的分享;file_status:1正常/2失效/11解析中/12待审核/13传输中/14失败。表里只有 user_id,无手机号,按手机号查需 JOIN uc_user.phone。
  • 传输方向映射(file.transfer.location:1内网/2外网):发送记录 = 内网端 rootType 2 / 外网端 rootType 3;接收记录取反。手机号只在传输 ZIP 包内 transferMetadata.json,接收端解包时靠它反查本地用户。

陷阱清单

  • 只能写 Java 8 语法(无 var/Set.of/record/switch 表达式;集合用 guava Sets.newHashSet 等也行)。
  • SQL 要兼容 DM8:布尔字面量用 TRUE/FALSE(bit 列),时间用 now();避免 MySQL 专属函数;分页依赖拦截器,XML 里不要手写 limit。
  • XML 放错位置不会被打包——必须放 java 源码目录(与现有 UserMapper.xml、UserFileMapper.xml 同级模式)。
  • 驼峰映射由 MyBatis-Plus 默认开启,XML 直接 SELECT u.real_name 即可映射 realName;列别名规避同名冲突(如 u.type AS user_type)。
  • 注销/禁用等敏感操作要防并发:参考 userCancel 的 RedissonUtils.tryLockAutomatically(LockDTO...) + @AutoUnLock 模式;禁止注销/禁用自己与超管。
  • 数据库初始化脚本在 db/(init-table.sql MySQL 版、init-table-postgres-full.sql PG 版),改表结构需同步两个版本;增量变更另建 db/upgrade-YYYYMMDD-*.sql(现有:upgrade-20260914-upload-config.sql),历史上有过 DDL 只加脚本、不改 init 的情况,新环境安装依赖 init 脚本,改表务必 init 与 upgrade 双写。
  • 给前端的接口变更请同步维护 docs/ 下的接口文档(现有:接口文档-用户管理与记录查询.md、接口文档-机构上传配置.md)。
  • .commandcode/ 为本地工具产物,勿提交。