feat: 完善小组绩效与有效端统计并修复审查问题
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user