| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164 |
- package opsdev
- import (
- "context"
- "fmt"
- "time"
- "dashoo.cn/opms_libary/myerrors"
- opsdevmodel "dashoo.cn/opms_parent/app/model/opsdev"
- "dashoo.cn/opms_parent/app/service"
- "github.com/gogf/gf/frame/g"
- )
- // rawHourRow UNION ALL 查询返回的中间行
- type rawHourRow struct {
- OpsUserId int
- OpsUserName string
- WorkDate string
- OpHour float64
- RdHour float64
- MtHour float64
- }
- // WorkHourStatService 工时统计服务
- type WorkHourStatService struct {
- *service.ContextService
- }
- // NewWorkHourStatService 创建工时统计服务实例
- func NewWorkHourStatService(ctx context.Context) (svc *WorkHourStatService, err error) {
- svc = new(WorkHourStatService)
- if svc.ContextService, err = svc.Init(ctx); err != nil {
- return nil, err
- }
- return svc, nil
- }
- // GetStat 获取工时统计
- func (s *WorkHourStatService) GetStat(req *opsdevmodel.WorkHourStatReq) (*opsdevmodel.WorkHourStatRsp, error) {
- startDate, err := time.Parse("2006-01-02", req.StartDate)
- if err != nil {
- return nil, myerrors.TipsError("开始日期格式错误: " + err.Error())
- }
- endDate, err := time.Parse("2006-01-02", req.EndDate)
- if err != nil {
- return nil, myerrors.TipsError("结束日期格式错误: " + err.Error())
- }
- var allDates []string
- var dayHeaders []opsdevmodel.DayHeader
- weekdayNames := []string{"周日", "周一", "周二", "周三", "周四", "周五", "周六"}
- for d := startDate; !d.After(endDate); d = d.AddDate(0, 0, 1) {
- dateStr := d.Format("2006-01-02")
- allDates = append(allDates, dateStr)
- label := d.Format("01-02")
- if req.Mode == "week" {
- label = weekdayNames[d.Weekday()]
- }
- dayHeaders = append(dayHeaders, opsdevmodel.DayHeader{
- Label: label,
- Date: dateStr,
- })
- }
- unionSQL := fmt.Sprintf(`
- SELECT ops_user_id, ops_user_name, DATE(work_date) AS work_date,
- SUM(work_hour) AS op_hour, 0.0 AS rd_hour, 0.0 AS mt_hour
- FROM ops_operation_work_hour
- WHERE work_date >= ? AND work_date <= ? AND deleted_time IS NULL
- GROUP BY ops_user_id, ops_user_name, DATE(work_date)
- UNION ALL
- SELECT ops_user_id, ops_user_name, DATE(actual_work_date) AS work_date,
- 0.0 AS op_hour, SUM(actual_work_hour) AS rd_hour, 0.0 AS mt_hour
- FROM ops_event_task_work_hour
- WHERE actual_work_date >= ? AND actual_work_date <= ? AND deleted_time IS NULL
- GROUP BY ops_user_id, ops_user_name, DATE(actual_work_date)
- UNION ALL
- SELECT user_id AS ops_user_id, user_name AS ops_user_name, DATE(work_date) AS work_date,
- 0.0 AS op_hour, 0.0 AS rd_hour, SUM(work_hour) AS mt_hour
- FROM plat_meeting_work_hour
- WHERE work_date >= ? AND work_date <= ? AND deleted_time IS NULL
- GROUP BY user_id, user_name, DATE(work_date)
- `)
- startDT := req.StartDate + " 00:00:00"
- endDT := req.EndDate + " 23:59:59"
- var rawRows []rawHourRow
- if err := g.DB(s.Tenant).GetScan(&rawRows, unionSQL, startDT, endDT, startDT, endDT, startDT, endDT); err != nil {
- return nil, myerrors.TipsError("查询工时数据失败: " + err.Error())
- }
- type personAgg struct {
- OpsUserId int
- OpsUserName string
- DailyHours map[string]opsdevmodel.DayData
- }
- personMap := make(map[int]*personAgg)
- for i := range rawRows {
- row := &rawRows[i]
- p, ok := personMap[row.OpsUserId]
- if !ok {
- p = &personAgg{
- OpsUserId: row.OpsUserId,
- OpsUserName: row.OpsUserName,
- DailyHours: make(map[string]opsdevmodel.DayData),
- }
- personMap[row.OpsUserId] = p
- }
- dd := p.DailyHours[row.WorkDate]
- dd.OpHour += row.OpHour
- dd.RdHour += row.RdHour
- dd.MtHour += row.MtHour
- p.DailyHours[row.WorkDate] = dd
- }
- var persons []opsdevmodel.PersonRow
- for _, p := range personMap {
- if len(req.UserIds) > 0 {
- found := false
- for _, uid := range req.UserIds {
- if uid == p.OpsUserId {
- found = true
- break
- }
- }
- if !found {
- continue
- }
- }
- dailyHours := make(map[string]opsdevmodel.DayData)
- var totalOp, totalRd, totalMt float64
- for _, dateStr := range allDates {
- dd := p.DailyHours[dateStr]
- dailyHours[dateStr] = dd
- totalOp += dd.OpHour
- totalRd += dd.RdHour
- totalMt += dd.MtHour
- }
- persons = append(persons, opsdevmodel.PersonRow{
- UserId: p.OpsUserId,
- UserName: p.OpsUserName,
- DailyHours: dailyHours,
- TotalOpHour: totalOp,
- TotalRdHour: totalRd,
- TotalMtHour: totalMt,
- })
- }
- return &opsdevmodel.WorkHourStatRsp{
- Header: dayHeaders,
- Persons: persons,
- }, nil
- }
|