package services import ( "ERP_salary/dto" db "ERP_salary/initialize" "ERP_salary/logs" "ERP_salary/models/Account" models "ERP_salary/models/Performance" "errors" "gogs.baozhida.cn/zoie/ERP_libs/lib" "gorm.io/gorm" ) type Performance struct { } func (e *Performance) GetPage(c *dto.PerformanceUserPageReq) (list []models.Perf, cnt int64) { var err error err = db.DB.Model(&models.Perf{}). Scopes( dto.MakeCondition(c.GetNeedSearch()), dto.Paginate(c.GetPageSize(), c.GetPageIndex()), dto.WithNormalState(), ). Preload("PointList", "t__state = ?", 1). Preload("PointList.PerformancePoints"). Preload("Target", "t__state = ?", 1). Find(&list).Limit(-1).Offset(-1). Count(&cnt).Error if err != nil { logs.Error("db error: %s ", err) return } for i := 0; i < len(list); i++ { list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit) } return } func (e *Performance) GetManagerPage(c *dto.PerformancePageReq) (list []models.Perf, cnt int64) { var err error err = db.DB.Model(&models.Perf{}). Scopes( dto.MakeCondition(c.GetNeedSearch()), dto.Paginate(c.GetPageSize(), c.GetPageIndex()), dto.WithNormalState(), ). Where("t_audit in (?)", []int{2, 3}). Preload("PointList", "t__state = ?", 1). Preload("PointList.PerformancePoints"). Preload("Target", "t__state = ?", 1). Find(&list).Limit(-1).Offset(-1). Count(&cnt).Error if err != nil { logs.Error("db error: %s ", err) return } for i := 0; i < len(list); i++ { list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit) } return } func (e *Performance) GetSubmitUserPage() (list []string) { var err error err = db.DB.Model(&models.Perf{}). Select("Distinct t_submit"). Scopes( dto.WithNormalState(), ). Where("t_audit in (?)", []int{2, 3}). Find(&list).Error if err != nil { logs.Error("db error: %s ", err) return } return } // GetPerfPointsByPerfId 根据绩效ID获取关联的绩效点列表 func (e *Performance) GetPerfPointsByPerfId(perfId int) (pointList []models.PerfPoint, err error) { err = db.DB.Model(&models.PerfPoint{}). Scopes(dto.WithNormalState()). Where("t_performance_id = ?", perfId). Find(&pointList).Error if err != nil { logs.Error("获取绩效点列表失败: %s", err) return } // 获取绩效点详细信息 for i := range pointList { var performancePoints models.PerformancePoints err = db.DB.Model(&models.PerformancePoints{}). Scopes(dto.WithNormalState()). Where("id = ?", pointList[i].T_performance_points_id). First(&performancePoints).Error if err == nil { pointList[i].PerformancePoints = performancePoints } } return } // InsertFromStats 从统计结果插入绩效记录 func (e *Performance) InsertFromStats(perf *models.Perf, pointList []models.PerfPoint) (id int, err error) { tx := db.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() // 查询是否存在相同 T_submit 和 T_date 的记录 var existingPerf models.Perf queryErr := tx.Model(&models.Perf{}). Scopes(dto.WithNormalState()). Where("t_submit = ? AND t_date = ?", perf.T_submit, perf.T_date). First(&existingPerf).Error // 如果找到了记录,先删除(软删除) if queryErr == nil && existingPerf.Id > 0 { // 软删除绩效主记录 err = tx.Model(&models.Perf{}). Where("id = ?", existingPerf.Id). Update("t__state", 0).Error if err != nil { logs.Error("删除旧绩效主记录失败: %s", err) return } // 软删除关联的绩效点记录 err = tx.Model(&models.PerfPoint{}). Where("t_performance_id = ?", existingPerf.Id). Update("t__state", 0).Error if err != nil { logs.Error("删除旧绩效点记录失败: %s", err) return } logs.Println("已删除旧记录 - 用户: %s, 日期: %s, ID: %d", perf.T_submit, perf.T_date, existingPerf.Id) } // 如果是查询错误(不是记录不存在的错误),则返回错误 if queryErr != nil && !errors.Is(queryErr, gorm.ErrRecordNotFound) { logs.Error("查询已存在记录失败: %s", queryErr) err = queryErr return } // 创建绩效主记录 err = tx.Create(perf).Error if err != nil { logs.Error("创建绩效主记录失败: %s", err) return } // 设置绩效点的关联ID for i := range pointList { pointList[i].T_performance_id = perf.Id pointList[i].T_State = 1 } // 批量创建绩效点记录 if len(pointList) > 0 { err = tx.Create(&pointList).Error if err != nil { logs.Error("创建绩效点记录失败: %s", err) return } } id = perf.Id return } // Get 获取单个绩效记录 func (e *Performance) Get(c dto.PerformanceGetReq) (r models.Perf, err error) { err = db.DB.Scopes(dto.WithNormalState()).Preload("Target", "t__state = ?", 1).First(&r, c.GetId()).Error if err != nil { logs.Error("db error: %s", err) return } return } // 添加 func (e *Performance) Insert(c *dto.PerformanceInsertReq) (id int, err error) { var data models.Perf // 开启事务 tx := db.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() // 生成主表数据 c.Generate(&data) // 唯一性校验:同一月份+同一用户不可重复 { var cnt int64 query := db.DB.Model(&models.Perf{}). Scopes(dto.WithNormalState()). Where("t_date = ? AND t_submit = ?", data.T_date, data.T_submit) err = query.Count(&cnt).Error if err != nil { logs.Error("db error: %s", err) return } if cnt > 0 { return 0, errors.New("当月该用户已添加过该绩效") } } // 读取员工考核指标,设置考核绩效点 user := Account.Read_User_Get(data.T_submit) if user.T_verify_perf_target == 0 { return 0, errors.New("用户未配置工资级别,请联系管理员配置!") } targetSvc := PerformanceTarget{} target, _ := targetSvc.Get(user.T_verify_perf_target) if target.Id > 0 { data.T_assess_points = target.T_assess_points data.T_perf = target.T_perf data.T_performance_target_id = target.Id } // 根据绩效点明细计算工作量 if len(c.PointList) > 0 { totalWorkload := 0.0 for _, p := range c.PointList { if p.T_points_denominator != 0 { totalWorkload += float64(p.T_points_numerator) / float64(p.T_points_denominator) * float64(p.T_quantity) } } data.T_workload = totalWorkload } // 创建绩效主记录 err = tx.Create(&data).Error if err != nil { logs.Error("db error: %s", err) return } // 批量创建绩效点明细 if len(c.PointList) > 0 { for i := range c.PointList { c.PointList[i].T_performance_id = data.Id c.PointList[i].T_State = 1 } err = tx.Create(&c.PointList).Error if err != nil { logs.Error("db error: %s", err) return } } id = data.Id return } // 修改 func (e *Performance) Update(c *dto.PerformanceUpdateReq) error { var performance = models.Perf{} err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error if err != nil { logs.Error("db error: %s", err) return dto.GetFailedErr } // 已打款 不可修改 if performance.T_audit == 3 { logs.Error("db error: %s", err) return errors.New("已打款,不可修改") } tx := db.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() // 先根据请求生成需要更新的主记录字段 c.Generate(&performance) // 如 T_submit 可能变更,则刷新考核指标 user := Account.Read_User_Get(performance.T_submit) targetSvc := PerformanceTarget{} target, _ := targetSvc.Get(user.T_verify_perf_target) if target.Id > 0 { performance.T_assess_points = target.T_assess_points performance.T_perf = target.T_perf performance.T_performance_target_id = target.Id } // 重新计算工作量(基于新绩效点列表) if len(c.PointList) > 0 { totalWorkload := 0.0 for _, p := range c.PointList { if p.T_points_denominator != 0 { totalWorkload += float64(p.T_points_numerator) / float64(p.T_points_denominator) * float64(p.T_quantity) } } performance.T_workload = totalWorkload } // 保存主记录 err = tx.Save(&performance).Error if err != nil { logs.Error("db error: %s", err) return err } // 软删除旧的绩效点 if err = tx.Model(&models.PerfPoint{}). Where("t_performance_id = ? AND t__state = ?", performance.Id, 1). Update("t__state", 0).Error; err != nil { logs.Error("db error: %s", err) return err } // 插入新的绩效点列表 if len(c.PointList) > 0 { for i := range c.PointList { c.PointList[i].T_performance_id = performance.Id c.PointList[i].T_State = 1 } if err = tx.Create(&c.PointList).Error; err != nil { logs.Error("db error: %s", err) return err } } return nil } func (e *Performance) UpdateAudit(c *dto.PerformanceUpdateAuditReq) error { var performance = models.Perf{} err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error if err != nil { logs.Error("db error: %s", err) return dto.GetFailedErr } // 已打款 不可修改 if performance.T_audit == 1 && c.T_audit == 3 { logs.Error("db error: %s", err) return errors.New("未提交,不可修改") } tx := db.DB.Begin() defer func() { if err != nil { tx.Rollback() } else { tx.Commit() } }() performance.T_audit = c.T_audit // 保存主记录 err = tx.Save(&performance).Error if err != nil { logs.Error("db error: %s", err) return err } return nil } // 删除 func (e *Performance) Delete(c *dto.PerformanceDeleteReq) error { var performance = models.Perf{} err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error if err != nil { logs.Error("db error: %s", err) return dto.GetFailedErr } performance.T_State = 0 err = db.DB.Save(&performance).Error if err != nil { logs.Error(lib.FuncName(), err) return dto.DeleteFailedErr } return nil }