作者 陈志颖

feat:添加分红订单导入和分红退货单导入服务

@@ -19,7 +19,7 @@ type CooperationContractByUndertakerDto struct { @@ -19,7 +19,7 @@ type CooperationContractByUndertakerDto struct {
19 // 项目合约名称 19 // 项目合约名称
20 CooperationContractName string `json:"cooperationContractName"` 20 CooperationContractName string `json:"cooperationContractName"`
21 // 合同附件 21 // 合同附件
22 - Attachment []*domain.Attachment 22 + Attachment []*domain.Attachment `json:"attachment"`
23 // 发起人姓名 23 // 发起人姓名
24 SponsorName string `json:"sponsorName"` 24 SponsorName string `json:"sponsorName"`
25 // 发起部门名称 25 // 发起部门名称
@@ -40,7 +40,7 @@ type CreateDividendsOrderCommand struct { @@ -40,7 +40,7 @@ type CreateDividendsOrderCommand struct {
40 // 订单操作人uid 40 // 订单操作人uid
41 OperatorUid string `cname:"订单操作人uid" json:"operatorUid,omitempty"` 41 OperatorUid string `cname:"订单操作人uid" json:"operatorUid,omitempty"`
42 // 订单产品列表 42 // 订单产品列表
43 - OrderGoods []*OrderGoods `cname:"订单产品列表" json:"orderGoods,omitempty"` 43 + OrderGoods []OrderGoods `cname:"订单产品列表" json:"orderGoods,omitempty"`
44 // 公司ID,通过集成REST上下文获取 44 // 公司ID,通过集成REST上下文获取
45 CompanyId int64 `cname:"公司ID" json:"companyId" valid:"Required"` 45 CompanyId int64 `cname:"公司ID" json:"companyId" valid:"Required"`
46 // 组织机构ID 46 // 组织机构ID
@@ -49,10 +49,11 @@ type CreateDividendsOrderCommand struct { @@ -49,10 +49,11 @@ type CreateDividendsOrderCommand struct {
49 UserId int64 `cname:"用户ID" json:"userId" valid:"Required"` 49 UserId int64 `cname:"用户ID" json:"userId" valid:"Required"`
50 // 用户基础信息id 50 // 用户基础信息id
51 UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId" valid:"Required"` 51 UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId" valid:"Required"`
  52 + // 记录行号
  53 + LineNumbers []int `cname:"记录行号" json:"lineNumbers"`
52 } 54 }
53 55
54 func (createDividendsOrderCommand *CreateDividendsOrderCommand) Valid(validation *validation.Validation) { 56 func (createDividendsOrderCommand *CreateDividendsOrderCommand) Valid(validation *validation.Validation) {
55 - //validation.SetError("CustomValid", "未实现的自定义认证")  
56 } 57 }
57 58
58 func (createDividendsOrderCommand *CreateDividendsOrderCommand) ValidateCommand() error { 59 func (createDividendsOrderCommand *CreateDividendsOrderCommand) ValidateCommand() error {
@@ -5,47 +5,46 @@ import ( @@ -5,47 +5,46 @@ import (
5 "github.com/beego/beego/v2/core/validation" 5 "github.com/beego/beego/v2/core/validation"
6 "reflect" 6 "reflect"
7 "strings" 7 "strings"
8 - "time"  
9 ) 8 )
10 9
11 -type ImportDividendsOrderCommand struct {  
12 - // 订单数据列表  
13 - DividendsOrderData []*DividendsOrderData `cname:"订单数据列表" json:"dividendsOrderData" valid:"Required"`  
14 - // 公司ID,通过集成REST上下文获取  
15 - CompanyId int64 `cname:"公司ID" json:"companyId"`  
16 - // 组织机构ID  
17 - OrgId int64 `cname:"组织机构ID" json:"orgId"`  
18 - // 用户ID,通过集成REST上下文获取,可翻译成发起人、承接人、推荐人、业务员  
19 - UserId int64 `cname:"用户ID" json:"userId"`  
20 - // 用户基础信息id  
21 - UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId"`  
22 -} 10 +type (
  11 + ImportDividendsOrderData struct {
  12 + //来源单号,源单号,订单号
  13 + OriginalOrderNum string `json:"originalOrderNum"`
  14 + //订单客户名称
  15 + DividendsCustomerName string `json:"dividendsCustomerName"`
  16 + //订单产品名称
  17 + OrderGoodName string `json:"orderGoodName"`
  18 + //订单日期
  19 + OrderTime string `json:"orderTime"`
  20 + //订单区域名称
  21 + RegionName string `json:"regionName"`
  22 + //订单产品数量
  23 + OrderGoodQuantity string `json:"orderGoodQuantity"`
  24 + //订单产品单价
  25 + OrderGoodPrice string `json:"orderGoodPrice"`
  26 + //费用
  27 + Expense string `json:"expense"`
  28 + //合约编号
  29 + CooperationContractNumber string `json:"cooperationContractNumber"`
  30 + }
23 31
24 -type DividendsOrderData struct {  
25 - // 客户名称  
26 - CustomerName string `cname:"客户名称" json:"customerName" valid:"Required"`  
27 - // 分红订单金额  
28 - DividendsOrderAmount float64 `cname:"分红订单金额" json:"dividendsOrderAmount" valid:"Required"`  
29 - // 分红订单号  
30 - DividendsOrderNumber string `cname:"分红订单号" json:"dividendsOrderNumber" valid:"Required"`  
31 - // 分红订单原单号  
32 - DividendsOriginalOrderNum string `cname:"分红订单原单号" json:"dividendsOriginalOrderNum" valid:"Required"`  
33 - // 订单产生时间  
34 - OrderTime time.Time `cname:"订单产生时间" json:"orderTime" valid:"Required"`  
35 - // 订单区域名称  
36 - RegionName string `cname:"订单区域名称" json:"regionName,omitempty"`  
37 - // 订单业务员uid  
38 - SalesmanUid string `cname:"订单业务员UID" json:"salesmanUid,omitempty"`  
39 - // 订单产品列表  
40 - OrderGoods []*OrderGoods `cname:"订单产品列表" json:"orderGoods,omitempty"`  
41 - // 订单操作人uid  
42 - OperatorUid string `cname:"订单操作人UID" json:"operatorUid,omitempty"`  
43 - // 备注  
44 - Remarks string `cname:"备注" json:"remarks,omitempty"`  
45 -} 32 + // ImportDividendsOrderCommand 请求参数
  33 + ImportDividendsOrderCommand struct {
  34 + // 分红订单数据
  35 + DividendsOrderData []ImportDividendsOrderData `json:"dividendsOrderData"` //分红订单数据列表
  36 + // 公司ID,通过集成REST上下文获取
  37 + CompanyId int64 `cname:"公司ID" json:"companyId"`
  38 + // 组织机构ID
  39 + OrgId int64 `cname:"组织机构ID" json:"orgId"`
  40 + // 用户ID,通过集成REST上下文获取,可翻译成发起人、承接人、推荐人、业务员
  41 + UserId int64 `cname:"用户ID" json:"userId"`
  42 + // 用户基础信息id
  43 + UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId"`
  44 + }
  45 +)
46 46
47 func (importDividendsOrderCommand *ImportDividendsOrderCommand) Valid(validation *validation.Validation) { 47 func (importDividendsOrderCommand *ImportDividendsOrderCommand) Valid(validation *validation.Validation) {
48 - //validation.SetError("CustomValid", "未实现的自定义认证")  
49 } 48 }
50 49
51 func (importDividendsOrderCommand *ImportDividendsOrderCommand) ValidateCommand() error { 50 func (importDividendsOrderCommand *ImportDividendsOrderCommand) ValidateCommand() error {
1 package service 1 package service
2 2
3 import ( 3 import (
  4 + "crypto/md5"
  5 + "encoding/hex"
4 "fmt" 6 "fmt"
5 "github.com/linmadan/egglib-go/core/application" 7 "github.com/linmadan/egglib-go/core/application"
6 "github.com/linmadan/egglib-go/utils/tool_funs" 8 "github.com/linmadan/egglib-go/utils/tool_funs"
@@ -11,7 +13,10 @@ import ( @@ -11,7 +13,10 @@ import (
11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain/service" 13 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain/service"
12 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/dao" 14 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/dao"
13 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/utils" 15 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/utils"
  16 + "reflect"
  17 + "regexp"
14 "strconv" 18 "strconv"
  19 + "strings"
15 "time" 20 "time"
16 ) 21 )
17 22
@@ -272,10 +277,340 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD @@ -272,10 +277,340 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD
272 dividendsOrderRepository = value 277 dividendsOrderRepository = value
273 } 278 }
274 279
275 - var dividendsOrderImportFailed []*domain.DividendsOrder  
276 - var dividendsOrderImportSuccessfully []*domain.DividendsOrder 280 + // 返回信息表头定义
  281 + var tableHeader = []string{"错误详情", "行号", "来源单号", "客户名称", "产品名称", "订单日期", "订单区域", "产品数量", "产品价格", "费用", "项目合约编号"}
  282 +
  283 + // 空文件校验
  284 + if len(importDividendsOrderCommand.DividendsOrderData) == 0 {
  285 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "导入的Excel文件为空文件,请上传正确的文件")
  286 + }
  287 +
  288 + // 必填项校验
  289 + nullCellError := make([]interface{}, 0)
  290 +
  291 + // 数据行计数
  292 + rowCnt := 0
  293 +
  294 + // 空行标志位
  295 + nullFlag := false
  296 +
  297 + for i, dividendsOrder := range importDividendsOrderCommand.DividendsOrderData {
  298 + rowCnt++
  299 + nullCell := make([]interface{}, 0)
  300 + var myRow []string
  301 + t := reflect.TypeOf(dividendsOrder)
  302 + v := reflect.ValueOf(dividendsOrder)
  303 + for k := 0; k < t.NumField(); k++ {
  304 + //fmt.Println("name:", fmt.Sprintf("%+v", t.Field(k).Name), ", value:", fmt.Sprintf("%v", v.Field(k).Interface()), ", yaml:", t.Field(k).Tag.Get("yaml"))
  305 + if k != 7 && k != 8 {
  306 + if v.Field(k).Interface() == "" {
  307 + col := strconv.Itoa(k + 1)
  308 + nullCell = append(nullCell, col)
  309 + nullFlag = true
  310 + }
  311 + }
  312 + }
  313 + if nullFlag {
  314 + s := strconv.Itoa(i + 1)
  315 + b := strings.Replace(strings.Trim(fmt.Sprint(nullCell), "[]"), " ", ",", -1)
  316 + myRow = append(myRow, "第"+s+"行的第"+b+"列必填项为空") // 错误信息
  317 + myRow = append(myRow, s) // 行号
  318 + myRow = append(myRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  319 + nullCellError = append(nullCellError, myRow)
  320 + nullFlag = false
  321 + }
  322 + }
  323 +
  324 + // 必填项错误返回
  325 + if len(nullCellError) > 0 {
  326 + return map[string]interface{}{
  327 + "successCount": 0,
  328 + "fail": map[string]interface{}{
  329 + "tableHeader": tableHeader,
  330 + "tableData": nullCellError,
  331 + },
  332 + }, nil
  333 + }
  334 +
  335 + // 单元格类型校验
  336 + typeError := make([]interface{}, 0)
  337 + for i, dividendsOrder := range importDividendsOrderCommand.DividendsOrderData { // 行
  338 + var myRow []string
  339 + t := reflect.TypeOf(dividendsOrder)
  340 + v := reflect.ValueOf(dividendsOrder)
  341 + for k := 0; k < t.NumField(); k++ { // 列
  342 + r := strconv.Itoa(i + 1)
  343 + col := strconv.Itoa(k + 1)
  344 +
  345 + switch k {
  346 + case 3: // 订单日期校验
  347 + {
  348 + regexpStr := `(\d{4})/(\d{2})/(\d{2})`
  349 + ok := regexp.MustCompile(regexpStr).MatchString(fmt.Sprintf("%v", v.Field(k).Interface()))
  350 + if !ok {
  351 + var tmpRow []string
  352 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列订单日期格式错误,请输入正确的订单日期") // 错误信息
  353 + tmpRow = append(tmpRow, r) // 行号
  354 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  355 + myRow = tmpRow
  356 + }
  357 + }
  358 + case 5: // 产品数量校验
  359 + {
  360 + //参数类型转换
  361 + orderGoodQuantity, err := strconv.ParseInt(fmt.Sprintf("%v", v.Field(k).Interface()), 10, 64)
  362 + if err != nil {
  363 + var tmpRow []string
  364 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列产品数量格式错误,产品数量必须整数") // 错误信息
  365 + tmpRow = append(tmpRow, r) // 行号
  366 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  367 + myRow = tmpRow
  368 + }
  369 + // 正负判断
  370 + if orderGoodQuantity < 0 {
  371 + var tmpRow []string
  372 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列产品数量必须大于0,请重新填写") // 错误信息
  373 + tmpRow = append(tmpRow, r) // 行号
  374 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  375 + myRow = tmpRow
  376 + }
  377 + }
  378 + case 6: // 产品价格校验
  379 + {
  380 + // 参数类型转换
  381 + univalent, typeErr := strconv.ParseFloat(fmt.Sprintf("%v", v.Field(k).Interface()), 64)
  382 + if typeErr != nil {
  383 + var tmpRow []string
  384 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列产品价格格式错误,产品价格必须为数字类型") // 错误信息
  385 + tmpRow = append(tmpRow, r) // 行号
  386 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  387 + myRow = tmpRow
  388 + }
  389 +
  390 + // 长度校验
  391 + if univalent >= 1e16 {
  392 + var tmpRow []string
  393 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列产品价格超过最大限制,产品价格小数点前面不能超过十六位数字,并保留两位小数") // 错误信息
  394 + tmpRow = append(tmpRow, r) // 行号
  395 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  396 + myRow = tmpRow
  397 + }
  398 + }
  399 + case 7: // 费用校验
  400 + {
  401 + if fmt.Sprintf("%v", v.Field(k).Interface()) != "" {
  402 + // 参数类型转换
  403 + univalent, typeErr := strconv.ParseFloat(fmt.Sprintf("%v", v.Field(k).Interface()), 64)
  404 + if typeErr != nil {
  405 + var tmpRow []string
  406 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列费用格式错误,费用必须为数字类型") // 错误信息
  407 + tmpRow = append(tmpRow, r) // 行号
  408 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  409 + myRow = tmpRow
  410 + }
  411 +
  412 + // 长度校验
  413 + if univalent >= 1e16 {
  414 + var tmpRow []string
  415 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列费用超过最大限制,费用小数点前面不能超过十六位数字,并保留两位小数") // 错误信息
  416 + tmpRow = append(tmpRow, r) // 行号
  417 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  418 + myRow = tmpRow
  419 + }
  420 + }
  421 + }
  422 + }
  423 + }
  424 + if myRow != nil {
  425 + typeError = append(typeError, myRow)
  426 + }
  427 + }
  428 +
  429 + // 类型错误行返回
  430 + if len(typeError) > 0 {
  431 + return map[string]interface{}{
  432 + "successCount": 0,
  433 + "fail": map[string]interface{}{
  434 + "tableHeader": tableHeader,
  435 + "tableData": typeError,
  436 + },
  437 + }, nil
  438 + }
  439 +
  440 + // 聚合订单并进行类型校验
  441 + aggregateErrorList := make([]interface{}, 0)
  442 +
  443 + var dividendsOrderCommands = make(map[string]*command.CreateDividendsOrderCommand)
  444 + for i, dividendsOrder := range importDividendsOrderCommand.DividendsOrderData {
  445 + hashValue := md5.Sum([]byte(dividendsOrder.OriginalOrderNum))
  446 + hashString := hex.EncodeToString(hashValue[:])
  447 + if _, ok := dividendsOrderCommands[hashString]; !ok {
  448 + // 来源单号
  449 + dividendsOrderCommands[hashString].DividendsOriginalOrderNum = dividendsOrder.OriginalOrderNum
  450 +
  451 + // 客户名称
  452 + dividendsOrderCommands[hashString].CustomerName = dividendsOrder.DividendsCustomerName
  453 +
  454 + // 订单日期时间格式转换
  455 + timeValue, err := time.ParseInLocation("2006/01/02", dividendsOrder.OrderTime, time.Local)
  456 + if err != nil {
  457 + var tmpRow []string
  458 + tmpRow = append(tmpRow, "无效的订单日期") // 错误信息
  459 + s := strconv.Itoa(i + 1)
  460 + tmpRow = append(tmpRow, s) // 行号
  461 + //tmpRow = append(tmpRow, dividendsOrder.OriginalOrderNum) // TODO 错误行数据
  462 + aggregateErrorList = append(aggregateErrorList, tmpRow)
  463 + break
  464 + }
  465 +
  466 + // 产品相关:产品名称,产品数量、产品价格、费用
  467 + quantity, err := strconv.ParseInt(dividendsOrder.OrderGoodQuantity, 10, 64)
  468 + if err != nil {
  469 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  470 + }
  471 + price, err := strconv.ParseFloat(dividendsOrder.OrderGoodPrice, 64)
  472 + if err != nil {
  473 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  474 + }
  475 + expense, err := strconv.ParseFloat(dividendsOrder.Expense, 64)
  476 + if err != nil {
  477 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  478 + }
  479 +
  480 + // 初始化新建分红订单命令集
  481 + dividendsOrderCommands[hashString] = &command.CreateDividendsOrderCommand{
  482 + CustomerName: dividendsOrder.DividendsCustomerName,
  483 + DividendsOriginalOrderNum: dividendsOrder.OriginalOrderNum,
  484 + OrderTime: string(rune(timeValue.Nanosecond() / 1000)),
  485 + Remarks: "",
  486 + RegionName: dividendsOrder.RegionName,
  487 + OperatorUid: strconv.FormatInt(importDividendsOrderCommand.UserId, 10),
  488 + OrderGoods: []command.OrderGoods{
  489 + {
  490 + OrderGoodId: "0",
  491 + OrderGoodAmount: 0,
  492 + OrderGoodName: dividendsOrder.OrderGoodName,
  493 + OrderGoodPrice: price,
  494 + OrderGoodQuantity: quantity,
  495 + DividendsOrderNumber: "",
  496 + CooperationContractNumber: dividendsOrder.CooperationContractNumber,
  497 + OrderGoodExpense: expense,
  498 + },
  499 + },
  500 + CompanyId: importDividendsOrderCommand.CompanyId,
  501 + OrgId: importDividendsOrderCommand.OrgId,
  502 + UserId: importDividendsOrderCommand.UserId,
  503 + UserBaseId: importDividendsOrderCommand.UserBaseId,
  504 + LineNumbers: []int{i}, // 记录行号
  505 + }
  506 + } else { // 聚合同一笔订单产品
  507 + // 产品相关:产品名称,产品数量、产品价格、费用
  508 + quantity, err := strconv.ParseInt(dividendsOrder.OrderGoodQuantity, 10, 64)
  509 + if err != nil {
  510 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  511 + }
  512 + price, err := strconv.ParseFloat(dividendsOrder.OrderGoodPrice, 64)
  513 + if err != nil {
  514 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  515 + }
  516 + expense, err := strconv.ParseFloat(dividendsOrder.Expense, 64)
  517 + if err != nil {
  518 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  519 + }
  520 +
  521 + dividendsOrderCommands[hashString].OrderGoods = append(dividendsOrderCommands[hashString].OrderGoods, command.OrderGoods{
  522 + OrderGoodId: "0",
  523 + OrderGoodAmount: 0,
  524 + OrderGoodName: dividendsOrder.OrderGoodName,
  525 + OrderGoodPrice: price,
  526 + OrderGoodQuantity: quantity,
  527 + DividendsOrderNumber: "",
  528 + CooperationContractNumber: dividendsOrder.CooperationContractNumber,
  529 + OrderGoodExpense: expense,
  530 + })
  531 +
  532 + // 记录聚合行号
  533 + dividendsOrderCommands[hashString].LineNumbers = append(dividendsOrderCommands[hashString].LineNumbers, i)
  534 + }
  535 + }
  536 +
  537 + // 聚合订单错误返回
  538 + if len(aggregateErrorList) > 0 {
  539 + return map[string]interface{}{
  540 + "successCount": 0,
  541 + "fail": map[string]interface{}{
  542 + "tableHeader": tableHeader,
  543 + "tableData": aggregateErrorList,
  544 + },
  545 + }, nil
  546 + }
  547 +
  548 + // 批量创建分红订单命令集
  549 + var createDividendsOrderCommands []*command.CreateDividendsOrderCommand
  550 + for _, dividendsOrderCommand := range dividendsOrderCommands {
  551 + createDividendsOrderCommands = append(createDividendsOrderCommands, dividendsOrderCommand)
  552 + }
  553 +
  554 + // 新增失败记录
  555 + failureDataList := make([]interface{}, 0)
  556 +
  557 + // 新增成功记录计数
  558 + var successDataCount int64
  559 +
  560 + // 错误数据返回
  561 + var errorDataList []*domain.ImportInfo
  562 +
  563 + // 循环校验命令
  564 + for _, cmd := range createDividendsOrderCommands {
  565 + if err = cmd.ValidateCommand(); err != nil {
  566 + // 返回信息
  567 + row := &domain.ImportInfo{
  568 + Error: application.ThrowError(application.BUSINESS_ERROR, err.Error()), // 错误信息
  569 + LineNumbers: cmd.LineNumbers, // 错误影响的行
  570 + GoodLine: map[int]interface{}{},
  571 + }
  572 + errorDataList = append(errorDataList, row)
  573 + continue
  574 + }
  575 + }
  576 +
  577 + // 循环校验命令失败返回
  578 + if len(errorDataList) > 0 {
  579 + successDataCount = 0
  580 + // 错误记录处理
  581 + for _, errorData := range errorDataList {
  582 + if len(errorData.GoodLine) == 0 { // 订单错误
  583 + for _, line := range errorData.LineNumbers {
  584 + var tmpRow []string
  585 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  586 + s := strconv.Itoa(line + 1)
  587 + tmpRow = append(tmpRow, s) // 行号
  588 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  589 + failureDataList = append(failureDataList, tmpRow)
  590 + }
  591 + } else if len(errorData.GoodLine) > 0 { // 订单产品错误
  592 + for line := range errorData.GoodLine {
  593 + var tmpRow []string
  594 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  595 + s := strconv.Itoa(line + 1)
  596 + tmpRow = append(tmpRow, s) // 行号
  597 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  598 + failureDataList = append(failureDataList, tmpRow)
  599 + }
  600 + }
  601 + }
  602 + return map[string]interface{}{
  603 + "successCount": successDataCount,
  604 + "fail": map[string]interface{}{
  605 + "tableHeader": tableHeader,
  606 + "tableData": failureDataList,
  607 + },
  608 + }, nil
  609 + }
  610 +
  611 + // 批量导入创建分红订单
  612 + for _, dividendsOrder := range createDividendsOrderCommands {
277 613
278 - for _, dividendsOrder := range importDividendsOrderCommand.DividendsOrderData {  
279 // 生成分红订单号 614 // 生成分红订单号
280 dividendsOrderNumber, err := dividendsOrderDao.GenerateDividendsOrderNumber() 615 dividendsOrderNumber, err := dividendsOrderDao.GenerateDividendsOrderNumber()
281 if err != nil { 616 if err != nil {
@@ -319,13 +654,20 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD @@ -319,13 +654,20 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD
319 dividendsOrderAmount = dividendsOrderAmount + orderGood.OrderGoodAmount 654 dividendsOrderAmount = dividendsOrderAmount + orderGood.OrderGoodAmount
320 } 655 }
321 656
  657 + // 订单时间转换
  658 + orderTimeInt, err := strconv.ParseInt(dividendsOrder.OrderTime, 10, 64)
  659 + if err != nil {
  660 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "订单时间错误")
  661 + }
  662 + orderTime := utils.TransformTimestampToTime(orderTimeInt)
  663 +
322 // 新增分红订单 664 // 新增分红订单
323 newDividendsOrder := &domain.DividendsOrder{ 665 newDividendsOrder := &domain.DividendsOrder{
324 DividendsOrderId: 0, 666 DividendsOrderId: 0,
325 DividendsOrderNumber: dividendsOrderNumber, 667 DividendsOrderNumber: dividendsOrderNumber,
326 DividendsOriginalOrderNum: dividendsOrder.DividendsOriginalOrderNum, 668 DividendsOriginalOrderNum: dividendsOrder.DividendsOriginalOrderNum,
327 DividendsOrderAmount: dividendsOrderAmount, 669 DividendsOrderAmount: dividendsOrderAmount,
328 - OrderTime: dividendsOrder.OrderTime, 670 + OrderTime: orderTime,
329 DividendTime: time.Time{}, 671 DividendTime: time.Time{},
330 DividendStatus: domain.TO_BE_DIVIDEND, 672 DividendStatus: domain.TO_BE_DIVIDEND,
331 Region: &domain.RegionInfo{ 673 Region: &domain.RegionInfo{
@@ -343,17 +685,58 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD @@ -343,17 +685,58 @@ func (dividendsOrderService *DividendsOrderService) ImportDividendsOrder(importD
343 Operator: operator, 685 Operator: operator,
344 } 686 }
345 687
346 - if dividendsOrderSaved, err2 := dividendsOrderRepository.Save(newDividendsOrder); err2 != nil {  
347 - dividendsOrderImportFailed = append(dividendsOrderImportFailed, newDividendsOrder)  
348 - } else {  
349 - dividendsOrderImportSuccessfully = append(dividendsOrderImportSuccessfully, dividendsOrderSaved) 688 + if _, err2 := dividendsOrderRepository.Save(newDividendsOrder); err2 != nil {
  689 + row := &domain.ImportInfo{
  690 + Error: application.ThrowError(application.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err)),
  691 + LineNumbers: dividendsOrder.LineNumbers, // 错误影响的行
  692 + GoodLine: map[int]interface{}{},
  693 + }
  694 + errorDataList = append(errorDataList, row)
  695 + continue
350 } 696 }
351 } 697 }
352 - if len(dividendsOrderImportFailed) == 0 { 698 + if len(errorDataList) <= 0 {
353 if err3 := transactionContext.CommitTransaction(); err3 != nil { 699 if err3 := transactionContext.CommitTransaction(); err3 != nil {
354 return nil, application.ThrowError(application.TRANSACTION_ERROR, err3.Error()) 700 return nil, application.ThrowError(application.TRANSACTION_ERROR, err3.Error())
355 } 701 }
356 - return dividendsOrderImportSuccessfully, nil 702 + successDataCount = int64(rowCnt - len(failureDataList))
  703 + if successDataCount == int64(rowCnt) {
  704 + return map[string]interface{}{
  705 + "successCount": successDataCount,
  706 + "fail": nil,
  707 + }, nil
  708 + }
  709 + } else {
  710 + successDataCount = 0
  711 + // 错误记录处理
  712 + for _, errorData := range errorDataList {
  713 + if len(errorData.GoodLine) == 0 { // 订单错误
  714 + for _, line := range errorData.LineNumbers {
  715 + var tmpRow []string
  716 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  717 + s := strconv.Itoa(line + 1)
  718 + tmpRow = append(tmpRow, s) // 行号
  719 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  720 + failureDataList = append(failureDataList, tmpRow)
  721 + }
  722 + } else if len(errorData.GoodLine) > 0 { // 订单产品错误
  723 + for line := range errorData.GoodLine {
  724 + var tmpRow []string
  725 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  726 + s := strconv.Itoa(line + 1)
  727 + tmpRow = append(tmpRow, s) // 行号
  728 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  729 + failureDataList = append(failureDataList, tmpRow)
  730 + }
  731 + }
  732 + }
  733 + return map[string]interface{}{
  734 + "successCount": successDataCount,
  735 + "fail": map[string]interface{}{
  736 + "tableHeader": tableHeader,
  737 + "tableData": failureDataList,
  738 + },
  739 + }, nil
357 } 740 }
358 return nil, nil 741 return nil, nil
359 } 742 }
@@ -5,7 +5,6 @@ import ( @@ -5,7 +5,6 @@ import (
5 "github.com/beego/beego/v2/core/validation" 5 "github.com/beego/beego/v2/core/validation"
6 "reflect" 6 "reflect"
7 "strings" 7 "strings"
8 - "time"  
9 ) 8 )
10 9
11 type OrderGoods struct { 10 type OrderGoods struct {
@@ -20,7 +19,7 @@ type OrderGoods struct { @@ -20,7 +19,7 @@ type OrderGoods struct {
20 // 订单产品数量 19 // 订单产品数量
21 OrderGoodQuantity int64 `cname:"订单产品数量" json:"orderGoodQuantity"` 20 OrderGoodQuantity int64 `cname:"订单产品数量" json:"orderGoodQuantity"`
22 // 关联分红订单号 21 // 关联分红订单号
23 - DividendsOrderNumber int64 `cname:"关联分红订单号" json:"dividendsOrderNumber"` 22 + DividendsOrderNumber string `cname:"关联分红订单号" json:"dividendsOrderNumber"`
24 // 关联的共创合约编号 23 // 关联的共创合约编号
25 CooperationContractNumber string `cname:"关联的共创合约编号" json:"cooperationContractNumber"` 24 CooperationContractNumber string `cname:"关联的共创合约编号" json:"cooperationContractNumber"`
26 // 订单产品费用 25 // 订单产品费用
@@ -39,13 +38,15 @@ type CreateDividendsReturnedOrderCommand struct { @@ -39,13 +38,15 @@ type CreateDividendsReturnedOrderCommand struct {
39 // 备注 38 // 备注
40 Remarks string `cname:"备注" json:"remarks" valid:"Required"` 39 Remarks string `cname:"备注" json:"remarks" valid:"Required"`
41 // 退货日期 40 // 退货日期
42 - DividendsReturnedDate time.Time `cname:"退货日期" json:"dividendsReturnedDate" valid:"Required"` 41 + DividendsReturnedDate string `cname:"退货日期" json:"dividendsReturnedDate" valid:"Required"`
43 // 订单日期 42 // 订单日期
44 OrderTime string `cname:"订单日期" json:"orderTime" valid:"Required"` 43 OrderTime string `cname:"订单日期" json:"orderTime" valid:"Required"`
45 // 退货区域名称 44 // 退货区域名称
46 RegionName string `cname:"退货区域名称" json:"regionName,omitempty"` 45 RegionName string `cname:"退货区域名称" json:"regionName,omitempty"`
  46 + // 订单操作人uid
  47 + OperatorUid string `cname:"订单操作人uid" json:"operatorUid,omitempty"`
47 // 订单产品列表 48 // 订单产品列表
48 - OrderGoods []*OrderGoods `cname:"订单产品列表" json:"orderGoods,omitempty"` 49 + OrderGoods []OrderGoods `cname:"订单产品列表" json:"orderGoods,omitempty"`
49 // 公司ID,通过集成REST上下文获取 50 // 公司ID,通过集成REST上下文获取
50 CompanyId int64 `cname:"公司ID" json:"companyId" valid:"Required"` 51 CompanyId int64 `cname:"公司ID" json:"companyId" valid:"Required"`
51 // 组织机构ID 52 // 组织机构ID
@@ -54,10 +55,11 @@ type CreateDividendsReturnedOrderCommand struct { @@ -54,10 +55,11 @@ type CreateDividendsReturnedOrderCommand struct {
54 UserId int64 `cname:"用户ID" json:"userId" valid:"Required"` 55 UserId int64 `cname:"用户ID" json:"userId" valid:"Required"`
55 // 用户基础数据id 56 // 用户基础数据id
56 UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId" valid:"Required"` 57 UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId" valid:"Required"`
  58 + // 记录行号
  59 + LineNumbers []int `cname:"记录行号" json:"lineNumbers"`
57 } 60 }
58 61
59 func (createDividendsReturnedOrderCommand *CreateDividendsReturnedOrderCommand) Valid(validation *validation.Validation) { 62 func (createDividendsReturnedOrderCommand *CreateDividendsReturnedOrderCommand) Valid(validation *validation.Validation) {
60 - //validation.SetError("CustomValid", "未实现的自定义认证")  
61 } 63 }
62 64
63 func (createDividendsReturnedOrderCommand *CreateDividendsReturnedOrderCommand) ValidateCommand() error { 65 func (createDividendsReturnedOrderCommand *CreateDividendsReturnedOrderCommand) ValidateCommand() error {
@@ -5,7 +5,6 @@ import ( @@ -5,7 +5,6 @@ import (
5 "github.com/beego/beego/v2/core/validation" 5 "github.com/beego/beego/v2/core/validation"
6 "reflect" 6 "reflect"
7 "strings" 7 "strings"
8 - "time"  
9 ) 8 )
10 9
11 type ( 10 type (
@@ -17,58 +16,35 @@ type ( @@ -17,58 +16,35 @@ type (
17 //订单产品名称 16 //订单产品名称
18 OrderGoodName string `json:"orderGoodName"` 17 OrderGoodName string `json:"orderGoodName"`
19 //退货日期 18 //退货日期
20 - DividendsReturnedDate time.Time `json:"dividendsReturnedDate"` 19 + DividendsReturnedDate string `json:"dividendsReturnedDate"`
21 //退货区域名称 20 //退货区域名称
22 RegionName string `json:"regionName"` 21 RegionName string `json:"regionName"`
23 //订单产品单价 22 //订单产品单价
24 - OrderGoodPrice float64 `json:"orderGoodPrice"` 23 + OrderGoodPrice string `json:"orderGoodPrice"`
25 //订单产品数量 24 //订单产品数量
26 - OrderGoodQuantity int64 `json:"orderGoodQuantity"` 25 + OrderGoodQuantity string `json:"orderGoodQuantity"`
27 //合约编号 26 //合约编号
28 CooperationContractNumber string `json:"cooperationContractNumber"` 27 CooperationContractNumber string `json:"cooperationContractNumber"`
29 //订单日期 28 //订单日期
30 OrderTime string `json:"orderTime"` 29 OrderTime string `json:"orderTime"`
31 } 30 }
32 - // ReqImportDividendsReturnedOrder 请求参数  
33 - ReqImportDividendsReturnedOrder struct { 31 +
  32 + // ImportDividendsReturnedOrderCommand 请求参数
  33 + ImportDividendsReturnedOrderCommand struct {
34 // 分红退货单数据 34 // 分红退货单数据
35 DividendsReturnedOrderData []ImportDividendsReturnedOrderData `json:"dividendsReturnedOrderData"` //分红退货单数据列表 35 DividendsReturnedOrderData []ImportDividendsReturnedOrderData `json:"dividendsReturnedOrderData"` //分红退货单数据列表
  36 + // 公司ID,通过集成REST上下文获取
  37 + CompanyId int64 `cname:"公司ID" json:"companyId"`
  38 + // 组织机构ID
  39 + OrgId int64 `cname:"组织机构ID" json:"orgId"`
  40 + // 用户ID,通过集成REST上下文获取,可翻译成发起人、承接人、推荐人、业务员
  41 + UserId int64 `cname:"用户ID" json:"userId"`
  42 + // 用户基础数据id
  43 + UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId"`
36 } 44 }
37 ) 45 )
38 46
39 -// DividendsReturnedOrderData 分红退货单数据  
40 -type DividendsReturnedOrderData struct {  
41 - // 退货金额  
42 - DividendsReturnedOrderRefund float64 `cname:"退货金额" json:"dividendsReturnedOrderRefund" valid:"Required"`  
43 - // 退货客户名称  
44 - DividendsReturnedCustomerName string `cname:"退货客户名称" json:"dividendsReturnedCustomerName" valid:"Required"`  
45 - // 来源单号,源单号,订单号  
46 - OriginalOrderNum string `cname:"来源单号" json:"originalOrderNum" valid:"Required"`  
47 - // 退货日期  
48 - DividendsReturnedDate time.Time `cname:"退货日期" json:"dividendsReturnedDate" valid:"Required"`  
49 - // 退货区域名称  
50 - RegionName string `cname:"退货区域名称" json:"regionName"`  
51 - // 订单产品列表  
52 - OrderGoods []*OrderGoods `cname:"订单产品列表" json:"orderGoods"`  
53 - // 备注  
54 - Remarks string `cname:"备注" json:"remarks"`  
55 -}  
56 -  
57 -type ImportDividendsReturnedOrderCommand struct {  
58 - // 分红退货单数据  
59 - DividendsReturnedOrderData []*DividendsReturnedOrderData `cname:"分红退货单数据列表" json:"dividendsReturnedOrderData" valid:"Required"`  
60 - // 公司ID,通过集成REST上下文获取  
61 - CompanyId int64 `cname:"公司ID" json:"companyId"`  
62 - // 组织机构ID  
63 - OrgId int64 `cname:"组织机构ID" json:"orgId"`  
64 - // 用户ID,通过集成REST上下文获取,可翻译成发起人、承接人、推荐人、业务员  
65 - UserId int64 `cname:"用户ID" json:"userId"`  
66 - // 用户基础数据id  
67 - UserBaseId int64 `cname:"用户基础数据ID" json:"userBaseId"`  
68 -}  
69 -  
70 func (importDividendsReturnedOrderCommand *ImportDividendsReturnedOrderCommand) Valid(validation *validation.Validation) { 47 func (importDividendsReturnedOrderCommand *ImportDividendsReturnedOrderCommand) Valid(validation *validation.Validation) {
71 - //validation.SetError("CustomValid", "未实现的自定义认证")  
72 } 48 }
73 49
74 func (importDividendsReturnedOrderCommand *ImportDividendsReturnedOrderCommand) ValidateCommand() error { 50 func (importDividendsReturnedOrderCommand *ImportDividendsReturnedOrderCommand) ValidateCommand() error {
1 package service 1 package service
2 2
3 import ( 3 import (
  4 + "crypto/md5"
  5 + "encoding/hex"
4 "fmt" 6 "fmt"
5 "github.com/linmadan/egglib-go/core/application" 7 "github.com/linmadan/egglib-go/core/application"
6 "github.com/linmadan/egglib-go/utils/tool_funs" 8 "github.com/linmadan/egglib-go/utils/tool_funs"
@@ -11,7 +13,10 @@ import ( @@ -11,7 +13,10 @@ import (
11 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain/service" 13 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/domain/service"
12 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/dao" 14 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/dao"
13 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/utils" 15 "gitlab.fjmaimaimai.com/allied-creation/allied-creation-cooperation/pkg/infrastructure/utils"
  16 + "reflect"
  17 + "regexp"
14 "strconv" 18 "strconv"
  19 + "strings"
15 "time" 20 "time"
16 ) 21 )
17 22
@@ -106,6 +111,13 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) CreateDivide @@ -106,6 +111,13 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) CreateDivide
106 } 111 }
107 orderTime := utils.TransformTimestampToTime(orderTimeInt) 112 orderTime := utils.TransformTimestampToTime(orderTimeInt)
108 113
  114 + // 退货时间转换
  115 + returnedTimeInt, err := strconv.ParseInt(createDividendsReturnedOrderCommand.DividendsReturnedDate, 10, 64)
  116 + if err != nil {
  117 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "退货时间错误")
  118 + }
  119 + returnedTime := utils.TransformTimestampToTime(returnedTimeInt)
  120 +
109 // 校验分红退货单编号是否唯一 121 // 校验分红退货单编号是否唯一
110 numberAvailable, err := dividendsReturnedOrderDao.CheckDividendsReturnedOrderNumberAvailable(map[string]interface{}{ 122 numberAvailable, err := dividendsReturnedOrderDao.CheckDividendsReturnedOrderNumberAvailable(map[string]interface{}{
111 "companyId": createDividendsReturnedOrderCommand.CompanyId, 123 "companyId": createDividendsReturnedOrderCommand.CompanyId,
@@ -147,7 +159,7 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) CreateDivide @@ -147,7 +159,7 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) CreateDivide
147 OriginalOrderNum: createDividendsReturnedOrderCommand.OriginalOrderNum, 159 OriginalOrderNum: createDividendsReturnedOrderCommand.OriginalOrderNum,
148 DividendsOrderNumber: createDividendsReturnedOrderCommand.DividendsOrderNumber, 160 DividendsOrderNumber: createDividendsReturnedOrderCommand.DividendsOrderNumber,
149 DividendsReturnedCustomerName: createDividendsReturnedOrderCommand.DividendsReturnedCustomerName, 161 DividendsReturnedCustomerName: createDividendsReturnedOrderCommand.DividendsReturnedCustomerName,
150 - DividendsReturnedDate: createDividendsReturnedOrderCommand.DividendsReturnedDate, 162 + DividendsReturnedDate: returnedTime,
151 Region: &domain.RegionInfo{ 163 Region: &domain.RegionInfo{
152 RegionNumber: "", 164 RegionNumber: "",
153 RegionName: createDividendsReturnedOrderCommand.RegionName, 165 RegionName: createDividendsReturnedOrderCommand.RegionName,
@@ -304,18 +316,342 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) ImportDivide @@ -304,18 +316,342 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) ImportDivide
304 dividendsReturnedOrderRepository = value 316 dividendsReturnedOrderRepository = value
305 } 317 }
306 318
307 - var dividendsReturnedOrderImportFailed []*domain.DividendsReturnedOrder  
308 - var dividendsReturnedOrderImportSuccessfully []*domain.DividendsReturnedOrder 319 + // 返回信息表头定义
  320 + var tableHeader = []string{"错误详情", "行号", "来源单号", "客户名称", "产品名称", "退货日期", "订单日期", "订单区域", "退货数量", "退货价格", "项目合约编号"}
  321 +
  322 + // 空文件校验
  323 + if len(importDividendsReturnedOrderCommand.DividendsReturnedOrderData) == 0 {
  324 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "导入的Excel文件为空文件,请上传正确的文件")
  325 + }
  326 +
  327 + // 必填项校验
  328 + nullCellError := make([]interface{}, 0)
  329 +
  330 + // 数据行计数
  331 + rowCnt := 0
  332 +
  333 + // 空行标志位
  334 + nullFlag := false
  335 +
  336 + for i, dividendsReturnedOrder := range importDividendsReturnedOrderCommand.DividendsReturnedOrderData {
  337 + rowCnt++
  338 + nullCell := make([]interface{}, 0)
  339 + var myRow []string
  340 + t := reflect.TypeOf(dividendsReturnedOrder)
  341 + v := reflect.ValueOf(dividendsReturnedOrder)
  342 + for k := 0; k < t.NumField(); k++ {
  343 + //fmt.Println("name:", fmt.Sprintf("%+v", t.Field(k).Name), ", value:", fmt.Sprintf("%v", v.Field(k).Interface()), ", yaml:", t.Field(k).Tag.Get("yaml"))
  344 + if k != 5 && k != 8 {
  345 + if v.Field(k).Interface() == "" {
  346 + col := strconv.Itoa(k + 1)
  347 + nullCell = append(nullCell, col)
  348 + nullFlag = true
  349 + }
  350 + }
  351 + }
  352 + if nullFlag {
  353 + s := strconv.Itoa(i + 1)
  354 + b := strings.Replace(strings.Trim(fmt.Sprint(nullCell), "[]"), " ", ",", -1)
  355 + myRow = append(myRow, "第"+s+"行的第"+b+"列必填项为空") // 错误信息
  356 + myRow = append(myRow, s) // 行号
  357 + myRow = append(myRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  358 + nullCellError = append(nullCellError, myRow)
  359 + nullFlag = false
  360 + }
  361 + }
  362 +
  363 + // 必填项错误返回
  364 + if len(nullCellError) > 0 {
  365 + return map[string]interface{}{
  366 + "successCount": 0,
  367 + "fail": map[string]interface{}{
  368 + "tableHeader": tableHeader,
  369 + "tableData": nullCellError,
  370 + },
  371 + }, nil
  372 + }
  373 +
  374 + // 单元格类型校验
  375 + typeError := make([]interface{}, 0)
  376 + for i, dividendsReturnedOrder := range importDividendsReturnedOrderCommand.DividendsReturnedOrderData { // 行
  377 + var myRow []string
  378 + t := reflect.TypeOf(dividendsReturnedOrder)
  379 + v := reflect.ValueOf(dividendsReturnedOrder)
  380 + for k := 0; k < t.NumField(); k++ { // 列
  381 + r := strconv.Itoa(i + 1)
  382 + col := strconv.Itoa(k + 1)
  383 +
  384 + switch k {
  385 + case 3: // 退货日期校验
  386 + {
  387 + regexpStr := `(\d{4})/(\d{2})/(\d{2})`
  388 + ok := regexp.MustCompile(regexpStr).MatchString(fmt.Sprintf("%v", v.Field(k).Interface()))
  389 + if !ok {
  390 + var tmpRow []string
  391 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列退货日期格式错误,请输入正确的退货日期") // 错误信息
  392 + tmpRow = append(tmpRow, r) // 行号
  393 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  394 + myRow = tmpRow
  395 + }
  396 + }
  397 + case 4: // 订单日期校验
  398 + {
  399 + regexpStr := `(\d{4})/(\d{2})/(\d{2})`
  400 + ok := regexp.MustCompile(regexpStr).MatchString(fmt.Sprintf("%v", v.Field(k).Interface()))
  401 + if !ok {
  402 + var tmpRow []string
  403 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列订单日期格式错误,请输入正确的订单日期") // 错误信息
  404 + tmpRow = append(tmpRow, r) // 行号
  405 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  406 + myRow = tmpRow
  407 + }
  408 + }
  409 + case 6: // 退货数量校验
  410 + {
  411 + //参数类型转换
  412 + orderGoodQuantity, err := strconv.ParseInt(fmt.Sprintf("%v", v.Field(k).Interface()), 10, 64)
  413 + if err != nil {
  414 + var tmpRow []string
  415 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列退货数量格式错误,退货数量必须整数") // 错误信息
  416 + tmpRow = append(tmpRow, r) // 行号
  417 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  418 + myRow = tmpRow
  419 + }
  420 + // 正负判断
  421 + if orderGoodQuantity < 0 {
  422 + var tmpRow []string
  423 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列退货数量必须大于0,请重新填写") // 错误信息
  424 + tmpRow = append(tmpRow, r) // 行号
  425 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  426 + myRow = tmpRow
  427 + }
  428 + }
  429 + case 7: // 退货价格校验
  430 + {
  431 + // 参数类型转换
  432 + univalent, typeErr := strconv.ParseFloat(fmt.Sprintf("%v", v.Field(k).Interface()), 64)
  433 + if typeErr != nil {
  434 + var tmpRow []string
  435 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列退货价格格式错误,退货价格必须为数字类型") // 错误信息
  436 + tmpRow = append(tmpRow, r) // 行号
  437 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  438 + myRow = tmpRow
  439 + }
  440 +
  441 + // 长度校验
  442 + if univalent >= 1e16 {
  443 + var tmpRow []string
  444 + tmpRow = append(tmpRow, "第"+r+"行第"+col+"列退货价格超过最大限制,退货价格小数点前面不能超过十六位数字,并保留两位小数") // 错误信息
  445 + tmpRow = append(tmpRow, r) // 行号
  446 + tmpRow = append(tmpRow, fmt.Sprintf("%v", v.Interface())) // 错误行数据
  447 + myRow = tmpRow
  448 + }
  449 + }
  450 + }
  451 + }
  452 + if myRow != nil {
  453 + typeError = append(typeError, myRow)
  454 + }
  455 + }
  456 +
  457 + // 类型错误行返回
  458 + if len(typeError) > 0 {
  459 + return map[string]interface{}{
  460 + "successCount": 0,
  461 + "fail": map[string]interface{}{
  462 + "tableHeader": tableHeader,
  463 + "tableData": typeError,
  464 + },
  465 + }, nil
  466 + }
  467 +
  468 + // 聚合订单并进行类型校验
  469 + aggregateErrorList := make([]interface{}, 0)
  470 +
  471 + var dividendsReturnedOrderCommands = make(map[string]*command.CreateDividendsReturnedOrderCommand)
  472 + for i, dividendsReturnedOrder := range importDividendsReturnedOrderCommand.DividendsReturnedOrderData {
  473 + hashValue := md5.Sum([]byte(dividendsReturnedOrder.OriginalOrderNum))
  474 + hashString := hex.EncodeToString(hashValue[:])
  475 + if _, ok := dividendsReturnedOrderCommands[hashString]; !ok {
  476 + // 来源单号
  477 + dividendsReturnedOrderCommands[hashString].OriginalOrderNum = dividendsReturnedOrder.OriginalOrderNum
  478 +
  479 + // 客户名称
  480 + dividendsReturnedOrderCommands[hashString].DividendsReturnedCustomerName = dividendsReturnedOrder.DividendsReturnedCustomerName
  481 +
  482 + // 订单日期时间格式转换
  483 + timeValue, err := time.ParseInLocation("2006/01/02", dividendsReturnedOrder.OrderTime, time.Local)
  484 + if err != nil {
  485 + var tmpRow []string
  486 + tmpRow = append(tmpRow, "无效的订单日期") // 错误信息
  487 + s := strconv.Itoa(i + 1)
  488 + tmpRow = append(tmpRow, s) // 行号
  489 + //tmpRow = append(tmpRow, dividendsReturnedOrder.OriginalOrderNum) // TODO 错误行数据
  490 + aggregateErrorList = append(aggregateErrorList, tmpRow)
  491 + break
  492 + }
  493 +
  494 + // 产品相关:产品名称,退货数量、退货价格
  495 + quantity, err := strconv.ParseInt(dividendsReturnedOrder.OrderGoodQuantity, 10, 64)
  496 + if err != nil {
  497 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  498 + }
  499 + price, err := strconv.ParseFloat(dividendsReturnedOrder.OrderGoodPrice, 64)
  500 + if err != nil {
  501 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  502 + }
  503 +
  504 + // 初始化新建分红订单命令集
  505 + dividendsReturnedOrderCommands[hashString] = &command.CreateDividendsReturnedOrderCommand{
  506 + DividendsReturnedCustomerName: dividendsReturnedOrder.DividendsReturnedCustomerName,
  507 + OriginalOrderNum: dividendsReturnedOrder.OriginalOrderNum,
  508 + OrderTime: string(rune(timeValue.Nanosecond() / 1000)),
  509 + Remarks: "",
  510 + RegionName: dividendsReturnedOrder.RegionName,
  511 + OperatorUid: strconv.FormatInt(importDividendsReturnedOrderCommand.UserId, 10),
  512 + OrderGoods: []command.OrderGoods{
  513 + {
  514 + OrderGoodId: "0",
  515 + OrderGoodAmount: 0,
  516 + OrderGoodName: dividendsReturnedOrder.OrderGoodName,
  517 + OrderGoodPrice: price,
  518 + OrderGoodQuantity: quantity,
  519 + DividendsOrderNumber: "",
  520 + CooperationContractNumber: dividendsReturnedOrder.CooperationContractNumber,
  521 + OrderGoodExpense: 0,
  522 + },
  523 + },
  524 + CompanyId: importDividendsReturnedOrderCommand.CompanyId,
  525 + OrgId: importDividendsReturnedOrderCommand.OrgId,
  526 + UserId: importDividendsReturnedOrderCommand.UserId,
  527 + UserBaseId: importDividendsReturnedOrderCommand.UserBaseId,
  528 + LineNumbers: []int{i}, // 记录行号
  529 + }
  530 + } else { // 聚合同一笔订单产品
  531 + // 产品相关:产品名称,退货数量、退货价格
  532 + quantity, err := strconv.ParseInt(dividendsReturnedOrder.OrderGoodQuantity, 10, 64)
  533 + if err != nil {
  534 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  535 + }
  536 + price, err := strconv.ParseFloat(dividendsReturnedOrder.OrderGoodPrice, 64)
  537 + if err != nil {
  538 + return nil, application.ThrowError(application.ARG_ERROR, err.Error())
  539 + }
309 540
310 - for _, dividendsReturnedOrder := range importDividendsReturnedOrderCommand.DividendsReturnedOrderData {  
311 - // 生成分红订单号 541 + dividendsReturnedOrderCommands[hashString].OrderGoods = append(dividendsReturnedOrderCommands[hashString].OrderGoods, command.OrderGoods{
  542 + OrderGoodId: "0",
  543 + OrderGoodAmount: 0,
  544 + OrderGoodName: dividendsReturnedOrder.OrderGoodName,
  545 + OrderGoodPrice: price,
  546 + OrderGoodQuantity: quantity,
  547 + DividendsOrderNumber: "",
  548 + CooperationContractNumber: dividendsReturnedOrder.CooperationContractNumber,
  549 + OrderGoodExpense: 0,
  550 + })
  551 +
  552 + // 记录聚合行号
  553 + dividendsReturnedOrderCommands[hashString].LineNumbers = append(dividendsReturnedOrderCommands[hashString].LineNumbers, i)
  554 + }
  555 + }
  556 +
  557 + // 聚合订单错误返回
  558 + if len(aggregateErrorList) > 0 {
  559 + return map[string]interface{}{
  560 + "successCount": 0,
  561 + "fail": map[string]interface{}{
  562 + "tableHeader": tableHeader,
  563 + "tableData": aggregateErrorList,
  564 + },
  565 + }, nil
  566 + }
  567 +
  568 + // 批量创建分红订单命令集
  569 + var createDividendsReturnedOrderCommands []*command.CreateDividendsReturnedOrderCommand
  570 + for _, dividendsReturnedOrderCommand := range dividendsReturnedOrderCommands {
  571 + createDividendsReturnedOrderCommands = append(createDividendsReturnedOrderCommands, dividendsReturnedOrderCommand)
  572 + }
  573 +
  574 + // 新增失败记录
  575 + failureDataList := make([]interface{}, 0)
  576 +
  577 + // 新增成功记录计数
  578 + var successDataCount int64
  579 +
  580 + // 错误数据返回
  581 + var errorDataList []*domain.ImportInfo
  582 +
  583 + // 循环校验命令
  584 + for _, cmd := range createDividendsReturnedOrderCommands {
  585 + if err = cmd.ValidateCommand(); err != nil {
  586 + // 返回信息
  587 + row := &domain.ImportInfo{
  588 + Error: application.ThrowError(application.BUSINESS_ERROR, err.Error()), // 错误信息
  589 + LineNumbers: cmd.LineNumbers, // 错误影响的行
  590 + GoodLine: map[int]interface{}{},
  591 + }
  592 + errorDataList = append(errorDataList, row)
  593 + continue
  594 + }
  595 + }
  596 +
  597 + // 循环校验命令失败返回
  598 + if len(errorDataList) > 0 {
  599 + successDataCount = 0
  600 + // 错误记录处理
  601 + for _, errorData := range errorDataList {
  602 + if len(errorData.GoodLine) == 0 { // 订单错误
  603 + for _, line := range errorData.LineNumbers {
  604 + var tmpRow []string
  605 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  606 + s := strconv.Itoa(line + 1)
  607 + tmpRow = append(tmpRow, s) // 行号
  608 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  609 + failureDataList = append(failureDataList, tmpRow)
  610 + }
  611 + } else if len(errorData.GoodLine) > 0 { // 订单产品错误
  612 + for line := range errorData.GoodLine {
  613 + var tmpRow []string
  614 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  615 + s := strconv.Itoa(line + 1)
  616 + tmpRow = append(tmpRow, s) // 行号
  617 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  618 + failureDataList = append(failureDataList, tmpRow)
  619 + }
  620 + }
  621 + }
  622 + return map[string]interface{}{
  623 + "successCount": successDataCount,
  624 + "fail": map[string]interface{}{
  625 + "tableHeader": tableHeader,
  626 + "tableData": failureDataList,
  627 + },
  628 + }, nil
  629 + }
  630 +
  631 + // 批量导入创建退货单
  632 + for _, dividendsReturnedOrder := range createDividendsReturnedOrderCommands {
  633 + // 生成退货订单号
312 dividendsReturnedOrderNumber, err := dividendsReturnedOrderDao.GenerateDividendsReturnedOrderNumber() 634 dividendsReturnedOrderNumber, err := dividendsReturnedOrderDao.GenerateDividendsReturnedOrderNumber()
313 if err != nil { 635 if err != nil {
314 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 636 return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error())
315 } 637 }
316 638
317 - // 获取分红退货单产品 639 + // 校验退货订单编号是否唯一
  640 + numberAvailable, err3 := dividendsReturnedOrderDao.CheckDividendsReturnedOrderNumberAvailable(map[string]interface{}{
  641 + "companyId": importDividendsReturnedOrderCommand.CompanyId,
  642 + "orgId": importDividendsReturnedOrderCommand.OrgId,
  643 + "dividendsReturnedOrderNumber": dividendsReturnedOrderNumber,
  644 + })
  645 + if err3 != nil {
  646 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err3.Error())
  647 + }
  648 + if !numberAvailable {
  649 + return nil, application.ThrowError(application.TRANSACTION_ERROR, "新增分红订单异常")
  650 + }
  651 +
  652 + // 新增订单产品
318 var orderGoods []*domain.OrderGood 653 var orderGoods []*domain.OrderGood
  654 + var dividendsReturnedOrderAmount float64
319 for _, orderGood := range dividendsReturnedOrder.OrderGoods { 655 for _, orderGood := range dividendsReturnedOrder.OrderGoods {
320 orderGoods = append(orderGoods, &domain.OrderGood{ 656 orderGoods = append(orderGoods, &domain.OrderGood{
321 OrderGoodId: 0, 657 OrderGoodId: 0,
@@ -326,49 +662,110 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) ImportDivide @@ -326,49 +662,110 @@ func (dividendsReturnedOrderService *DividendsReturnedOrderService) ImportDivide
326 DividendsOrderNumber: "", 662 DividendsOrderNumber: "",
327 DividendsReturnedOrderNumber: dividendsReturnedOrderNumber, 663 DividendsReturnedOrderNumber: dividendsReturnedOrderNumber,
328 CooperationContractNumber: orderGood.CooperationContractNumber, 664 CooperationContractNumber: orderGood.CooperationContractNumber,
329 - OrderGoodExpense: 0, 665 + OrderGoodExpense: orderGood.OrderGoodExpense,
330 OrgId: importDividendsReturnedOrderCommand.OrgId, 666 OrgId: importDividendsReturnedOrderCommand.OrgId,
331 CompanyId: importDividendsReturnedOrderCommand.CompanyId, 667 CompanyId: importDividendsReturnedOrderCommand.CompanyId,
332 CreatedAt: time.Now(), 668 CreatedAt: time.Now(),
333 DeletedAt: time.Time{}, 669 DeletedAt: time.Time{},
334 UpdatedAt: time.Time{}, 670 UpdatedAt: time.Time{},
335 }) 671 })
  672 + // 计算分红订单金额
  673 + dividendsReturnedOrderAmount = dividendsReturnedOrderAmount + orderGood.OrderGoodAmount
  674 + }
  675 +
  676 + // 订单时间转换
  677 + orderTimeInt, err := strconv.ParseInt(dividendsReturnedOrder.OrderTime, 10, 64)
  678 + if err != nil {
  679 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "订单时间错误")
  680 + }
  681 + orderTime := utils.TransformTimestampToTime(orderTimeInt)
  682 +
  683 + // 退货时间转换
  684 + returnedTimeInt, err := strconv.ParseInt(dividendsReturnedOrder.DividendsReturnedDate, 10, 64)
  685 + if err != nil {
  686 + return nil, application.ThrowError(application.INTERNAL_SERVER_ERROR, "退货时间错误")
336 } 687 }
  688 + returnedTime := utils.TransformTimestampToTime(returnedTimeInt)
337 689
  690 + // 新增退货单
338 newDividendsReturnedOrder := &domain.DividendsReturnedOrder{ 691 newDividendsReturnedOrder := &domain.DividendsReturnedOrder{
  692 + DividendsReturnedOrderId: 0,
339 DividendsReturnedOrderNumber: dividendsReturnedOrderNumber, 693 DividendsReturnedOrderNumber: dividendsReturnedOrderNumber,
340 - DividendsReturnedOrderRefund: dividendsReturnedOrder.DividendsReturnedOrderRefund, 694 + DividendsReturnedOrderRefund: dividendsReturnedOrderAmount,
341 OriginalOrderNum: dividendsReturnedOrder.OriginalOrderNum, 695 OriginalOrderNum: dividendsReturnedOrder.OriginalOrderNum,
342 DividendsOrderNumber: "", 696 DividendsOrderNumber: "",
343 DividendsReturnedCustomerName: dividendsReturnedOrder.DividendsReturnedCustomerName, 697 DividendsReturnedCustomerName: dividendsReturnedOrder.DividendsReturnedCustomerName,
344 - DividendsReturnedDate: dividendsReturnedOrder.DividendsReturnedDate, 698 + OrderTime: orderTime,
  699 + DividendsReturnedDate: returnedTime,
345 Region: &domain.RegionInfo{ 700 Region: &domain.RegionInfo{
346 RegionNumber: "", 701 RegionNumber: "",
347 RegionName: dividendsReturnedOrder.RegionName, 702 RegionName: dividendsReturnedOrder.RegionName,
348 }, 703 },
349 Goods: orderGoods, 704 Goods: orderGoods,
350 - Remarks: dividendsReturnedOrder.Remarks,  
351 - DividendStatus: domain.TO_BE_DIVIDENDED, 705 + Remarks: "",
  706 + DividendStatus: 1,
352 DividendTime: time.Time{}, 707 DividendTime: time.Time{},
353 Org: organization, 708 Org: organization,
354 Company: company, 709 Company: company,
355 CreatedAt: time.Now(), 710 CreatedAt: time.Now(),
  711 + DeletedAt: time.Time{},
356 UpdatedAt: time.Time{}, 712 UpdatedAt: time.Time{},
357 Operator: operator, 713 Operator: operator,
358 OperateTime: time.Now(), 714 OperateTime: time.Now(),
359 } 715 }
360 716
361 - if dividendsReturnedOrderSaved, err := dividendsReturnedOrderRepository.Save(newDividendsReturnedOrder); err != nil {  
362 - dividendsReturnedOrderImportFailed = append(dividendsReturnedOrderImportFailed, newDividendsReturnedOrder)  
363 - } else {  
364 - dividendsReturnedOrderImportSuccessfully = append(dividendsReturnedOrderImportSuccessfully, dividendsReturnedOrderSaved) 717 + if _, err2 := dividendsReturnedOrderRepository.Save(newDividendsReturnedOrder); err2 != nil {
  718 + row := &domain.ImportInfo{
  719 + Error: application.ThrowError(application.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存退货单数据失败:%s", err)),
  720 + LineNumbers: dividendsReturnedOrder.LineNumbers, // 错误影响的行
  721 + GoodLine: map[int]interface{}{},
  722 + }
  723 + errorDataList = append(errorDataList, row)
  724 + continue
365 } 725 }
366 } 726 }
367 - if len(dividendsReturnedOrderImportFailed) == 0 {  
368 - if err := transactionContext.CommitTransaction(); err != nil {  
369 - return nil, application.ThrowError(application.TRANSACTION_ERROR, err.Error()) 727 + if len(errorDataList) <= 0 {
  728 + if err3 := transactionContext.CommitTransaction(); err3 != nil {
  729 + return nil, application.ThrowError(application.TRANSACTION_ERROR, err3.Error())
  730 + }
  731 + successDataCount = int64(rowCnt - len(failureDataList))
  732 + if successDataCount == int64(rowCnt) {
  733 + return map[string]interface{}{
  734 + "successCount": successDataCount,
  735 + "fail": nil,
  736 + }, nil
370 } 737 }
371 - return dividendsReturnedOrderImportSuccessfully, nil 738 + } else {
  739 + successDataCount = 0
  740 + // 错误记录处理
  741 + for _, errorData := range errorDataList {
  742 + if len(errorData.GoodLine) == 0 { // 订单错误
  743 + for _, line := range errorData.LineNumbers {
  744 + var tmpRow []string
  745 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  746 + s := strconv.Itoa(line + 1)
  747 + tmpRow = append(tmpRow, s) // 行号
  748 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  749 + failureDataList = append(failureDataList, tmpRow)
  750 + }
  751 + } else if len(errorData.GoodLine) > 0 { // 订单产品错误
  752 + for line := range errorData.GoodLine {
  753 + var tmpRow []string
  754 + tmpRow = append(tmpRow, errorData.Error.Error()) // 错误信息
  755 + s := strconv.Itoa(line + 1)
  756 + tmpRow = append(tmpRow, s) // 行号
  757 + //tmpRow = append(tmpRow, importDividendsOrderCommand.DividendsOrderData[line]...) // 错误行数据
  758 + failureDataList = append(failureDataList, tmpRow)
  759 + }
  760 + }
  761 + }
  762 + return map[string]interface{}{
  763 + "successCount": successDataCount,
  764 + "fail": map[string]interface{}{
  765 + "tableHeader": tableHeader,
  766 + "tableData": failureDataList,
  767 + },
  768 + }, nil
372 } 769 }
373 return nil, nil 770 return nil, nil
374 } 771 }
@@ -50,6 +50,13 @@ type DividendsOrder struct { @@ -50,6 +50,13 @@ type DividendsOrder struct {
50 Remarks string `json:"remarks"` 50 Remarks string `json:"remarks"`
51 } 51 }
52 52
  53 +// ImportInfo 导入错误信息
  54 +type ImportInfo struct {
  55 + Error error
  56 + LineNumbers []int
  57 + GoodLine map[int]interface{}
  58 +}
  59 +
53 type DividendsOrderRepository interface { 60 type DividendsOrderRepository interface {
54 Save(dividendsOrder *DividendsOrder) (*DividendsOrder, error) 61 Save(dividendsOrder *DividendsOrder) (*DividendsOrder, error)
55 UpdateMany(dividendsOrders []*DividendsOrder) ([]*DividendsOrder, error) 62 UpdateMany(dividendsOrders []*DividendsOrder) ([]*DividendsOrder, error)