作者 陈志颖

feat:批量创建订单

@@ -19,10 +19,19 @@ type CreateOrderCommand struct { @@ -19,10 +19,19 @@ type CreateOrderCommand struct {
19 //业务员抽成比例 19 //业务员抽成比例
20 SalesmanBonusPercent float64 `json:"salesmanBonusPercent"` 20 SalesmanBonusPercent float64 `json:"salesmanBonusPercent"`
21 //货品 21 //货品
22 - Goods []OrderGoodData `json:"goods"`  
23 - CompanyId int64 `json:"companyId"`  
24 - 22 + Goods []OrderGoodData `json:"goods"`
  23 + //公司id
  24 + CompanyId int64 `json:"companyId"`
  25 + //合伙人类型
25 PartnerCategory int64 `json:"partner_category"` 26 PartnerCategory int64 `json:"partner_category"`
  27 + //行号-错误信息返回
  28 + LineNumbers []int `json:"lineNumber"`
  29 + //合伙人姓名
  30 + PartnerName string `json:"partnerName"`
  31 + //编号-错误信息返回
  32 + Code string `json:"code"`
  33 + //合伙人类型名称-错误信息返回
  34 + PartnerCategoryName string `json:"partnerCategoryName"`
26 } 35 }
27 36
28 func (postData *CreateOrderCommand) Valid() error { 37 func (postData *CreateOrderCommand) Valid() error {
@@ -20,6 +20,8 @@ type OrderGoodData struct { @@ -20,6 +20,8 @@ type OrderGoodData struct {
20 PartnerBonusPercent float64 `json:"partnerBonusPercent"` 20 PartnerBonusPercent float64 `json:"partnerBonusPercent"`
21 //备注信息 21 //备注信息
22 Remark string `json:"remark"` 22 Remark string `json:"remark"`
  23 + //行号-错误信息返回
  24 + LineNumber int `json:"lineNumber"`
23 } 25 }
24 26
25 func (postData OrderGoodData) Valid() error { 27 func (postData OrderGoodData) Valid() error {
@@ -18,8 +18,9 @@ type UpdateOrderCommand struct { @@ -18,8 +18,9 @@ type UpdateOrderCommand struct {
18 //订单类型 18 //订单类型
19 OrderType int `json:"orderType"` 19 OrderType int `json:"orderType"`
20 //货品 20 //货品
21 - Goods []OrderGoodData `json:"goods"`  
22 - CompanyId int64 `json:"companyId"`  
23 - 21 + Goods []OrderGoodData `json:"goods"`
  22 + //公司id
  23 + CompanyId int64 `json:"companyId"`
  24 + // 合伙人类型
24 PartnerCategory int64 `json:"partner_category"` 25 PartnerCategory int64 `json:"partner_category"`
25 } 26 }
  1 +/**
  2 + @author: stevechan
  3 + @date: 2021/1/6
  4 + @note:
  5 +**/
  6 +
  7 +package query
  8 +
  9 +/**
  10 + * @Author SteveChan
  11 + * @Description //TODO 查询合伙人id
  12 + * @Date 23:18 2021/1/6
  13 + **/
  14 +type GetPartnerIdQuery struct {
  15 + Code string `json:"code"`
  16 + PartnerCategory int `json:"partnerCategory"`
  17 + CompanyId int64 `json:"companyId"`
  18 +}
  1 +/**
  2 + @author: stevechan
  3 + @date: 2021/1/6
  4 + @note:
  5 +**/
  6 +
  7 +package query
  8 +
  9 +/**
  10 + * @Author SteveChan
  11 + * @Description //TODO 查询产品id
  12 + * @Date 23:18 2021/1/6
  13 + **/
  14 +type GetProductIdQuery struct {
  15 + ProductName int64 `json:"productName"`
  16 +}
@@ -941,3 +941,261 @@ func (service OrderInfoService) ListOrderForExcel(listOrderQuery query.ListOrder @@ -941,3 +941,261 @@ func (service OrderInfoService) ListOrderForExcel(listOrderQuery query.ListOrder
941 } 941 }
942 return resultMaps, column, nil 942 return resultMaps, column, nil
943 } 943 }
  944 +
  945 +/**
  946 + * @Author SteveChan
  947 + * @Description // 批量导入创建订单
  948 + * @Date 11:00 2021/1/7
  949 + * @Param
  950 + * @return
  951 + **/
  952 +func (service OrderInfoService) CreateNewOrderByImport(createOrderCommands []*command.CreateOrderCommand) ([]interface{}, error) {
  953 + // 事务初始化
  954 + var (
  955 + transactionContext, _ = factory.CreateTransactionContext(nil)
  956 + err error
  957 + failureDataList []interface{} // 错误数据返回
  958 + )
  959 +
  960 + // 循环校验命令
  961 + for _, cmd := range createOrderCommands {
  962 + if err = cmd.Valid(); err != nil {
  963 + // 返回信息 0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
  964 + row := []interface{}{
  965 + lib.ThrowError(lib.BUSINESS_ERROR, err.Error()), // 错误信息
  966 + cmd.LineNumbers, // 错误影响的行
  967 + }
  968 + failureDataList = append(failureDataList, row)
  969 + continue
  970 + }
  971 + }
  972 +
  973 + // 开始事务
  974 + if err = transactionContext.StartTransaction(); err != nil {
  975 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  976 + }
  977 +
  978 + defer func() {
  979 + transactionContext.RollbackTransaction()
  980 + }()
  981 +
  982 + // 仓储、数据访问对象初始化
  983 + var (
  984 + orderBaseRepository domain.OrderBaseRepository
  985 + orderGoodRepository domain.OrderGoodRepository
  986 + PartnerInfoRepository domain.PartnerInfoRepository
  987 + categoryRepository domain.PartnerCategoryRepository
  988 + orderBaseDao *dao.OrderBaseDao
  989 + )
  990 + // 合伙人信息仓储初始化
  991 + if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  992 + "transactionContext": transactionContext,
  993 + }); err != nil {
  994 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  995 + }
  996 +
  997 + // 订单仓储初始化
  998 + if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
  999 + "transactionContext": transactionContext,
  1000 + }); err != nil {
  1001 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1002 + }
  1003 +
  1004 + // 订单产品仓储初始化
  1005 + if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
  1006 + "transactionContext": transactionContext,
  1007 + }); err != nil {
  1008 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1009 + }
  1010 +
  1011 + // 合伙人类型仓储初始化
  1012 + if categoryRepository, err = factory.CreatePartnerCategoryRepository(map[string]interface{}{
  1013 + "transactionContext": transactionContext,
  1014 + }); err != nil {
  1015 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1016 + }
  1017 +
  1018 + // 订单数据访问对象初始化
  1019 + if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
  1020 + "transactionContext": transactionContext,
  1021 + }); err != nil {
  1022 + return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1023 + }
  1024 +
  1025 + // 批量创建订单
  1026 + for _, cmd := range createOrderCommands {
  1027 + // 批量校验合伙人信息
  1028 + var partnerData *domain.PartnerInfo
  1029 + partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{UserId: cmd.PartnerId})
  1030 + if err != nil {
  1031 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人数据失败"))
  1032 + }
  1033 +
  1034 + // 批量校验订单
  1035 + if ok, err := orderBaseDao.CheckOrderExist(cmd.CompanyId, cmd.OrderCode, cmd.DeliveryCode,
  1036 + cmd.PartnerCategory, cmd.PartnerId, 0); err != nil {
  1037 + return nil, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1038 + } else if ok {
  1039 + return nil, lib.ThrowError(lib.BUSINESS_ERROR, "订单已存在")
  1040 + }
  1041 +
  1042 + // 批量校验产品
  1043 + var goodMap = map[string]int{}
  1044 + for i := range cmd.Goods {
  1045 + goodName := cmd.Goods[i].GoodName
  1046 + if _, ok := goodMap[goodName]; ok {
  1047 + return nil, lib.ThrowError(lib.BUSINESS_ERROR, "订单中货品重复已存在")
  1048 + }
  1049 + goodMap[goodName] = 1
  1050 + }
  1051 +
  1052 + newOrder := &domain.OrderBase{
  1053 + OrderType: cmd.OrderType, OrderCode: cmd.OrderCode,
  1054 + DeliveryCode: cmd.DeliveryCode,
  1055 + Buyer: domain.Buyer{
  1056 + BuyerName: cmd.BuyerName,
  1057 + },
  1058 + RegionInfo: domain.RegionInfo{
  1059 + RegionName: cmd.OrderRegion,
  1060 + },
  1061 + PartnerId: cmd.PartnerId,
  1062 + PartnerInfo: partnerData.Partner,
  1063 + SalesmanBonusPercent: cmd.SalesmanBonusPercent,
  1064 + CompanyId: cmd.CompanyId,
  1065 + }
  1066 +
  1067 + // 批量校验合伙人分类数据
  1068 + var cmdPartnerCategoryOk bool
  1069 + for _, v := range partnerData.PartnerCategoryInfos {
  1070 + if v.Id == cmd.PartnerCategory {
  1071 + _, categories, err := categoryRepository.Find(domain.PartnerCategoryFindQuery{
  1072 + Ids: []int64{v.Id},
  1073 + })
  1074 + if err != nil {
  1075 + e := fmt.Sprintf("获取合伙人分类数据失败:%s", err)
  1076 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  1077 + }
  1078 + if len(categories) > 0 {
  1079 + newOrder.PartnerCategory = categories[0]
  1080 + cmdPartnerCategoryOk = true
  1081 + }
  1082 + break
  1083 + }
  1084 + }
  1085 + if !cmdPartnerCategoryOk {
  1086 + return nil, lib.ThrowError(lib.BUSINESS_ERROR, "合伙人类型选择错误")
  1087 + }
  1088 +
  1089 + // 订单产品分红核算
  1090 + var orderGoods []domain.OrderGood
  1091 + for _, good := range cmd.Goods {
  1092 + m := domain.NewOrderGood()
  1093 + m.OrderId = 0
  1094 + m.GoodName = good.GoodName
  1095 + m.PlanGoodNumber = good.PlanGoodNumber
  1096 + m.Price = good.Price
  1097 + m.PartnerBonusPercent = good.PartnerBonusPercent
  1098 + m.Remark = good.Remark
  1099 + m.CompanyId = cmd.CompanyId
  1100 + err = m.Compute()
  1101 + if err != nil {
  1102 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的数值失败:%s", err))
  1103 + }
  1104 + err = m.CurrentBonusStatus.WartPayPartnerBonus(&m)
  1105 + if err != nil {
  1106 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中商品的分红数值失败:%s", err))
  1107 + }
  1108 + orderGoods = append(orderGoods, m)
  1109 + }
  1110 +
  1111 + newOrder.Goods = orderGoods
  1112 +
  1113 + err = newOrder.Compute()
  1114 + if err != nil {
  1115 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err))
  1116 + }
  1117 +
  1118 + // 保存订单数据
  1119 + err = orderBaseRepository.Save(newOrder)
  1120 + if err != nil {
  1121 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单数据失败:%s", err))
  1122 + }
  1123 +
  1124 + for i := range newOrder.Goods {
  1125 + newOrder.Goods[i].OrderId = newOrder.Id
  1126 + }
  1127 +
  1128 + // 保存订单产品
  1129 + err = orderGoodRepository.Save(orderGoods)
  1130 + if err != nil {
  1131 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("保存订单中的商品数据失败:%s", err))
  1132 + }
  1133 +
  1134 + newOrder.Goods = orderGoods
  1135 + }
  1136 +
  1137 + if len(failureDataList) == 0 {
  1138 + // 完成事务
  1139 + err = transactionContext.CommitTransaction()
  1140 + if err != nil {
  1141 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1142 + }
  1143 + return failureDataList, nil
  1144 + }
  1145 +
  1146 + return failureDataList, nil
  1147 +}
  1148 +
  1149 +/**
  1150 + * @Author SteveChan
  1151 + * @Description // 根据合伙人编号和合伙人类型获取合伙人id
  1152 + * @Date 23:15 2021/1/6
  1153 + * @Param
  1154 + * @return
  1155 + **/
  1156 +func (service OrderInfoService) GetPartnerIdByCodeAndCategory(getPartnerIdQuery query.GetPartnerIdQuery) (*domain.PartnerInfo, error) {
  1157 + // 事务初始化
  1158 + var (
  1159 + transactionContext, _ = factory.CreateTransactionContext(nil)
  1160 + err error
  1161 + partnerData *domain.PartnerInfo
  1162 + )
  1163 +
  1164 + // 开始事务
  1165 + if err = transactionContext.StartTransaction(); err != nil {
  1166 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1167 + }
  1168 +
  1169 + // 收尾
  1170 + defer func() {
  1171 + transactionContext.RollbackTransaction()
  1172 + }()
  1173 +
  1174 + // 仓储、数据访问对象初始化
  1175 + var (
  1176 + PartnerInfoRepository domain.PartnerInfoRepository
  1177 + )
  1178 + // 合伙人信息仓储初始化
  1179 + if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  1180 + "transactionContext": transactionContext,
  1181 + }); err != nil {
  1182 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1183 + }
  1184 +
  1185 + //var partnerData *domain.PartnerInfo
  1186 + partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
  1187 + CompanyId: getPartnerIdQuery.CompanyId,
  1188 + Code: getPartnerIdQuery.Code,
  1189 + PartnerCategory: getPartnerIdQuery.PartnerCategory,
  1190 + })
  1191 + if err != nil {
  1192 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("检索合伙人数据失败"))
  1193 + }
  1194 +
  1195 + // 完成事务
  1196 + err = transactionContext.CommitTransaction()
  1197 + if err != nil {
  1198 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1199 + }
  1200 + return partnerData, nil
  1201 +}
@@ -15,7 +15,7 @@ var KafkaCfg KafkaConfig @@ -15,7 +15,7 @@ var KafkaCfg KafkaConfig
15 func init() { 15 func init() {
16 KafkaCfg = KafkaConfig{ 16 KafkaCfg = KafkaConfig{
17 Servers: []string{"127.0.0.1:9092"}, 17 Servers: []string{"127.0.0.1:9092"},
18 - ConsumerId: "partnermg_local", 18 + ConsumerId: "partnermg_dev",
19 } 19 }
20 if os.Getenv("KAFKA_HOST") != "" { 20 if os.Getenv("KAFKA_HOST") != "" {
21 kafkaHost := os.Getenv("KAFKA_HOST") 21 kafkaHost := os.Getenv("KAFKA_HOST")
@@ -84,7 +84,8 @@ type OrderGood struct { @@ -84,7 +84,8 @@ type OrderGood struct {
84 CompanyId int64 `json:"companyId"` 84 CompanyId int64 `json:"companyId"`
85 //原因备注 85 //原因备注
86 RemarkReason OrderGoodRemarkReason `json:"remarkReason"` 86 RemarkReason OrderGoodRemarkReason `json:"remarkReason"`
87 - DataFrom OrderDataFrom `json:"data_from"` 87 + //数据来源
  88 + DataFrom OrderDataFrom `json:"data_from"`
88 } 89 }
89 90
90 //NewOrderGood 初始值设定 91 //NewOrderGood 初始值设定
@@ -61,9 +61,11 @@ func (p *PartnerInfo) IsCompany(companyId int64) bool { @@ -61,9 +61,11 @@ func (p *PartnerInfo) IsCompany(companyId int64) bool {
61 } 61 }
62 62
63 type PartnerFindOneQuery struct { 63 type PartnerFindOneQuery struct {
64 - UserId int64  
65 - AccountEqual string  
66 - CompanyId int64 64 + UserId int64
  65 + AccountEqual string
  66 + CompanyId int64
  67 + Code string // 合伙人编码
  68 + PartnerCategory int // 合伙人类型
67 } 69 }
68 70
69 type PartnerFindQuery struct { 71 type PartnerFindQuery struct {
@@ -43,6 +43,6 @@ type OrderGood struct { @@ -43,6 +43,6 @@ type OrderGood struct {
43 CompanyId int64 43 CompanyId int64
44 //原因备注 44 //原因备注
45 RemarkReason domain.OrderGoodRemarkReason `` 45 RemarkReason domain.OrderGoodRemarkReason ``
46 - 46 + //数据来源
47 DataFrom domain.OrderDataFrom `` 47 DataFrom domain.OrderDataFrom ``
48 } 48 }
@@ -3,6 +3,7 @@ package repository @@ -3,6 +3,7 @@ package repository
3 import ( 3 import (
4 "errors" 4 "errors"
5 "fmt" 5 "fmt"
  6 + "github.com/go-pg/pg/v10"
6 7
7 "github.com/go-pg/pg/v10/orm" 8 "github.com/go-pg/pg/v10/orm"
8 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain" 9 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
@@ -81,6 +82,10 @@ func (repository *PartnerInfoRepository) FindOne(queryOptions domain.PartnerFind @@ -81,6 +82,10 @@ func (repository *PartnerInfoRepository) FindOne(queryOptions domain.PartnerFind
81 hasCondition = true 82 hasCondition = true
82 query = query.Where("company_id=?", queryOptions.CompanyId) 83 query = query.Where("company_id=?", queryOptions.CompanyId)
83 } 84 }
  85 + if queryOptions.PartnerCategory > 0 && queryOptions.Code != "" { // 合伙人类型和编码判断
  86 + hasCondition = true
  87 + query = query.Where(`partner_category_infos@> '[{"id":?,"code":?}]'`, queryOptions.PartnerCategory, pg.Ident(queryOptions.Code))
  88 + }
84 if !hasCondition { 89 if !hasCondition {
85 return nil, errors.New("FindOne 必须要有查询条件") 90 return nil, errors.New("FindOne 必须要有查询条件")
86 } 91 }
@@ -8,7 +8,6 @@ import ( @@ -8,7 +8,6 @@ import (
8 ) 8 )
9 9
10 func init() { 10 func init() {
11 -  
12 logs.SetLevel(logLevel(constant.LOG_LEVEL)) 11 logs.SetLevel(logLevel(constant.LOG_LEVEL))
13 logs.SetLogFuncCall(false) 12 logs.SetLogFuncCall(false)
14 logs.SetLogger("file", getlogFileConfig()) 13 logs.SetLogger("file", getlogFileConfig())
1 package controllers 1 package controllers
2 2
3 import ( 3 import (
  4 + "crypto/md5"
  5 + "encoding/hex"
4 "encoding/json" 6 "encoding/json"
5 "errors" 7 "errors"
6 "fmt" 8 "fmt"
@@ -618,11 +620,14 @@ func (c *OrderInfoController) ListOrderForExcel() { @@ -618,11 +620,14 @@ func (c *OrderInfoController) ListOrderForExcel() {
618 * @return 620 * @return
619 **/ 621 **/
620 func (c *OrderInfoController) ImportOrderFromExcel() { 622 func (c *OrderInfoController) ImportOrderFromExcel() {
  623 + // 获取参数
621 where := c.GetString("where") 624 where := c.GetString("where")
622 file, h, _ := c.GetFile("file") 625 file, h, _ := c.GetFile("file")
623 626
624 - jsonMap := make(map[string]interface{}) 627 + companyId := c.GetUserCompany()
625 628
  629 + // Json数据解析
  630 + jsonMap := make(map[string]interface{})
626 err := json.Unmarshal([]byte(where), &jsonMap) 631 err := json.Unmarshal([]byte(where), &jsonMap)
627 if err != nil { 632 if err != nil {
628 logs.Error(err) 633 logs.Error(err)
@@ -632,8 +637,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -632,8 +637,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
632 // 返回字段定义 637 // 返回字段定义
633 ret := map[string]interface{}{} 638 ret := map[string]interface{}{}
634 639
635 - // 返回信息表头定义  
636 - // 0: 订单号, 1: 发货单号, 3: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例 640 + // 返回信息表头定义 0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例, 8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
637 var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "编号", "合伙人", "类型", "业务抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"} 641 var tableHeader = []string{"错误详情", "行号", "订单号", "发货单号", "客户名称", "订单区域", "编号", "合伙人", "类型", "业务抽成比例", "产品名称", "数量", "单价", "合伙人分红比例"}
638 642
639 // 文件后缀名校验 643 // 文件后缀名校验
@@ -642,14 +646,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -642,14 +646,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
642 ".xlsx": true, 646 ".xlsx": true,
643 } 647 }
644 if _, ok := AllowExtMap[ext]; !ok { 648 if _, ok := AllowExtMap[ext]; !ok {
645 - c.ResponseError(errors.New("文件后缀名不符合上传要求,请上传正确的文件")) 649 + c.ResponseError(errors.New("文件后缀名不符合上传要求,请上传正确格式的文件"))
646 return 650 return
647 } 651 }
648 652
649 // 打开文件 653 // 打开文件
650 xlsx, err := excelize.OpenReader(file) 654 xlsx, err := excelize.OpenReader(file)
651 if err != nil { 655 if err != nil {
652 - c.ResponseError(errors.New("文件打开失败")) 656 + c.ResponseError(errors.New("文件打开失败,请确定文件能够正常打开"))
653 return 657 return
654 } 658 }
655 659
@@ -669,13 +673,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -669,13 +673,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
669 nullLine := make([]interface{}, 0) 673 nullLine := make([]interface{}, 0)
670 nullFlag := false 674 nullFlag := false
671 for i, row := range rows { 675 for i, row := range rows {
672 - if i > 2 { 676 + if i > 2 && row != nil {
673 if len(row) == constant.EXCEL_COLUMN { // 中间空字符校验 677 if len(row) == constant.EXCEL_COLUMN { // 中间空字符校验
674 - var myRow = row 678 + var tmpRow = row
  679 + var myRow []string
675 for j, cell := range row { 680 for j, cell := range row {
676 if j != 8 { // 业务员抽成比例不校验 681 if j != 8 { // 业务员抽成比例不校验
677 if cell == "" || cell == " " { // 空字符串填充 682 if cell == "" || cell == " " { // 空字符串填充
678 - myRow[j] = "null" 683 + tmpRow[j] = "null"
679 nullFlag = true 684 nullFlag = true
680 } 685 }
681 } 686 }
@@ -683,14 +688,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -683,14 +688,14 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
683 if nullFlag { 688 if nullFlag {
684 myRow = append(myRow, "必填项不能为空") // 错误信息 689 myRow = append(myRow, "必填项不能为空") // 错误信息
685 s := strconv.Itoa(i + 1) 690 s := strconv.Itoa(i + 1)
686 - myRow = append(myRow, s) // 行号  
687 - myRow = append(myRow, row...) // 错误行数据 691 + myRow = append(myRow, s) // 行号
  692 + myRow = append(myRow, tmpRow...) // 错误行数据
688 nullLine = append(nullLine, myRow) 693 nullLine = append(nullLine, myRow)
689 nullFlag = false 694 nullFlag = false
690 } 695 }
691 - } else if len(row) < constant.EXCEL_COLUMN && len(row) > 0 { // 尾部空字符校验 696 + } else if len(row) > 0 && len(row) < constant.EXCEL_COLUMN { // 尾部空字符校验
692 var myRow []string 697 var myRow []string
693 - for i := 0; i < constant.EXCEL_COLUMN-len(row); i++ { 698 + for i := 0; i < constant.EXCEL_COLUMN-len(row); i++ { // null补位
694 myRow = append(myRow, "null") 699 myRow = append(myRow, "null")
695 } 700 }
696 myRow = append(myRow, "必填项不能为空") // 错误信息 701 myRow = append(myRow, "必填项不能为空") // 错误信息
@@ -702,6 +707,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -702,6 +707,7 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
702 } 707 }
703 } 708 }
704 709
  710 + // 空单元格返回
705 if len(nullLine) > 0 { 711 if len(nullLine) > 0 {
706 ret = map[string]interface{}{ 712 ret = map[string]interface{}{
707 "successCount": 0, 713 "successCount": 0,
@@ -714,11 +720,11 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -714,11 +720,11 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
714 return 720 return
715 } 721 }
716 722
717 - // 单元格长度、内容校验 723 + // 内容校验
718 errorLine := make([]interface{}, 0) 724 errorLine := make([]interface{}, 0)
719 var partnerType = []string{"事业合伙", "业务合伙", "研发合伙", "业务-产品应用合伙"} 725 var partnerType = []string{"事业合伙", "业务合伙", "研发合伙", "业务-产品应用合伙"}
720 for i, row := range rows { 726 for i, row := range rows {
721 - if i > 2 && len(row) == constant.EXCEL_COLUMN { // 数据行 727 + if i > 2 && row != nil && len(row) == constant.EXCEL_COLUMN { // 数据行
722 var myRow []string 728 var myRow []string
723 for j, cell := range row { 729 for j, cell := range row {
724 switch j { 730 switch j {
@@ -829,10 +835,13 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -829,10 +835,13 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
829 } 835 }
830 } 836 }
831 } 837 }
832 - errorLine = append(errorLine, myRow) 838 + if myRow != nil {
  839 + errorLine = append(errorLine, myRow)
  840 + }
833 } 841 }
834 } 842 }
835 843
  844 + // 内容错误行返回
836 if len(errorLine) > 0 { 845 if len(errorLine) > 0 {
837 ret = map[string]interface{}{ 846 ret = map[string]interface{}{
838 "successCount": 0, 847 "successCount": 0,
@@ -845,20 +854,134 @@ func (c *OrderInfoController) ImportOrderFromExcel() { @@ -845,20 +854,134 @@ func (c *OrderInfoController) ImportOrderFromExcel() {
845 return 854 return
846 } 855 }
847 856
848 - // 归类订单 857 + // 创建订单服务
  858 + orderSrv := orderService.NewOrderInfoService(nil)
  859 +
  860 + // 聚合订单产品
  861 + var orderCommands = make(map[string]*orderCmd.CreateOrderCommand, 0)
849 for i, row := range rows { 862 for i, row := range rows {
850 - if i > 2 && len(row) == 13 { 863 + if i > 2 && len(row) == constant.EXCEL_COLUMN {
  864 + hashValue := md5.Sum([]byte(row[0] + row[1] + row[4] + row[6])) // 根据:订单号+发货单号+合伙人编号+合伙类型计算哈希值
  865 + hashString := hex.EncodeToString(hashValue[:])
  866 +
  867 + if _, ok := orderCommands[hashString]; !ok {
  868 + //订单相关,0: 订单号, 1: 发货单号, 2: 客户名称, 3: 订单区域, 4: 编号, 5: 合伙人, 6: 类型, 7: 业务抽成比例,
  869 + sbPercent, _ := strconv.ParseFloat(row[7], 64) //业务抽成比例
  870 +
  871 + //产品相关,8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
  872 + amount, _ := strconv.ParseInt(row[9], 10, 64) // 数量
  873 + price, _ := strconv.ParseFloat(row[10], 64) // 单价
  874 + percent, _ := strconv.ParseFloat(row[11], 64) // 合伙人分红比例
  875 +
  876 + // 初始化建订单命令集
  877 + orderCommands[hashString] = &orderCmd.CreateOrderCommand{
  878 + OrderType: 0,
  879 + OrderCode: row[0],
  880 + DeliveryCode: row[1],
  881 + BuyerName: row[2],
  882 + OrderRegion: row[3],
  883 + PartnerId: 0, // 根据合伙人类型+合伙人编号查找合伙人id
  884 + SalesmanBonusPercent: sbPercent,
  885 + Goods: []orderCmd.OrderGoodData{
  886 + {
  887 + GoodName: row[8],
  888 + PlanGoodNumber: int(amount),
  889 + Price: price,
  890 + PartnerBonusPercent: percent,
  891 + },
  892 + },
  893 + CompanyId: companyId,
  894 + PartnerCategory: 1,
  895 + LineNumbers: []int{i},
  896 + }
  897 +
  898 + // 获取partnerId
  899 + var partnerInfo *domain.PartnerInfo
  900 + partnerInfo, err = orderSrv.GetPartnerIdByCodeAndCategory(orderQuery.GetPartnerIdQuery{
  901 + Code: row[4],
  902 + PartnerCategory: 0,
  903 + CompanyId: companyId,
  904 + })
  905 + if err != nil {
851 906
  907 + }
  908 + if partnerInfo != nil {
  909 + orderCommands[hashString].PartnerId = partnerInfo.Partner.Id
  910 + // 1: 事业合伙、2: 业务合伙、3: 研发合伙、4: 业务-产品应用合伙
  911 + switch row[6] {
  912 + case "事业合伙":
  913 + partnerInfo.PartnerCategory = 1
  914 + case "业务合伙":
  915 + partnerInfo.PartnerCategory = 2
  916 + case "研发合伙":
  917 + partnerInfo.PartnerCategory = 3
  918 + case "业务-产品应用合伙":
  919 + partnerInfo.PartnerCategory = 4
  920 + }
  921 + }
  922 + } else {
  923 + //产品相关,8: 产品名称, 9: 数量, 10: 单价, 11: 合伙人分红比例
  924 + amount, _ := strconv.ParseInt(row[9], 10, 64) // 数量
  925 + price, _ := strconv.ParseFloat(row[10], 64) // 单价
  926 + percent, _ := strconv.ParseFloat(row[11], 64) // 合伙人分红比例
  927 +
  928 + // 记录同一笔订单产品
  929 + orderCommands[hashString].Goods = append(orderCommands[hashString].Goods, orderCmd.OrderGoodData{
  930 + GoodName: row[8],
  931 + PlanGoodNumber: int(amount),
  932 + Price: price,
  933 + PartnerBonusPercent: percent,
  934 + LineNumber: i, // 记录行号
  935 + })
  936 +
  937 + // 记录聚合行号
  938 + orderCommands[hashString].LineNumbers = append(orderCommands[hashString].LineNumbers, i)
  939 + }
852 } 940 }
853 } 941 }
854 942
  943 + // 批量创建订单命令集
  944 + var createOrderCommands []*orderCmd.CreateOrderCommand
  945 + for _, orderCommand := range orderCommands {
  946 + createOrderCommands = append(createOrderCommands, orderCommand)
  947 + }
  948 +
855 // 新增失败记录 949 // 新增失败记录
856 failureDataList := make([]interface{}, 0) 950 failureDataList := make([]interface{}, 0)
857 951
858 // 新增成功记录计数 952 // 新增成功记录计数
859 - //var successDataCount int64 953 + var successDataCount int64
860 954
861 - c.ResponseData(failureDataList) 955 + // 新增错误信息
  956 + var createError error
  957 +
  958 + // 批量新增订单
  959 + failureDataList, createError = orderSrv.CreateNewOrderByImport(createOrderCommands)
  960 + if createError != nil {
  961 + c.ResponseError(createError)
  962 + return
  963 + } else {
  964 + if len(failureDataList) > 0 { // 导入失败返回
  965 + successDataCount = 0
  966 + ret = map[string]interface{}{
  967 + "successCount": successDataCount,
  968 + "fail": map[string]interface{}{
  969 + "tableHeader": tableHeader,
  970 + "tableData": failureDataList,
  971 + },
  972 + }
  973 + } else { // 导入成功返回
  974 + successDataCount = int64(len(rows) - 3 - len(failureDataList))
  975 + if successDataCount == int64(len(rows)-3) {
  976 + ret = map[string]interface{}{
  977 + "successCount": successDataCount,
  978 + "fail": nil,
  979 + }
  980 + }
  981 + }
  982 + }
862 983
  984 + // 返回错误详情
  985 + c.ResponseData(ret)
863 return 986 return
864 } 987 }
@@ -35,12 +35,12 @@ func init() { @@ -35,12 +35,12 @@ func init() {
35 beego.NSRouter("/list/excel", &controllers.OrderDividendController{}, "POST:ListOrderBonusForExcel"), 35 beego.NSRouter("/list/excel", &controllers.OrderDividendController{}, "POST:ListOrderBonusForExcel"),
36 ), 36 ),
37 beego.NSNamespace("/order", 37 beego.NSNamespace("/order",
38 - beego.NSRouter("/actual/list", &controllers.OrderInfoController{}, "POST:PageListOrderReal"), 38 + beego.NSRouter("/actual/list", &controllers.OrderInfoController{}, "POST:PageListOrderReal"), // 返归订单列表
39 beego.NSRouter("/actual/list/excel", &controllers.OrderInfoController{}, "POST:ListOrderForExcel"), // 导出excel 39 beego.NSRouter("/actual/list/excel", &controllers.OrderInfoController{}, "POST:ListOrderForExcel"), // 导出excel
40 beego.NSRouter("/actual/import/excel", &controllers.OrderInfoController{}, "POST:ImportOrderFromExcel"), // 导入订单数据 40 beego.NSRouter("/actual/import/excel", &controllers.OrderInfoController{}, "POST:ImportOrderFromExcel"), // 导入订单数据
41 - beego.NSRouter("/actual/detail", &controllers.OrderInfoController{}, "POST:GetOrderReal"),  
42 - beego.NSRouter("/actual/del", &controllers.OrderInfoController{}, "POST:RemoveOrderReal"),  
43 - beego.NSRouter("/actual/update", &controllers.OrderInfoController{}, "POST:UpdateOrderReal"), 41 + beego.NSRouter("/actual/detail", &controllers.OrderInfoController{}, "POST:GetOrderReal"), // 查看实际订单详情
  42 + beego.NSRouter("/actual/del", &controllers.OrderInfoController{}, "POST:RemoveOrderReal"), // 删除实际订单
  43 + beego.NSRouter("/actual/update", &controllers.OrderInfoController{}, "POST:UpdateOrderReal"), // 新增实际订单
44 beego.NSRouter("/actual/close", &controllers.OrderInfoController{}, "POST:OrderDisable"), 44 beego.NSRouter("/actual/close", &controllers.OrderInfoController{}, "POST:OrderDisable"),
45 ), 45 ),
46 beego.NSNamespace("/common", 46 beego.NSNamespace("/common",