外观
系统设计
架构、部署、角色体系、技术选型 + 文档索引
目录
1. 系统概述
CodeNote 是一个二维码管理与场景化服务平台,采用三端分离架构,支持离线优先的移动端体验、强大的后端 API 服务以及完善的管理后台。
1.1 项目组成总览
| 端 | 仓库 | 文档 |
|---|---|---|
| Server | gitee.com/7688/codenote-server (exp) | ./README.md · /reference/backend.md · /architecture/data-model.md |
| Admin | gitee.com/7688/codenote-admin (exp) | ./README.md · /reference/admin.md |
| Android | gitee.com/7688/codenote-android (exp) | ./README.md · /reference/android.md |
| 官网 | gitee.com/7688/la998 (master) | index.html(CodeNote 项目介绍页,部署 la998.com) |
| 知识库 | gitee.com/7688/codenote-docs (main) | VitePress 静态站,部署 blog.la998.com,聚合全部文档 |
2. 部署架构
2.1 整体架构图
用户 ─→ NPM (Nginx Proxy Manager, 80/443)
│
├── codenote.la998.com ──→ codenote-admin:80 (nginx 容器)
│ │
│ └── /api/ ──→ codenote-server:8080
│
└── api.la998.com ────────→ codenote-server:8080
│
└── MySQL (本地容器, 3306)2.2 服务器环境
| 项目 | 配置 |
|---|---|
| 部署环境 | 阿里云服务器(Alibaba Cloud Linux),容器化部署 |
| Docker 网络 | web_network(自定义网络,容器间通过名称解析) |
| 工作目录 | 服务器 /data/www/ 下各项目独立目录 |
| 域名配置 | codenote.la998.com(管理后台)api.la998.com(API 服务) |
| NPM 管理 | 81 端口 (npm.la998.com) |
2.3 容器部署
| 容器名称 | 镜像来源 | 端口 | 说明 |
|---|---|---|---|
| codenote-server | registry.cn-guangzhou.aliyuncs.com/codenote/codenote-server | 8080 | Spring Boot 应用,提供 REST API |
| codenote-admin | 静态文件(Git 拉取 dist) | 80 | Nginx 托管 Vue 前端,反向代理 /api/ 到后端 |
| mysql | MySQL 8.0 | 3306 | 数据库服务,本地容器部署 |
2.4 部署流程
后端部署:
- 本地构建 jar 或 Docker 镜像
- 推送到阿里云容器镜像服务
- 服务器执行
deploy.sh拉取镜像并重启容器 - 健康检查验证服务状态
前端部署:
- 本地执行
pnpm build构建 dist - Git 提交并推送到 Gitee
- 服务器执行
git pull拉取最新静态文件 - NPM 自动生效(无需重启)
Android 端:
- 直接安装 APK,配置 API 地址为
https://api.la998.com - 支持热更新(通过应用内下载新版本)
2.5 技术栈
| 组件 | 技术选型 | 说明 |
|---|---|---|
| Android SDK | 阿里云OSS SDK 2.9.18 | 客户端直传OSS |
| 服务端SDK | 阿里云STS SDK 1.1.6 | 生成临时凭证 |
| 数据库 | MySQL files 表 | 记录文件元数据 |
| 认证方式 | STS临时凭证 | 15分钟有效期,AK/SK 不暴露 |
| 图片压缩 | ImageCompressor | 智能压缩,95% 压缩率 |
3. 用户角色体系
RBAC 化(v3.3 定稿,实施完成):角色体系已重构为通用三域 RBAC(PLATFORM/APP/ORG)。
users.role/org_members.role列已删除,权限判定统一走rbac_user_roles+@RequirePermission切面。以下为 RBAC 落地后的角色语义。
CodeNote 采用多层次的角色权限体系,不同端支持不同的角色类型和权限范围。
3.1 三域 RBAC 概览
| 权限域 | 服务对象 | 角色管理方 | 预置角色 |
|---|---|---|---|
PLATFORM | 管理后台 | 系统管理员(后台可完全控制) | SYSTEM_ADMIN / USER_ADMIN / ORG_ADMIN(可自定义) |
APP | Android App 用户 | 系统管理员(后台定义) | USER(=全部 APP 权限点,行为不变) |
ORG | 组织成员(scope=orgId) | 组织拥有者 | OWNER / ADMIN / MEMBER(可自定义) |
判定机制:JwtAuthFilter 注入 PLATFORM 域角色 → PermissionAspect 解析 @RequirePermission(域/scope/短路)→ RbacService.hasPermission(角色权限并集 + 例外授权,Caffeine 60s 缓存)。短路:ORG OWNER / PLATFORM SYSTEM_ADMIN 放行。
3.2 角色语义(RBAC 后)
| 角色 | 域 | 说明 |
|---|---|---|
| SYSTEM_ADMIN | PLATFORM | 平台全部权限(短路);初始 admin 绑定不可撤销(§1.1#6) |
| USER_ADMIN / ORG_ADMIN | PLATFORM | 用户管理 / 组织管理相关权限(预置默认,后台可调整) |
| USER | APP | 默认角色 = 全部个人功能(决策 #1 行为不变);新注册用户自动绑定 |
| OWNER | ORG | 组织内全部权限(短路);创建组织自动绑定;转让后旧 OWNER 降为 ADMIN(§1.2.2) |
| ADMIN | ORG | 成员/资源管理,不可解散/转让;rbac_user_role 不可操作 OWNER 角色(防自提权) |
| MEMBER | ORG | 组织资源只读(资产/活动/qrcode/album 副本)+ 参与类(checkin:create、share:create、pass:read) |
权限控制机制(RBAC 后):
- JWT Token 携带用户 ID(不再写 role claim);角色每次请求从 RBAC 读取(缓存)
- Controller 逐方法
@RequirePermission(domain, resource, action, orgIdParam, fallbackDomain) - 双域资源接口(asset/activity/qrcode/album):orgId 为空降级 APP 域,不回退 current_org_id(§6.1)
- 组织资源属主语义(决策 B):组织内资源由组织角色管理(ADMIN/自定义角色可管理组织内全部资源);个人资源(org_id 空)属主私有
- 分享 = 复制副本 + 组织接管(qr/album 副本归组织,§1.2.9)
3.3 组织角色明细(ORG 域预置矩阵)
| 权限 | OWNER | ADMIN | MEMBER |
|---|---|---|---|
| 全部权限(短路) | ✅ | ||
| org:read / member:read / asset:read / activity:read / qrcode:read / album:read / share:read | ✅ | ✅ | ✅ |
| org:update / member:invite·update_role·remove·approve / asset:写 / activity:写 / qrcode:写 / album:upload·delete / share:delete / notification:send | ✅ | ✅ | ✗ 只读 |
| checkin:create(参与语义,成员即可)/ share:create | ✅ | ✅ | ✅ |
| pass:issue·verify·revoke | ✅ | ✅ | 仅活动创建者豁免(Service 属主判定) |
| org:transfer·dissolve·regenerate_code / rbac_role:*(自定义角色管理) | ✅ | ✗ | ✗ |
| rbac_user_role:grant·revoke | ✅ | ✅(不可操作 OWNER 角色) | ✗ |
3.4 管理后台(PLATFORM 域)
管理后台登录校验「PLATFORM 域存在任一角色」;端点权限按权限点(user:read / org:manage_member / rbac_role:* 等)逐方法控制。后台「权限管理」三页:权限点管理(无物理删除,停用代替删除)、平台角色管理(PLATFORM/APP 域 CRUD + 权限勾选)、用户授权(rbac_user_role)。
3.4b 通用动态数据模型(meta_*)
元数据驱动四层:业务对象 → 字段 → 模板 → 值。新业务只注册
meta_objects,三端配置驱动渲染,零新增表结构。表结构详见/architecture/data-model.md,接口详见/reference/api.mdA21 节。
谁管理什么(meta_ 权限点)*:
| 角色 | 可管理内容 | 权限点 |
|---|---|---|
| 平台 SYSTEM_ADMIN | 一切(含对象注册 meta_object:*) | PLATFORM 域 meta_* 全部 |
| 平台 BUSINESS_ADMIN | GLOBAL 字段/模板/绑定读写(不含对象注册) | PLATFORM 域 meta_field/meta_template/meta_binding |
| 组织 owner/admin(复用 ORG 域角色) | 本组织 ORG 字段库、ORG 模板(可 fork 全局)、本组织分类绑定 | ORG 域 meta_field/meta_template/meta_binding |
| 组织 MEMBER | 只读使用,不可改模板 | —(MEMBER 白名单不含 meta_*) |
| 普通用户(APP 域) | 个人 USER 级字段/模板/个人分类绑定 | APP 域 meta_field/meta_template/meta_binding |
可见性合并(App 端取字段):可见字段 = 对象默认模板字段(GLOBAL) ∪ 实体绑定模板字段 ∪ 归属组织的 ORG 字段(绑定过的) ∪ 有值的字段;软删字段过滤;按绑定顺序 + 模板内 sort_order 排序,field_id 去重。
混合存储(单一写路径):8 个高频字段(品牌/型号/序列号/购买日期/购买价格/供应商/保修到期日/备注)升为 assets 固定列,定义仍在 meta_fields(entity_column 映射),值读写统一走 PUT /api/meta/.../values 由 MetaValueService 转写;扩展字段走 meta_values(EAV + value_num/value_date 冗余列)。
3.5 Android 端(移动 App)
Android 端面向普通用户(USER 角色)和组织成员,提供完整的业务功能。
| 角色场景 | 说明 | 可用功能 |
|---|---|---|
| 组织 OWNER | 创建或接管组织的用户 | 可管理组织成员、共享资源、转移所有权、解散组织 |
| 组织 ADMIN | 被提升为管理员的用户 | 可管理组织成员和资源,但不可解散组织 |
| 组织 MEMBER | 普通成员 | 使用组织共享资源 |
| 个人用户 | 未加入组织的独立用户 | 所有个人业务功能 |
权限特点:
- 支持多组织切换:用户可在头像下拉菜单中切换当前活跃组织
- 离线优先:所有核心功能完全离线可用,联网后自动同步
- 扫码智能路由:根据二维码类型自动跳转到对应业务模块
- 数据隔离:只显示当前用户有权限访问的个人数据和组织共享数据
客户端按钮显隐映射(实施):
Android 端各页面操作按钮按 ORG 域权限点显隐——无权限不显示,不再提交后才报错。统一入口
OrgRepository.getOrgPermissions(orgId)(内部复用 GET /orgs/{id} 的 permissions 字段),权限常量集中在OrgPerms。个人场景(无 orgId / orgId=-1)不限制;后端@RequirePermission仍为最终校验。
| 页面 | 按钮/操作 | 权限点 |
|---|---|---|
| 组织成员 | 升降级 / 移除成员 | member:update_role / member:remove |
| 邀请记录 | 撤回邀请 | invitation:cancel |
| 角色权限 | 创建/编辑/删除角色 | rbac_role:create / update / delete |
| 组织资产 | 新增 / 分类管理入口 | asset:create / asset_category:read |
| 资产详情 | 编辑/流转/报废/删除/盘点 | asset:update / transfer / scrap / delete / inventory |
| 资产编辑 | 删除 | asset:delete |
| 资产盘点 | 新建盘点任务 | asset:inventory |
| 资产分类管理 | 添加/编辑/删除/排序/置顶/长按选择 | asset_category:create / update / delete / reorder / pin |
| 位置管理 | 添加/编辑/删除/排序/置顶/长按选择 | location:create / update / delete / reorder / pin |
| 组织模板 | 新建/复制/编辑/删除模板 | meta_template:create / update / delete |
| 组织活动 | 「组织活动」tab(仅 OWNER/ADMIN 可见「发起活动」) | activity:create |
| 活动编辑 | 删除 | activity:delete |
| 活动可见性 | 公开/组织内部/仅邀请(创建/编辑页选择,个人禁组织内部) | §可见性架构 |
| 组织可见性 | 公开/内部(创建/设置页,INTERNAL 锁定 joinPolicy=INVITE) | §可见性架构 |
| 发现页 | 底部 tab:公开活动/公开组织;非成员点公开组织 → OrgPreview 申请加入(apply) | 无需权限(PUBLIC 资源) |
| 通行证 | 签发 / 核验 | pass:issue / pass:verify |
| 组织分享 | 取消共享 | share:delete |
注:二维码域(列表/详情/批量/分类)为个人功能,无组织权限控制;组织内二维码副本在组织分享页管理(share:delete 已控)。签到(checkin:create)为参与语义,MEMBER 默认拥有,不做显隐控制。
3.4 权限继承关系
- 用户可以同时属于多个组织,在不同组织中可以拥有不同角色
- 组织管理员(ADMIN)拥有所有组织的查看权限,但需要加入组织才能进行操作
- 组织 OWNER 可以转移所有权给其他成员,转移后原 OWNER 降级为 MEMBER
典型应用场景:
| 场景 | 说明 |
|---|---|
| 设备身份 | 用户主动选择设备登录(免注册)时自动注册账号(DEVICE identity),与手机/邮箱登录平级;一账号可绑多设备;首次进入显示登录页,不自动注册 |
| 个人用户 | 绑定账户后的正式用户,可使用所有个人业务功能(二维码、扫码、资源等) |
| 系统管理员 | 全局监控系统运行状态、审计用户行为、配置系统参数 |
3.5 各角色可用功能明细
| 功能模块 | 个人用户 | 组织 MEMBER | 组织 ADMIN | 组织 OWNER | 系统管理员 | 未登录 GUEST |
|---|---|---|---|---|---|---|
| 二维码管理 | ✓ | ✓ | ✓ | ✓ | ✓ | - |
| 扫码功能 | ✓ | ✓ | ✓ | ✓ | ✓ | - |
| 资源管理 | ✓ | ✓ | ✓ | ✓ | ✓ | 仅查看公开 |
| 活动管理 | ✓ | ✓ | ✓ | ✓ | ✓ | 仅查看公开 |
| 签到系统 | ✓ | ✓ | ✓ | ✓ | ✓ | 仅查看公开 |
| 通行证系统 | ✓ | ✓ | ✓ | ✓ | ✓ | 仅查看公开 |
| 联系人聊天 | ✓ | ✓ | ✓ | ✓ | - | - |
| 组织信息查看 | - | ✓(部分) | ✓ | ✓ | ✓ | - |
| 组织资源管理 | - | - | ✓ | ✓ | ✓(需入组织) | - |
| 组织成员管理 | - | - | ✓ | ✓ | ✓(需入组织) | - |
| 转移所有权 | - | - | - | ✓ | - | - |
| 解散组织 | - | - | - | ✓ | - | - |
| 全局数据查看 | - | - | - | - | ✓ | - |
| 管理后台登录 | - | - | - | - | ✓ | - |
图例: ✓ = 完全可用 · ✓(部分)= 部分可见/受限访问 · - = 不可用
注意事项:
- 用户可以同时拥有多个角色身份
- 权限遵循最小权限原则,用户只能访问其有权限的资源
- 离线状态下,用户仍可操作本地数据,联网后自动同步到服务端并进行权限验证
- 所有敏感操作(删除、转移所有权、解散组织等)都需要二次确认
4. 环境与部署信息
4.1 环境要求
| 端 | 要求 |
|---|---|
| Server | JDK 17+, MySQL 8.0, Gradle 8.x |
| Admin | Node.js 18+, pnpm 8+ |
| Android | Android Studio Hedgehog+, JDK 17+, Android SDK 26+, Gradle 8.x |
4.2 NPM 反向代理配置
登录 https://npm.la998.com 配置:
api.la998.com→ codenote-server:8080,Advanced 添加 WebSocket 支持:location /ws/ { proxy_pass http://codenote-server:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; }codenote.la998.com→ codenote-admin:80
4.3 快速开始
bash
# Server
cd codenote-server && ./gradlew bootRun
# Admin
cd codenote-admin && pnpm install && pnpm dev
# Android
# Android Studio 打开 codenote-android/,等待 Gradle sync5. 文档索引
每次 session 初始仅加载:/architecture/overview.md + /standards/index.md。其他文档按需读取。
| 文档 | 大小 | 加载策略 | 说明 |
|---|---|---|---|
/architecture/overview.md | ~9KB | 初始 | 架构、部署、角色 |
/standards/index.md | ~3KB | 初始 | 跨端硬性规则 |
/reference/backend.md | ~12KB | 按需 | 后端模块+Service清单 |
/reference/api.md | ~25KB | 按需 | 所有 REST API 端点 |
/reference/android.md | ~37KB | 按需 | Android 页面+组件 |
/reference/admin.md | ~15KB | 按需 | Admin 页面路由 |
/designs/auth/user-state.md | ~44KB | 按需 | Session/Token 完整设计 |
/designs/activity.md | ~13KB | 按需 | 活动/签到/通行证 |
/designs/messaging/contacts-chat.md | ~18KB | 按需 | 通讯录/单聊/多类型消息/WS 实时(一期方案) |
/designs/camera/scan-flow.md | ~12KB | 按需 | 扫码全流程 |
/designs/camera/watermark-flow.md | ~9KB | 按需 | 水印拍照流程 |
/designs/camera/memory.md | ~7KB | 按需 | 相机记忆 JSON 持久化 |
/reference/app-update.md | ~11KB | 按需 | 版本发布 |
/architecture/data-model.md | ~42KB | 按需 | 所有 MySQL+Room 表定义 |
/standards/android-coding.md | ~22KB | 按需 | Android 编码+UI 规范 |
/standards/qr-display.md | ~2KB | 按需 | 二维码渲染一致 |
/standards/location.md | ~8KB | 按需 | GPS 定位模型 |
/standards/camera.md | ~17KB | 按需 | 相机架构与分层 |
附录:账户模型与认证体系
账户模型(身份分离后)
| 认证方式 | 存储 | 设置入口 | 解绑入口 |
|---|---|---|---|
| 用户名+密码 | users.username + password | set-username / password/set(两步独立) | —(不可解绑,登出即退出) |
| 邮箱 | user_identities(EMAIL) | email-bind | email/unbind |
| 手机 | user_identities(PHONE) | phone-bind / verify-mobile | phone/unbind |
| 设备 | user_identities(DEVICE,可多条) | device-login 自动登记 / 凭据登录自动登记 | devices/{deviceId} 移除 |
- 用户名不可修改(set-username / updateProfile / admin 编辑全链路封禁)
- 换绑 = 删旧插新,仅校验新凭证未被他人占用
- 验证码注册用户不再自动生成 user_xxx 用户名,自动生成昵称
- 绑定 = 给当前账号追加身份;
hasRecoverableCredential = password 非空 ‖ 有 PHONE/EMAIL identity,false 时驱动设备丢失/更换提醒 - 个性签名:users.signature VARCHAR(200),≤100 字符,updateProfile 写入,用户中心/管理后台展示
- 昵称可修改:updateProfile 支持 nickname(≤50 字符,null 不改,空串清空);用户中心编辑资料页新增昵称输入,头像/昵称/个性签名统一入口
昵称机制
nickname字段全端显示默认用它;username 仅内部逻辑可见- 生成:NicknameService 词库随机组合(nickname_adjectives + nickname_nouns 各 100 条,admin 可管理);空词库降级「用户+6位随机」
- 用户可自行修改昵称:编辑资料页输入,≤50 字符,空串清空
- 资源 assignee 快照存 nickname(assets.assignee_name)
密码体系
- 忘记密码(公开):/api/auth/password/forgot-code + /reset,凭证须已注册,限频防轰炸
- 修改密码(登录态):/api/auth/password/change-code + /change,原密码/手机码/邮箱码三选一
- 改密/重置成功后 tokenVersion+1,全部旧 token 失效重新登录(JwtAuthFilter 已校验)