Files
backmanager-server/API.md
2026-06-25 21:53:24 +08:00

40 KiB
Raw Blame History

蜜雪冰城企业管理系统 —— 后端 API 文档

蜜雪冰城总部用于管理加盟商、合同、员工、产品、供应商及售后服务的企业信息管理系统后端服务。

目录


快速开始

环境要求

  • Node.js >= 18
  • MySQL 5.7+ / MariaDB 10.2+

安装与运行

# 1. 安装依赖
npm install

# 2. 配置环境变量
cp .env.example .env
# 编辑 .env 填入数据库连接信息和 JWT 密钥

# 3. 启动开发服务(自动重启)
npm run dev

# 4. 启动生产服务
npm start

# 5. 运行集成测试(需先启动服务)
node test-all.js

环境变量 (.env)

变量 说明 默认值
PORT 服务端口 3000
DB_HOST MySQL 主机
DB_PORT MySQL 端口 3306
DB_USER MySQL 用户名
DB_PASSWORD MySQL 密码
DB_NAME 数据库名 backmanager
JWT_SECRET JWT 签名密钥
JWT_EXPIRES_IN Token 有效期 2h

首次启动时,系统会自动创建数据库、建表、初始化角色权限和预置用户。


技术栈

技术 用途
Express 5 Web 框架
mysql2/promise MySQL 驱动(连接池 + Promise
jsonwebtoken JWT 认证
bcryptjs 密码哈希加密
dotenv 环境变量管理

项目结构

backmanager-server/
├── server.js                  # 入口Express 应用、鉴权中间件、路由注册
├── db.js                      # 数据库:连接池、建表、种子数据
├── middleware/
│   └── permissions.js         # RBAC权限检查 + 数据范围过滤
├── routes/
│   ├── users.js               # 用户登录/信息/CRUD
│   ├── customers.js           # 加盟商 CRUD
│   ├── employees.js           # 员工 CRUD
│   ├── contracts.js           # 合同 CRUD
│   ├── afterSales.js          # 售后 CRUD
│   ├── products.js            # 产品 CRUD
│   └── suppliers.js           # 供应商 CRUD
├── test-all.js                # 集成测试(覆盖 6 个角色的权限与数据隔离)
├── .env.example               # 环境变量模板
└── package.json

认证机制

所有 API除登录外需要在请求头中携带 JWT Token

Authorization: Bearer <token>

Token 获取

通过 POST /api/user/login 登录获取 Token。

Token 有效载荷 (Payload)

{
  "id": 1,
  "username": "admin",
  "name": "系统管理员",
  "role_id": 1,
  "roleName": "admin",
  "department": "信息技术部",
  "permissions": ["customer:read", "customer:create", "customer:update", "customer:delete", "contract:read", "..."]
}

认证流程

客户端请求 → auth 中间件验证 Token → checkPermission 检查权限 → 路由处理 → 数据范围过滤getDataScope→ 返回响应

错误响应

HTTP 状态码 场景
401 未携带 Token 或 Token 无效/过期
403 权限不足(无对应操作权限或数据不在可见范围内)

API 接口总览

通用说明

  • 分页参数:所有列表接口支持 page(页码,从 1 开始,默认 1pageSize(每页条数,默认 10最大 100
  • 分页响应:列表接口返回 { list, total, page, pageSize, totalPages }
  • 搜索参数:通过 URL Query String 传递,如 GET /api/customers?name=张&phone=138
  • 部分更新PUT 接口只传需要修改的字段即可,未传字段保持不变

1. 用户认证

POST /api/user/login — 登录

无需 Token。

请求体:

{
  "username": "admin",
  "password": "123456"
}

成功响应:

{
  "code": 200,
  "message": "ok",
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "userInfo": {
      "id": 1,
      "username": "admin",
      "name": "系统管理员",
      "role_id": 1,
      "roleName": "admin",
      "department": "信息技术部",
      "permissions": ["customer:read", "customer:create", "..."]
    }
  }
}

注意:登录成功返回 code: 200,其他接口统一返回 code: 0。前端通过 res.code === 0 || res.code === 200 兼容判断。

错误响应:

code message
400 用户名和密码必填
400 账号或密码错误
403 账号已被禁用,请联系管理员

GET /api/user/info — 获取当前用户信息

需要 Token。返回当前登录用户的完整信息含角色名、员工名

GET /api/user/list — 简易用户列表

需要 Token。返回所有启用用户的基本信息id、用户名、真实姓名用于前端下拉选择负责人。

响应数据字段:

字段 类型 说明
id number 用户 ID
username string 用户名
real_name string 真实姓名(来自员工表,可能为 null

POST /api/user/logout — 登出

需要 Token。服务端无状态仅返回成功应答客户端自行清除 Token。

PUT /api/user/password — 修改密码

需要 Token。修改当前登录用户自己的密码。

请求体:

{
  "oldPassword": "123456",
  "newPassword": "654321"
}

校验规则:

  • 旧密码和新密码必填
  • 新密码至少 6 位
  • 新密码不能与旧密码相同

2. 用户管理

需要 user:manage 权限(仅系统管理员拥有)。

GET /api/users — 用户列表

查询参数:

参数 说明 示例
username 按用户名模糊搜索 ?username=admin
real_name 按真实姓名模糊搜索 ?real_name=张
id 按用户 ID 精确搜索 ?id=1
role_id 按角色 ID 过滤 ?role_id=2
is_active 按状态过滤0-禁用, 1-启用) ?is_active=1
page 页码 ?page=1
pageSize 每页条数 ?pageSize=10

响应数据字段:

字段 类型 说明
id number 用户 ID
username string 用户名
is_active number 状态0-禁用, 1-启用
role_id number 角色 ID
role_name string 角色标识(如 admin
role_description string 角色描述(如 系统管理员)
employee_id number 关联员工 ID
real_name string 真实姓名(来自员工表)
department string 所属部门
created_at datetime 创建时间
updated_at datetime 更新时间

GET /api/users/:id — 用户详情

返回单个用户完整信息。

POST /api/users — 创建用户

请求体:

字段 必填 说明
username 用户名3-50 字符)
password 密码(至少 6 位)
role_id 角色 ID需为已存在的角色
employee_id 关联员工 ID需为已存在的员工会自动同步部门信息
department 所属部门(若填了 employee_id 且未传 department会自动从员工表同步
is_active 状态,默认 1

PUT /api/users/:id — 更新用户

可更新字段: usernamerole_idemployee_iddepartmentis_activepassword

限制:

  • 不能修改自己的角色
  • 不能禁用自己

DELETE /api/users/:id — 删除用户

限制:

  • 不能删除自己
  • 不能删除最后一个管理员账号(当系统中仅剩 1 个 admin 角色用户时,拒绝删除)

3. 加盟商管理

需要 customer:read / customer:create / customer:update / customer:delete 权限。

GET /api/customers — 加盟商列表

查询参数:

参数 说明
id 按 ID 精确搜索
name 按加盟商名称模糊搜索
phone 按电话模糊搜索
province 按省份精确匹配
city 按城市精确匹配

响应数据字段(含 JOIN 字段):

字段 类型 说明
id number 加盟商 ID
name string 加盟商姓名
phone string 联系电话
province string
city string
district string
address string 详细地址
email string 电子邮箱
remark string 备注信息
responsible_user_id number 负责人用户 ID
responsible_user_name string 负责人姓名JOIN 自 users → employees
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/customers — 新增加盟商

请求体:

字段 必填 说明
name 加盟商姓名
phone 联系电话
province
city
district
address 详细地址
email 电子邮箱
remark 备注
responsible_user_id 负责人(默认为当前登录用户,仅管理员可在前端修改)

PUT /api/customers/:id — 更新加盟商

所有字段均可选,只传需要修改的字段。

DELETE /api/customers/:id — 删除加盟商


4. 员工管理

需要 employee:read / employee:create / employee:update / employee:delete 权限。

GET /api/employees/simple — 简易员工列表

需要 Token。无数据范围限制用于前端下拉选择如售后分配业务员。支持按部门过滤。

查询参数:

参数 说明
department 按部门精确过滤(如 ?department=运营部

响应数据字段:

字段 类型 说明
id number 员工 ID
name string 姓名
department string 所属部门
position string 职务/岗位

GET /api/employees — 员工列表

查询参数:

参数 说明
id 按 ID 精确搜索
name 按姓名模糊搜索
department 按部门模糊搜索
status 按在职状态过滤0-离职, 1-在职)

响应数据字段:

字段 类型 说明
id number 员工 ID
name string 姓名
gender string 性别(男/女)
age number 年龄
education string 学历
department string 所属部门
entry_date date 入职时间
position string 职务/岗位
salary number 工资金额
phone string 联系电话
email string 电子邮箱
status number 在职状态0-离职, 1-在职
remark string 备注
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/employees — 新增员工

请求体:

字段 必填 说明
name 员工姓名
gender 性别
age 年龄
education 学历
department 部门
entry_date 入职时间格式YYYY-MM-DD
position 职务
salary 工资
phone 电话
email 邮箱
status 在职状态,默认 1
remark 备注

PUT /api/employees/:id — 更新员工

所有字段均可选,只传需要修改的字段。

特殊行为: 更新 department 字段时,会自动同步到关联的 users 表的 department 字段。

DELETE /api/employees/:id — 删除员工

特殊行为:

  • 删除员工时会同步删除关联的用户账号users 表中 employee_id 匹配的记录)
  • 不能删除当前登录用户自己关联的员工账号

5. 合同管理

需要 contract:read / contract:create / contract:update / contract:delete 权限。

GET /api/contracts — 合同列表

查询参数:

参数 说明
id 按 ID 精确搜索
status 按合同状态过滤(草稿/生效中/已完成/作废)
customer_name 按客户名称模糊搜索
contract_no 按合同编号模糊搜索
contract_name 按合同名称模糊搜索
employee_name 按业务员姓名模糊搜索
effective_date_start 按生效日期起始过滤格式YYYY-MM-DD
effective_date_end 按生效日期截止过滤格式YYYY-MM-DD

响应数据字段(含 JOIN 字段):

字段 类型 说明
id number 合同 ID
customer_id number 客户 ID
customer_name string 客户名称JOIN 自 customers
supplier_id number 供应商 ID采购合同必填
supplier_name string 供应商名称JOIN 自 suppliers
contract_name string 合同名称
contract_no string 合同编号
contract_content string 合同内容/条款
amount number 合同金额
effective_date date 生效日期
expiry_date date 到期日期
employee_id number 业务员 ID
employee_name string 业务员姓名JOIN 自 employees
status string 状态:草稿/生效中/已完成/作废
remark string 备注
type string 合同类型:franchise(加盟)/ supply(采购)
responsible_user_id number 负责人用户 ID
responsible_user_name string 负责人姓名JOIN 自 users → employees
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/contracts — 新增合同

请求体:

字段 必填 说明
customer_id 条件必填 关联客户 ID加盟合同必填
supplier_id 条件必填 关联供应商 ID采购合同必填
contract_name 合同名称
contract_no 合同编号
contract_content 合同内容
amount 合同金额
effective_date 生效日期
expiry_date 到期日期
employee_id 业务员 ID
status 状态,默认 生效中
remark 备注
type 合同类型(见下方说明)
responsible_user_id 负责人(默认为当前用户,仅管理员可在前端修改)

合同类型自动设置与角色限制规则:

  • 采购经理(procurement_manager)创建的合同只能supply(采购合同),且必须选择 supplier_id
  • 招商经理(franchise_manager)创建的合同只能franchise(加盟合同),且必须选择 customer_id
  • 其他角色默认 franchise,也可手动指定 type

校验规则:

  • customer_id 必须为已存在的客户
  • supplier_id 必须为已存在的供应商
  • employee_id(如填写)必须为已存在的员工

PUT /api/contracts/:id — 更新合同

所有字段均可选。可更新字段包括 typesupplier_idresponsible_user_id

校验规则: 更新 customer_idsupplier_idemployee_id 时会校验关联记录是否存在。

DELETE /api/contracts/:id — 删除合同


6. 售后管理

需要 after_sale:read / after_sale:create / after_sale:update / after_sale:delete 权限。

GET /api/after-sales — 售后列表

查询参数:

参数 说明
id 按 ID 精确搜索
customer_id 按客户 ID 精确搜索
customer_name 按客户名称模糊搜索
handle_status 按处理状态过滤(待处理/处理中/已完成)
feedback 按反馈内容模糊搜索

响应数据字段(含 JOIN 字段):

字段 类型 说明
id number 售后记录 ID
customer_id number 客户 ID
customer_name string 客户名称JOIN 自 customers
feedback string 客户反馈意见
employee_id number 处理业务员 ID
employee_name string 业务员姓名JOIN 自 employees
handle_method string 处理方式/解决方案
handle_status string 处理状态:待处理/处理中/已完成
service_date date 售后日期
remark string 备注
responsible_user_id number 负责人用户 ID
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/after-sales — 新增售后

请求体:

字段 必填 说明
customer_id 关联客户 ID
feedback 售后反馈内容
employee_id 处理业务员 ID前端仅显示运营部员工
handle_method 处理方式
handle_status 处理状态,默认 待处理
service_date 售后日期
remark 备注
responsible_user_id 负责人(默认为当前用户,仅管理员可在前端修改)

校验规则:

  • customer_id 必须为已存在的客户
  • employee_id(如填写)必须为已存在的员工

PUT /api/after-sales/:id — 更新售后

所有字段均可选。

校验规则: 更新 customer_idemployee_id 时会校验关联记录是否存在。

DELETE /api/after-sales/:id — 删除售后


7. 产品管理

需要 product:read / product:create / product:update / product:delete 权限。 无数据范围隔离,拥有权限即可查看所有产品。

GET /api/products — 产品列表

查询参数:

参数 说明
id 按 ID 精确搜索
name 按产品名称模糊搜索
type 按产品类型模糊搜索
supplier 按供应商名称模糊搜索

响应数据字段:

字段 类型 说明
id number 产品 ID
name string 产品名称
type string 产品类型/分类
quantity number 库存数量
price number 单价
unit string 计量单位(默认"件"
specification string 规格/型号
supplier string 供应商名称
remark string 备注
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/products — 新增产品

请求体:

字段 必填 说明
name 产品名称
type 类型
quantity 库存数量,默认 0
price 单价,默认 0.00
unit 单位,默认"件"
specification 规格
supplier 供应商名称
remark 备注

PUT /api/products/:id — 更新产品

所有字段均可选。

DELETE /api/products/:id — 删除产品


8. 供应商管理

需要 supplier:read / supplier:create / supplier:update / supplier:delete 权限。 无数据范围隔离,拥有权限即可查看所有供应商。

GET /api/suppliers — 供应商列表

查询参数:

参数 说明
id 按 ID 精确搜索
name 按供应商名称模糊搜索
type 按类型模糊搜索
status 按状态过滤0-停用, 1-正常)

响应数据字段:

字段 类型 说明
id number 供应商 ID
name string 供应商名称
contact string 联系人
phone string 联系电话
address string 地址
type string 类型(原材料/包装/设备)
content string 备注说明
status number 状态0-停用, 1-正常
created_at datetime 创建时间
updated_at datetime 更新时间

POST /api/suppliers — 新增供应商

请求体:

字段 必填 说明
name 供应商名称
contact 联系人
phone 联系电话
address 地址
type 类型
content 备注说明
status 状态,默认 1

PUT /api/suppliers/:id — 更新供应商

所有字段均可选。

DELETE /api/suppliers/:id — 删除供应商


统一响应格式

成功响应

{
  "code": 0,
  "message": "ok",
  "data": { ... }
}

列表响应

{
  "code": 0,
  "message": "ok",
  "data": {
    "list": [ ... ],
    "total": 100,
    "page": 1,
    "pageSize": 10,
    "totalPages": 10
  }
}

错误响应

{
  "code": 403,
  "message": "权限不足"
}
HTTP 状态码 code 说明
400 400 参数错误 / 校验失败 / 关联记录不存在
401 401 未登录 / Token 无效
403 403 权限不足 / 账号被禁用 / 角色操作限制
404 404 资源不存在
409 409 数据冲突(如用户名重复)
500 500 服务器内部错误

数据库设计

表结构详情

1. users — 系统用户表

存储系统登录账号,每个用户关联一个角色和一个员工。

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 用户 ID
username VARCHAR(50) NOT NULL, UNIQUE 用户名(登录账号)
password VARCHAR(255) NOT NULL 密码bcrypt 哈希)
is_active TINYINT(1) NOT NULL DEFAULT 1 账号状态0-禁用, 1-启用
role_id INT NULLABLE 角色 ID → roles.id
employee_id INT NULLABLE, UNIQUE 员工 ID → employees.id
department VARCHAR(100) NULLABLE 所属部门(冗余字段,从 employees 同步)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

2. roles — 角色表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 角色 ID
name VARCHAR(50) NOT NULL, UNIQUE 角色标识(英文)
description VARCHAR(200) NULLABLE 角色描述(中文)
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间

3. permissions — 权限表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 权限 ID
name VARCHAR(100) NOT NULL, UNIQUE 权限标识(resource:action 格式)
description VARCHAR(200) NULLABLE 权限描述(中文)
resource VARCHAR(50) NOT NULL 资源名称
action VARCHAR(50) NOT NULL 操作类型

4. role_permissions — 角色-权限关联表

字段 类型 约束 说明
role_id INT PK (联合) 角色 ID → roles.id
permission_id INT PK (联合) 权限 ID → permissions.id

5. customers — 加盟商信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 加盟商 ID
name VARCHAR(100) NOT NULL, INDEX 加盟商姓名
phone VARCHAR(20) INDEX 联系电话
province VARCHAR(50)
city VARCHAR(50)
district VARCHAR(50)
address VARCHAR(200) 详细地址
email VARCHAR(100) 电子邮箱
remark TEXT 备注信息
responsible_user_id INT 负责人用户 ID → users.id
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

6. employees — 员工信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 员工 ID
name VARCHAR(100) NOT NULL, INDEX 姓名
gender VARCHAR(4) 性别:男/女
age INT 年龄
education VARCHAR(50) 学历
department VARCHAR(100) INDEX 所属部门
entry_date DATE 入职时间
position VARCHAR(100) 职务/岗位
salary DECIMAL(10,2) 工资金额
phone VARCHAR(20) 联系电话
email VARCHAR(100) 电子邮箱
status TINYINT(1) NOT NULL DEFAULT 1 在职状态0-离职, 1-在职
remark TEXT 备注
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

7. contracts — 合同信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 合同 ID
customer_id INT NULLABLE, INDEX 客户 ID → customers.id加盟合同必填
supplier_id INT NULLABLE, INDEX 供应商 ID → suppliers.id采购合同必填
contract_name VARCHAR(200) NOT NULL 合同名称
contract_no VARCHAR(100) 合同编号
contract_content TEXT 合同内容/条款
amount DECIMAL(12,2) 合同金额
effective_date DATE INDEX 生效日期
expiry_date DATE 到期日期
employee_id INT INDEX 业务员 ID → employees.id
status VARCHAR(20) NOT NULL DEFAULT '生效中' 状态:草稿/生效中/已完成/作废
remark TEXT 备注
type VARCHAR(20) NOT NULL DEFAULT 'franchise' 类型:franchise(加盟) / supply(采购)
responsible_user_id INT 负责人用户 ID → users.id
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

8. after_sales — 售后信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 售后记录 ID
customer_id INT NOT NULL, INDEX 客户 ID → customers.id
feedback TEXT NOT NULL 客户反馈意见
employee_id INT INDEX 处理业务员 ID → employees.id
handle_method TEXT 处理方式/解决方案
handle_status VARCHAR(20) NOT NULL DEFAULT '待处理', INDEX 状态:待处理/处理中/已完成
service_date DATE 售后日期
remark TEXT 备注
responsible_user_id INT 负责人用户 ID → users.id
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

9. products — 产品信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 产品 ID
name VARCHAR(200) NOT NULL, INDEX 产品名称
type VARCHAR(100) INDEX 产品类型/分类
quantity INT NOT NULL DEFAULT 0 库存数量
price DECIMAL(10,2) NOT NULL DEFAULT 0.00 单价
unit VARCHAR(20) DEFAULT '件' 计量单位
specification VARCHAR(200) 规格/型号
supplier VARCHAR(200) 供应商名称
remark TEXT 备注
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

10. suppliers — 供应商信息表

字段 类型 约束 说明
id INT PK, AUTO_INCREMENT 供应商 ID
name VARCHAR(200) NOT NULL, INDEX 供应商名称
contact VARCHAR(100) 联系人
phone VARCHAR(50) 联系电话
address VARCHAR(500) 地址
type VARCHAR(50) 类型(原材料/包装/设备)
content TEXT 备注说明
status TINYINT(1) NOT NULL DEFAULT 1 状态0-停用, 1-正常
created_at DATETIME DEFAULT CURRENT_TIMESTAMP 创建时间
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP 更新时间

表关系 ER 图

┌──────────────┐     ┌──────────────┐     ┌──────────────────┐
│    roles      │     │  permissions  │     │ role_permissions  │
│──────────────│     │──────────────│     │──────────────────│
│ id (PK)      │◄─┐  │ id (PK)      │◄─┐  │ role_id (PK,FK)  │
│ name         │  │  │ name         │  └──│ permission_id     │
│ description  │  │  │ description  │     │   (PK,FK)         │
└──────────────┘  │  │ resource     │     └──────────────────┘
                  │  │ action       │
                  │  └──────────────┘
                  │
┌──────────────┐  │  ┌──────────────┐
│    users      │  │  │  employees   │
│──────────────│  │  │──────────────│
│ id (PK)      │  │  │ id (PK)      │
│ username     │  │  │ name         │
│ password     │  │  │ gender       │
│ is_active    │  │  │ age          │
│ role_id (FK)─┼──┘  │ education    │
│ employee_id  │─ ─ ─│ department   │◄──────── users.department (冗余)
│   (FK) ──────┼──→  │ entry_date   │
│ department   │     │ position     │
│   (冗余)     │     │ salary       │
└──────┬───────┘     │ phone        │
       │             │ email        │
       │             │ status       │
       │             └──────┬───────┘
       │                    │
       ▼                    ▼
┌──────────────────────────────────────────────┐
│               customers (加盟商)               │
│──────────────────────────────────────────────│
│ id (PK)                                       │
│ name, phone, province, city, district, ...    │
│ responsible_user_id ──────────→ users.id      │
└────────────────────┬─────────────────────────┘
                     │
          ┌──────────┴──────────┐
          ▼                     ▼
┌──────────────────┐  ┌──────────────────┐
│    contracts      │  │   after_sales    │
│──────────────────│  │──────────────────│
│ id (PK)          │  │ id (PK)          │
│ customer_id (FK) │  │ customer_id (FK) │
│   → customers.id │  │   → customers.id │
│ supplier_id (FK) │  │ feedback         │
│   → suppliers.id │  │ employee_id (FK) │
│ contract_name    │  │   → employees.id │
│ contract_no      │  │ handle_method    │
│ amount           │  │ handle_status    │
│ employee_id (FK) │  │ service_date     │
│   → employees.id │  │ responsible_user │
│ status           │  │   _id → users.id │
│ type             │  └──────────────────┘
│   franchise/     │
│   supply         │
│ responsible_user │
│   _id → users.id │
└──────────────────┘

┌──────────────┐  ┌──────────────┐
│   products    │  │  suppliers   │
│──────────────│  │──────────────│
│ id (PK)      │  │ id (PK)      │
│ name         │  │ name         │
│ type         │  │ contact      │
│ quantity     │  │ phone        │
│ price        │  │ address      │
│ unit         │  │ type         │
│ specification│  │ content      │
│ supplier     │  │ status       │
└──────────────┘  └──────────────┘

关系说明:

关系 类型 说明
users → roles 多对一 一个用户属于一个角色,一个角色可以有多个用户
users → employees 一对一 一个用户关联一个员工(通过 employee_id唯一约束
roles ↔ permissions 多对多 通过 role_permissions 中间表关联
customers → users 多对一 通过 responsible_user_id 指定负责人
contracts → customers 多对一 通过 customer_id 关联客户(加盟合同必填)
contracts → suppliers 多对一 通过 supplier_id 关联供应商(采购合同必填)
contracts → employees 多对一 通过 employee_id 关联业务员
contracts → users 多对一 通过 responsible_user_id 指定负责人
after_sales → customers 多对一 通过 customer_id 关联客户
after_sales → employees 多对一 通过 employee_id 关联业务员
after_sales → users 多对一 通过 responsible_user_id 指定负责人

注意:数据库未设置外键约束,引用完整性由应用代码保证(插入/更新前检查关联记录是否存在)。


RBAC 权限系统

角色定义

系统预置 6 个角色,对应蜜雪冰城总部的组织架构:

角色标识 中文名 所属部门 职责概述
admin 系统管理员 信息技术部 系统全权管理,拥有所有权限
general_manager 总经理 总经理办公室 全局只读,查看所有业务数据
franchise_manager 招商经理 招商部 管理加盟商和加盟合同
operations_manager 运营经理 运营部 维护加盟商信息、处理售后
procurement_manager 采购经理 采购部 管理产品、供应商和采购合同
finance 财务人员 财务部 只读查看业务数据(加盟商、合同、售后、员工)

权限列表

共 25 个权限,按 资源:操作 格式命名:

权限标识 中文描述
加盟商 (customer)
customer:read 查看加盟商
customer:create 新增加盟商
customer:update 修改加盟商
customer:delete 删除加盟商
合同 (contract)
contract:read 查看合同
contract:create 新增合同
contract:update 修改合同
contract:delete 删除合同
售后 (after_sale)
after_sale:read 查看售后
after_sale:create 新增售后
after_sale:update 修改售后
after_sale:delete 删除售后
产品 (product)
product:read 查看产品原料
product:create 新增产品原料
product:update 修改产品原料
product:delete 删除产品原料
供应商 (supplier)
supplier:read 查看供应商
supplier:create 新增供应商
supplier:update 修改供应商
supplier:delete 删除供应商
员工 (employee)
employee:read 查看员工
employee:create 新增员工
employee:update 修改员工
employee:delete 删除员工
用户 (user)
user:manage 管理用户账号

角色-权限映射

权限 admin general_manager franchise_manager operations_manager procurement_manager finance
customer:read
customer:create
customer:update
customer:delete
contract:read
contract:create
contract:update
contract:delete
after_sale:read
after_sale:create
after_sale:update
after_sale:delete
product:read
product:create
product:update
product:delete
supplier:read
supplier:create
supplier:update
supplier:delete
employee:read
employee:create
employee:update
employee:delete
user:manage

数据范围隔离

拥有操作权限 ≠ 能看到所有数据。系统通过 getDataScope() 函数在 SQL 查询层面做数据隔离:

资源 admin general_manager franchise_manager operations_manager procurement_manager finance
customers 全部 全部 仅自己负责 仅自己负责 全部
contracts 全部 全部 仅自己负责的加盟合同 仅自己负责的加盟合同 仅采购合同 全部
after_sales 全部 全部 仅自己负责 全部
employees 全部 全部 仅本部门 仅本部门 仅本部门 全部
products 全部 全部 全部
suppliers 全部 全部 全部
users 全部

"—" 表示该角色无此资源的权限,请求会被权限中间件直接拦截(返回 403

隔离机制说明:

  • 负责人类资源customers、contracts、after_sales通过 responsible_user_id 字段过滤,只能看到自己负责的记录
  • 合同类型过滤contracts除了负责人类过滤还按合同 type 字段过滤franchise/supply
  • 部门类资源employees通过 department 字段过滤,只能看到自己部门的员工
  • 全局类资源products、suppliers无数据范围过滤只要有权限就能看到全部

合同类型与角色限制:

  • 采购经理(procurement_manager)只能查看和操作采购合同(type = 'supply'
  • 招商经理(franchise_manager)和运营经理(operations_manager)只能查看和操作加盟合同(type = 'franchise')中自己负责的记录
  • 创建合同时,采购经理只能创建采购合同,招商经理只能创建加盟合同

预置账号

系统首次启动时自动创建以下账号,密码均为 123456

用户名 姓名 角色 部门 职位
admin 系统管理员 admin 信息技术部 系统管理员
zhangchao 张超 general_manager 总经理办公室 总经理
liming 李明 franchise_manager 招商部 招商经理
wangli 王丽 operations_manager 运营部 运营经理
zhaoqiang 赵强 procurement_manager 采购部 采购经理
chenfang 陈芳 finance 财务部 财务主管

快速测试

# 以管理员身份登录
curl -X POST http://127.0.0.1:3000/api/user/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"123456"}'

# 以招商经理身份登录(只能看到自己负责的加盟商)
curl -X POST http://127.0.0.1:3000/api/user/login \
  -H "Content-Type: application/json" \
  -d '{"username":"liming","password":"123456"}'