包含 s-file 后端、React 前端、MeshSafe 安全检测对接,以及内外网两套 compose/nginx/配置(仅前端 28180/28280 对外发布,其余端口不暴露)。 说明:deploy/config/application-iw.yml 与 application-ow.yml 按维护者 明确要求原样入库,其中含本机 Docker 用的库口令、RabbitMQ 口令与 JWT 密钥;上生产前需替换。
7.4 KiB
7.4 KiB
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),改动前先确认是否为刻意覆写,不要删除。
新增一个接口的标准动作
- DTO:查询 DTO 继承
PageQueryDTO<XxxDTO>(自带 pageNo/pageSize/needPage/pageResult);出参 DTO 继承BaseDTO(用@SuperBuilder);时间字段统一Date+@DateTimeFormat+@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss", timezone="GMT+8")。 - Entity:继承
BaseEntity(带机构的继承OrgBaseEntity),@TableName注解,逻辑删除字段deleted。 - Mapper:接口继承
MyMapper<T>(已有saveEntity/updateEntitySelective/getById/deleteEntity,自动填充 createBy/updateBy),放**/dao/;自定义 SQL 的 XML 放同名 java 源码目录的mapper/下(pom 已配置打包 java 目录下**/*.xml),XML 中参数一律@Param("param")+param.xxx引用。 - Service:接口 +
impl。权限校验用命令式断言(项目无 @PreAuthorize):- 平台超管:
Assert.isTrue(UserContextHolder.isSuperior(), "当前用户无操作权限"),注意字段拼写就是supeiror(历史笔误,勿"修复") - 机构管理员:
UserContextHolder.isAdministrator();平台机构:checkPlatformOrg()
- 平台超管:
- Controller:返回一律
AlitaResult<T>(AlitaResult.success(data));@Api(tags=...)+@ApiOperation;分页接口返回AlitaResult<Page<T>>,模式:Service 把 queryDTO 传给 mapper 即自动分页,Controller 返回queryDTO.getPageResult()。查询类用 GET + query 参数绑定,操作类用 POST +@Validated @RequestBody。 - URL 前缀有语义:
anon/**匿名(清单在配置security.anonymous)、unac/**已登录未激活可用、authed/**已实名;普通前缀 = 登录即可。
关键业务概念
- 用户(
uc_user):status1待激活/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,无手机号,按手机号查需 JOINuc_user.phone。 - 传输方向映射(
file.transfer.location:1内网/2外网):发送记录 = 内网端 rootType 2 / 外网端 rootType 3;接收记录取反。手机号只在传输 ZIP 包内transferMetadata.json,接收端解包时靠它反查本地用户。
陷阱清单
- 只能写 Java 8 语法(无
var/Set.of/record/switch 表达式;集合用 guavaSets.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.sqlMySQL 版、init-table-postgres-full.sqlPG 版),改表结构需同步两个版本;增量变更另建db/upgrade-YYYYMMDD-*.sql(现有:upgrade-20260914-upload-config.sql),历史上有过 DDL 只加脚本、不改 init 的情况,新环境安装依赖 init 脚本,改表务必 init 与 upgrade 双写。 - 给前端的接口变更请同步维护
docs/下的接口文档(现有:接口文档-用户管理与记录查询.md、接口文档-机构上传配置.md)。 .commandcode/为本地工具产物,勿提交。