diff --git a/doc/API接口文档.md b/doc/API接口文档.md new file mode 100644 index 0000000..5cff6d0 --- /dev/null +++ b/doc/API接口文档.md @@ -0,0 +1,1083 @@ +# 资金服务平台 API 接口文档 + +> 版本: v1.0 +> 更新日期: 2026-02-13 +> 作者: zhangjf + +--- + +## 一、API 规范 + +### 1.1 基础信息 + +| 项目 | 说明 | +|------|------| +| 协议 | HTTPS(生产环境)/ HTTP(开发环境) | +| 数据格式 | JSON | +| 字符编码 | UTF-8 | +| 时间格式 | ISO 8601(yyyy-MM-dd HH:mm:ss) | +| 日期格式 | yyyy-MM-dd | +| 金额格式 | Decimal(保留2位小数) | + +### 1.2 请求规范 + +#### 请求头(Headers) + +| 参数名 | 必填 | 说明 | +|--------|------|------| +| Content-Type | 是 | 固定值:`application/json` | +| Authorization | 是 | Bearer Token:`Bearer {accessToken}` | +| X-Tenant-Id | 是 | 租户ID | +| X-Trace-Id | 否 | 链路追踪ID(系统自动生成) | + +#### 请求示例 + +```http +POST /api/v1/user/login HTTP/1.1 +Host: api.fundplatform.com +Content-Type: application/json +X-Tenant-Id: 1 + +{ + "username": "admin", + "password": "admin123" +} +``` + +### 1.3 响应规范 + +#### 统一响应格式 + +```json +{ + "code": 200, + "message": "操作成功", + "data": {}, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +#### 响应字段说明 + +| 字段 | 类型 | 说明 | +|------|------|------| +| code | Integer | 状态码(200成功,其他为错误码) | +| message | String | 提示信息 | +| data | Object | 业务数据(可为 null) | +| timestamp | Long | 时间戳(毫秒) | +| traceId | String | 链路追踪ID | + +#### 分页响应格式 + +```json +{ + "code": 200, + "message": "操作成功", + "data": { + "records": [], + "total": 100, + "size": 10, + "current": 1, + "pages": 10 + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +#### 分页字段说明 + +| 字段 | 类型 | 说明 | +|------|------|------| +| records | Array | 数据列表 | +| total | Long | 总记录数 | +| size | Integer | 每页大小 | +| current | Integer | 当前页码(从1开始) | +| pages | Integer | 总页数 | + +### 1.4 状态码定义 + +#### 成功状态码 + +| 状态码 | 说明 | +|--------|------| +| 200 | 操作成功 | +| 201 | 创建成功 | +| 204 | 删除成功(无返回内容) | + +#### 错误状态码 + +| 状态码 | 说明 | 处理建议 | +|--------|------|----------| +| 400 | 请求参数错误 | 检查请求参数格式 | +| 401 | 未授权 | Token无效或过期,重新登录 | +| 403 | 禁止访问 | 无权限访问该资源 | +| 404 | 资源不存在 | 检查请求路径或ID | +| 409 | 资源冲突 | 数据已存在或状态冲突 | +| 429 | 请求过于频繁 | 稍后重试 | +| 500 | 服务器内部错误 | 联系管理员 | +| 503 | 服务不可用 | 服务维护中 | + +#### 业务错误码(code字段) + +| 错误码 | 说明 | +|--------|------| +| 1001 | 用户名或密码错误 | +| 1002 | 账号已被禁用 | +| 1003 | Token已过期 | +| 1004 | Token无效 | +| 1005 | 无权限访问 | +| 2001 | 数据已存在 | +| 2002 | 数据不存在 | +| 2003 | 数据关联冲突 | +| 3001 | 租户已过期 | +| 3002 | 租户已被禁用 | + +### 1.5 分页请求参数 + +| 参数名 | 类型 | 必填 | 默认值 | 说明 | +|--------|------|------|--------|------| +| current | Integer | 否 | 1 | 当前页码 | +| size | Integer | 否 | 10 | 每页大小(最大100) | +| sortField | String | 否 | - | 排序字段 | +| sortOrder | String | 否 | asc | 排序方式:asc/desc | + +--- + +## 二、认证接口 + +### 2.1 用户登录 + +**接口地址:** `POST /api/v1/auth/login` + +**接口说明:** 用户登录获取访问令牌 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| username | String | 是 | 用户名 | +| password | String | 是 | 密码(MD5加密后传输) | +| tenantCode | String | 否 | 租户编码(多租户模式必填) | + +**请求示例:** + +```json +{ + "username": "admin", + "password": "e10adc3949ba59abbe56e057f20f883e", + "tenantCode": "SYSTEM" +} +``` + +**响应参数:** + +| 参数名 | 类型 | 说明 | +|--------|------|------| +| accessToken | String | 访问令牌 | +| refreshToken | String | 刷新令牌 | +| expiresIn | Long | 访问令牌过期时间(秒) | +| tokenType | String | 令牌类型(Bearer) | +| userInfo | Object | 用户信息 | + +**响应示例:** + +```json +{ + "code": 200, + "message": "登录成功", + "data": { + "accessToken": "eyJhbGciOiJIUzI1NiIs...", + "refreshToken": "eyJhbGciOiJIUzI1NiIs...", + "expiresIn": 7200, + "tokenType": "Bearer", + "userInfo": { + "userId": 1, + "username": "admin", + "realName": "系统管理员", + "avatar": "https://...", + "tenantId": 1, + "tenantName": "系统管理租户", + "deptId": 1, + "deptName": "总部", + "roles": ["super_admin"], + "permissions": ["*:*:*"] + } + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +### 2.2 用户登出 + +**接口地址:** `POST /api/v1/auth/logout` + +**接口说明:** 用户登出,使Token失效 + +**请求头:** + +| 参数名 | 必填 | 说明 | +|--------|------|------| +| Authorization | 是 | Bearer Token | + +**响应示例:** + +```json +{ + "code": 200, + "message": "登出成功", + "data": null, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +### 2.3 刷新Token + +**接口地址:** `POST /api/v1/auth/refresh` + +**接口说明:** 使用刷新令牌获取新的访问令牌 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| refreshToken | String | 是 | 刷新令牌 | + +**响应参数:** 同登录接口 + +--- + +### 2.4 获取当前用户信息 + +**接口地址:** `GET /api/v1/auth/userinfo` + +**接口说明:** 获取当前登录用户详细信息 + +**响应示例:** + +```json +{ + "code": 200, + "message": "操作成功", + "data": { + "userId": 1, + "username": "admin", + "realName": "系统管理员", + "gender": 1, + "phone": "13800138000", + "email": "admin@fundplatform.com", + "avatar": "https://...", + "deptId": 1, + "deptName": "总部", + "position": "系统管理员", + "tenantId": 1, + "tenantName": "系统管理租户", + "roles": [ + { + "roleId": 1, + "roleCode": "super_admin", + "roleName": "超级管理员" + } + ], + "permissions": ["*:*:*"], + "menus": [ + { + "menuId": 1, + "menuName": "系统管理", + "menuType": "dir", + "icon": "Setting", + "path": "/system", + "children": [...] + } + ] + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +## 三、用户管理接口 + +### 3.1 获取用户列表 + +**接口地址:** `GET /api/v1/user/list` + +**接口说明:** 分页查询用户列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| username | String | 否 | 用户名(模糊查询) | +| realName | String | 否 | 真实姓名(模糊查询) | +| deptId | Long | 否 | 部门ID | +| status | Integer | 否 | 状态:0-禁用,1-启用 | + +**响应示例:** + +```json +{ + "code": 200, + "message": "操作成功", + "data": { + "records": [ + { + "userId": 1, + "username": "admin", + "realName": "系统管理员", + "gender": 1, + "phone": "13800138000", + "email": "admin@fundplatform.com", + "deptId": 1, + "deptName": "总部", + "position": "系统管理员", + "status": 1, + "lastLoginTime": "2026-02-13 14:30:00", + "createdTime": "2024-01-01 00:00:00" + } + ], + "total": 6, + "size": 10, + "current": 1, + "pages": 1 + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +### 3.2 获取用户详情 + +**接口地址:** `GET /api/v1/user/{userId}` + +**接口说明:** 根据用户ID获取用户详细信息 + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| userId | Long | 是 | 用户ID | + +**响应示例:** + +```json +{ + "code": 200, + "message": "操作成功", + "data": { + "userId": 1, + "username": "admin", + "realName": "系统管理员", + "gender": 1, + "phone": "13800138000", + "email": "admin@fundplatform.com", + "avatar": "https://...", + "deptId": 1, + "deptName": "总部", + "position": "系统管理员", + "status": 1, + "roleIds": [1], + "lastLoginTime": "2026-02-13 14:30:00", + "lastLoginIp": "192.168.1.1", + "createdTime": "2024-01-01 00:00:00", + "updatedTime": "2026-02-13 10:00:00" + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +### 3.3 新增用户 + +**接口地址:** `POST /api/v1/user` + +**接口说明:** 创建新用户 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| username | String | 是 | 用户名(2-20位字母数字) | +| password | String | 是 | 密码(6-20位) | +| realName | String | 是 | 真实姓名 | +| gender | Integer | 否 | 性别:0-未知,1-男,2-女 | +| phone | String | 否 | 手机号码 | +| email | String | 否 | 邮箱地址 | +| deptId | Long | 否 | 部门ID | +| position | String | 否 | 职位 | +| roleIds | Array | 否 | 角色ID列表 | +| status | Integer | 否 | 状态:0-禁用,1-启用(默认1) | + +**请求示例:** + +```json +{ + "username": "newuser", + "password": "123456", + "realName": "新用户", + "gender": 1, + "phone": "13800138010", + "email": "newuser@fundplatform.com", + "deptId": 2, + "position": "开发工程师", + "roleIds": [5], + "status": 1 +} +``` + +**响应示例:** + +```json +{ + "code": 201, + "message": "创建成功", + "data": { + "userId": 7, + "username": "newuser", + "realName": "新用户", + "createdTime": "2026-02-13 15:00:00" + }, + "timestamp": 1707811200000, + "traceId": "abc123def456" +} +``` + +--- + +### 3.4 更新用户 + +**接口地址:** `PUT /api/v1/user/{userId}` + +**接口说明:** 更新用户信息 + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| userId | Long | 是 | 用户ID | + +**请求参数:** 同新增用户(password可选) + +--- + +### 3.5 删除用户 + +**接口地址:** `DELETE /api/v1/user/{userId}` + +**接口说明:** 删除用户(逻辑删除) + +**路径参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| userId | Long | 是 | 用户ID | + +--- + +### 3.6 重置密码 + +**接口地址:** `PUT /api/v1/user/{userId}/reset-password` + +**接口说明:** 重置用户密码 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| newPassword | String | 是 | 新密码 | + +--- + +## 四、租户管理接口 + +### 4.1 获取租户列表 + +**接口地址:** `GET /api/v1/tenant/list` + +**接口说明:** 分页查询租户列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| tenantCode | String | 否 | 租户编码(模糊查询) | +| tenantName | String | 否 | 租户名称(模糊查询) | +| status | Integer | 否 | 状态:0-禁用,1-启用 | + +--- + +### 4.2 获取租户详情 + +**接口地址:** `GET /api/v1/tenant/{tenantId}` + +**接口说明:** 根据租户ID获取租户详细信息 + +--- + +### 4.3 新增租户 + +**接口地址:** `POST /api/v1/tenant` + +**接口说明:** 创建新租户 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| tenantCode | String | 是 | 租户编码(唯一) | +| tenantName | String | 是 | 租户名称 | +| tenantType | Integer | 是 | 租户类型:1-一库多租户,2-一库一租户 | +| contactName | String | 否 | 联系人姓名 | +| contactPhone | String | 否 | 联系人电话 | +| contactEmail | String | 否 | 联系人邮箱 | +| expireTime | String | 否 | 过期时间(yyyy-MM-dd HH:mm:ss) | + +--- + +### 4.4 更新租户 + +**接口地址:** `PUT /api/v1/tenant/{tenantId}` + +**接口说明:** 更新租户信息 + +--- + +### 4.5 删除租户 + +**接口地址:** `DELETE /api/v1/tenant/{tenantId}` + +**接口说明:** 删除租户 + +--- + +## 五、客户管理接口 + +### 5.1 获取客户列表 + +**接口地址:** `GET /api/v1/customer/list` + +**接口说明:** 分页查询客户列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| customerName | String | 否 | 客户名称(模糊查询) | +| customerType | String | 否 | 客户类型 | +| level | String | 否 | 客户等级 | +| status | Integer | 否 | 状态 | + +--- + +### 5.2 获取客户详情 + +**接口地址:** `GET /api/v1/customer/{customerId}` + +**接口说明:** 根据客户ID获取客户详细信息 + +--- + +### 5.3 新增客户 + +**接口地址:** `POST /api/v1/customer` + +**接口说明:** 创建新客户 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| customerCode | String | 是 | 客户编码 | +| customerName | String | 是 | 客户名称 | +| customerShort | String | 否 | 客户简称 | +| customerType | String | 否 | 客户类型 | +| industry | String | 否 | 所属行业 | +| scale | String | 否 | 企业规模 | +| level | String | 否 | 客户等级 | +| taxNo | String | 否 | 纳税人识别号 | +| legalPerson | String | 否 | 法定代表人 | +| address | String | 否 | 公司地址 | +| phone | String | 否 | 联系电话 | +| email | String | 否 | 邮箱地址 | +| website | String | 否 | 公司网站 | + +--- + +### 5.4 更新客户 + +**接口地址:** `PUT /api/v1/customer/{customerId}` + +**接口说明:** 更新客户信息 + +--- + +### 5.5 删除客户 + +**接口地址:** `DELETE /api/v1/customer/{customerId}` + +**接口说明:** 删除客户 + +--- + +### 5.6 获取联系人列表 + +**接口地址:** `GET /api/v1/customer/{customerId}/contacts` + +**接口说明:** 获取客户的联系人列表 + +--- + +### 5.7 新增联系人 + +**接口地址:** `POST /api/v1/customer/{customerId}/contacts` + +**接口说明:** 为客户添加联系人 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| contactName | String | 是 | 联系人姓名 | +| position | String | 否 | 职位 | +| department | String | 否 | 部门 | +| phone | String | 否 | 电话 | +| mobile | String | 否 | 手机 | +| email | String | 否 | 邮箱 | +| isPrimary | Integer | 否 | 是否主要联系人:0-否,1-是 | + +--- + +## 六、项目管理接口 + +### 6.1 获取项目列表 + +**接口地址:** `GET /api/v1/project/list` + +**接口说明:** 分页查询项目列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| projectName | String | 否 | 项目名称(模糊查询) | +| customerId | Long | 否 | 客户ID | +| projectType | String | 否 | 项目类型 | +| status | String | 否 | 项目状态 | + +--- + +### 6.2 获取项目详情 + +**接口地址:** `GET /api/v1/project/{projectId}` + +**接口说明:** 根据项目ID获取项目详细信息 + +--- + +### 6.3 新增项目 + +**接口地址:** `POST /api/v1/project` + +**接口说明:** 创建新项目 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| projectCode | String | 是 | 项目编号 | +| projectName | String | 是 | 项目名称 | +| projectShort | String | 否 | 项目简称 | +| customerId | Long | 是 | 客户ID | +| projectType | String | 否 | 项目类型 | +| projectManagerId | Long | 否 | 项目经理ID | +| startDate | String | 否 | 开始日期(yyyy-MM-dd) | +| endDate | String | 否 | 结束日期(yyyy-MM-dd) | +| budgetAmount | BigDecimal | 否 | 预算金额 | +| contractAmount | BigDecimal | 否 | 合同金额 | +| description | String | 否 | 项目描述 | + +--- + +### 6.4 更新项目 + +**接口地址:** `PUT /api/v1/project/{projectId}` + +**接口说明:** 更新项目信息 + +--- + +### 6.5 删除项目 + +**接口地址:** `DELETE /api/v1/project/{projectId}` + +**接口说明:** 删除项目 + +--- + +### 6.6 获取项目成员列表 + +**接口地址:** `GET /api/v1/project/{projectId}/members` + +**接口说明:** 获取项目成员列表 + +--- + +### 6.7 添加项目成员 + +**接口地址:** `POST /api/v1/project/{projectId}/members` + +**接口说明:** 为项目添加成员 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| userId | Long | 是 | 用户ID | +| role | String | 是 | 项目角色 | +| workload | BigDecimal | 否 | 工作量占比 | + +--- + +## 七、需求工单接口 + +### 7.1 获取需求列表 + +**接口地址:** `GET /api/v1/requirement/list` + +**接口说明:** 分页查询需求工单列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| requirementName | String | 否 | 需求名称(模糊查询) | +| projectId | Long | 否 | 项目ID | +| priority | String | 否 | 优先级 | +| status | String | 否 | 状态 | + +--- + +### 7.2 获取需求详情 + +**接口地址:** `GET /api/v1/requirement/{requirementId}` + +**接口说明:** 根据需求ID获取需求详细信息 + +--- + +### 7.3 新增需求 + +**接口地址:** `POST /api/v1/requirement` + +**接口说明:** 创建新需求工单 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| requirementCode | String | 是 | 需求编号 | +| requirementName | String | 是 | 需求名称 | +| description | String | 否 | 需求描述 | +| projectId | Long | 是 | 项目ID | +| customerId | Long | 是 | 客户ID | +| priority | String | 否 | 优先级 | +| estimatedHours | BigDecimal | 否 | 预估工时 | +| plannedStart | String | 否 | 计划开始日期 | +| plannedEnd | String | 否 | 计划结束日期 | +| receivableAmount | BigDecimal | 否 | 应收款金额 | +| receivableDate | String | 否 | 应收款日期 | + +--- + +### 7.4 更新需求 + +**接口地址:** `PUT /api/v1/requirement/{requirementId}` + +**接口说明:** 更新需求信息 + +--- + +### 7.5 删除需求 + +**接口地址:** `DELETE /api/v1/requirement/{requirementId}` + +**接口说明:** 删除需求 + +--- + +## 八、支出管理接口 + +### 8.1 获取支出类型列表 + +**接口地址:** `GET /api/v1/expense-type/list` + +**接口说明:** 获取支出类型树形列表 + +--- + +### 8.2 获取支出列表 + +**接口地址:** `GET /api/v1/expense/list` + +**接口说明:** 分页查询支出列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| expenseTypeId | Long | 否 | 支出类型ID | +| projectId | Long | 否 | 项目ID | +| startDate | String | 否 | 开始日期 | +| endDate | String | 否 | 结束日期 | +| status | String | 否 | 状态 | + +--- + +### 8.3 新增支出 + +**接口地址:** `POST /api/v1/expense` + +**接口说明:** 创建新支出记录 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| expenseCode | String | 是 | 支出编号 | +| expenseTypeId | Long | 是 | 支出类型ID | +| expenseAmount | BigDecimal | 是 | 支出金额 | +| expenseDate | String | 是 | 支出日期 | +| expenseReason | String | 否 | 支出事由 | +| projectId | Long | 否 | 项目ID | +| paymentMethod | String | 否 | 付款方式 | + +--- + +### 8.4 更新支出 + +**接口地址:** `PUT /api/v1/expense/{expenseId}` + +**接口说明:** 更新支出信息 + +--- + +### 8.5 删除支出 + +**接口地址:** `DELETE /api/v1/expense/{expenseId}` + +**接口说明:** 删除支出记录 + +--- + +## 九、应收款管理接口 + +### 9.1 获取应收款列表 + +**接口地址:** `GET /api/v1/receivable/list` + +**接口说明:** 分页查询应收款列表 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| current | Integer | 否 | 当前页码 | +| size | Integer | 否 | 每页大小 | +| projectId | Long | 否 | 项目ID | +| customerId | Long | 否 | 客户ID | +| status | String | 否 | 状态 | + +--- + +### 9.2 获取应收款详情 + +**接口地址:** `GET /api/v1/receivable/{receivableId}` + +**接口说明:** 根据应收款ID获取详细信息 + +--- + +### 9.3 新增应收款 + +**接口地址:** `POST /api/v1/receivable` + +**接口说明:** 创建新应收款 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| receivableCode | String | 是 | 应收款编号 | +| requirementId | Long | 是 | 需求ID | +| projectId | Long | 是 | 项目ID | +| customerId | Long | 是 | 客户ID | +| receivableAmount | BigDecimal | 是 | 应收款金额 | +| receivableDate | String | 是 | 应收款日期 | +| paymentDueDate | String | 否 | 付款截止日期 | + +--- + +### 9.4 获取收款记录列表 + +**接口地址:** `GET /api/v1/receivable/{receivableId}/receipts` + +**接口说明:** 获取应收款的收款记录 + +--- + +### 9.5 新增收款记录 + +**接口地址:** `POST /api/v1/receivable/{receivableId}/receipts` + +**接口说明:** 添加收款记录 + +**请求参数:** + +| 参数名 | 类型 | 必填 | 说明 | +|--------|------|------|------| +| receiptAmount | BigDecimal | 是 | 收款金额 | +| receiptDate | String | 是 | 收款日期 | +| receiptMethod | String | 否 | 收款方式 | +| receiptAccount | String | 否 | 收款账户 | +| payerName | String | 否 | 付款方名称 | + +--- + +## 十、附录 + +### 10.1 枚举值定义 + +#### 性别(gender) + +| 值 | 说明 | +|----|------| +| 0 | 未知 | +| 1 | 男 | +| 2 | 女 | + +#### 状态(status) + +| 值 | 说明 | +|----|------| +| 0 | 禁用/停用 | +| 1 | 启用/正常 | + +#### 租户类型(tenantType) + +| 值 | 说明 | +|----|------| +| 1 | 一库多租户 | +| 2 | 一库一租户 | + +#### 客户类型(customerType) + +| 值 | 说明 | +|----|------| +| enterprise | 企业 | +| individual | 个人 | + +#### 客户等级(level) + +| 值 | 说明 | +|----|------| +| A | A级客户 | +| B | B级客户 | +| C | C级客户 | +| D | D级客户 | +| normal | 普通客户 | + +#### 项目类型(projectType) + +| 值 | 说明 | +|----|------| +| development | 开发 | +| maintenance | 维护 | +| consulting | 咨询 | + +#### 项目状态(status) + +| 值 | 说明 | +|----|------| +| preparing | 筹备中 | +| ongoing | 进行中 | +| completed | 已完成 | +| archived | 已归档 | +| cancelled | 已取消 | + +#### 需求优先级(priority) + +| 值 | 说明 | +|----|------| +| high | 高 | +| normal | 中 | +| low | 低 | + +#### 需求状态(status) + +| 值 | 说明 | +|----|------| +| pending | 待开发 | +| developing | 开发中 | +| delivered | 已交付 | +| completed | 已完成 | + +#### 支出状态(status) + +| 值 | 说明 | +|----|------| +| pending | 待付款 | +| paid | 已付款 | +| completed | 已完成 | +| cancelled | 已作废 | + +#### 应收款状态(status) + +| 值 | 说明 | +|----|------| +| pending | 待收款 | +| partial | 部分收款 | +| received | 已收款 | +| overdue | 逾期 | + +--- + +### 10.2 数据类型说明 + +| 类型 | 说明 | 示例 | +|------|------|------| +| String | 字符串 | "hello" | +| Integer | 整数 | 100 | +| Long | 长整数 | 10000000000 | +| BigDecimal | 高精度小数(金额) | 100.50 | +| Boolean | 布尔值 | true/false | +| Array | 数组 | [1, 2, 3] | +| Object | 对象 | {"key": "value"} | + +--- + +**文档结束** diff --git a/doc/数据库设计文档.md b/doc/数据库设计文档.md new file mode 100644 index 0000000..45317b5 --- /dev/null +++ b/doc/数据库设计文档.md @@ -0,0 +1,710 @@ +# 资金服务平台数据库设计文档 + +> 版本: v1.0 +> 更新日期: 2026-02-13 +> 作者: zhangjf +> 数据库: MySQL 8.0 +> 字符集: utf8mb4 + +--- + +## 一、数据库概览 + +### 1.1 数据库信息 + +| 项目 | 值 | +|------|-----| +| 数据库名 | fund_platform | +| 字符集 | utf8mb4 | +| 排序规则 | utf8mb4_unicode_ci | +| 存储引擎 | InnoDB | +| 时区 | +08:00 | + +### 1.2 表清单 + +| 模块 | 表名 | 说明 | 记录数 | +|------|------|------|--------| +| **系统管理** | sys_tenant | 租户表 | 2 | +| | sys_dept | 部门表 | 7 | +| | sys_user | 用户表 | 6 | +| | sys_role | 角色表 | 7 | +| | sys_menu | 菜单表 | 38 | +| | sys_user_role | 用户角色关联表 | 6 | +| | sys_role_menu | 角色菜单关联表 | 动态 | +| | sys_operation_log | 操作日志表 | 动态 | +| **客户管理** | customer | 客户表 | 3 | +| | customer_contact | 客户联系人表 | 0 | +| **项目管理** | project | 项目表 | 3 | +| | project_member | 项目成员表 | 6 | +| **需求工单** | requirement | 需求工单表 | 0 | +| **支出管理** | expense_type | 支出类型表 | 12 | +| | expense | 支出表 | 0 | +| **应收款管理** | receivable | 应收款表 | 0 | +| | receipt | 收款记录表 | 0 | + +--- + +## 二、ER 图 + +``` +┌─────────────────────────────────────────────────────────────────────────────────────────┐ +│ 资金服务平台数据库 ER 图 │ +├─────────────────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ sys_tenant │ │ sys_user │ │ sys_role │ │ +│ │ (租户表) │ │ (用户表) │ │ (角色表) │ │ +│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ +│ │ PK tenant_id │◄────────┤ FK tenant_id │ │ FK tenant_id │ │ +│ │ code │ │ PK user_id │◄───────►│ PK role_id │ │ +│ │ name │ │ username │ │ code │ │ +│ │ type │ │ password │ │ name │ │ +│ │ status │ │ real_name │ │ type │ │ +│ └──────────────┘ │ dept_id │────────►│ scope │ │ +│ │ status │ └──────────────┘ │ +│ └──────────────┘ ▲ │ +│ ▲ │ │ +│ │ │ │ +│ ┌──────┴──────┐ ┌──────┴──────┐ │ +│ │ sys_dept │ │sys_user_role│ │ +│ │ (部门表) │ │(用户角色关联)│ │ +│ ├─────────────┤ ├─────────────┤ │ +│ │ PK dept_id │ │ PK id │ │ +│ │ FK tenant_id│ │ FK user_id │ │ +│ │ name │ │ FK role_id │ │ +│ │ parent_id │ └─────────────┘ │ +│ └─────────────┘ │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ customer │ │ project │ │ requirement │ │ +│ │ (客户表) │ │ (项目表) │ │ (需求工单表) │ │ +│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ +│ │ PK customer_id│◄───────┤ FK customer_id│◄───────┤ FK customer_id│ │ +│ │ FK tenant_id │ │ FK tenant_id │ │ FK tenant_id │ │ +│ │ code │ │ PK project_id│◄───────┤ FK project_id│ │ +│ │ name │ │ code │ │ PK req_id │ │ +│ │ type │ │ name │ │ code │ │ +│ │ level │ │ manager_id│ │ name │ │ +│ └──────────────┘ │ status │ │ amount │ │ +│ │ └──────────────┘ │ status │ │ +│ │ ▲ └──────────────┘ │ +│ │ │ │ +│ │ ┌──────┴──────┐ │ +│ │ │project_member│ │ +│ │ │(项目成员表) │ │ +│ │ ├─────────────┤ │ +│ │ │ PK member_id│ │ +│ │ │ FK project_id│ │ +│ │ │ FK user_id │ │ +│ │ │ role │ │ +│ │ └─────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌──────────────┐ │ +│ │customer_contact│ │ +│ │(客户联系人表) │ │ +│ ├──────────────┤ │ +│ │ PK contact_id │ │ +│ │ FK customer_id│ │ +│ │ name │ │ +│ │ phone │ │ +│ │ is_primary │ │ +│ └──────────────┘ │ +│ │ +│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ +│ │ expense_type │ │ expense │ │ receivable │ │ +│ │ (支出类型表) │ │ (支出表) │ │ (应收款表) │ │ +│ ├──────────────┤ ├──────────────┤ ├──────────────┤ │ +│ │ PK type_id │◄────────┤ FK type_id │ │ PK receiv_id │ │ +│ │ FK tenant_id │ │ FK tenant_id │ │ FK tenant_id │ │ +│ │ code │ │ PK expense_id│ │ FK project_id│ │ +│ │ name │ │ code │ │ FK customer_id│ │ +│ │ parent_id │ │ amount │ │ FK req_id │ │ +│ └──────────────┘ │ date │ │ amount │ │ +│ │ status │ │ status │ │ +│ └──────────────┘ └──────┬───────┘ │ +│ │ │ +│ ┌──────┴──────┐ │ +│ │ receipt │ │ +│ │ (收款记录表) │ │ +│ ├─────────────┤ │ +│ │ PK receipt_id│ │ +│ │ FK receiv_id │ │ +│ │ amount │ │ +│ │ date │ │ +│ └─────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 三、表结构详细说明 + +### 3.1 系统管理模块 + +#### 3.1.1 sys_tenant(租户表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| tenant_id | BIGINT | - | 是 | 自增 | 主键,租户ID | +| tenant_code | VARCHAR | 50 | 是 | - | 租户编码(唯一) | +| tenant_name | VARCHAR | 100 | 是 | - | 租户名称 | +| tenant_type | TINYINT | - | 否 | 1 | 租户类型:1-一库多租户,2-一库一租户 | +| contact_name | VARCHAR | 50 | 否 | - | 联系人姓名 | +| contact_phone | VARCHAR | 20 | 否 | - | 联系人电话 | +| contact_email | VARCHAR | 100 | 否 | - | 联系人邮箱 | +| db_config | JSON | - | 否 | - | 数据库配置(一库一租户模式使用) | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| expire_time | DATETIME | - | 否 | - | 过期时间 | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | + +**索引:** +- PRIMARY KEY (`tenant_id`) +- UNIQUE KEY `uk_code` (`tenant_code`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.1.2 sys_dept(部门表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| dept_id | BIGINT | - | 是 | 自增 | 主键,部门ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| dept_name | VARCHAR | 100 | 是 | - | 部门名称 | +| parent_id | BIGINT | - | 否 | 0 | 父部门ID(0表示顶级部门) | +| dept_code | VARCHAR | 50 | 否 | - | 部门编码 | +| dept_level | INT | - | 否 | 1 | 部门层级 | +| sort_order | INT | - | 否 | 0 | 排序顺序 | +| leader | VARCHAR | 50 | 否 | - | 部门负责人 | +| leader_phone | VARCHAR | 20 | 否 | - | 负责人电话 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`dept_id`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_parent` (`parent_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.1.3 sys_user(用户表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| user_id | BIGINT | - | 是 | 自增 | 主键,用户ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| username | VARCHAR | 50 | 是 | - | 用户名(登录账号) | +| password | VARCHAR | 100 | 是 | - | 密码(BCrypt加密存储) | +| real_name | VARCHAR | 50 | 是 | - | 真实姓名 | +| gender | TINYINT | - | 否 | 0 | 性别:0-未知,1-男,2-女 | +| phone | VARCHAR | 20 | 否 | - | 手机号码 | +| email | VARCHAR | 100 | 否 | - | 邮箱地址 | +| dept_id | BIGINT | - | 否 | - | 所属部门ID(外键) | +| position | VARCHAR | 50 | 否 | - | 岗位/职位 | +| avatar | VARCHAR | 255 | 否 | - | 头像URL | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| last_login_time | DATETIME | - | 否 | - | 最后登录时间 | +| last_login_ip | VARCHAR | 50 | 否 | - | 最后登录IP | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`user_id`) +- UNIQUE KEY `uk_tenant_username` (`tenant_id`, `username`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_dept` (`dept_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.1.4 sys_role(角色表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| role_id | BIGINT | - | 是 | 自增 | 主键,角色ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| role_code | VARCHAR | 50 | 是 | - | 角色编码 | +| role_name | VARCHAR | 100 | 是 | - | 角色名称 | +| role_type | VARCHAR | 20 | 否 | custom | 角色类型:system-系统角色,custom-自定义角色 | +| data_scope | VARCHAR | 20 | 否 | self | 数据范围:all-全部,dept-本部门,self-本人 | +| sort_order | INT | - | 否 | 0 | 排序顺序 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`role_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `role_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.1.5 sys_menu(菜单表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| menu_id | BIGINT | - | 是 | 自增 | 主键,菜单ID | +| tenant_id | BIGINT | - | 否 | 0 | 租户ID(0表示系统通用菜单) | +| menu_name | VARCHAR | 100 | 是 | - | 菜单名称 | +| menu_type | VARCHAR | 20 | 是 | - | 菜单类型:dir-目录,menu-菜单,button-按钮 | +| parent_id | BIGINT | - | 否 | 0 | 父菜单ID(0表示顶级菜单) | +| menu_level | INT | - | 否 | 1 | 菜单层级 | +| icon | VARCHAR | 100 | 否 | - | 菜单图标 | +| path | VARCHAR | 200 | 否 | - | 路由路径 | +| component | VARCHAR | 200 | 否 | - | 组件路径 | +| permission | VARCHAR | 100 | 否 | - | 权限标识(如:user:list) | +| sort_order | INT | - | 否 | 0 | 排序顺序 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`menu_id`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_parent` (`parent_id`) +- INDEX `idx_type` (`menu_type`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.1.6 sys_user_role(用户角色关联表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| id | BIGINT | - | 是 | 自增 | 主键,ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| user_id | BIGINT | - | 是 | - | 用户ID(外键) | +| role_id | BIGINT | - | 是 | - | 角色ID(外键) | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | + +**索引:** +- PRIMARY KEY (`id`) +- UNIQUE KEY `uk_user_role` (`tenant_id`, `user_id`, `role_id`) +- INDEX `idx_user` (`user_id`) +- INDEX `idx_role` (`role_id`) + +--- + +#### 3.1.7 sys_role_menu(角色菜单关联表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| id | BIGINT | - | 是 | 自增 | 主键,ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| role_id | BIGINT | - | 是 | - | 角色ID(外键) | +| menu_id | BIGINT | - | 是 | - | 菜单ID(外键) | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | + +**索引:** +- PRIMARY KEY (`id`) +- UNIQUE KEY `uk_role_menu` (`tenant_id`, `role_id`, `menu_id`) +- INDEX `idx_role` (`role_id`) +- INDEX `idx_menu` (`menu_id`) + +--- + +#### 3.1.8 sys_operation_log(操作日志表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| log_id | BIGINT | - | 是 | 自增 | 主键,日志ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| user_id | BIGINT | - | 否 | - | 操作人ID(外键) | +| username | VARCHAR | 50 | 否 | - | 操作人用户名 | +| operation | VARCHAR | 100 | 否 | - | 操作描述 | +| method | VARCHAR | 200 | 否 | - | 操作方法 | +| params | TEXT | - | 否 | - | 操作参数(JSON格式) | +| ip | VARCHAR | 50 | 否 | - | 操作IP | +| user_agent | VARCHAR | 500 | 否 | - | 用户代理 | +| operation_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 操作时间 | +| cost_time | BIGINT | - | 否 | 0 | 耗时(毫秒) | +| result | VARCHAR | 20 | 否 | success | 操作结果:success-成功,fail-失败 | +| error_msg | TEXT | - | 否 | - | 错误信息 | + +**索引:** +- PRIMARY KEY (`log_id`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_user` (`user_id`) +- INDEX `idx_time` (`operation_time`) +- INDEX `idx_result` (`result`) + +--- + +### 3.2 客户管理模块 + +#### 3.2.1 customer(客户表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| customer_id | BIGINT | - | 是 | 自增 | 主键,客户ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| customer_code | VARCHAR | 50 | 是 | - | 客户编码(唯一) | +| customer_name | VARCHAR | 200 | 是 | - | 客户名称 | +| customer_short | VARCHAR | 100 | 否 | - | 客户简称 | +| customer_type | VARCHAR | 20 | 否 | enterprise | 客户类型:enterprise-企业,individual-个人 | +| industry | VARCHAR | 50 | 否 | - | 所属行业 | +| scale | VARCHAR | 20 | 否 | - | 企业规模:small-小型,medium-中型,large-大型 | +| level | VARCHAR | 20 | 否 | normal | 客户等级:A/B/C/D/normal | +| tax_no | VARCHAR | 50 | 否 | - | 纳税人识别号 | +| legal_person | VARCHAR | 50 | 否 | - | 法定代表人 | +| address | VARCHAR | 500 | 否 | - | 公司地址 | +| phone | VARCHAR | 20 | 否 | - | 联系电话 | +| email | VARCHAR | 100 | 否 | - | 邮箱地址 | +| website | VARCHAR | 200 | 否 | - | 公司网站 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| cooperation_start | DATE | - | 否 | - | 合作开始日期 | +| cooperation_end | DATE | - | 否 | - | 合作结束日期 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`customer_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `customer_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_status` (`status`) +- INDEX `idx_level` (`level`) + +--- + +#### 3.2.2 customer_contact(客户联系人表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| contact_id | BIGINT | - | 是 | 自增 | 主键,联系人ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| customer_id | BIGINT | - | 是 | - | 客户ID(外键) | +| contact_name | VARCHAR | 50 | 是 | - | 联系人姓名 | +| position | VARCHAR | 50 | 否 | - | 职位/职务 | +| department | VARCHAR | 100 | 否 | - | 所属部门 | +| phone | VARCHAR | 20 | 否 | - | 联系电话 | +| mobile | VARCHAR | 20 | 否 | - | 手机号码 | +| email | VARCHAR | 100 | 否 | - | 邮箱地址 | +| wechat | VARCHAR | 50 | 否 | - | 微信号 | +| qq | VARCHAR | 20 | 否 | - | QQ号 | +| is_primary | TINYINT | - | 否 | 0 | 是否主要联系人:0-否,1-是 | +| sort_order | INT | - | 否 | 0 | 排序顺序 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| remark | VARCHAR | 200 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`contact_id`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_customer` (`customer_id`) +- INDEX `idx_status` (`status`) + +--- + +### 3.3 项目管理模块 + +#### 3.3.1 project(项目表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| project_id | BIGINT | - | 是 | 自增 | 主键,项目ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| project_code | VARCHAR | 50 | 是 | - | 项目编号(唯一) | +| project_name | VARCHAR | 200 | 是 | - | 项目名称 | +| project_short | VARCHAR | 100 | 否 | - | 项目简称 | +| customer_id | BIGINT | - | 是 | - | 客户ID(外键) | +| project_type | VARCHAR | 20 | 否 | development | 项目类型:development-开发,maintenance-维护,consulting-咨询 | +| project_manager_id | BIGINT | - | 否 | - | 项目经理ID(外键) | +| start_date | DATE | - | 否 | - | 项目开始日期 | +| end_date | DATE | - | 否 | - | 项目结束日期 | +| budget_amount | DECIMAL | 15,2 | 否 | 0.00 | 项目预算金额 | +| contract_amount | DECIMAL | 15,2 | 否 | 0.00 | 合同金额 | +| status | VARCHAR | 20 | 否 | preparing | 项目状态:preparing-筹备中,ongoing-进行中,completed-已完成,archived-已归档,cancelled-已取消 | +| progress | INT | - | 否 | 0 | 项目进度(0-100) | +| description | TEXT | - | 否 | - | 项目描述 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| attachment_url | VARCHAR | 500 | 否 | - | 附件URL | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`project_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `project_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_customer` (`customer_id`) +- INDEX `idx_manager` (`project_manager_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.3.2 project_member(项目成员表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| member_id | BIGINT | - | 是 | 自增 | 主键,成员关系ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| project_id | BIGINT | - | 是 | - | 项目ID(外键) | +| user_id | BIGINT | - | 是 | - | 用户ID(外键) | +| role | VARCHAR | 50 | 否 | member | 项目角色:pm-项目经理,dev-开发,test-测试,finance-财务,member-普通成员 | +| join_date | DATE | - | 否 | - | 加入日期 | +| leave_date | DATE | - | 否 | - | 离开日期 | +| workload | DECIMAL | 5,2 | 否 | 0.00 | 工作量占比(0-100) | +| status | TINYINT | - | 否 | 1 | 状态:0-已离开,1-在职 | +| remark | VARCHAR | 200 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`member_id`) +- UNIQUE KEY `uk_project_user` (`tenant_id`, `project_id`, `user_id`) +- INDEX `idx_project` (`project_id`) +- INDEX `idx_user` (`user_id`) + +--- + +### 3.4 需求工单模块 + +#### 3.4.1 requirement(需求工单表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| requirement_id | BIGINT | - | 是 | 自增 | 主键,需求ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| requirement_code | VARCHAR | 50 | 是 | - | 需求编号(唯一) | +| requirement_name | VARCHAR | 200 | 是 | - | 需求名称 | +| description | TEXT | - | 否 | - | 需求描述 | +| project_id | BIGINT | - | 是 | - | 项目ID(外键) | +| customer_id | BIGINT | - | 是 | - | 客户ID(外键) | +| priority | VARCHAR | 20 | 否 | normal | 优先级:high-高,normal-中,low-低 | +| estimated_hours | DECIMAL | 8,2 | 否 | 0.00 | 预估开发工时(小时) | +| actual_hours | DECIMAL | 8,2 | 否 | 0.00 | 实际开发工时(小时) | +| planned_start | DATE | - | 否 | - | 计划开始日期 | +| planned_end | DATE | - | 否 | - | 计划结束日期 | +| actual_start | DATE | - | 否 | - | 实际开始日期 | +| actual_end | DATE | - | 否 | - | 实际结束日期 | +| delivery_date | DATE | - | 否 | - | 交付日期 | +| receivable_amount | DECIMAL | 15,2 | 否 | 0.00 | 应收款金额 | +| receivable_date | DATE | - | 否 | - | 应收款日期 | +| status | VARCHAR | 20 | 否 | pending | 状态:pending-待开发,developing-开发中,delivered-已交付,completed-已完成 | +| progress | INT | - | 否 | 0 | 开发进度(0-100) | +| attachment_url | VARCHAR | 500 | 否 | - | 附件URL | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`requirement_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `requirement_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_project` (`project_id`) +- INDEX `idx_customer` (`customer_id`) +- INDEX `idx_status` (`status`) + +--- + +### 3.5 支出管理模块 + +#### 3.5.1 expense_type(支出类型表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| type_id | BIGINT | - | 是 | 自增 | 主键,支出类型ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| type_code | VARCHAR | 50 | 否 | - | 支出类型编码 | +| type_name | VARCHAR | 100 | 是 | - | 支出类型名称 | +| parent_id | BIGINT | - | 否 | 0 | 父类型ID(0表示一级类型) | +| type_level | INT | - | 否 | 1 | 类型层级 | +| sort_order | INT | - | 否 | 0 | 排序顺序 | +| description | VARCHAR | 200 | 否 | - | 类型描述 | +| status | TINYINT | - | 否 | 1 | 状态:0-禁用,1-启用 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`type_id`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_parent` (`parent_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.5.2 expense(支出表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| expense_id | BIGINT | - | 是 | 自增 | 主键,支出ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| expense_code | VARCHAR | 50 | 是 | - | 支出编号(唯一) | +| expense_type_id | BIGINT | - | 是 | - | 支出类型ID(外键) | +| expense_amount | DECIMAL | 15,2 | 否 | 0.00 | 支出金额 | +| expense_date | DATE | - | 否 | - | 支出日期 | +| expense_reason | TEXT | - | 否 | - | 支出事由 | +| project_id | BIGINT | - | 否 | - | 所属项目ID(外键) | +| applicant_id | BIGINT | - | 是 | - | 申请人ID(外键) | +| department_id | BIGINT | - | 否 | - | 申请部门ID(外键) | +| payment_method | VARCHAR | 20 | 否 | transfer | 付款方式:transfer-转账,cash-现金,check-支票,other-其他 | +| payment_account | VARCHAR | 100 | 否 | - | 付款账户 | +| attachment_url | VARCHAR | 500 | 否 | - | 附件URL | +| status | VARCHAR | 20 | 否 | pending | 状态:pending-待付款,paid-已付款,completed-已完成,cancelled-已作废 | +| payment_date | DATE | - | 否 | - | 付款日期 | +| payment_voucher | VARCHAR | 255 | 否 | - | 付款凭证 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`expense_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `expense_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_type` (`expense_type_id`) +- INDEX `idx_project` (`project_id`) +- INDEX `idx_applicant` (`applicant_id`) +- INDEX `idx_status` (`status`) + +--- + +### 3.6 应收款管理模块 + +#### 3.6.1 receivable(应收款表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| receivable_id | BIGINT | - | 是 | 自增 | 主键,应收款ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| receivable_code | VARCHAR | 50 | 是 | - | 应收款编号(唯一) | +| requirement_id | BIGINT | - | 是 | - | 需求ID(外键) | +| project_id | BIGINT | - | 是 | - | 项目ID(外键) | +| customer_id | BIGINT | - | 是 | - | 客户ID(外键) | +| receivable_amount | DECIMAL | 15,2 | 否 | 0.00 | 应收款金额 | +| receivable_date | DATE | - | 否 | - | 应收款日期 | +| payment_due_date | DATE | - | 否 | - | 付款截止日期 | +| payment_method | VARCHAR | 20 | 否 | - | 付款方式:transfer-转账,cash-现金,check-支票,other-其他 | +| bank_account | VARCHAR | 100 | 否 | - | 收款账户 | +| status | VARCHAR | 20 | 否 | pending | 状态:pending-待收款,partial-部分收款,received-已收款,overdue-逾期 | +| received_amount | DECIMAL | 15,2 | 否 | 0.00 | 已收款金额 | +| unpaid_amount | DECIMAL | 15,2 | 否 | 0.00 | 未收款金额 | +| overdue_days | INT | - | 否 | 0 | 逾期天数 | +| remark | VARCHAR | 500 | 否 | - | 备注说明 | +| created_by | BIGINT | - | 否 | - | 创建人ID | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | +| updated_by | BIGINT | - | 否 | - | 更新人ID | +| updated_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 更新时间 | +| deleted | TINYINT | - | 否 | 0 | 逻辑删除:0-未删除,1-已删除 | + +**索引:** +- PRIMARY KEY (`receivable_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `receivable_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_requirement` (`requirement_id`) +- INDEX `idx_project` (`project_id`) +- INDEX `idx_customer` (`customer_id`) +- INDEX `idx_status` (`status`) + +--- + +#### 3.6.2 receipt(收款记录表) + +| 字段名 | 类型 | 长度 | 必填 | 默认值 | 说明 | +|--------|------|------|------|--------|------| +| receipt_id | BIGINT | - | 是 | 自增 | 主键,收款记录ID | +| tenant_id | BIGINT | - | 是 | - | 租户ID(外键) | +| receipt_code | VARCHAR | 50 | 是 | - | 收款编号(唯一) | +| receivable_id | BIGINT | - | 是 | - | 应收款ID(外键) | +| receipt_amount | DECIMAL | 15,2 | 否 | 0.00 | 收款金额 | +| receipt_date | DATE | - | 否 | - | 收款日期 | +| receipt_method | VARCHAR | 20 | 否 | transfer | 收款方式:transfer-转账,cash-现金,check-支票,other-其他 | +| receipt_account | VARCHAR | 100 | 否 | - | 收款账户 | +| payer_name | VARCHAR | 100 | 否 | - | 付款方名称 | +| receipt_voucher | VARCHAR | 255 | 否 | - | 收款凭证URL | +| operator_id | BIGINT | - | 否 | - | 操作人ID(外键) | +| remark | VARCHAR | 200 | 否 | - | 备注说明 | +| created_time | DATETIME | - | 否 | CURRENT_TIMESTAMP | 创建时间 | + +**索引:** +- PRIMARY KEY (`receipt_id`) +- UNIQUE KEY `uk_tenant_code` (`tenant_id`, `receipt_code`) +- INDEX `idx_tenant` (`tenant_id`) +- INDEX `idx_receivable` (`receivable_id`) + +--- + +## 四、数据库设计规范 + +### 4.1 命名规范 + +| 项目 | 规范 | 示例 | +|------|------|------| +| 数据库名 | 小写,下划线分隔 | fund_platform | +| 表名 | 小写,下划线分隔 | sys_user | +| 字段名 | 小写,下划线分隔 | user_name | +| 索引名 | 前缀_表名_字段名 | uk_tenant_username | +| 外键名 | fk_表名_字段名 | fk_user_dept | + +### 4.2 字段规范 + +| 字段类型 | 使用场景 | 示例 | +|----------|----------|------| +| BIGINT | 主键、外键、ID | user_id | +| VARCHAR(50) | 编码、用户名、短文本 | user_code | +| VARCHAR(100) | 名称、标题 | user_name | +| VARCHAR(200) | 长名称、URL | project_name | +| VARCHAR(500) | 备注、描述 | remark | +| TEXT | 长文本、JSON | description | +| TINYINT | 状态、布尔值 | status | +| INT | 数量、排序 | sort_order | +| DECIMAL(15,2) | 金额 | amount | +| DATETIME | 日期时间 | created_time | +| DATE | 日期 | start_date | + +### 4.3 通用字段 + +所有表必须包含以下字段: + +| 字段名 | 类型 | 说明 | +|--------|------|------| +| created_by | BIGINT | 创建人ID | +| created_time | DATETIME | 创建时间(DEFAULT CURRENT_TIMESTAMP) | +| updated_by | BIGINT | 更新人ID | +| updated_time | DATETIME | 更新时间(DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP) | +| deleted | TINYINT | 逻辑删除标志(DEFAULT 0) | + +--- + +**文档结束** diff --git a/doc/部署运维文档.md b/doc/部署运维文档.md new file mode 100644 index 0000000..05a888a --- /dev/null +++ b/doc/部署运维文档.md @@ -0,0 +1,783 @@ +# 资金服务平台部署运维文档 + +> 版本: v1.0 +> 更新日期: 2026-02-13 +> 作者: zhangjf + +--- + +## 一、本地开发环境搭建 + +### 1.1 环境要求 + +| 组件 | 版本要求 | 说明 | +|------|----------|------| +| JDK | 21+ | Java开发工具包 | +| Maven | 3.9+ | 项目构建工具 | +| MySQL | 8.0+ | 数据库 | +| Redis | 7.0+ | 缓存服务 | +| Nacos | 3.0+ | 服务注册与配置中心 | +| Node.js | 18+ | 前端开发环境 | + +### 1.2 安装步骤 + +#### 1.2.1 安装 JDK 21 + +```bash +# 下载并解压 JDK 21 +wget https://download.java.net/openjdk/jdk21/ri/openjdk-21+35_linux-x64_bin.tar.gz +tar -xzf openjdk-21+35_linux-x64_bin.tar.gz -C /opt/ + +# 配置环境变量 +echo 'export JAVA_HOME=/opt/jdk-21' >> ~/.bashrc +echo 'export PATH=$JAVA_HOME/bin:$PATH' >> ~/.bashrc +source ~/.bashrc + +# 验证安装 +java -version +``` + +#### 1.2.2 安装 Maven 3.9 + +```bash +# 下载并解压 Maven +wget https://dlcdn.apache.org/maven/maven-3/3.9.9/binaries/apache-maven-3.9.9-bin.tar.gz +tar -xzf apache-maven-3.9.9-bin.tar.gz -C /opt/ + +# 配置环境变量 +echo 'export MAVEN_HOME=/opt/apache-maven-3.9.9' >> ~/.bashrc +echo 'export PATH=$MAVEN_HOME/bin:$PATH' >> ~/.bashrc +source ~/.bashrc + +# 验证安装 +mvn -version +``` + +#### 1.2.3 安装 MySQL 8.0 + +```bash +# Ubuntu/Debian +sudo apt update +sudo apt install mysql-server-8.0 + +# 启动 MySQL +sudo systemctl start mysql +sudo systemctl enable mysql + +# 配置 root 密码 +sudo mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password BY 'zjf@123456';" + +# 创建数据库 +mysql -u root -p'zjf@123456' -e "CREATE DATABASE fund_platform CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" +``` + +#### 1.2.4 安装 Redis + +```bash +# Ubuntu/Debian +sudo apt update +sudo apt install redis-server + +# 配置密码 +sudo sed -i 's/# requirepass foobared/requirepass zjf@123456/' /etc/redis/redis.conf + +# 启动 Redis +sudo systemctl restart redis +sudo systemctl enable redis + +# 验证安装 +redis-cli -a zjf@123456 ping +``` + +#### 1.2.5 安装 Nacos 3.0 + +```bash +# 下载 Nacos +cd /opt +wget https://github.com/alibaba/nacos/releases/download/3.0.0/nacos-server-3.0.0.tar.gz +tar -xzf nacos-server-3.0.0.tar.gz + +# 配置端口 +cd nacos/conf +sed -i 's/server.port=8848/server.port=8048/' application.properties + +# 启动 Nacos(单机模式) +cd /opt/nacos/bin +sh startup.sh -m standalone + +# 访问控制台:http://localhost:8048/nacos +# 默认账号密码:nacos / nacos +``` + +#### 1.2.6 安装 Node.js 18 + +```bash +# 使用 nvm 安装 +curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash +source ~/.bashrc +nvm install 18 +nvm use 18 + +# 验证安装 +node -v +npm -v +``` + +### 1.3 项目初始化 + +```bash +# 克隆项目 +git clone +cd fundplatform + +# 初始化数据库 +mysql -u root -p'zjf@123456' < sql/fund_platform_schema.sql +mysql -u root -p'zjf@123456' < sql/fund_platform_init.sql + +# 配置环境变量 +cp .env.example .env +# 编辑 .env 文件,配置数据库、Redis、Nacos 连接信息 +``` + +### 1.4 启动服务 + +```bash +# 1. 确保 MySQL、Redis、Nacos 已启动 + +# 2. 启动后端服务(在各自服务目录执行) +cd fund-gateway +mvn spring-boot:run + +cd fund-sys +mvn spring-boot:run + +# 3. 启动前端(Vue 3) +cd fund-admin +npm install +npm run dev + +# 4. 访问系统 +# 管理后台:http://localhost:5173 +# 网关地址:http://localhost:8080 +# Nacos 控制台:http://localhost:8048/nacos +``` + +--- + +## 二、测试环境部署 + +### 2.1 服务器配置 + +| 组件 | 配置 | 数量 | +|------|------|------| +| 应用服务器 | 4核8G | 2台 | +| 数据库服务器 | 4核8G | 1台 | +| 缓存服务器 | 2核4G | 1台 | + +### 2.2 部署架构 + +``` +┌─────────────────────────────────────────────────────────────┐ +│ 测试环境部署架构 │ +├─────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ │ +│ │ Nginx │ ← 负载均衡 + 静态资源 │ +│ │ (80/443) │ │ +│ └──────┬───────┘ │ +│ │ │ +│ ┌──────┴──────┐ │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌─────────┐ ┌─────────┐ │ +│ │AppSrv-1 │ │AppSrv-2 │ ← 应用服务器(Gateway + Services)│ +│ │:8080-8090│ │:8080-8090│ │ +│ └────┬────┘ └────┬────┘ │ +│ │ │ │ +│ └─────┬──────┘ │ +│ │ │ +│ ┌────────┴────────┐ │ +│ │ │ │ +│ ▼ ▼ │ +│ ┌─────────┐ ┌─────────┐ │ +│ │ MySQL │ │ Redis │ │ +│ │ :3306 │ │ :6379 │ │ +│ └─────────┘ └─────────┘ │ +│ │ +│ ┌─────────┐ │ +│ │ Nacos │ ← 服务注册与配置中心 │ +│ │ :8848 │ │ +│ └─────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────┘ +``` + +### 2.3 部署步骤 + +#### 2.3.1 部署 Nacos + +```bash +# 在服务器上安装 Nacos +cd /opt +wget https://github.com/alibaba/nacos/releases/download/3.0.0/nacos-server-3.0.0.tar.gz +tar -xzf nacos-server-3.0.0.tar.gz +cd nacos/conf + +# 配置 MySQL 持久化 +cat >> application.properties << EOF +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://mysql-server:3306/nacos?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=Asia/Shanghai +db.user.0=nacos +db.password.0=nacos_password +EOF + +# 启动 Nacos(集群模式) +cd /opt/nacos/bin +sh startup.sh +``` + +#### 2.3.2 部署 MySQL + +```bash +# 创建数据库和用户 +mysql -u root -p << EOF +CREATE DATABASE IF NOT EXISTS fund_platform CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; +CREATE USER 'fund_user'@'%' IDENTIFIED BY 'Fund@123456'; +GRANT ALL PRIVILEGES ON fund_platform.* TO 'fund_user'@'%'; +FLUSH PRIVILEGES; +EOF + +# 导入表结构和数据 +mysql -u fund_user -p'Fund@123456' fund_platform < fund_platform_schema.sql +mysql -u fund_user -p'Fund@123456' fund_platform < fund_platform_init.sql +``` + +#### 2.3.3 部署 Redis + +```bash +# 配置 Redis +sudo tee /etc/redis/redis.conf > /dev/null << EOF +bind 0.0.0.0 +port 6379 +requirepass Redis@123456 +maxmemory 2gb +maxmemory-policy allkeys-lru +appendonly yes +EOF + +# 启动 Redis +sudo systemctl restart redis +``` + +#### 2.3.4 部署应用服务 + +```bash +# 1. 打包应用 +cd fundplatform +mvn clean package -DskipTests + +# 2. 上传 jar 包到服务器 +scp fund-gateway/target/fund-gateway-1.0.0.jar user@app-server-1:/opt/fundplatform/ +scp fund-sys/target/fund-sys-1.0.0.jar user@app-server-1:/opt/fundplatform/ + +# 3. 创建启动脚本 +cat > /opt/fundplatform/start.sh << 'EOF' +#!/bin/bash +APP_NAME=$1 +JAR_FILE=$2 + +nohup java -Xms512m -Xmx1024m \ + -Dspring.profiles.active=test \ + -Dfile.encoding=UTF-8 \ + -jar $JAR_FILE > logs/$APP_NAME.log 2>&1 & + +echo "$APP_NAME started, PID: $!" +EOF + +chmod +x /opt/fundplatform/start.sh + +# 4. 启动服务 +./start.sh gateway fund-gateway-1.0.0.jar +./start.sh sys fund-sys-1.0.0.jar +``` + +#### 2.3.5 部署 Nginx + +```bash +# 安装 Nginx +sudo apt install nginx + +# 配置反向代理 +sudo tee /etc/nginx/sites-available/fundplatform << 'EOF' +upstream gateway { + server app-server-1:8080 weight=5; + server app-server-2:8080 weight=5; +} + +server { + listen 80; + server_name test.fundplatform.com; + + # 前端静态资源 + location / { + root /opt/fundplatform/admin; + try_files $uri $uri/ /index.html; + } + + # API 代理 + location /api/ { + proxy_pass http://gateway/; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} +EOF + +sudo ln -s /etc/nginx/sites-available/fundplatform /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl restart nginx +``` + +--- + +## 三、生产环境部署 + +### 3.1 服务器配置 + +| 组件 | 配置 | 数量 | 说明 | +|------|------|------|------| +| 应用服务器 | 8核16G | 3台 | 运行 Gateway 和微服务 | +| 数据库服务器 | 8核16G | 2台 | MySQL 主从 | +| 缓存服务器 | 4核8G | 3台 | Redis 集群 | +| Nacos 服务器 | 4核8G | 3台 | Nacos 集群 | +| Nginx 服务器 | 4核8G | 2台 | 负载均衡 | + +### 3.2 部署架构 + +``` +┌─────────────────────────────────────────────────────────────────────────────┐ +│ 生产环境部署架构 │ +├─────────────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────────┐ ┌──────────────┐ │ +│ │ Nginx-1 │◄────────────►│ Nginx-2 │ ← 负载均衡(Keepalived) │ +│ │ (VIP:80/443)│ │ │ │ +│ └──────┬───────┘ └──────┬───────┘ │ +│ │ │ │ +│ └──────────────┬───────────────┘ │ +│ │ │ +│ ┌─────────────────────┼─────────────────────┐ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │AppSrv-1 │ │AppSrv-2 │ │AppSrv-3 │ ← 应用服务集群 │ +│ │:8080-8090│ │:8080-8090│ │:8080-8090│ │ +│ └────┬────┘ └────┬────┘ └────┬────┘ │ +│ │ │ │ │ +│ └───────────────────┼───────────────────┘ │ +│ │ │ +│ ┌──────────────────────┼──────────────────────┐ │ +│ │ │ │ │ +│ ▼ ▼ ▼ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ MySQL │◄────────►│ MySQL │ │ Redis │ ← 数据层 │ +│ │ Master │ 主从 │ Slave │ │ Cluster │ │ +│ │ :3306 │ 复制 │ :3306 │ │ :6379 │ │ +│ └─────────┘ └─────────┘ └────┬────┘ │ +│ │ │ +│ ┌─────────────────────────────────────────────┘ │ +│ │ │ +│ ▼ │ +│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ +│ │ Nacos-1 │◄►│ Nacos-2 │◄►│ Nacos-3 │ ← Nacos 集群(外置 MySQL) │ +│ │ :8848 │ │ :8848 │ │ :8848 │ │ +│ └─────────┘ └─────────┘ └─────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────────────┘ +``` + +### 3.3 高可用配置 + +#### 3.3.1 MySQL 主从配置 + +```bash +# 主库配置 +[mysqld] +server-id=1 +log-bin=mysql-bin +binlog-do-db=fund_platform + +# 从库配置 +[mysqld] +server-id=2 +relay-log=mysql-relay-bin +replicate-do-db=fund_platform + +# 创建复制用户 +CREATE USER 'repl'@'%' IDENTIFIED BY 'Repl@123456'; +GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; + +# 从库执行 +CHANGE MASTER TO + MASTER_HOST='master-host', + MASTER_USER='repl', + MASTER_PASSWORD='Repl@123456', + MASTER_LOG_FILE='mysql-bin.000001', + MASTER_LOG_POS=154; +START SLAVE; +``` + +#### 3.3.2 Redis 集群配置 + +```bash +# 创建 6 个节点(3主3从) +redis-server --port 7001 --cluster-enabled yes --cluster-config-file nodes-7001.conf +redis-server --port 7002 --cluster-enabled yes --cluster-config-file nodes-7002.conf +redis-server --port 7003 --cluster-enabled yes --cluster-config-file nodes-7003.conf +redis-server --port 7004 --cluster-enabled yes --cluster-config-file nodes-7004.conf +redis-server --port 7005 --cluster-enabled yes --cluster-config-file nodes-7005.conf +redis-server --port 7006 --cluster-enabled yes --cluster-config-file nodes-7006.conf + +# 创建集群 +redis-cli --cluster create \ + node1:7001 node1:7002 node2:7003 node2:7004 node3:7005 node3:7006 \ + --cluster-replicas 1 +``` + +#### 3.3.3 Nacos 集群配置 + +```bash +# 配置 cluster.conf +cat > /opt/nacos/conf/cluster.conf << EOF +nacos-1:8848 +nacos-2:8848 +nacos-3:8848 +EOF + +# 配置 MySQL 持久化 +spring.datasource.platform=mysql +db.num=1 +db.url.0=jdbc:mysql://mysql-cluster:3306/nacos?... +db.user.0=nacos +db.password.0=nacos_password + +# 启动 Nacos +sh startup.sh +``` + +#### 3.3.4 Nginx + Keepalived + +```bash +# 安装 Keepalived +sudo apt install keepalived + +# 配置 Keepalived(主节点) +cat > /etc/keepalived/keepalived.conf << EOF +global_defs { + router_id NGINX_MASTER +} + +vrrp_script check_nginx { + script "/etc/keepalived/check_nginx.sh" + interval 2 + weight -20 +} + +vrrp_instance VI_1 { + state MASTER + interface eth0 + virtual_router_id 51 + priority 100 + advert_int 1 + + authentication { + auth_type PASS + auth_pass 1111 + } + + virtual_ipaddress { + 192.168.1.100/24 + } + + track_script { + check_nginx + } +} +EOF + +# 健康检查脚本 +cat > /etc/keepalived/check_nginx.sh << 'EOF' +#!/bin/bash +if ! pgrep nginx > /dev/null; then + systemctl start nginx + sleep 2 + if ! pgrep nginx > /dev/null; then + systemctl stop keepalived + fi +fi +EOF + +chmod +x /etc/keepalived/check_nginx.sh +``` + +--- + +## 四、运维手册 + +### 4.1 监控体系 + +#### 4.1.1 应用监控(Prometheus + Grafana) + +```yaml +# prometheus.yml +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'fund-gateway' + metrics_path: '/actuator/prometheus' + static_configs: + - targets: ['app-server-1:8080', 'app-server-2:8080', 'app-server-3:8080'] + + - job_name: 'fund-sys' + metrics_path: '/actuator/prometheus' + static_configs: + - targets: ['app-server-1:8081', 'app-server-2:8081', 'app-server-3:8081'] +``` + +#### 4.1.2 关键监控指标 + +| 指标 | 告警阈值 | 说明 | +|------|----------|------| +| JVM 内存使用率 | > 80% | JVM 堆内存使用百分比 | +| CPU 使用率 | > 80% | 服务器 CPU 使用率 | +| 磁盘使用率 | > 85% | 磁盘空间使用百分比 | +| 接口响应时间 | > 2s | API 平均响应时间 | +| 错误率 | > 5% | HTTP 5xx 错误率 | +| MySQL 连接数 | > 80% | 数据库连接数使用率 | +| Redis 内存使用率 | > 80% | Redis 内存使用百分比 | + +### 4.2 日志管理 + +#### 4.2.1 日志配置 + +```xml + + + + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] [%X{tid}] [%X{uid}] [%X{uname}] %-5level %logger{36} - %msg%n + + + + + + /var/log/fundplatform/app.log + + /var/log/fundplatform/app.%d{yyyy-MM-dd}.%i.log + 30 + 100MB + + + %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{traceId}] %-5level %logger{36} - %msg%n + + + + + + + + +``` + +#### 4.2.2 ELK 日志收集 + +```yaml +# filebeat.yml +filebeat.inputs: +- type: log + enabled: true + paths: + - /var/log/fundplatform/*.log + fields: + service: fundplatform + multiline.pattern: '^\d{4}-\d{2}-\d{2}' + multiline.negate: true + multiline.match: after + +output.elasticsearch: + hosts: ["elasticsearch:9200"] + index: "fundplatform-%{+yyyy.MM.dd}" +``` + +### 4.3 备份策略 + +#### 4.3.1 数据库备份 + +```bash +#!/bin/bash +# 数据库备份脚本 + +BACKUP_DIR="/backup/mysql" +DATE=$(date +%Y%m%d_%H%M%S) +DB_NAME="fund_platform" +DB_USER="backup_user" +DB_PASS="Backup@123456" + +# 全量备份 +mysqldump -u$DB_USER -p$DB_PASS --single-transaction --routines --triggers $DB_NAME > $BACKUP_DIR/${DB_NAME}_${DATE}.sql + +# 压缩 +gzip $BACKUP_DIR/${DB_NAME}_${DATE}.sql + +# 删除 7 天前的备份 +find $BACKUP_DIR -name "${DB_NAME}_*.sql.gz" -mtime +7 -delete + +# 上传到对象存储 +aws s3 cp $BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz s3://fundplatform-backup/mysql/ +``` + +#### 4.3.2 备份计划 + +| 备份类型 | 频率 | 保留时间 | +|----------|------|----------| +| 全量备份 | 每天 02:00 | 30 天 | +| 增量备份 | 每小时 | 7 天 | +| 二进制日志 | 实时 | 7 天 | + +### 4.4 故障处理 + +#### 4.4.1 常见故障及处理 + +| 故障现象 | 可能原因 | 处理方案 | +|----------|----------|----------| +| 服务无法启动 | 端口冲突 | 检查端口占用,修改配置 | +| 数据库连接失败 | 连接池耗尽 | 增加连接池大小,检查慢查询 | +| 内存溢出 | 内存泄漏 | 分析堆转储,重启服务 | +| 接口超时 | 下游服务慢 | 检查依赖服务,增加熔断 | +| Redis 连接失败 | 连接数超限 | 增加连接池,检查连接泄露 | + +#### 4.4.2 应急处理流程 + +``` +1. 故障发现 + ↓ +2. 故障确认(查看监控、日志) + ↓ +3. 故障定级(P0-核心功能不可用,P1-部分功能受影响,P2-轻微影响) + ↓ +4. 启动应急预案 + - P0:立即回滚或重启 + - P1:限流降级,保留核心功能 + - P2:记录问题,计划修复 + ↓ +5. 故障恢复验证 + ↓ +6. 故障复盘 +``` + +### 4.5 性能优化 + +#### 4.5.1 JVM 调优 + +```bash +# 生产环境 JVM 参数 +java -server \ + -Xms4g -Xmx4g \ + -XX:MetaspaceSize=256m \ + -XX:MaxMetaspaceSize=512m \ + -XX:+UseG1GC \ + -XX:MaxGCPauseMillis=200 \ + -XX:+HeapDumpOnOutOfMemoryError \ + -XX:HeapDumpPath=/var/log/fundplatform/heapdump.hprof \ + -jar app.jar +``` + +#### 4.5.2 MySQL 调优 + +```ini +# my.cnf +[mysqld] +# 连接配置 +max_connections = 500 +max_connect_errors = 1000 +wait_timeout = 600 +interactive_timeout = 600 + +# InnoDB 配置 +innodb_buffer_pool_size = 4G +innodb_log_file_size = 512M +innodb_flush_log_at_trx_commit = 2 +innodb_flush_method = O_DIRECT + +# 查询缓存 +query_cache_type = 1 +query_cache_size = 256M + +# 慢查询日志 +slow_query_log = 1 +slow_query_log_file = /var/log/mysql/slow.log +long_query_time = 2 +``` + +#### 4.5.3 Redis 调优 + +```bash +# redis.conf +maxmemory 4gb +maxmemory-policy allkeys-lru +tcp-keepalive 300 +timeout 0 +``` + +--- + +## 五、附录 + +### 5.1 常用命令 + +```bash +# 查看服务状态 +systemctl status mysql +systemctl status redis +systemctl status nginx + +# 查看日志 +tail -f /var/log/fundplatform/app.log +tail -f /var/log/nginx/access.log + +# 查看进程 +ps -ef | grep java +netstat -tlnp | grep 8080 + +# 数据库操作 +mysql -u root -p +redis-cli -a password + +# Nacos 管理 +curl http://localhost:8848/nacos/v1/ns/instance/list?serviceName=fund-sys +``` + +### 5.2 端口清单 + +| 服务 | 端口 | 说明 | +|------|------|------| +| Nginx | 80/443 | Web 服务 | +| Gateway | 8080 | API 网关 | +| fund-sys | 8081 | 系统服务 | +| fund-cust | 8082 | 客户中心 | +| fund-proj | 8083 | 项目中心 | +| fund-req | 8084 | 需求中心 | +| fund-exp | 8085 | 支出中心 | +| fund-receipt | 8086 | 收款中心 | +| MySQL | 3306 | 数据库 | +| Redis | 6379 | 缓存 | +| Nacos | 8848 | 服务注册 | +| Nacos 控制台 | 8048 | 配置中心 | + +--- + +**文档结束**