Files
kra-new/internal/service/business/performance_excel.go
T

146 lines
5.4 KiB
Go

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)
}