Merge branch 'dev-zhengzhou' into test
正在显示
7 个修改的文件
包含
312 行增加
和
6 行删除
@@ -2,14 +2,16 @@ package command | @@ -2,14 +2,16 @@ package command | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "github.com/beego/beego/v2/core/validation" | 4 | "github.com/beego/beego/v2/core/validation" |
5 | + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/domain" | ||
5 | "unicode/utf8" | 6 | "unicode/utf8" |
6 | ) | 7 | ) |
7 | 8 | ||
8 | type CreateTemplateCommand struct { | 9 | type CreateTemplateCommand struct { |
9 | - CompanyId int64 `cname:"公司ID" json:"companyId"` | ||
10 | - CreatorId int64 `cname:"创建人ID" json:"creatorId"` | ||
11 | - Name string `cname:"模板名称" json:"name" valid:"Required"` | ||
12 | - Describe string `cname:"模板描述" json:"describe"` | 10 | + CompanyId int64 `cname:"公司ID" json:"companyId"` |
11 | + CreatorId int64 `cname:"创建人ID" json:"creatorId"` | ||
12 | + Name string `cname:"模板名称" json:"name" valid:"Required"` | ||
13 | + Describe string `cname:"模板描述" json:"describe"` | ||
14 | + NodeContents []*domain.NodeContent `cname:"环节-评估内容" json:"nodeContents"` | ||
13 | } | 15 | } |
14 | 16 | ||
15 | func (in *CreateTemplateCommand) Valid(validation *validation.Validation) { | 17 | func (in *CreateTemplateCommand) Valid(validation *validation.Validation) { |
@@ -40,13 +40,21 @@ func (rs *EvaluationTemplateService) Create(in *command.CreateTemplateCommand) ( | @@ -40,13 +40,21 @@ func (rs *EvaluationTemplateService) Create(in *command.CreateTemplateCommand) ( | ||
40 | linkNodes := make([]*domain.LinkNode, 0) | 40 | linkNodes := make([]*domain.LinkNode, 0) |
41 | 41 | ||
42 | sid, _ := utils.NewSnowflakeId() | 42 | sid, _ := utils.NewSnowflakeId() |
43 | - linkNodes = append(linkNodes, &domain.LinkNode{ | 43 | + |
44 | + // 自评反馈 | ||
45 | + selfLinkNode := &domain.LinkNode{ | ||
44 | Id: sid + 1, | 46 | Id: sid + 1, |
45 | Type: domain.LinkNodeSelfAssessment, | 47 | Type: domain.LinkNodeSelfAssessment, |
46 | Name: "填写自评反馈", | 48 | Name: "填写自评反馈", |
47 | NodeContents: make([]*domain.NodeContent, 0), | 49 | NodeContents: make([]*domain.NodeContent, 0), |
48 | KpiCycle: domain.KpiCycleDay, | 50 | KpiCycle: domain.KpiCycleDay, |
49 | - }) | 51 | + } |
52 | + // 有环节自评评估内容,则直接使用 | ||
53 | + if len(in.NodeContents) > 0 { | ||
54 | + selfLinkNode.NodeContents = in.NodeContents | ||
55 | + } | ||
56 | + | ||
57 | + linkNodes = append(linkNodes, selfLinkNode) | ||
50 | linkNodes = append(linkNodes, &domain.LinkNode{ | 58 | linkNodes = append(linkNodes, &domain.LinkNode{ |
51 | Id: sid + 2, | 59 | Id: sid + 2, |
52 | Type: domain.LinkNodeAllInvite, | 60 | Type: domain.LinkNodeAllInvite, |
@@ -17,6 +17,9 @@ var AdminJwtExpiresIn = int64(3600 * 24 * 7) | @@ -17,6 +17,9 @@ var AdminJwtExpiresIn = int64(3600 * 24 * 7) | ||
17 | 17 | ||
18 | var AdminJWTSecretKey = "sg-storage" | 18 | var AdminJWTSecretKey = "sg-storage" |
19 | 19 | ||
20 | +// 上传临时Zip文件 | ||
21 | +var UPLOAD_ZIP_PATH = "./uploads/zip" | ||
22 | + | ||
20 | // Env 判断当前环境变量 | 23 | // Env 判断当前环境变量 |
21 | var Env = "dev" | 24 | var Env = "dev" |
22 | 25 |
pkg/infrastructure/xredis/constans.go
0 → 100644
@@ -2,8 +2,12 @@ package xredis | @@ -2,8 +2,12 @@ package xredis | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "encoding/json" | ||
5 | "fmt" | 6 | "fmt" |
7 | + "reflect" | ||
6 | "strconv" | 8 | "strconv" |
9 | + "strings" | ||
10 | + "time" | ||
7 | 11 | ||
8 | "github.com/go-redis/redis/v8" | 12 | "github.com/go-redis/redis/v8" |
9 | "github.com/go-redsync/redsync/v4" | 13 | "github.com/go-redsync/redsync/v4" |
@@ -35,3 +39,37 @@ func init() { | @@ -35,3 +39,37 @@ func init() { | ||
35 | pool := goredis.NewPool(rdb) | 39 | pool := goredis.NewPool(rdb) |
36 | rsync = redsync.New(pool) | 40 | rsync = redsync.New(pool) |
37 | } | 41 | } |
42 | + | ||
43 | +func Set(key string, value interface{}, timeout time.Duration) error { | ||
44 | + valueOf := reflect.ValueOf(value) | ||
45 | + typeName := strings.ToLower(valueOf.Type().Name()) | ||
46 | + var newValue interface{} | ||
47 | + if typeName == "string" || typeName == "int" || typeName == "int64" || typeName == "float64" { | ||
48 | + newValue = value | ||
49 | + } else { | ||
50 | + mBytes, err := json.Marshal(value) | ||
51 | + if err != nil { | ||
52 | + return err | ||
53 | + } | ||
54 | + newValue = string(mBytes) | ||
55 | + } | ||
56 | + | ||
57 | + err := rdb.Set(rdb.Context(), key, newValue, timeout*time.Second).Err() | ||
58 | + return err | ||
59 | +} | ||
60 | + | ||
61 | +func Get(key string) string { | ||
62 | + value, err := rdb.Get(rdb.Context(), key).Result() | ||
63 | + if err != nil { | ||
64 | + return "" | ||
65 | + } | ||
66 | + return value | ||
67 | +} | ||
68 | + | ||
69 | +func GetBytes(key string) ([]byte, error) { | ||
70 | + return rdb.Get(rdb.Context(), key).Bytes() | ||
71 | +} | ||
72 | + | ||
73 | +func Remove(key string) error { | ||
74 | + return rdb.Del(rdb.Context(), key).Err() | ||
75 | +} |
1 | package controllers | 1 | package controllers |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | + "archive/zip" | ||
5 | + "bufio" | ||
6 | + "encoding/json" | ||
4 | "fmt" | 7 | "fmt" |
8 | + service "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/evaluation_template" | ||
9 | + templateCommand "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/evaluation_template/command" | ||
10 | + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/application/import/command" | ||
11 | + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/constant" | ||
12 | + "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/infrastructure/xredis" | ||
5 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/utils" | 13 | "gitlab.fjmaimaimai.com/allied-creation/performance/pkg/utils" |
14 | + "io" | ||
15 | + "mime/multipart" | ||
16 | + "os" | ||
17 | + "path" | ||
18 | + "path/filepath" | ||
6 | "strconv" | 19 | "strconv" |
7 | "strings" | 20 | "strings" |
21 | + "time" | ||
8 | 22 | ||
9 | "github.com/linmadan/egglib-go/core/application" | 23 | "github.com/linmadan/egglib-go/core/application" |
10 | "github.com/linmadan/egglib-go/utils/tool_funs" | 24 | "github.com/linmadan/egglib-go/utils/tool_funs" |
@@ -183,3 +197,233 @@ func (controller *ImportController) parseTemplateNodeContent(data []*domain.Perf | @@ -183,3 +197,233 @@ func (controller *ImportController) parseTemplateNodeContent(data []*domain.Perf | ||
183 | 197 | ||
184 | return nil, nodeContents | 198 | return nil, nodeContents |
185 | } | 199 | } |
200 | + | ||
201 | +func (controller *ImportController) ZipVerify() { | ||
202 | + in := &command.VerifyKeyCommand{} | ||
203 | + if err := controller.Unmarshal(in); err != nil { | ||
204 | + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error())) | ||
205 | + } else { | ||
206 | + bytes, err := xredis.GetBytes(in.VerifyKey) | ||
207 | + if err != nil { | ||
208 | + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error())) | ||
209 | + } else { | ||
210 | + out := &command.OutResult{} | ||
211 | + err := json.Unmarshal(bytes, out) | ||
212 | + if err != nil { | ||
213 | + controller.Response(nil, application.ThrowError(application.ARG_ERROR, err.Error())) | ||
214 | + } else { | ||
215 | + controller.Response(out, nil) | ||
216 | + } | ||
217 | + } | ||
218 | + } | ||
219 | +} | ||
220 | + | ||
221 | +func (controller *ImportController) ZipImport() { | ||
222 | + _, header, err := controller.GetFile("file") | ||
223 | + if err != nil { | ||
224 | + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error())) | ||
225 | + return | ||
226 | + } | ||
227 | + file, err := header.Open() | ||
228 | + if err != nil { | ||
229 | + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "文件错误:"+err.Error())) | ||
230 | + return | ||
231 | + } | ||
232 | + | ||
233 | + // 写入本地 | ||
234 | + zipPath, day, id, err := controller.writeLocal(file) | ||
235 | + if err != nil { | ||
236 | + controller.Response(nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, err.Error())) | ||
237 | + return | ||
238 | + } | ||
239 | + | ||
240 | + out := command.OutResult{ | ||
241 | + Status: "uncompleted", | ||
242 | + Success: make([]command.ErrorI, 0), | ||
243 | + Failure: make([]command.ErrorI, 0), | ||
244 | + } | ||
245 | + key := xredis.CreateUploadZipKey(id) | ||
246 | + _ = xredis.Set(key, out, 2*time.Hour) | ||
247 | + controller.Response(map[string]string{"key": key}, nil) | ||
248 | + go func() { | ||
249 | + // 解压目标文件夹 | ||
250 | + dstDir := constant.UPLOAD_ZIP_PATH + "/" + day + "/" + id | ||
251 | + fileNames, err := controller.Unzip(zipPath, dstDir) | ||
252 | + if err != nil { | ||
253 | + _ = xredis.Remove(key) | ||
254 | + } else { | ||
255 | + | ||
256 | + success := make([]command.ErrorI, 0) | ||
257 | + failure := make([]command.ErrorI, 0) | ||
258 | + | ||
259 | + for i := range fileNames { | ||
260 | + fn := fileNames[i] | ||
261 | + f, err := os.Open(path.Join(dstDir, fn)) | ||
262 | + if err != nil { | ||
263 | + failure = append(failure, command.ErrorI{ | ||
264 | + FileName: fn, | ||
265 | + Message: err.Error(), | ||
266 | + }) | ||
267 | + continue | ||
268 | + } | ||
269 | + if err := controller.parserAndInsert(f); err != nil { | ||
270 | + failure = append(failure, command.ErrorI{ | ||
271 | + FileName: fn, | ||
272 | + Message: err.Error(), | ||
273 | + }) | ||
274 | + continue | ||
275 | + } | ||
276 | + | ||
277 | + success = append(success, command.ErrorI{ | ||
278 | + FileName: fn, | ||
279 | + Message: "", | ||
280 | + }) | ||
281 | + } | ||
282 | + out = command.OutResult{ | ||
283 | + Status: "completed", | ||
284 | + Success: success, | ||
285 | + Failure: failure, | ||
286 | + } | ||
287 | + _ = xredis.Set(key, out, 1*time.Hour) | ||
288 | + } | ||
289 | + | ||
290 | + }() | ||
291 | + | ||
292 | +} | ||
293 | + | ||
294 | +func (controller *ImportController) writeLocal(file multipart.File) (string, string, string, error) { | ||
295 | + var err error | ||
296 | + id, err := utils.NewSnowflakeId() | ||
297 | + if err != nil { | ||
298 | + return "", "", "", err | ||
299 | + } | ||
300 | + id2 := fmt.Sprintf("%v", id) | ||
301 | + day := time.Now().Format("2006-01-02") | ||
302 | + zipPath := constant.UPLOAD_ZIP_PATH + "/" + day + "/" + id2 + "/" + "temp" | ||
303 | + | ||
304 | + var fd *os.File | ||
305 | + | ||
306 | + dir := filepath.Dir(zipPath) | ||
307 | + err = os.MkdirAll(dir, os.ModePerm) | ||
308 | + if err != nil { | ||
309 | + return "", "", "", err | ||
310 | + } | ||
311 | + | ||
312 | + fd, err = os.OpenFile(zipPath, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0666) | ||
313 | + if err != nil { | ||
314 | + return "", "", "", err | ||
315 | + } | ||
316 | + defer func(fd *os.File) { | ||
317 | + if err = fd.Close(); err != nil { | ||
318 | + | ||
319 | + } | ||
320 | + }(fd) | ||
321 | + | ||
322 | + wt := bufio.NewWriter(fd) | ||
323 | + _, err = file.Seek(0, io.SeekStart) | ||
324 | + if err != nil { | ||
325 | + return "", "", "", err | ||
326 | + } | ||
327 | + _, err = io.Copy(wt, file) | ||
328 | + if err != nil { | ||
329 | + return "", "", "", err | ||
330 | + } | ||
331 | + | ||
332 | + err = wt.Flush() | ||
333 | + if err != nil { | ||
334 | + return "", "", "", err | ||
335 | + } | ||
336 | + | ||
337 | + return zipPath, day, id2, err | ||
338 | +} | ||
339 | + | ||
340 | +func (controller *ImportController) Unzip(zipPath, dstDir string) ([]string, error) { | ||
341 | + // 文件名称 | ||
342 | + fileNames := make([]string, 0) | ||
343 | + // open zip file | ||
344 | + reader, err := zip.OpenReader(zipPath) | ||
345 | + if err != nil { | ||
346 | + return fileNames, err | ||
347 | + } | ||
348 | + defer reader.Close() | ||
349 | + | ||
350 | + for _, file := range reader.File { | ||
351 | + if err := controller.unzipFile(file, dstDir); err != nil { | ||
352 | + return fileNames, err | ||
353 | + } else { | ||
354 | + fileNames = append(fileNames, file.Name) | ||
355 | + } | ||
356 | + } | ||
357 | + return fileNames, nil | ||
358 | +} | ||
359 | + | ||
360 | +// 解析文件并插入数据 | ||
361 | +func (controller *ImportController) parserAndInsert(file *os.File) error { | ||
362 | + reader, err := excelize.OpenReader(file) | ||
363 | + if err != nil { | ||
364 | + return application.ThrowError(application.INTERNAL_SERVER_ERROR, "上传错误:"+err.Error()) | ||
365 | + } | ||
366 | + index := reader.GetActiveSheetIndex() | ||
367 | + rows, err := reader.GetRows(reader.GetSheetName(index)) | ||
368 | + if err != nil { | ||
369 | + return application.ThrowError(application.INTERNAL_SERVER_ERROR, "读取excel错误:"+err.Error()) | ||
370 | + } | ||
371 | + dimensions, err := domain.LoadPerformanceDimensions(rows) | ||
372 | + if err != nil { | ||
373 | + return application.ThrowError(application.ARG_ERROR, err.Error()) | ||
374 | + } | ||
375 | + if err, list := controller.parseTemplateNodeContent(dimensions); err != nil { | ||
376 | + return application.ThrowError(application.ARG_ERROR, err.Error()) | ||
377 | + } else { | ||
378 | + if len(list) == 0 { | ||
379 | + return application.ThrowError(application.ARG_ERROR, "没有数据内容") | ||
380 | + } | ||
381 | + | ||
382 | + ruService := service.NewEvaluationTemplateService() | ||
383 | + in := &templateCommand.CreateTemplateCommand{} | ||
384 | + | ||
385 | + ua := middlewares.GetUser(controller.Ctx) | ||
386 | + in.CompanyId = ua.CompanyId | ||
387 | + in.CreatorId = ua.UserId | ||
388 | + in.Name = file.Name() | ||
389 | + in.Describe = "" | ||
390 | + in.NodeContents = list | ||
391 | + | ||
392 | + if _, err := ruService.Create(in); err != nil { | ||
393 | + return application.ThrowError(application.ARG_ERROR, "数据创建错误") | ||
394 | + } | ||
395 | + } | ||
396 | + return nil | ||
397 | +} | ||
398 | + | ||
399 | +func (controller *ImportController) unzipFile(file *zip.File, dstDir string) error { | ||
400 | + // create the directory of file | ||
401 | + filePath := path.Join(dstDir, file.Name) | ||
402 | + if file.FileInfo().IsDir() { | ||
403 | + if err := os.MkdirAll(filePath, os.ModePerm); err != nil { | ||
404 | + return err | ||
405 | + } | ||
406 | + return nil | ||
407 | + } | ||
408 | + if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { | ||
409 | + return err | ||
410 | + } | ||
411 | + | ||
412 | + // open the file | ||
413 | + rc, err := file.Open() | ||
414 | + if err != nil { | ||
415 | + return err | ||
416 | + } | ||
417 | + defer rc.Close() | ||
418 | + | ||
419 | + // create the file | ||
420 | + w, err := os.Create(filePath) | ||
421 | + if err != nil { | ||
422 | + return err | ||
423 | + } | ||
424 | + defer w.Close() | ||
425 | + | ||
426 | + // save the decompressed file content | ||
427 | + _, err = io.Copy(w, rc) | ||
428 | + return err | ||
429 | +} |
@@ -11,6 +11,8 @@ func init() { | @@ -11,6 +11,8 @@ func init() { | ||
11 | ns := web.NewNamespace("/v1/import", | 11 | ns := web.NewNamespace("/v1/import", |
12 | web.NSBefore(filters.AllowCors(), middlewares.CheckAdminToken()), | 12 | web.NSBefore(filters.AllowCors(), middlewares.CheckAdminToken()), |
13 | web.NSRouter("/", &controllers.ImportController{}, "Post:Import"), | 13 | web.NSRouter("/", &controllers.ImportController{}, "Post:Import"), |
14 | + web.NSRouter("/zip", &controllers.ImportController{}, "Post:ZipImport"), | ||
15 | + web.NSRouter("/zip-verify", &controllers.ImportController{}, "Post:ZipVerify"), | ||
14 | ) | 16 | ) |
15 | web.AddNamespace(ns) | 17 | web.AddNamespace(ns) |
16 | } | 18 | } |
-
请 注册 或 登录 后发表评论