# X-Swap **Repository Path**: lancemorii-git/x-swap ## Basic Information - **Project Name**: X-Swap - **Description**: X-Swap 是一个面向高校场景的多租户校园二手交易 SaaS 平台,支持学校级租户隔离、角色权限控制、商品发布审核、线下预约交易、信用评价与举报治理。后端基于 Spring Boot + Sa-Token,前端支持 Web 管理端与 uni-app 用户端,开箱即用,支持多学校快速部署。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-02-10 - **Last Updated**: 2026-03-08 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 

CampusSwap SaaS

多租户校园二手交易平台

一套系统服务多个大学,支持 Web 管理端 + 用户端(H5 / 微信小程序)
纯线下交易为核心,构建完整的校园二手交易闭环

快速启动技术栈架构演示API

Java 17+ Spring Boot 3.2 Vue 3 uni-app MIT License

--- ## 项目亮点 | 特性 | 说明 | |:---:|:---| | **多租户 SaaS** | 一套部署服务多所大学,共享库共享表 + tenant_id 隔离 | | **纯线下交易** | 系统负责撮合、预约、状态流转、评价、举报,不接入支付 | | **三端覆盖** | 管理端 Web + 用户端 H5 + 微信小程序 | | **安全优先** | 鉴权、多租户隔离、审计日志、限流、输入校验全部落地 | --- ## 系统架构 ``` ┌─────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ admin-web │ │ client-app │ │ client-app │ │ Vue3+ElementPlus│ │ uni-app H5 │ │ uni-app 微信小程序 │ └────────┬────────┘ └────────┬─────────┘ └────────┬─────────┘ └────────────────────┼─────────────────────┘ ▼ ┌──────────────────────────┐ │ Spring Boot 3.2 + Sa-Token │ │ MyBatis-Plus 多租户拦截 │ └──────────┬───────────────┘ ┌──────┴──────┐ ▼ ▼ MySQL 8.0 Redis 7 │ ▼ ┌─────────────────────┐ │ 文件存储(可选) │ │ Local/MinIO/OSS/COS │ └─────────────────────┘ ``` --- ## 技术栈
**后端技术** - Java 17 + Spring Boot 3.2.5 - Sa-Token 1.38(Redis 会话) - MyBatis-Plus 3.5.6(多租户拦截) - MySQL 8.0 + Redis 7 - Springdoc OpenAPI 2.5 - Docker Compose **前端技术** - Vue 3 + TypeScript + Element Plus - uni-app(Vue 3)→ H5 + 小程序 - Pinia 状态管理 - Vue Router
**文件存储**:本地 / MinIO / 阿里云 OSS / 腾讯云 COS(策略模式,配置切换) --- ## 多租户设计 ``` ┌─────────────────────────────────────────────────────────────┐ │ 共享数据库 │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ 清华大学 │ │ 北京大学 │ │ 复旦大学 │ │ ... │ │ │ │tenant=1 │ │tenant=2 │ │tenant=3 │ │ │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ │ 数据完全隔离 │ └─────────────────────────────────────────────────────────────┘ ``` - **隔离方式**:共享数据库共享表,所有核心业务表包含 `tenant_id` 字段 - **租户识别**:登录时通过 `tenantCode` 确定租户,登录后 tenantId 存入 Sa-Token Session - **自动过滤**:MyBatis-Plus `TenantLineInnerInterceptor` 自动为所有 SQL 追加 `tenant_id` 条件 - **安全原则**:租户信息仅从 Session 获取,禁止从 URL/请求参数传入 ### 角色体系 | 角色 | 说明 | 接口前缀 | |:---:|:---|:---| | SUPER_ADMIN | 平台超管,管理所有租户 | `/api/platform/**` | | TENANT_ADMIN | 学校管理员,管理本校数据 | `/api/admin/**` | | USER | 学生用户 | `/api/app/**` | --- ## 安全设计
鉴权与会话 - Sa-Token 登录体系,`StpUtil.login(userId)` 签发 Token - Token 通过 `Authorization: Bearer ` 传递 - 会话存储于 Redis,支持分布式部署 - Token 有效期 7 天,登出即失效
限流与风控 - **IP 级限流**:登录接口 Redis 滑动窗口限流,防暴力破解 - **用户级限流**:发布商品频率限制,防刷 - 限流触发返回 `429` 错误码,前端友好提示
输入安全 - `@Valid` 统一参数校验(JSR-380) - 排序字段白名单,防 SQL 注入 - 文件上传 MIME 白名单(jpg/png/webp)+ 5MB 大小限制 + 路径穿越防护 - BCrypt 密码加密存储 - 统一返回体,禁止暴露异常堆栈
审计与追踪 - 每个请求生成 `traceId`(MDC),响应头返回 `X-Trace-Id` - 关键业务操作写入 `audit_log`(谁、何时、做了什么、对象、租户) - 安全事件写入 `security_event`(登录失败、限流触发等)
--- ## 交易状态机 ``` ┌──────────────────────────────────────────┐ │ 商品状态流转 │ └──────────────────────────────────────────┘ 发布商品 创建预约单 │ │ ▼ ▼ ┌────────┐ 审核通过 ┌──────────┐ 下单锁定 ┌──────────┐ │PENDING │ ──────────▶ │ APPROVED │ ────────▶ │ RESERVED │ └────────┘ └──────────┘ └──────────┘ │ │ │ │ 审核拒绝 │ 卖家下架 │ 创建订单 ▼ ▼ ▼ ┌────────┐ ┌──────────┐ ┌────────┐ │REJECTED│ │OFF_SHELF │ │ INIT │ ◀─── 订单状态 └────────┘ └──────────┘ └────────┘ │ ┌──────────┴──────────┐ │ │ 双方确认 取消 │ │ ▼ ▼ ┌──────────┐ ┌──────────┐ │CONFIRMED │ │CANCELLED │ └──────────┘ └──────────┘ │ │ 线下完成 商品恢复 APPROVED │ ▼ ┌──────────┐ │COMPLETED │ └──────────┘ │ 评价 │ ▼ ┌──────────┐ │ REVIEWED │ └──────────┘ ``` > **关键安全点**:下单原子锁定、状态变更严格校验、取消自动释放商品、一单一评信用分机制 --- ## 快速启动 ### 前置条件 | 工具 | 版本要求 | |:---:|:---:| | Java | 17+ | | Maven | 3.8+ | | Node.js | 18+ | | Docker | 最新版 | ### 一键启动 ```bash # 1. 克隆项目 git clone https://github.com/your-org/campusswap-saas.git cd campusswap-saas # 2. 启动 MySQL + Redis docker-compose up -d # 3. 启动后端 cd backend && mvn spring-boot:run # 4. 启动管理端 cd admin-web && npm install && npm run dev # 5. 启动用户端 H5 cd client-app && npm install && npm run dev:h5 ```
启动 MinIO(可选) ```bash docker-compose --profile minio up -d ``` MinIO 控制台:http://localhost:9001(minioadmin / minioadmin)
启动微信小程序 ```bash cd client-app npm run dev:mp-weixin ``` 用微信开发者工具打开 `dist/dev/mp-weixin` 目录
### 访问地址 | 服务 | 地址 | |:---:|:---| | Swagger API | http://localhost:8080/swagger-ui.html | | 管理端 | http://localhost:5173 | | 用户端 H5 | http://localhost:3000 | --- ## 演示账号 > 密码均为 `password123` | 角色 | 租户编码 | 用户名 | 说明 | |:---:|:---:|:---:|:---| | 平台超管 | platform | superadmin | 管理所有租户 | | 学校管理员 | demo | demoadmin | 管理 demo 大学 | | 学生用户 | demo | alice | 普通学生 | | 学生用户 | demo | bob | 普通学生 | --- ## 接口文档 ### 接口分区 | 前缀 | 说明 | 权限 | |:---|:---|:---:| | `/api/public/**` | 公开接口(登录、注册、租户列表) | 无需登录 | | `/api/app/**` | 用户端接口(商品、订单、评价、举报) | USER+ | | `/api/admin/**` | 学校管理接口(审核、举报处理、用户管理) | TENANT_ADMIN+ | | `/api/platform/**` | 平台管理接口(租户管理) | SUPER_ADMIN | ### 统一返回体 ```json { "code": 0, "message": "ok", "data": {}, "traceId": "a1b2c3d4", "timestamp": 1700000000000 } ``` ### 错误码速查 | 错误码 | 说明 | | 错误码 | 说明 | |:---:|:---|:---:|:---:|:---| | `0` | 成功 | | `40400` | 资源不存在 | | `40001` | 参数错误 | | `40900` | 状态冲突 | | `40100` | 未登录 / Token 失效 | | `42900` | 限流触发 | | `40300` | 无权限 | | `50000` | 系统错误 | --- ## 项目结构 ``` campusswap-saas/ ├── backend/ # Spring Boot 后端 │ └── src/main/java/com/campusswap/ │ ├── common/ # 通用模块(auth/enums/exception/ratelimit/tenant) │ ├── config/ # 配置(CORS/MyBatis-Plus/Redis/Sa-Token/Swagger) │ ├── controller/ # 控制器(admin/app/platform) │ ├── dto/ # 数据传输对象 │ ├── entity/ # 实体类 │ ├── mapper/ # MyBatis-Plus Mapper │ └── service/ # 业务逻辑 + 存储策略 │ ├── admin-web/ # Vue3 管理端 │ └── src/ │ ├── layout/ # 布局组件 │ ├── router/ # 路由 │ ├── stores/ # Pinia 状态管理 │ └── views/ # 页面组件 │ ├── client-app/ # uni-app 用户端(H5 + 小程序) │ └── src/ │ ├── pages/ # 页面 │ ├── stores/ # Pinia 状态管理 │ └── utils/ # 请求封装 │ ├── sql/ # 数据库脚本 ├── docs/ # 设计文档 ├── docker-compose.yml # Docker 编排 ├── .env.example # 环境变量模板 └── README.md ``` --- ## 环境变量 复制 `.env.example` 为 `.env` 并按需修改:
数据库配置 | 变量 | 默认值 | 说明 | |:---|:---:|:---| | `DB_HOST` | localhost | MySQL 地址 | | `DB_PORT` | 3306 | MySQL 端口 | | `DB_USER` | root | MySQL 用户名 | | `DB_PASS` | root123 | MySQL 密码 | | `REDIS_HOST` | localhost | Redis 地址 | | `REDIS_PORT` | 6379 | Redis 端口 | | `REDIS_PASS` | (空) | Redis 密码 |
存储配置 | 变量 | 默认值 | 说明 | |:---|:---:|:---| | `STORAGE_TYPE` | local | 存储类型:local / minio / aliyun / tencent | | `UPLOAD_PATH` | ./uploads | 本地存储路径 | | `MINIO_ENDPOINT` | http://localhost:9000 | MinIO 地址 | | `MINIO_ACCESS_KEY` | minioadmin | MinIO 访问密钥 | | `MINIO_SECRET_KEY` | minioadmin | MinIO 秘密密钥 | | `MINIO_BUCKET` | campusswap | MinIO 桶名 |
云存储配置 | 变量 | 说明 | |:---|:---| | `ALIYUN_OSS_ENDPOINT` | 阿里云 OSS Endpoint | | `ALIYUN_OSS_ACCESS_KEY_ID` | 阿里云 AccessKeyId | | `ALIYUN_OSS_ACCESS_KEY_SECRET` | 阿里云 AccessKeySecret | | `ALIYUN_OSS_BUCKET` | 阿里云 OSS 桶名 | | `TENCENT_COS_SECRET_ID` | 腾讯云 SecretId | | `TENCENT_COS_SECRET_KEY` | 腾讯云 SecretKey | | `TENCENT_COS_REGION` | 腾讯云 COS 地域 | | `TENCENT_COS_BUCKET` | 腾讯云 COS 桶名 |
--- ## Roadmap ### 已完成 - [x] 多租户数据隔离 - [x] Sa-Token 鉴权与权限 - [x] 商品发布与审核 - [x] 预约单与交易状态机 - [x] 评价与信用分 - [x] 举报与运营处理 - [x] 审计日志与安全事件 - [x] IP / 用户级限流 - [x] 多存储支持(Local / MinIO / 阿里云 OSS / 腾讯云 COS) - [x] 管理端 Web(Vue3 + Element Plus) - [x] 用户端 uni-app(H5 + 微信小程序) ### 规划中 - [ ] 担保交易 / 支付插件 - [ ] IM 即时通讯 - [ ] 短信 / 邮箱验证码 - [ ] 商品推荐算法 - [ ] 数据导出 - [ ] 敏感词过滤增强 - [ ] Kubernetes 部署方案 --- ## 参与贡献 欢迎提交 Issue 和 Pull Request! - [贡献指南](CONTRIBUTING.md) - [安全漏洞报告](SECURITY.md) --- ## License 本项目基于 [MIT License](LICENSE) 开源。