Performance.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. package services
  2. import (
  3. "ERP_salary/dto"
  4. db "ERP_salary/initialize"
  5. "ERP_salary/logs"
  6. "ERP_salary/models/Account"
  7. models "ERP_salary/models/Performance"
  8. "errors"
  9. "gogs.baozhida.cn/zoie/ERP_libs/lib"
  10. "gorm.io/gorm"
  11. )
  12. type Performance struct {
  13. }
  14. func (e *Performance) GetPage(c *dto.PerformanceUserPageReq) (list []models.Perf, cnt int64) {
  15. var err error
  16. err = db.DB.Model(&models.Perf{}).
  17. Scopes(
  18. dto.MakeCondition(c.GetNeedSearch()),
  19. dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
  20. dto.WithNormalState(),
  21. ).
  22. Preload("PointList", "t__state = ?", 1).
  23. Preload("PointList.PerformancePoints").
  24. Preload("Target", "t__state = ?", 1).
  25. Find(&list).Limit(-1).Offset(-1).
  26. Count(&cnt).Error
  27. if err != nil {
  28. logs.Error("db error: %s ", err)
  29. return
  30. }
  31. for i := 0; i < len(list); i++ {
  32. list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit)
  33. }
  34. return
  35. }
  36. func (e *Performance) GetManagerPage(c *dto.PerformancePageReq) (list []models.Perf, cnt int64) {
  37. var err error
  38. err = db.DB.Model(&models.Perf{}).
  39. Scopes(
  40. dto.MakeCondition(c.GetNeedSearch()),
  41. dto.Paginate(c.GetPageSize(), c.GetPageIndex()),
  42. dto.WithNormalState(),
  43. ).
  44. Where("t_audit in (?)", []int{2, 3}).
  45. Preload("PointList", "t__state = ?", 1).
  46. Preload("PointList.PerformancePoints").
  47. Preload("Target", "t__state = ?", 1).
  48. Find(&list).Limit(-1).Offset(-1).
  49. Count(&cnt).Error
  50. if err != nil {
  51. logs.Error("db error: %s ", err)
  52. return
  53. }
  54. for i := 0; i < len(list); i++ {
  55. list[i].T_submit_name = Account.Read_User_T_name_Get(list[i].T_submit)
  56. }
  57. return
  58. }
  59. func (e *Performance) GetSubmitUserPage() (list []string) {
  60. var err error
  61. err = db.DB.Model(&models.Perf{}).
  62. Select("Distinct t_submit").
  63. Scopes(
  64. dto.WithNormalState(),
  65. ).
  66. Where("t_audit in (?)", []int{2, 3}).
  67. Find(&list).Error
  68. if err != nil {
  69. logs.Error("db error: %s ", err)
  70. return
  71. }
  72. return
  73. }
  74. // GetPerfPointsByPerfId 根据绩效ID获取关联的绩效点列表
  75. func (e *Performance) GetPerfPointsByPerfId(perfId int) (pointList []models.PerfPoint, err error) {
  76. err = db.DB.Model(&models.PerfPoint{}).
  77. Scopes(dto.WithNormalState()).
  78. Where("t_performance_id = ?", perfId).
  79. Find(&pointList).Error
  80. if err != nil {
  81. logs.Error("获取绩效点列表失败: %s", err)
  82. return
  83. }
  84. // 获取绩效点详细信息
  85. for i := range pointList {
  86. var performancePoints models.PerformancePoints
  87. err = db.DB.Model(&models.PerformancePoints{}).
  88. Scopes(dto.WithNormalState()).
  89. Where("id = ?", pointList[i].T_performance_points_id).
  90. First(&performancePoints).Error
  91. if err == nil {
  92. pointList[i].PerformancePoints = performancePoints
  93. }
  94. }
  95. return
  96. }
  97. // InsertFromStats 从统计结果插入绩效记录
  98. func (e *Performance) InsertFromStats(perf *models.Perf, pointList []models.PerfPoint) (id int, err error) {
  99. tx := db.DB.Begin()
  100. defer func() {
  101. if err != nil {
  102. tx.Rollback()
  103. } else {
  104. tx.Commit()
  105. }
  106. }()
  107. // 查询是否存在相同 T_submit 和 T_date 的记录
  108. var existingPerf models.Perf
  109. queryErr := tx.Model(&models.Perf{}).
  110. Scopes(dto.WithNormalState()).
  111. Where("t_submit = ? AND t_date = ?", perf.T_submit, perf.T_date).
  112. First(&existingPerf).Error
  113. // 如果找到了记录,先删除(软删除)
  114. if queryErr == nil && existingPerf.Id > 0 {
  115. // 软删除绩效主记录
  116. err = tx.Model(&models.Perf{}).
  117. Where("id = ?", existingPerf.Id).
  118. Update("t__state", 0).Error
  119. if err != nil {
  120. logs.Error("删除旧绩效主记录失败: %s", err)
  121. return
  122. }
  123. // 软删除关联的绩效点记录
  124. err = tx.Model(&models.PerfPoint{}).
  125. Where("t_performance_id = ?", existingPerf.Id).
  126. Update("t__state", 0).Error
  127. if err != nil {
  128. logs.Error("删除旧绩效点记录失败: %s", err)
  129. return
  130. }
  131. logs.Println("已删除旧记录 - 用户: %s, 日期: %s, ID: %d", perf.T_submit, perf.T_date, existingPerf.Id)
  132. }
  133. // 如果是查询错误(不是记录不存在的错误),则返回错误
  134. if queryErr != nil && !errors.Is(queryErr, gorm.ErrRecordNotFound) {
  135. logs.Error("查询已存在记录失败: %s", queryErr)
  136. err = queryErr
  137. return
  138. }
  139. // 创建绩效主记录
  140. err = tx.Create(perf).Error
  141. if err != nil {
  142. logs.Error("创建绩效主记录失败: %s", err)
  143. return
  144. }
  145. // 设置绩效点的关联ID
  146. for i := range pointList {
  147. pointList[i].T_performance_id = perf.Id
  148. pointList[i].T_State = 1
  149. }
  150. // 批量创建绩效点记录
  151. if len(pointList) > 0 {
  152. err = tx.Create(&pointList).Error
  153. if err != nil {
  154. logs.Error("创建绩效点记录失败: %s", err)
  155. return
  156. }
  157. }
  158. id = perf.Id
  159. return
  160. }
  161. // Get 获取单个绩效记录
  162. func (e *Performance) Get(c dto.PerformanceGetReq) (r models.Perf, err error) {
  163. err = db.DB.Scopes(dto.WithNormalState()).Preload("Target", "t__state = ?", 1).First(&r, c.GetId()).Error
  164. if err != nil {
  165. logs.Error("db error: %s", err)
  166. return
  167. }
  168. return
  169. }
  170. // 添加
  171. func (e *Performance) Insert(c *dto.PerformanceInsertReq) (id int, err error) {
  172. var data models.Perf
  173. // 开启事务
  174. tx := db.DB.Begin()
  175. defer func() {
  176. if err != nil {
  177. tx.Rollback()
  178. } else {
  179. tx.Commit()
  180. }
  181. }()
  182. // 生成主表数据
  183. c.Generate(&data)
  184. // 唯一性校验:同一月份+同一用户不可重复
  185. {
  186. var cnt int64
  187. query := db.DB.Model(&models.Perf{}).
  188. Scopes(dto.WithNormalState()).
  189. Where("t_date = ? AND t_submit = ?", data.T_date, data.T_submit)
  190. err = query.Count(&cnt).Error
  191. if err != nil {
  192. logs.Error("db error: %s", err)
  193. return
  194. }
  195. if cnt > 0 {
  196. return 0, errors.New("当月该用户已添加过该绩效")
  197. }
  198. }
  199. // 读取员工考核指标,设置考核绩效点
  200. user := Account.Read_User_Get(data.T_submit)
  201. if user.T_verify_perf_target == 0 {
  202. return 0, errors.New("用户未配置工资级别,请联系管理员配置!")
  203. }
  204. targetSvc := PerformanceTarget{}
  205. target, _ := targetSvc.Get(user.T_verify_perf_target)
  206. if target.Id > 0 {
  207. data.T_assess_points = target.T_assess_points
  208. data.T_perf = target.T_perf
  209. data.T_performance_target_id = target.Id
  210. }
  211. // 根据绩效点明细计算工作量
  212. if len(c.PointList) > 0 {
  213. totalWorkload := 0.0
  214. for _, p := range c.PointList {
  215. if p.T_points_denominator != 0 {
  216. totalWorkload += float64(p.T_points_numerator) / float64(p.T_points_denominator) * float64(p.T_quantity)
  217. }
  218. }
  219. data.T_workload = totalWorkload
  220. }
  221. // 创建绩效主记录
  222. err = tx.Create(&data).Error
  223. if err != nil {
  224. logs.Error("db error: %s", err)
  225. return
  226. }
  227. // 批量创建绩效点明细
  228. if len(c.PointList) > 0 {
  229. for i := range c.PointList {
  230. c.PointList[i].T_performance_id = data.Id
  231. c.PointList[i].T_State = 1
  232. }
  233. err = tx.Create(&c.PointList).Error
  234. if err != nil {
  235. logs.Error("db error: %s", err)
  236. return
  237. }
  238. }
  239. id = data.Id
  240. return
  241. }
  242. // 修改
  243. func (e *Performance) Update(c *dto.PerformanceUpdateReq) error {
  244. var performance = models.Perf{}
  245. err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error
  246. if err != nil {
  247. logs.Error("db error: %s", err)
  248. return dto.GetFailedErr
  249. }
  250. // 已打款 不可修改
  251. if performance.T_audit == 3 {
  252. logs.Error("db error: %s", err)
  253. return errors.New("已打款,不可修改")
  254. }
  255. tx := db.DB.Begin()
  256. defer func() {
  257. if err != nil {
  258. tx.Rollback()
  259. } else {
  260. tx.Commit()
  261. }
  262. }()
  263. // 先根据请求生成需要更新的主记录字段
  264. c.Generate(&performance)
  265. // 如 T_submit 可能变更,则刷新考核指标
  266. user := Account.Read_User_Get(performance.T_submit)
  267. targetSvc := PerformanceTarget{}
  268. target, _ := targetSvc.Get(user.T_verify_perf_target)
  269. if target.Id > 0 {
  270. performance.T_assess_points = target.T_assess_points
  271. performance.T_perf = target.T_perf
  272. performance.T_performance_target_id = target.Id
  273. }
  274. // 重新计算工作量(基于新绩效点列表)
  275. if len(c.PointList) > 0 {
  276. totalWorkload := 0.0
  277. for _, p := range c.PointList {
  278. if p.T_points_denominator != 0 {
  279. totalWorkload += float64(p.T_points_numerator) / float64(p.T_points_denominator) * float64(p.T_quantity)
  280. }
  281. }
  282. performance.T_workload = totalWorkload
  283. }
  284. // 保存主记录
  285. err = tx.Save(&performance).Error
  286. if err != nil {
  287. logs.Error("db error: %s", err)
  288. return err
  289. }
  290. // 软删除旧的绩效点
  291. if err = tx.Model(&models.PerfPoint{}).
  292. Where("t_performance_id = ? AND t__state = ?", performance.Id, 1).
  293. Update("t__state", 0).Error; err != nil {
  294. logs.Error("db error: %s", err)
  295. return err
  296. }
  297. // 插入新的绩效点列表
  298. if len(c.PointList) > 0 {
  299. for i := range c.PointList {
  300. c.PointList[i].T_performance_id = performance.Id
  301. c.PointList[i].T_State = 1
  302. }
  303. if err = tx.Create(&c.PointList).Error; err != nil {
  304. logs.Error("db error: %s", err)
  305. return err
  306. }
  307. }
  308. return nil
  309. }
  310. func (e *Performance) UpdateAudit(c *dto.PerformanceUpdateAuditReq) error {
  311. var performance = models.Perf{}
  312. err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error
  313. if err != nil {
  314. logs.Error("db error: %s", err)
  315. return dto.GetFailedErr
  316. }
  317. // 已打款 不可修改
  318. if performance.T_audit == 1 && c.T_audit == 3 {
  319. logs.Error("db error: %s", err)
  320. return errors.New("未提交,不可修改")
  321. }
  322. tx := db.DB.Begin()
  323. defer func() {
  324. if err != nil {
  325. tx.Rollback()
  326. } else {
  327. tx.Commit()
  328. }
  329. }()
  330. performance.T_audit = c.T_audit
  331. // 保存主记录
  332. err = tx.Save(&performance).Error
  333. if err != nil {
  334. logs.Error("db error: %s", err)
  335. return err
  336. }
  337. return nil
  338. }
  339. // 删除
  340. func (e *Performance) Delete(c *dto.PerformanceDeleteReq) error {
  341. var performance = models.Perf{}
  342. err := db.DB.Scopes(dto.WithNormalState()).First(&performance, c.GetId()).Error
  343. if err != nil {
  344. logs.Error("db error: %s", err)
  345. return dto.GetFailedErr
  346. }
  347. performance.T_State = 0
  348. err = db.DB.Save(&performance).Error
  349. if err != nil {
  350. logs.Error(lib.FuncName(), err)
  351. return dto.DeleteFailedErr
  352. }
  353. return nil
  354. }