Asone 开发者文档Asone 开发者文档
  • 项目架构
  • 技术栈
  • 目录结构
  • 本地启动
  • 新增功能
  • 开发规范
  • 数据库
  • 图表语法
  • 部署
  • 文档同步规则
  • 相关文档
  • 项目架构
  • 技术栈
  • 目录结构
  • 本地启动
  • 新增功能
  • 开发规范
  • 数据库
  • 图表语法
  • 部署
  • 文档同步规则
  • 相关文档
  • 项目架构

项目架构

Asone 是面向广告投放与渠道运营的一体化后台系统,由一个 Spring Boot 单体多模块后端、一个 UmiJS Max 前端、一个 XXL-JOB 调度中心组成,整体以 Docker 镜像交付,由 Nginx / OpenResty 统一反向代理。

整体拓扑

图 1 · 请求入口与依赖的中间件

业务容器只绑定 127.0.0.1,不直接对外暴露端口;对外访问统一经过 OpenResty 的站点配置与证书。

运行时按层次自上而下依赖:

  1. 1使用者运营与管理员浏览器、开放 API 调用方
  2. 2接入层OpenResty 反向代理、HTTPS 证书、前端静态资源
  3. 3接口层asone-front 页面与后端 /api 控制器
  4. 4领域层advertisement · channel-report · iaa 业务模块
  5. 5内核层asone-server-system:鉴权、审批、通知、导出、通用配置
  6. 6基础设施MySQL、Redis、OSS、SMTP、XXL-JOB、渠道开放 API
图 2 · 运行时分层

后端:单体多模块

后端是一个进程、多个 Maven 模块。除 asone-server-boot 外,其它模块都不是可独立部署的服务。

模块根包职责
asone-server-systemcom.qianxunclub.asone共享内核:登录鉴权、管理员 / 角色 / 菜单、审批、通知、导出、文件、系统配置、操作日志、第三方身份登录;同时提供全局配置与通用工具
asone-module-advertisementcom.qianxunclub.asone.advertisement广告主、渠道、产品、广告计划、点击日志、数据报表等广告投放分析能力
asone-module-channel-reportcom.qianxunclub.asone.channelreport各渠道(Ad Manager、IDG、Adsentri、Alldata、泽耀等)日报 / 国家 / 单元 / 明细报表同步与查询
asone-module-iaacom.qianxunclub.asone.iaaIAA 客户、产品、ROAS 等变现数据分析
asone-server-bootcom.qianxunclub.asone唯一启动模块:启动类 AsoneServerApplication、全局 application.yml、logback.xml

依赖方向:

图 3 · Maven 模块依赖(业务模块之间不互相依赖)

三条硬约束:

  • 业务模块之间不互相依赖,需要跨域复用的能力一律下沉到 asone-server-system。
  • 新模块必须同时登记到父 POM 的 <modules> 与 <dependencyManagement>,并由 asone-server-boot 显式依赖,否则不会被启动。
  • 每个模块自带 application-<模块后缀>.yml,通过 asone-server-boot/src/main/resources/application.yml 的 spring.profiles.include 装配(当前为 system、channel-report)。

请求处理链路

一次前端请求在后端的流转路径固定,新增接口不需要自己写包装与异常处理:

图 4 · 一次 /api 请求在后端的流转

要点:

  • GlobalResponseBodyAdvice 会把业务对象包成 Result;已是 Result 的返回值原样透传,两种写法都能工作,新接口优先直接返回业务对象。/v3/api-docs、/swagger-ui、/actuator、SSE、StreamingResponseBody 一律透传不包装。
  • 错误码集中在 asone-server-system 的 constants/ResponseCodeEnum,业务异常抛 configuration/BizException,不要在 Controller 里自己拼错误响应。
  • 写操作统一加 @OperationLog(summaryTemplate 用 SpEL 生成可读日志);需要被 API Key 调用的接口显式加 @ApiKeyAllowed。

鉴权与授权模型

图 5 · 认证与授权两段判定
  • 认证:Spring Security SecurityFilterChain(@EnableWebSecurity + @EnableMethodSecurity),JWT 使用 HS512 多 kid 密钥集,口令散列走 DelegatingPasswordEncoder("bcrypt")(cost 12)。
  • 授权:接口侧用 hasAuthority('资源:动作'),读用 xxx:read,写用 xxx:manage 并叠加 @authenticationType.isSession(authentication),把写操作限制在真人会话内。
  • 资源与菜单:system_resource 表驱动,role_scope 决定该资源可否分配给普通角色(BUSINESS 可分配,SYSTEM 仅系统 / 超级管理员),沿菜单层级向下继承。
  • 第三方身份登录(飞书 / 钉钉 / 企业微信 / OIDC / SAML)在 asone-server-system 的 identity 包,配置方法见平台文档站的《第三方账号登录》。

数据访问

  • MyBatis-Plus 3.5(mybatis-plus-spring-boot4-starter + mybatis-plus-jsqlparser),依赖版本由父 POM import 的 mybatis-plus-bom 统一管理。
  • Mapper 接口逐个标注 @Mapper(项目不使用 @MapperScan),extends BaseMapper<T>;Service 继承 MyBatis-Plus 的 ServiceImpl<M, E>。
  • XML 放各模块 src/main/resources/mapper/,由 starter 默认扫描,YAML 中没有覆盖 mapper-locations。
  • 分页统一用 Page / IPage,插件配置在 asone-server-system/.../configuration/MybatisPlusConfiguration.java:PaginationInnerInterceptor(DbType.MYSQL) + BlockAttackInnerInterceptor(拦截无 where 的全表更新删除)。
  • 连接池 Druid;SQL 日志本地通过 p6spy 开关控制(decorator.datasource.p6spy.enable-logging)。
  • 没有自动迁移工具:表结构唯一来源是开发者文档站随附的 全量 DDL,由人工执行,详见数据库。

异步与调度

图 6 · 定时任务的注册与触发
  • Tomcat / MVC 运行在虚拟线程上(spring.threads.virtual.enabled=true),异步请求不超时(spring.mvc.async.request-timeout=-1),由各自的 SseEmitter 控制生命周期。
  • 定时任务全部走 XXL-JOB:执行器由 XxlJobExecutorConfiguration 按 xxl.job.executor.enabled 条件装配,@XxlJob handler 放在业务模块的 task/ 包,任务参数通过 XxlJobHelper.getJobParam() 读取。本地 Profile 默认关闭执行器注册。
  • 大批量导出走异步导出任务:业务模块实现 ExportTaskHandler,由 asone-server-system 的 ExportTaskScheduler 驱动,前端通过全局 Model 轮询进度。状态流转见图表语法的导出任务示例。

前端架构

图 7 · 页面一次数据加载的落位链路
  • 框架:UmiJS Max(@umijs/max 4.7)+ React 19 + antd 6 + ProComponents,构建已启用 utoopack。
  • 路由:配置式,config/routes.ts 汇总展开 config/routes/{advRoutes,iaaRoutes,systemRoutes,channelReportRoutes,approvalRoutes}.ts,按业务域一个文件。
  • 菜单与权限:菜单可见性由后台「菜单管理」中的资源记录决定(path 必须与路由一致),路由过滤走 src/access.ts 的 normalRouteFilter,按钮级判断走 hasPermission / hasAnyPermission。
  • 接口层:src/services/asone-server/<域>/<controller>.ts,由 pnpm openapi 从后端 /v3/api-docs/asone-server 生成;页面只调用 service 函数,不直接发请求。
  • 全局约定:src/globalRequestConfig.ts 处理 ResponseStructure {success, code, message, data}、登录失效跳转、限流验证码与 X-Locale 请求头;src/app.tsx 提供 getInitialState(当前管理员、菜单与权限集合)。
  • 国际化:src/locales/{zh-CN,en-US},新增页面必须两侧同时补文案,pnpm i18n-check 校验缺失。

多环境与配置装配

文件作用
asone-server-boot/src/main/resources/application.yml端口 8001、profiles.include、虚拟线程、优雅停机、i18n basename、数据源 / Redis / 邮件、xxl.job.*、actuator
asone-server-boot/src/main/resources/application-local.yml本地覆盖:立即停机、本地 MySQL、开启 p6spy SQL 日志、关闭 Sentry、关闭执行器注册
asone-server-system/src/main/resources/application-system.ymlsecurity.permit-all-paths 等系统域配置
asone-module-channel-report/src/main/resources/application-channel-report.ymlchannel-api.request-interval-millis 与各渠道 *-report.* 配置
asone-front/config/config.ts + config/proxy.ts前端构建与插件配置,按 UMI_ENV 选择代理

生产环境以 SPRING_PROFILES_ACTIVE=production 由镜像注入,密钥类配置应通过环境变量或部署平台外部配置提供,不落仓库。

下一步

  • 具体版本与依赖清单见技术栈
  • 每个目录放什么见目录结构
  • 动手改代码见新增功能