package business import ( "context" "strconv" "kra/internal/biz/business" "kra/internal/service/dto" ) func (s *BusinessPerformanceService) Export(ctx context.Context, req *dto.PerformanceQuery) ([]byte, error) { f, err := performanceRequest(req, false) if err != nil { return nil, err } data, err := s.performance.Query(ctx, f) if err != nil { return nil, err } if !data.Available { return nil, business.ErrWorkbenchUnavailable } if len(data.Rows) > 10000 { return nil, business.ErrLedgerExportLimit } if req.View == "groups" { return exportGroupPerformance(data) } if req.View == "trend" { return exportPerformanceTrend(data) } headers := []string{"小组", "商务", "入职日期", "在职状态", "区间开端", "区间有效端", "区间充值流水", "有效率"} for i := len(data.Periods) - 1; i >= 0; i-- { p := data.Periods[i] headers = append(headers, p.Key+" 开端", p.Key+" 有效端", p.Key+" 充值流水") } rows := [][]ledgerCell{} appendRow := func(group, name, hire, employment string, total business.PerformanceMetrics, rate *string, periods map[string]business.PerformanceMetrics) { r := []ledgerCell{textCell(group), textCell(name), textCell(hire), textCell(employment), numericCell(strconv.FormatInt(total.Open, 10)), numericCell(strconv.FormatInt(total.Effective, 10)), numericCell(total.Pay), textCell("")} if rate != nil { r[7] = textCell(*rate + "%") } for i := len(data.Periods) - 1; i >= 0; i-- { m := periods[data.Periods[i].Key] r = append(r, numericCell(strconv.FormatInt(m.Open, 10)), numericCell(strconv.FormatInt(m.Effective, 10)), numericCell(m.Pay)) } rows = append(rows, r) } { groups := map[uint64]*business.PerformanceGroupRow{} for _, g := range data.Groups { groups[g.Group.ID] = g } for i, r := range data.Rows { name := r.Member.NickName if name == "" { name = r.Member.Username } appendRow(r.Member.GroupName, name, r.Member.HireDate, map[string]string{"employed": "在职", "probation": "试用", "departed": "离职"}[r.Member.Employment], r.Total, r.Rate, r.Periods) if g := groups[r.Member.GroupID]; g != nil && (i == len(data.Rows)-1 || data.Rows[i+1].Member.GroupID != r.Member.GroupID) { appendRow(g.Group.Name, g.Group.Name+" 小计", "", "", g.UniqueTotal, business.PerformanceRate(g.UniqueTotal), g.UniquePeriods) } } } appendRow("筛选结果去重合计", "上下级不重复计算", "", "", data.MatrixTotal, data.MatrixRate, data.MatrixTrend) return ledgerWorkbook("商务绩效统计", headers, rows) } func exportGroupPerformance(data *business.PerformancePage) ([]byte, error) { headers := []string{"小组", "人数", "区间开端", "区间有效端", "区间流水", "开端完成率", "有效端完成率", "流水完成率"} for i := len(data.Periods) - 1; i >= 0; i-- { p := data.Periods[i] for _, metric := range []string{"开端", "有效端", "流水"} { headers = append(headers, p.Key+" "+metric+"目标", p.Key+" "+metric+"实际") } } rows := [][]ledgerCell{} for _, g := range data.Groups { row := []ledgerCell{textCell(g.Group.Name), numericCell(strconv.Itoa(len(g.Group.MemberIDs))), numericCell(strconv.FormatInt(g.Total.Open, 10)), numericCell(strconv.FormatInt(g.Total.Effective, 10)), numericCell(g.Total.Pay)} for _, key := range []string{"open", "effective", "pay"} { rate := business.GoalCompletion(g.Periods, g.Goals, key) if rate == nil { row = append(row, textCell("—")) } else { row = append(row, textCell(*rate+"%")) } } for i := len(data.Periods) - 1; i >= 0; i-- { p := data.Periods[i] goal := g.Goals[p.Key[:7]] value := g.Periods[p.Key] for _, key := range []string{"open", "effective", "pay"} { target := business.GoalPeriodTarget(goal, key, p.Key, data.Granularity) if target == nil { row = append(row, textCell("—")) } else { row = append(row, numericCell(*target)) } if goal == nil { row = append(row, textCell("—")) continue } actual := value.Pay if key == "open" { actual = strconv.FormatInt(value.Open, 10) } else if key == "effective" { actual = strconv.FormatInt(value.Effective, 10) } row = append(row, numericCell(actual)) } } rows = append(rows, row) } return ledgerWorkbook("小组绩效", headers, rows) } func exportPerformanceTrend(data *business.PerformancePage) ([]byte, error) { headers := []string{"日期/月份", "开端数", "有效端数", "充值流水", "有效率", "开端环比", "有效端环比", "流水环比"} rows := [][]ledgerCell{} for i := len(data.Periods) - 1; i >= 0; i-- { p := data.Periods[i] value := data.Trend[p.Key] previous := data.Prior if i > 0 { previous = data.Trend[data.Periods[i-1].Key] } row := []ledgerCell{textCell(p.Key), numericCell(strconv.FormatInt(value.Open, 10)), numericCell(strconv.FormatInt(value.Effective, 10)), numericCell(value.Pay)} rate := business.PerformanceRate(value) if rate == nil { row = append(row, textCell("—")) } else { row = append(row, textCell(*rate+"%")) } for _, key := range []string{"open", "effective", "pay"} { change := business.PerformanceChange(value, previous, key) if change == nil { row = append(row, textCell("—")) } else { row = append(row, textCell(*change+"%")) } } rows = append(rows, row) } return ledgerWorkbook("趋势图", headers, rows) }