146 lines
5.4 KiB
Go
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)
|
|
}
|