1
|
package service
|
1
|
package service
|
2
|
|
2
|
|
3
|
import (
|
3
|
import (
|
|
|
4
|
+ "fmt"
|
|
|
5
|
+ "strings"
|
|
|
6
|
+
|
4
|
"github.com/linmadan/egglib-go/core/application"
|
7
|
"github.com/linmadan/egglib-go/core/application"
|
5
|
"github.com/xuri/excelize/v2"
|
8
|
"github.com/xuri/excelize/v2"
|
6
|
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
|
9
|
"gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/factory"
|
|
@@ -30,49 +33,213 @@ func (srv *StaffAssessServeice) ExportUserAssess2V2(param *query.ExportUserAsses |
|
@@ -30,49 +33,213 @@ func (srv *StaffAssessServeice) ExportUserAssess2V2(param *query.ExportUserAsses |
30
|
// 按照cycleId获取项目的指标项
|
33
|
// 按照cycleId获取项目的指标项
|
31
|
evaluationItemList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId,
|
34
|
evaluationItemList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId,
|
32
|
param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
|
35
|
param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
|
|
|
36
|
+ if err != nil {
|
|
|
37
|
+ return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
|
|
|
38
|
+ }
|
33
|
// 按照项目获取填写的内容
|
39
|
// 按照项目获取填写的内容
|
34
|
- assessContentList, err := assessDao.SearchEvaluationItemUsed2(param.CompanyId,
|
40
|
+ assessContentList, err := assessDao.SearchStaffAssessContent2(param.CompanyId,
|
35
|
param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
|
41
|
param.CycleId, param.OperatorId, hrbp, param.ExportUserId)
|
|
|
42
|
+ if err != nil {
|
|
|
43
|
+ return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
|
|
|
44
|
+ }
|
36
|
if err := transactionContext.CommitTransaction(); err != nil {
|
45
|
if err := transactionContext.CommitTransaction(); err != nil {
|
37
|
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
|
46
|
return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())
|
38
|
}
|
47
|
}
|
|
|
48
|
+ eData := newExportData3()
|
|
|
49
|
+ eData.FormatTableHead(evaluationItemList)
|
|
|
50
|
+ eData.FormatListValue(assessContentList)
|
|
|
51
|
+ xlsxFile := excelize.NewFile()
|
|
|
52
|
+ //设置默认的第一个sheet
|
|
|
53
|
+ sheetIndex := xlsxFile.GetActiveSheetIndex()
|
|
|
54
|
+ firstSheetName := xlsxFile.GetSheetName(sheetIndex)
|
|
|
55
|
+ cycleName := ""
|
|
|
56
|
+ if len(evaluationItemList) > 0 {
|
|
|
57
|
+ cycleName = evaluationItemList[0].CycleName
|
|
|
58
|
+ }
|
|
|
59
|
+ for k1, val := range eData.userProjcetMap {
|
|
|
60
|
+ for k2, val2 := range val {
|
|
|
61
|
+ // 根据员工名称 添加一个sheet
|
|
|
62
|
+ uname := eData.userIdName[k1]
|
|
|
63
|
+ if len(uname) == 0 {
|
|
|
64
|
+ continue
|
|
|
65
|
+ }
|
|
|
66
|
+ tableHeader, ok := eData.tableHeader[k1+val2]
|
|
|
67
|
+ if !ok {
|
|
|
68
|
+ continue
|
|
|
69
|
+ }
|
|
|
70
|
+
|
|
|
71
|
+ newSheetName := uname + fmt.Sprintf("_%d", k2+1)
|
|
|
72
|
+ xlsxFile.NewSheet(newSheetName)
|
|
|
73
|
+ xlsxFile.SetCellStr(newSheetName, "B2", uname)
|
|
|
74
|
+ xlsxFile.MergeCell(newSheetName, "B2", "B4")
|
|
|
75
|
+ //填充第一列数据
|
|
|
76
|
+ xlsxFile.SetCellStr(newSheetName, "A1", tableHeader.Name)
|
|
|
77
|
+ xlsxFile.SetCellStr(newSheetName, "A2", cycleName)
|
|
|
78
|
+ xlsxFile.MergeCell(newSheetName, "A2", "A4")
|
|
|
79
|
+ xlsxFile.SetCellStr(newSheetName, "A5", "权重")
|
|
|
80
|
+ xlsxFile.MergeCell(newSheetName, "A5", "B5")
|
|
|
81
|
+ xlsxFile.SetCellStr(newSheetName, "A6", "评估标准")
|
|
|
82
|
+ xlsxFile.MergeCell(newSheetName, "A6", "B6")
|
|
|
83
|
+ // 日期
|
|
|
84
|
+ dayList := eData.userDayMap[eData.userDayKey(k1, val2)]
|
|
|
85
|
+ for ii, vv := range dayList {
|
|
|
86
|
+ //填写在第几行
|
|
|
87
|
+ axisNum := 7 + 3*ii
|
|
|
88
|
+ axis := fmt.Sprintf("A%d", axisNum)
|
|
|
89
|
+ xlsxFile.SetCellStr(newSheetName, axis, vv)
|
|
|
90
|
+ axisEnd := fmt.Sprintf("B%d", axisNum+2)
|
|
|
91
|
+ xlsxFile.MergeCell(newSheetName, axis, axisEnd) //单元格高度按三个单元格合并
|
|
|
92
|
+ }
|
|
|
93
|
+ allColNum := 0 //计算总共有多少列
|
|
|
94
|
+ //第一行
|
|
|
95
|
+ for _, v2 := range tableHeader.Child {
|
39
|
|
96
|
|
40
|
- return nil, nil
|
97
|
+ //第二行
|
|
|
98
|
+ for _, v3 := range v2.Child {
|
|
|
99
|
+ //第三行
|
|
|
100
|
+ for _, v4 := range v3.Child {
|
|
|
101
|
+ allColNum++
|
|
|
102
|
+ //按列填充数据
|
|
|
103
|
+ colName, _ := excelize.ColumnNumberToName(allColNum + 2) //第3列开始
|
|
|
104
|
+ xlsxFile.SetCellStr(newSheetName, colName+"2", v2.Name) //分类
|
|
|
105
|
+ xlsxFile.SetCellStr(newSheetName, colName+"3", v3.Name) //加分项 得分项
|
|
|
106
|
+ xlsxFile.SetCellStr(newSheetName, colName+"4", v4.Name) // 评估项名称
|
|
|
107
|
+ //权重 填写第5行数据
|
|
|
108
|
+ k23 := eData.data23Key(k1, v2.Name, v3.Name, v4.Name)
|
|
|
109
|
+ xlsxFile.SetCellStr(newSheetName, colName+"5", eData.data3[k23])
|
|
|
110
|
+ //评估标准 填写第6行数据
|
|
|
111
|
+ xlsxFile.SetCellStr(newSheetName, colName+"6", eData.data2[k23])
|
|
|
112
|
+ //按日期填充评估的填写的值
|
|
|
113
|
+ for i5, v5 := range dayList {
|
|
|
114
|
+ k1 := eData.dataKey(k1, val2, v5, v2.Name, v3.Name, v4.Name)
|
|
|
115
|
+ //填写在第几行
|
|
|
116
|
+ axisNum := 7 + 3*i5
|
|
|
117
|
+ axis := fmt.Sprintf("%s%d", colName, axisNum)
|
|
|
118
|
+ if d, ok := eData.data[k1]; ok {
|
|
|
119
|
+ xlsxFile.SetCellStr(newSheetName, axis, d.String())
|
|
|
120
|
+ }
|
|
|
121
|
+ //单元格高度按三个单元格合并
|
|
|
122
|
+ axisEnd := fmt.Sprintf("%s%d", colName, axisNum+2)
|
|
|
123
|
+ xlsxFile.MergeCell(newSheetName, axis, axisEnd)
|
|
|
124
|
+ }
|
|
|
125
|
+ }
|
|
|
126
|
+ }
|
|
|
127
|
+ }
|
|
|
128
|
+ //
|
|
|
129
|
+ colName, _ := excelize.ColumnNumberToName(allColNum + 2)
|
|
|
130
|
+ xlsxFile.MergeCell(newSheetName, "A1", fmt.Sprintf("%s1", colName))
|
|
|
131
|
+ }
|
|
|
132
|
+ }
|
|
|
133
|
+ //删除默认的第一个sheet
|
|
|
134
|
+ xlsxFile.DeleteSheet(firstSheetName)
|
|
|
135
|
+ return xlsxFile, nil
|
41
|
}
|
136
|
}
|
42
|
|
137
|
|
43
|
// 处理原始数据,方便进行 excel导出
|
138
|
// 处理原始数据,方便进行 excel导出
|
44
|
type exportData3 struct {
|
139
|
type exportData3 struct {
|
45
|
- sheetList []string //excel的sheet列表
|
|
|
46
|
- tableHeader map[string]*HeaderLevel //表头数据
|
140
|
+ userIdName map[string]string //员工id对应的名字 id=>员工名称
|
|
|
141
|
+ userProjcetMap map[string][]string //员工的项目 员工id=>项目id
|
|
|
142
|
+ tableHeader map[string]*HeaderLevel //表头数据 key=员工id+项目id
|
|
|
143
|
+ userDayMap map[string][]string //每个员工对应的日期列表 key=员工id+项目id value= 日期列表
|
|
|
144
|
+ data map[string]*strings.Builder //每个员工表头对应的评估填写的数据 key=员工id+项目id+日期+表头
|
|
|
145
|
+ data2 map[string]string //每个员工评估项的标准描述 key=员工id+项目id+表头
|
|
|
146
|
+ data3 map[string]string //每个员工评估项的标准权重 key=员工id+项目id+表头
|
|
|
147
|
+}
|
|
|
148
|
+
|
|
|
149
|
+func newExportData3() *exportData3 {
|
|
|
150
|
+ return &exportData3{
|
|
|
151
|
+ userIdName: map[string]string{},
|
|
|
152
|
+ userProjcetMap: map[string][]string{},
|
|
|
153
|
+ tableHeader: map[string]*HeaderLevel{},
|
|
|
154
|
+ userDayMap: map[string][]string{},
|
|
|
155
|
+ data: map[string]*strings.Builder{},
|
|
|
156
|
+ data2: map[string]string{}, data3: map[string]string{}}
|
47
|
}
|
157
|
}
|
48
|
|
158
|
|
49
|
func (e *exportData3) FormatTableHead(param []dao.DataEvaluationItemUsed2) {
|
159
|
func (e *exportData3) FormatTableHead(param []dao.DataEvaluationItemUsed2) {
|
50
|
- userNameMap := map[string]struct{}{} //员工名字过滤
|
|
|
51
|
- userProjcetMap := map[string]map[string]string{}
|
|
|
52
|
- userIdName := map[string]string{} //员工id=> 员工名称
|
|
|
53
|
- sheetMap := HeaderLevel{}
|
160
|
+ userNameMap := map[string]struct{}{} //员工名字过滤
|
|
|
161
|
+ projectIdMap := map[string]struct{}{} //项目id
|
54
|
for _, val := range param {
|
162
|
for _, val := range param {
|
55
|
- // child := sheetMap.addChild(val.TargetUserId)
|
|
|
56
|
- // _ = child.addChild(val.EvaluationProjectId)
|
163
|
+ //
|
57
|
if _, ok := userNameMap[val.TargetUserId]; !ok {
|
164
|
if _, ok := userNameMap[val.TargetUserId]; !ok {
|
58
|
- userProjcetMap[val.TargetUserId] = map[string]string{}
|
165
|
+ e.userProjcetMap[val.TargetUserId] = []string{}
|
59
|
}
|
166
|
}
|
60
|
- userProjcetMap[val.TargetUserId][val.EvaluationProjectId] = ""
|
|
|
61
|
- if _, ok := userIdName[val.TargetUserId]; !ok {
|
|
|
62
|
- userIdName[val.TargetUserId] = val.TargetUserName
|
|
|
63
|
- userNameMap[val.TargetUserName] = struct{}{}
|
167
|
+ //处理一个员工多项目的情况
|
|
|
168
|
+ if _, ok := projectIdMap[val.EvaluationProjectId]; !ok {
|
|
|
169
|
+ e.userProjcetMap[val.TargetUserId] = append(e.userProjcetMap[val.TargetUserId], val.EvaluationProjectId)
|
64
|
}
|
170
|
}
|
|
|
171
|
+ //处理员工的名称
|
|
|
172
|
+ if _, ok := e.userIdName[val.TargetUserId]; !ok {
|
|
|
173
|
+ if _, ok := userNameMap[val.TargetUserName]; ok {
|
|
|
174
|
+ uname := fmt.Sprintf("%s(%d)", val.TargetUserName, len(userNameMap))
|
|
|
175
|
+ e.userIdName[val.TargetUserId] = uname
|
|
|
176
|
+ userNameMap[uname] = struct{}{}
|
|
|
177
|
+ } else {
|
|
|
178
|
+ e.userIdName[val.TargetUserId] = val.TargetUserName
|
|
|
179
|
+ userNameMap[val.TargetUserName] = struct{}{}
|
|
|
180
|
+ }
|
|
|
181
|
+ }
|
|
|
182
|
+ //每个员工对应的日期列表
|
|
|
183
|
+ key1 := val.TargetUserId + "+" + val.EvaluationProjectId
|
|
|
184
|
+ if _, ok := e.tableHeader[key1]; !ok {
|
|
|
185
|
+ e.tableHeader[key1] = &HeaderLevel{
|
|
|
186
|
+ Name: "个人绩效评估等级统计表",
|
|
|
187
|
+ Filter: map[string]int{},
|
|
|
188
|
+ Child: []HeaderLevel{},
|
|
|
189
|
+ }
|
|
|
190
|
+ }
|
|
|
191
|
+ child := e.tableHeader[key1].addChild(val.Category) //第一级,"分类"
|
|
|
192
|
+ weight := e.weightDesc(val.Weight)
|
|
|
193
|
+ child = child.addChild(weight) //第二级 '得分项' '加分项'
|
|
|
194
|
+ child.addChild(val.ContentName) //第三级 评估项名称
|
65
|
}
|
195
|
}
|
|
|
196
|
+}
|
66
|
|
197
|
|
67
|
- for _, val := range sheetMap.Child {
|
198
|
+func (e *exportData3) FormatListValue(param []dao.DataStaffAssessContent2) {
|
|
|
199
|
+ userDay := map[string]struct{}{}
|
|
|
200
|
+ for _, val := range param {
|
|
|
201
|
+ weight := e.weightDesc(val.Weight)
|
|
|
202
|
+ key := e.dataKey(val.TargetUserId, val.EvaluationProjectId, val.BeginDay, val.Category, weight, val.ContentName)
|
|
|
203
|
+ e.data[key] = &strings.Builder{}
|
|
|
204
|
+ e.data[key].WriteString(val.Value + "\n") //填写的等级
|
|
|
205
|
+ for _, vv := range val.Remark {
|
|
|
206
|
+ e.data[key].WriteString(vv.Title + "\n")
|
|
|
207
|
+ e.data[key].WriteString(vv.RemarkText + "\n")
|
|
|
208
|
+ }
|
|
|
209
|
+ dayKey := val.TargetUserId + val.EvaluationProjectId + val.BeginDay
|
|
|
210
|
+ if _, ok := userDay[dayKey]; !ok {
|
|
|
211
|
+ userDay[dayKey] = struct{}{}
|
|
|
212
|
+ k := e.userDayKey(val.TargetUserId, val.EvaluationProjectId)
|
|
|
213
|
+ e.userDayMap[k] = append(e.userDayMap[k], val.BeginDay)
|
|
|
214
|
+ }
|
|
|
215
|
+ key23 := e.data23Key(val.TargetUserId, val.Category, weight, val.ContentName)
|
|
|
216
|
+ e.data2[key23] = val.PromptText
|
|
|
217
|
+ if val.Weight == 0 {
|
|
|
218
|
+ e.data3[key23] = ""
|
|
|
219
|
+ } else {
|
|
|
220
|
+ e.data3[key23] = fmt.Sprintf("%.2f%%", val.Weight)
|
|
|
221
|
+ }
|
|
|
222
|
+ }
|
|
|
223
|
+}
|
68
|
|
224
|
|
|
|
225
|
+func (e *exportData3) weightDesc(weight float64) string {
|
|
|
226
|
+ if weight == 0 {
|
|
|
227
|
+ return "加分项"
|
|
|
228
|
+ } else {
|
|
|
229
|
+ return "得分项"
|
69
|
}
|
230
|
}
|
70
|
}
|
231
|
}
|
71
|
|
232
|
|
72
|
-func (e *exportData3) FormatListValue(param []dao.DataStaffAssessContent2) {
|
233
|
+func (e *exportData3) dataKey(userId string, projectId string, beginDay string, category string, weight string, contentName string) string {
|
|
|
234
|
+ key := fmt.Sprintf("%s-%s-%s-%s-%s-%s", userId, projectId, weight, beginDay, category, contentName)
|
|
|
235
|
+ return key
|
|
|
236
|
+}
|
73
|
|
237
|
|
|
|
238
|
+func (e *exportData3) data23Key(userId string, category string, weight string, contentName string) string {
|
|
|
239
|
+ key := fmt.Sprintf("%s-%s-%s-%s", userId, weight, category, contentName)
|
|
|
240
|
+ return key
|
74
|
}
|
241
|
}
|
75
|
|
242
|
|
76
|
-func (e *exportData3) DataKey(userName string, projectId string, beginDay string, category string, weight string, contentName string) string {
|
|
|
77
|
- return ""
|
243
|
+func (e *exportData3) userDayKey(userId string, projectId string) string {
|
|
|
244
|
+ return fmt.Sprintf("%s-%s", userId, projectId)
|
78
|
} |
245
|
} |