UiTrainplanRequest 前后台共用实现优化建议
通过分析 UiTrainplanRequest 的实现,我发现它已经具备了前后台共用的基础架构,但仍有一些可以优化的地方。以下是具体的建议:
1. 架构优化
1.1 分层设计
- 建议:将前后台逻辑分离到不同的方法中,使用接口定义公共行为
- 实现:

go
type TrainplanRequestInterface interface {
List() *pagemodel.PageResult[*planentity.TrainPlan]
GetById(id int64) *pagemodel.PageResult[*planentity.TrainPlan]
}type BaseTrainplanRequest struct {
basedto.BaseEntity
common.BaseService
uiframe.UiQueryRequest[int64, *planentity.TrainPlan]
}type FrontTrainplanRequest struct {
BaseTrainplanRequest
}type BackendTrainplanRequest struct {
BaseTrainplanRequest
}
1.2 配置驱动
- 建议:使用配置区分前后台行为,而非硬编码
- 实现:

go
type RequestConfig struct {
IsFrontend bool
UserRoles []string
Permissions map[string]bool
}func (self *UiTrainplanRequest) Init(config RequestConfig) {
self.IfFront = config.IsFrontend
// 其他初始化逻辑
}
2. 代码优化
2.1 参数验证
- 建议:增加更严格的参数验证,特别是前后台共用的参数
- 实现:

go
func (self *UiTrainplanRequest) ValidateParams() error {
if self.IfFront {
// 前台参数验证
if self.User == nil {
return errors.New("前台请求必须传入用户信息")
}
} else {
// 后台参数验证
if self.OpcId <= 0 {
return errors.New("后台请求必须指定运营中心")
}
}
return nil
}
2.2 错误处理
- 建议:统一错误处理机制,区分前后台错误信息
- 实现:

go
func (self *UiTrainplanRequest) HandleError(err error) *pagemodel.PageResult[*planentity.TrainPlan] {
if self.IfFront {
// 前台友好错误信息
return self.PageResultFailUser("操作失败:" + err.Error())
} else {
// 后台详细错误信息
golog.Error(err)
return self.PageResultFailSys("系统错误:" + err.Error())
}
}
2.3 缓存策略
- 建议:针对前后台不同场景优化缓存策略
- 实现:

go
func (self *UiTrainplanRequest) GetCacheKey() string {
prefix := "trainplan:backend"
if self.IfFront {
prefix = "trainplan:frontend"
// 前台缓存包含用户ID
return fmt.Sprintf("%s:%d:%s", prefix, self.UserId, self.Param.TrainPlanId)
}
// 后台缓存包含运营中心
return fmt.Sprintf("%s:%d:%s", prefix, self.OpcId, self.Param.TrainPlanId)
}
3. 功能优化
3.1 权限控制
- 建议:增强前后台权限控制,特别是前台不同角色的权限
- 实现:

go
func (self *UiTrainplanRequest) CheckPermission(action string) bool {
if !self.IfFront {
// 后台权限检查
return self.User.HasPermission(action)
}// 前台权限检查
switch self.User.GetRole() {
case apiconst.ROLE_COACH:
return self.checkCoachPermission(action)
case apiconst.ROLE_STUDENT:
return self.checkStudentPermission(action)
case apiconst.ROLE_PARENT:
return self.checkParentPermission(action)
default:
return false
}
}
3.2 数据过滤
- 建议:根据前后台和用户角色自动过滤数据
- 实现:

go
func (self *UiTrainplanRequest) ApplyDataFilter() {
if self.IfFront {
switch self.User.GetRole() {
case apiconst.ROLE_COACH:
// 教练只能看到自己的学员
self.DbEq("coach_id", self.UserId)
case apiconst.ROLE_STUDENT:
// 学生只能看到自己的计划
self.DbEq("student_id", self.UserId)
case apiconst.ROLE_PARENT:
// 家长只能看到自己孩子的计划
studentIds := self.getParentStudentIds()
self.DbIn("student_id", studentIds)
}
}
}
3.3 响应格式
- 建议:根据前后台返回不同的响应格式
- 实现:

go
func (self *UiTrainplanRequest) FormatResponse(ret *pagemodel.PageResult[*planentity.TrainPlan]) *pagemodel.PageResult[*planentity.TrainPlan] {
if self.IfFront {
// 前台响应:简化数据结构,只返回必要字段
self.simplifyFrontendResponse(ret)
} else {
// 后台响应:包含完整数据和统计信息
self.enhanceBackendResponse(ret)
}
return ret
}
4. 性能优化
4.1 数据库查询
- 建议:根据前后台需求优化数据库查询
- 实现:

go
func (self *UiTrainplanRequest) BuildQuery() {
if self.IfFront {
// 前台:只查询必要字段,使用索引
self.Select("id,student_id,coach_id,name,train_plan_id,status,type")
self.UseIndex("idx_train_plan_student_status")
} else {
// 后台:查询完整字段,支持排序和筛选
self.Select("*")
self.UseIndex("idx_train_plan_coach_status")
}
}
4.2 并发处理
- 建议:优化并发处理,特别是统计计算
- 实现:

go
func (self *UiTrainplanRequest) ComputeStatsAsync(ret *pagemodel.PageResult[*planentity.TrainPlan]) {
if self.IfFront {
// 前台:同步计算,确保响应及时
self.ComputeStudentStats(ret)
} else {
// 后台:异步计算,不阻塞响应
go self.ComputeStudentStats(ret)
}
}
5. 可维护性优化
5.1 代码结构
- 建议:优化代码结构,提高可读性和可维护性
- 实现:
- 将前后台逻辑分离到不同的方法
- 使用注释说明每个方法的用途和适用场景
- 提取公共逻辑到单独的方法
5.2 测试覆盖
- 建议:增加针对前后台不同场景的测试
- 实现:

go
func TestUiTrainplanRequest_Frontend(t *testing.T) {
req := NewUiTrainplanRequest()
req.IfFront = true
// 测试前台场景
}func TestUiTrainplanRequest_Backend(t *testing.T) {
req := NewUiTrainplanRequest()
req.IfFront = false
// 测试后台场景
}
6. 安全性优化
6.1 输入验证
- 建议:增强输入验证,防止恶意输入
- 实现:

go
func (self *UiTrainplanRequest) SanitizeInput() {
// 清理和验证输入参数
self.Param.Name = strings.TrimSpace(self.Param.Name)
if len(self.Param.Name) > 100 {
self.Param.Name = self.Param.Name[:100]
}
// 其他参数验证…
}
6.2 权限检查
- 建议:在关键操作前进行权限检查
- 实现:

go
func (self *UiTrainplanRequest) BeforeUpdate() error {
if !self.CheckPermission("trainplan:update") {
return errors.New("无权限执行此操作")
}
return nil
}
输入输出示例
输入输出示例
前台请求示例:

go
// 前台学生请求
req := uiplan.NewUiTrainplanRequest()
req.IfFront = true
req.User = currentStudentUser
req.Param.Type = apiconst.TRAIN_TYPE_WORD
// 执行查询
result := req.UiList()
后台请求示例:

go
// 后台管理员请求
req := uiplan.NewUiTrainplanRequest()
req.IfFront = false
req.OpcId = 1
req.Param.CoachId = 123
req.Param.Status = apiconst.PLANStatusActive
// 执行查询
result := req.UiList()
响应示例:

json
// 前台响应
{
"code": 200,
"msg": "success",
"data": [
{
"id": 1,
"name": "单词训练计划",
"trainPlanId": "TP202603250001",
"status": 10,
"type": 1
}
],
"dataAgg": {
"totalPlans": 5,
"completedPlans": 3
}
}
// 后台响应
{
"code": 200,
"msg": "success",
"data": [
{
"id": 1,
"studentId": 1001,
"studentName": "张三",
"coachId": 123,
"coachName": "李四",
"name": "单词训练计划",
"trainPlanId": "TP202603250001",
"status": 10,
"type": 1,
"createdAt": "2026-03-25T10:00:00Z",
"updatedAt": "2026-03-25T10:30:00Z"
}
],
"dataAgg": {
"totalPlans": 100,
"completedPlans": 80,
"pendingPlans": 20
},
"dataExtend": {
"dateRange": "2026-03-01至2026-03-31"
}
}
总结
通过以上优化建议,UiTrainplanRequest 可以更好地支持前后台共用的场景,同时提高代码的可维护性、性能和安全性。主要优化点包括:
这些优化措施将使 UiTrainplanRequest 更加灵活、高效地服务于前后台不同的业务场景,同时保持代码的清晰和可维护性。




