export_data_1.go 6.9 KB
package service

import (
	"fmt"
	"strings"

	"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/dao"
)

// 员工绩效-综合管理-导出绩效-个人

// excel表头部字段
type HeaderLevel struct {
	Name   string         `json:"name"`
	Filter map[string]int `json:"-"`
	Child  []HeaderLevel  `json:"child"`
}

// 添加下一层级的字段
func (h *HeaderLevel) addChild(name string) (child *HeaderLevel) {
	cIndex, ok := h.Filter[name]
	if !ok {
		h.Child = append(h.Child, HeaderLevel{
			Name:   name,
			Filter: map[string]int{},
			Child:  []HeaderLevel{},
		})
		h.Filter[name] = len(h.Child) - 1
		cIndex = h.Filter[name]
	}
	return &h.Child[cIndex]
}

// 获取表头的所有列表名
func (h *HeaderLevel) collectAllColumn(all *[][]string) {
	for _, v := range h.Child {
		v.collectColumn(&v, all, nil)
	}
}

func (h *HeaderLevel) collectColumn(child *HeaderLevel, columns *[][]string, column *[]string) {
	if column == nil {
		column = &[]string{}
	}
	*column = append(*column, h.Name)
	for _, v := range child.Child {
		if len(v.Child) > 0 {
			v.collectColumn(&v, columns, column)
		}
		if len(v.Child) == 0 {
			item := make([]string, len(*column))
			copy(item, *column)
			item = append(item, v.Name)
			*columns = append(*columns, item)
		}
	}
}

type exportData struct {
	userName    []string //员工的名称列表 ,对应excel文件的多个sheet
	usrIdMap    map[string]string
	userDayMap  map[string][]string         //每个员工对应的日期列表  key=员工名称 value= 日期列表
	tableHeader map[string]*HeaderLevel     //每个员工数据表格对应表头 key=员工名称
	data        map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工名称+日期+表头
	data2       map[string]string           //每个员工评估项的标准描述
	data3       map[string]string           //每个员工评估项的标准权重
}

func newExportData() *exportData {
	return &exportData{
		userName:    nil,
		usrIdMap:    map[string]string{},
		userDayMap:  map[string][]string{},
		tableHeader: map[string]*HeaderLevel{},
		data:        map[string]*strings.Builder{},
		data2:       map[string]string{},
		data3:       map[string]string{},
	}
}

// 设置表格头部字段。和对应的员工列表
func (e *exportData) setCategoryNameList(param []dao.ContentCategoryName) {
	for _, v := range param {
		if _, ok := e.usrIdMap[v.TargetUserId]; !ok {
			if _, ok := e.tableHeader[v.TargetUserName]; ok {
				//出现重名,id不同但名称相同
				uname := fmt.Sprintf("%s%d", v.TargetUserName, len(e.usrIdMap))
				e.usrIdMap[v.TargetUserId] = uname
			} else {
				e.usrIdMap[v.TargetUserId] = v.TargetUserName
			}
			e.userName = append(e.userName, e.usrIdMap[v.TargetUserId])
		}
		userName := e.usrIdMap[v.TargetUserId]
		if _, ok := e.tableHeader[userName]; !ok {
			e.tableHeader[userName] = &HeaderLevel{
				Name:   "个人绩效评估等级统计表",
				Filter: map[string]int{},
				Child:  []HeaderLevel{},
			}
		}
		child := e.tableHeader[userName].addChild(v.Category) //第一级,"分类"
		weight := e.weightDesc(v.Weight)
		child = child.addChild(weight) //第二级 '得分项' '加分项'
		child.addChild(v.Name)         //第三级 评估项名称
	}
}

func (e *exportData) setData(param []*dao.ExportData2) {
	userName := ""
	key := ""
	userDay := map[string]struct{}{}
	for _, v := range param {
		//员工填写的评估内容
		if _, ok := e.usrIdMap[v.TargetUserId]; !ok {
			continue
		}
		userName = e.usrIdMap[v.TargetUserId]
		weight := e.weightDesc(v.Weight)
		key = e.dataKey(userName, v.BeginDay, v.Category, weight, v.ContentName)
		e.data[key] = &strings.Builder{}
		e.data[key].WriteString(v.Value + "\n") //填写的等级
		for _, vv := range v.Remark {
			e.data[key].WriteString(vv.Definition + "\n")
			e.data[key].WriteString(vv.RemarkText + "\n")
		}
		if _, ok := userDay[userName+v.BeginDay]; !ok {
			userDay[userName+v.BeginDay] = struct{}{}
			e.userDayMap[userName] = append(e.userDayMap[userName], v.BeginDay)
		}
		key23 := e.data23Key(userName, v.Category, weight, v.ContentName)
		e.data2[key23] = v.PromptText
		if v.Weight == 0 {
			e.data3[key23] = ""
		} else {
			e.data3[key23] = fmt.Sprintf("%.2f%%", v.Weight)
		}
	}
}

func (e *exportData) dataKey(userName string, beginDay string, category string, weight string, contentName string) string {
	key := fmt.Sprintf("%s-%s-%s-%s-%s", userName, weight, beginDay, category, contentName)
	return key
}

func (e *exportData) data23Key(userName string, category string, weight string, contentName string) string {
	key := fmt.Sprintf("%s-%s-%s-%s", userName, weight, category, contentName)
	return key
}

func (e *exportData) weightDesc(weight float64) string {
	if weight == 0 {
		return "加分项"
	} else {
		return "得分项"
	}
}

func (e *exportData) userDayKey(userName string) string {
	return userName
}

type exportData2 struct {
	tableHeader HeaderLevel                 //数据表格对应表头
	userIdMap   map[string]string           //员工id 对应的名称
	rowSort     HeaderLevel                 //
	data        map[string]*strings.Builder //需要导出的数据 key=员工Id+日期+表头

}

func newExportData2() *exportData2 {
	return &exportData2{
		tableHeader: HeaderLevel{
			Name:   "每日绩效汇总",
			Filter: map[string]int{},
			Child:  []HeaderLevel{},
		},
		userIdMap: map[string]string{},
		rowSort: HeaderLevel{
			Name:   "",
			Filter: map[string]int{},
			Child:  []HeaderLevel{},
		},
		data: map[string]*strings.Builder{},
	}
}

func (e *exportData2) setData(param []dao.ExportData1) {
	for _, v := range param {
		e.userIdMap[v.TargetUserId] = v.TargetUserName
		//提取表头数据
		child := e.tableHeader.addChild(v.Category) //第一级 ,分类
		weigh := e.weightDesc(v.Weight)
		child = child.addChild(weigh)         //第二级,加分项、得分项
		child = child.addChild(v.ContentName) //第三级,评估项名称
		child.addChild(v.PromptText)          //第四级, 标准

		//提取 纵向列表 索引
		child = e.rowSort.addChild(v.BeginDay) //日期
		child.addChild(v.TargetUserId)         //员工id
		key := e.dataKey(v.TargetUserId, v.BeginDay, v.Category, v.ContentName)
		e.data[key] = &strings.Builder{}
		e.data[key].WriteString(v.Value + "\n")
		for _, v2 := range v.Remark {
			e.data[key].WriteString(v2.Definition + "\n")
			e.data[key].WriteString(v2.RemarkText + "\n")
		}
	}
}

func (e *exportData2) weightDesc(weight float64) string {
	if weight == 0 {
		return "加分项"
	} else {
		return "得分项"
	}
}

func (e *exportData2) dataKey(userId string, beginDay string, category string, contentName string) string {
	key := fmt.Sprintf("%s-%s-%s-%s", userId, beginDay, category, contentName)
	return key
}