设计一个通用的"在职继承和离职交接"模块,适用于教务CRM系统中的不同模块和业务,首先需要考虑以下几个方面:
- 跨模块支持: 该模块必须能够适应不同的业务需求,如教务管理、学员管理、课程管理等。因此,我们需要设计一个灵活的系统,能够支持不同模块的继承和交接。
- 角色区分: 需要支持不同角色的继承和交接,如老师、顾问、学员经理等。
- 交接记录: 对交接过程的每一个步骤进行记录,以便追溯。
- 交接状态管理: 管理交接的不同状态,如待交接、交接完成、交接中等。
1. 数据库表设计
1.1 基本表设计
我们需要设计以下几张表来支持"在职继承"和"离职交接":
- 员工表(employees):记录系统中所有员工的基本信息。
- 交接记录表(handover_records):记录员工的离职交接过程。
- 任务表(tasks):交接过程中涉及的具体任务。
- 角色表(roles):记录不同的角色类型,如顾问、老师、学员经理等。
- 业务模块表(business_modules):记录不同业务模块,如学员、课程、咨询等,便于后续支持多模块的交接。
1.2 数据库表结构
sql
-- 员工表
CREATE TABLE `employees` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 员工ID
`name` VARCHAR(100) NOT NULL, -- 姓名
`email` VARCHAR(100), -- 邮箱
`phone` VARCHAR(20), -- 电话
`role_id` BIGINT UNSIGNED NOT NULL, -- 角色ID
`status` INT NOT NULL DEFAULT 1, -- 状态: 1 在职, 0 离职
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 交接记录表
CREATE TABLE `handover_records` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 交接记录ID
`employee_id` BIGINT UNSIGNED NOT NULL, -- 员工ID
`handover_to_id` BIGINT UNSIGNED NOT NULL, -- 交接给谁
`handover_date` DATE NOT NULL, -- 交接日期
`status` INT NOT NULL DEFAULT 0, -- 状态: 0 待交接, 1 已交接, 2 交接中
`remarks` TEXT, -- 交接备注
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 交接任务表
CREATE TABLE `handover_tasks` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 任务ID
`handover_record_id` BIGINT UNSIGNED NOT NULL, -- 交接记录ID
`task_description` TEXT NOT NULL, -- 任务描述
`status` INT NOT NULL DEFAULT 0, -- 任务状态: 0 待完成, 1 完成, 2 进行中
`due_date` DATE, -- 任务截止日期
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 创建时间
`update_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP -- 更新时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色表
CREATE TABLE `roles` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 角色ID
`role_name` VARCHAR(50) NOT NULL, -- 角色名称
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 业务模块表
CREATE TABLE `business_modules` (
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, -- 模块ID
`module_name` VARCHAR(100) NOT NULL, -- 模块名称
`description` TEXT, -- 模块描述
`create_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. GoZero 实现简单的 Demo
接下来,我们用 GoZero 实现一个简单的 Demo,展示如何管理员工的离职交接和在职继承。
2.1 GoZero 项目结构
假设我们的项目结构如下:
go
/handover
/model
handover.go
employee.go
/service
handover_service.go
/controller
handover_controller.go
main.go
2.2 GoZero Model 定义
在 model
目录下,定义 HandoverRecord
和 Employee
两个模型。
go
// model/employee.go
package model
type Employee struct {
ID uint64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Phone string `json:"phone"`
RoleID uint64 `json:"role_id"`
Status int `json:"status"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
}
// model/handover.go
package model
type HandoverRecord struct {
ID uint64 `json:"id"`
EmployeeID uint64 `json:"employee_id"`
HandoverToID uint64 `json:"handover_to_id"`
HandoverDate string `json:"handover_date"`
Status int `json:"status"`
Remarks string `json:"remarks"`
CreateTime string `json:"create_time"`
UpdateTime string `json:"update_time"`
}
2.3 GoZero Service 实现
HandoverService
负责处理交接业务。
go
// service/handover_service.go
package service
import (
"context"
"handover/model"
"time"
)
type HandoverService struct {
// You can add dependencies like database or cache here
}
func (s *HandoverService) CreateHandoverRecord(ctx context.Context, record *model.HandoverRecord) (*model.HandoverRecord, error) {
record.CreateTime = time.Now().Format("2006-01-02 15:04:05")
record.UpdateTime = record.CreateTime
// In real implementation, save to database and return the result
return record, nil
}
func (s *HandoverService) GetHandoverRecord(ctx context.Context, id uint64) (*model.HandoverRecord, error) {
// Fetch the handover record from the database
return &model.HandoverRecord{
ID: id,
EmployeeID: 1,
HandoverToID: 2,
HandoverDate: "2025-01-05",
Status: 0,
Remarks: "Transfer task",
}, nil
}
2.4 GoZero Controller 实现
HandoverController
负责处理 HTTP 请求。
go
// controller/handover_controller.go
package controller
import (
"context"
"handover/service"
"handover/model"
"github.com/tal-tech/go-zero/rest"
"net/http"
)
type HandoverController struct {
HandoverService *service.HandoverService
}
func (c *HandoverController) CreateHandoverRecord(w http.ResponseWriter, r *http.Request) {
var record model.HandoverRecord
if err := rest.Parse(r, &record); err != nil {
rest.Error(w, err)
return
}
result, err := c.HandoverService.CreateHandoverRecord(context.Background(), &record)
if err != nil {
rest.Error(w, err)
return
}
rest.Response(w, result)
}
func (c *HandoverController) GetHandoverRecord(w http.ResponseWriter, r *http.Request) {
// Assume the record ID is passed as a query parameter
id := r.URL.Query().Get("id")
result, err := c.HandoverService.GetHandoverRecord(context.Background(), id)
if err != nil {
rest.Error(w, err)
return
}
rest.Response(w, result)
}
2.5 Main 函数 (继续)
go
// main.go
package main
import (
"handover/controller"
"handover/service"
"github.com/tal-tech/go-zero/rest"
"log"
"net/http"
)
func main() {
// Initialize the service layer
handoverService := &service.HandoverService{}
// Initialize the controller layer
handoverController := &controller.HandoverController{HandoverService: handoverService}
// Create a new router
r := rest.NewRouter()
// Define routes for the controller methods
r.Add(http.MethodPost, "/handover", handoverController.CreateHandoverRecord)
r.Add(http.MethodGet, "/handover", handoverController.GetHandoverRecord)
// Start the server on port 8080
log.Println("Starting server on :8080...")
if err := r.Start(":8080"); err != nil {
log.Fatalf("Failed to start server: %v", err)
}
}
在这个 main.go
文件中,我们通过 rest.NewRouter()
创建了一个新的路由实例,并添加了两个 HTTP 路由,分别是:
POST /handover
用于创建交接记录GET /handover
用于查询交接记录
启动服务器后,监听 8080
端口,等待 HTTP 请求。
3. 测试和验证
3.1 测试接口
在本地启动 GoZero 服务后,你可以使用 curl
或者 Postman 测试这两个接口。
- 创建交接记录 (POST)
使用以下 curl
命令来创建一个交接记录:
bash
curl -X POST http://localhost:8080/handover \
-H "Content-Type: application/json" \
-d '{
"employee_id": 1,
"handover_to_id": 2,
"handover_date": "2025-01-05",
"status": 0,
"remarks": "Task transfer to new employee"
}'
这将会向服务器发送一个请求,创建一个新的交接记录。
- 查询交接记录 (GET)
查询交接记录时,可以通过 URL 参数传递交接记录的 ID:
bash
curl -X GET "http://localhost:8080/handover?id=1"
如果查询成功,返回的 JSON 将包含交接记录的详细信息。
4. 补充功能
这个基础系统已经涵盖了交接记录的创建和查询,下面是一些额外的功能,适合扩展和完善交接模块。
4.1 交接任务管理
交接过程中,每个交接记录可能包含多个具体的任务。我们可以扩展交接记录功能,添加交接任务的创建、更新、查询和删除功能。
- 每个交接任务可以有独立的状态,如:待完成、已完成、进行中。
- 可以通过关联
handover_tasks
表来跟踪任务的执行情况。
4.2 通知和提醒
交接过程可能涉及多个步骤,可以为系统添加通知功能,例如:
- 当交接任务完成时,向相关员工或管理者发送通知。
- 设置任务的提醒,确保交接不被遗漏。
4.3 状态管理与流程控制
为了确保交接的顺利进行,可以为每个交接记录和任务设置更复杂的状态管理,增加流程控制功能:
- 每个交接记录从创建、处理中、完成等不同状态转变。
- 每个交接任务也可以设置状态,只有在任务完成后,交接记录才能标记为完成。
5. 安全与权限管理
在实际项目中,不同员工的角色可能有不同的权限。例如,某些角色只能查看交接记录,而其他角色则有权限修改或创建交接记录。因此,您可以进一步扩展权限管理:
- 角色权限管理:根据用户的角色,限制他们访问某些接口或者数据。
- 身份验证与授权:引入 JWT 令牌或者 OAuth 等认证机制,确保接口的安全性。
示例:基于角色限制权限
在 handover_service.go
中,可以加入一些简单的权限检查。例如,只有管理员角色的用户才有权限创建交接记录:
go
func (s *HandoverService) CreateHandoverRecord(ctx context.Context, record *model.HandoverRecord, user *model.Employee) (*model.HandoverRecord, error) {
if user.RoleID != 1 { // 假设角色ID 1 是管理员
return nil, fmt.Errorf("permission denied")
}
record.CreateTime = time.Now().Format("2006-01-02 15:04:05")
record.UpdateTime = record.CreateTime
// Save to database and return
return record, nil
}
这样,在处理创建交接记录时,可以检查当前用户的角色,确保只有有权限的用户才能进行操作。
6. 总结
通过以上步骤,我们实现了一个基础的交接管理模块,支持员工离职时的交接任务管理。在此基础上,我们还可以扩展以下功能:
- 交接任务管理:支持更详细的任务管理和状态追踪。
- 通知和提醒:为交接过程中的重要事件添加通知功能。
- 权限控制:通过角色和权限控制,确保敏感数据不被滥用。
该系统适用于教务 CRM 系统中的多种场景,可以根据实际需求灵活扩展。