作者 唐旭辉

Merge branch 'test'

正在显示 65 个修改的文件 包含 4053 行增加145 行删除

要显示太多修改。

为保证性能只显示 65 of 65+ 个文件。

@@ -78,6 +78,10 @@ spec: @@ -78,6 +78,10 @@ spec:
78 value: "6DwjBO735" 78 value: "6DwjBO735"
79 - name: BUSINESS_ADMIN_HOST 79 - name: BUSINESS_ADMIN_HOST
80 value: "http://suplus-business-admin-dev.fjmaimaimai.com" 80 value: "http://suplus-business-admin-dev.fjmaimaimai.com"
  81 + - name: KAFKA_HOST
  82 + value: "192.168.0.250:9092;192.168.0.251:9092;192.168.0.252:9092"
  83 + - name: KAFKA_CONSUMER_ID
  84 + value: "partnermg_dev"
81 volumes: 85 volumes:
82 - name: accesslogs 86 - name: accesslogs
83 emptyDir: {} 87 emptyDir: {}
@@ -60,7 +60,7 @@ spec: @@ -60,7 +60,7 @@ spec:
60 - name: POSTGRESQL_PORT 60 - name: POSTGRESQL_PORT
61 value: "31544" 61 value: "31544"
62 - name: LOG_LEVEL 62 - name: LOG_LEVEL
63 - value: "debug" 63 + value: "info"
64 - name: ERROR_BASE_CODE 64 - name: ERROR_BASE_CODE
65 value: "1" 65 value: "1"
66 - name: ERROR_BASE_CODE_MULTIPLE 66 - name: ERROR_BASE_CODE_MULTIPLE
@@ -75,6 +75,10 @@ spec: @@ -75,6 +75,10 @@ spec:
75 value: "rsF0pL!6DwjBO735" 75 value: "rsF0pL!6DwjBO735"
76 - name: BUSINESS_ADMIN_HOST 76 - name: BUSINESS_ADMIN_HOST
77 value: "http://suplus-business-admin-prd.fjmaimaimai.com" 77 value: "http://suplus-business-admin-prd.fjmaimaimai.com"
  78 + - name: KAFKA_HOST
  79 + value: "192.168.0.250:9092;192.168.0.251:9092;192.168.0.252:9092"
  80 + - name: KAFKA_CONSUMER_ID
  81 + value: "partnermg_prd"
78 volumes: 82 volumes:
79 - name: accesslogs 83 - name: accesslogs
80 - emptyDir: {}  
  84 + emptyDir: {}
@@ -75,6 +75,10 @@ spec: @@ -75,6 +75,10 @@ spec:
75 value: "rsF0pL!6DwjBO735" 75 value: "rsF0pL!6DwjBO735"
76 - name: BUSINESS_ADMIN_HOST 76 - name: BUSINESS_ADMIN_HOST
77 value: "http://suplus-business-admin-test.fjmaimaimai.com" 77 value: "http://suplus-business-admin-test.fjmaimaimai.com"
  78 + - name: KAFKA_HOST
  79 + value: "192.168.0.250:9092;192.168.0.251:9092;192.168.0.252:9092"
  80 + - name: KAFKA_CONSUMER_ID
  81 + value: "partnermg_test"
78 volumes: 82 volumes:
79 - name: accesslogs 83 - name: accesslogs
80 emptyDir: {} 84 emptyDir: {}
@@ -4,8 +4,10 @@ go 1.14 @@ -4,8 +4,10 @@ go 1.14
4 4
5 require ( 5 require (
6 github.com/GeeTeam/gt3-golang-sdk v0.0.0-20200116043922-446ca8a507d2 6 github.com/GeeTeam/gt3-golang-sdk v0.0.0-20200116043922-446ca8a507d2
  7 + github.com/Shopify/sarama v1.23.1
7 github.com/ajg/form v1.5.1 // indirect 8 github.com/ajg/form v1.5.1 // indirect
8 github.com/astaxie/beego v1.12.2 9 github.com/astaxie/beego v1.12.2
  10 + github.com/bsm/sarama-cluster v2.1.15+incompatible
9 github.com/dgrijalva/jwt-go v3.2.0+incompatible 11 github.com/dgrijalva/jwt-go v3.2.0+incompatible
10 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect 12 github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072 // indirect
11 github.com/fatih/structs v1.1.0 // indirect 13 github.com/fatih/structs v1.1.0 // indirect
1 package main 1 package main
2 2
3 import ( 3 import (
  4 + "context"
  5 + "os"
  6 + "os/signal"
  7 + "syscall"
  8 +
4 "github.com/astaxie/beego" 9 "github.com/astaxie/beego"
5 "github.com/astaxie/beego/logs" 10 "github.com/astaxie/beego/logs"
6 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg" 11 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg"
7 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/log" 12 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/log"
8 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego" 13 _ "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/beego"
  14 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/consumer"
9 ) 15 )
10 16
11 func main() { 17 func main() {
12 - logs.Info("应用启动")  
13 - beego.Run() 18 + sigs := make(chan os.Signal, 1)
  19 + signal.Notify(sigs, os.Interrupt, os.Kill, syscall.SIGINT, syscall.SIGTERM)
  20 + ctx, cancel := context.WithCancel(context.Background())
  21 + go func() {
  22 + logs.Info("应用启动")
  23 + beego.Run()
  24 + }()
  25 + consumerRun := consumer.NewRuner()
  26 +
  27 + if err := consumerRun.InitConsumer(); err != nil {
  28 + logs.Error("启动kafka消息消费者失败:%s", err)
  29 + }
  30 +
  31 + go func() {
  32 + consumerRun.Start(ctx)
  33 + }()
  34 + go func() {
  35 + <-consumerRun.IsReady()
  36 + logs.Info("Sarama consumer up and running!...")
  37 + }()
  38 + for {
  39 + select {
  40 + case <-sigs:
  41 + cancel()
  42 + return
  43 + default:
  44 + }
  45 + }
14 } 46 }
  1 +package subscriber
  2 +
  3 +import (
  4 + "fmt"
  5 + "time"
  6 +
  7 + coreDomain "github.com/linmadan/egglib-go/core/domain"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain/event"
  10 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  11 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/repository"
  12 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
  13 +)
  14 +
  15 +//订单数据修改触发的订阅事件
  16 +type OrderLogSubscriber struct {
  17 + TransactionContext *transaction.TransactionContext
  18 +}
  19 +
  20 +var _ coreDomain.DomainEventSubscriber = (*OrderLogSubscriber)(nil)
  21 +
  22 +func (subscriber *OrderLogSubscriber) HandleEvent(domainEvent coreDomain.DomainEvent) error {
  23 + var (
  24 + orderLogRepository domain.OrderLogRepository
  25 + userRepository domain.UsersRepository
  26 + adminUser domain.Users
  27 + err error
  28 + )
  29 +
  30 + if orderLogRepository, err = repository.NewOrderLogRepository(subscriber.TransactionContext); err != nil {
  31 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  32 + }
  33 + if userRepository, err = repository.NewUsersRepository(subscriber.TransactionContext); err != nil {
  34 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  35 + }
  36 +
  37 + switch domainEvent.EventType() {
  38 + //订单分红因为货品的数量变动而发送改变
  39 + case event.UPDATE_BONUS_BY_GOOD_NUMBER_EVENT:
  40 + currentEvent := domainEvent.(event.UpdateBonusByGoodNumber)
  41 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: currentEvent.AdminId})
  42 + if err != nil {
  43 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  44 + }
  45 + orderLog := domain.OrderLog{
  46 + OperatorType: domain.ORDER_LOG_OPERATOR_ADMIN,
  47 + OperatorId: currentEvent.AdminId,
  48 + Operator: adminUser.Name,
  49 + AlterTime: time.Now(),
  50 + DataFrom: domain.ORDER_LOG_FROM,
  51 + LogAction: "修改",
  52 + OrderId: currentEvent.OrderId,
  53 + GoodId: currentEvent.GoodId,
  54 + Descript: []domain.OrderLogDescript{
  55 + domain.OrderLogDescript{
  56 + Title: "调整商品数量",
  57 + Item: currentEvent.GoodName,
  58 + Action: []string{
  59 + fmt.Sprintf(`购买数量由"%s"调整为"%s"`, currentEvent.FormerNumber, currentEvent.NewNumber),
  60 + fmt.Sprintf(`商品总价由"¥%s"调整为"¥%s"`, currentEvent.FormerAmount, currentEvent.NewAmount),
  61 + },
  62 + },
  63 + },
  64 + }
  65 + err = orderLogRepository.Add(&orderLog)
  66 + break
  67 + //订单分红因为合伙人分红比例变动而发送改变
  68 + case event.UPDATE_BONUS_BY_PARTENT_BONUS_PERCENT_EVENT:
  69 + currentEvent := domainEvent.(event.UpdateBounsByPartnerBonusPercent)
  70 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: currentEvent.AdminId})
  71 + if err != nil {
  72 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  73 + }
  74 + orderLog := domain.OrderLog{
  75 + OperatorType: domain.ORDER_LOG_OPERATOR_ADMIN,
  76 + OperatorId: currentEvent.AdminId,
  77 + Operator: adminUser.Name,
  78 + AlterTime: time.Now(),
  79 + DataFrom: domain.ORDER_LOG_FROM,
  80 + LogAction: "修改",
  81 + OrderId: currentEvent.OrderId,
  82 + GoodId: currentEvent.GoodId,
  83 + Descript: []domain.OrderLogDescript{
  84 + domain.OrderLogDescript{
  85 + Title: "合伙人分红比例",
  86 + Item: currentEvent.GoodName,
  87 + Action: []string{
  88 + fmt.Sprintf(`分红比例由"%s"调整为"%s"`, currentEvent.FormerPartnerBonusPercent, currentEvent.NewPartnerBonusPercent),
  89 + fmt.Sprintf(`应收分红由"¥%s"调整为"¥%s"`, currentEvent.FormerPartnerBonus, currentEvent.NewPartnerBonus),
  90 + },
  91 + },
  92 + },
  93 + }
  94 + err = orderLogRepository.Add(&orderLog)
  95 + break
  96 + //更新订单的备注
  97 + case event.UPDATE_ORDER_REMARK:
  98 + currentEvent := domainEvent.(event.UpdateOrderRemark)
  99 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: currentEvent.AdminId})
  100 + if err != nil {
  101 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  102 + }
  103 + orderLog := domain.OrderLog{
  104 + OperatorType: domain.ORDER_LOG_OPERATOR_ADMIN,
  105 + OperatorId: currentEvent.AdminId,
  106 + Operator: adminUser.Name,
  107 + AlterTime: time.Now(),
  108 + DataFrom: domain.ORDER_LOG_FROM,
  109 + LogAction: "修改",
  110 + OrderId: currentEvent.OrderId,
  111 + GoodId: 0,
  112 + Descript: []domain.OrderLogDescript{
  113 + domain.OrderLogDescript{
  114 + Title: "编辑备注",
  115 + Item: currentEvent.NewRemark,
  116 + Action: []string{},
  117 + },
  118 + },
  119 + }
  120 + err = orderLogRepository.Add(&orderLog)
  121 + break
  122 + // 支付订单中货品的分红
  123 + case event.PAY_ORDER_GOOD_BONUS_EVENT:
  124 + currentEvent := domainEvent.(event.PayOrderGoodBonus)
  125 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: currentEvent.AdminId})
  126 + if err != nil {
  127 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  128 + }
  129 + orderLog := domain.OrderLog{
  130 + OperatorType: domain.ORDER_LOG_OPERATOR_ADMIN,
  131 + OperatorId: currentEvent.AdminId,
  132 + Operator: adminUser.Name,
  133 + AlterTime: time.Now(),
  134 + DataFrom: domain.ORDER_LOG_FROM,
  135 + LogAction: "支付",
  136 + OrderId: currentEvent.OrderId,
  137 + GoodId: currentEvent.GoodId,
  138 + Descript: []domain.OrderLogDescript{
  139 + domain.OrderLogDescript{
  140 + Title: "支付分红",
  141 + Item: currentEvent.GoodName,
  142 + Action: []string{
  143 + fmt.Sprintf(`支付分红"¥%.2f"`, currentEvent.PartnerBonus),
  144 + },
  145 + },
  146 + },
  147 + }
  148 + err = orderLogRepository.Add(&orderLog)
  149 + break
  150 + }
  151 + return err
  152 +}
  153 +
  154 +func (subscriber *OrderLogSubscriber) SubscribedToEventTypes() []string {
  155 + return []string{
  156 + event.UPDATE_BONUS_BY_GOOD_NUMBER_EVENT,
  157 + event.UPDATE_BONUS_BY_PARTENT_BONUS_PERCENT_EVENT,
  158 + event.UPDATE_ORDER_REMARK,
  159 + event.PAY_ORDER_GOOD_BONUS_EVENT,
  160 + }
  161 +}
@@ -21,6 +21,14 @@ func CreateOrderBaseDao(options map[string]interface{}) (*dao.OrderBaseDao, erro @@ -21,6 +21,14 @@ func CreateOrderBaseDao(options map[string]interface{}) (*dao.OrderBaseDao, erro
21 return dao.NewOrderBaseDao(transactionContext) 21 return dao.NewOrderBaseDao(transactionContext)
22 } 22 }
23 23
  24 +func CreateOrderBestshopDao(options map[string]interface{}) (*dao.OrderBestshopDao, error) {
  25 + var transactionContext *transaction.TransactionContext
  26 + if value, ok := options["transactionContext"]; ok {
  27 + transactionContext = value.(*transaction.TransactionContext)
  28 + }
  29 + return dao.NewOrderBestshopDao(transactionContext)
  30 +}
  31 +
24 func CreateUsersDao(options map[string]interface{}) (*dao.UsersDao, error) { 32 func CreateUsersDao(options map[string]interface{}) (*dao.UsersDao, error) {
25 var transactionContext *transaction.TransactionContext 33 var transactionContext *transaction.TransactionContext
26 if value, ok := options["transactionContext"]; ok { 34 if value, ok := options["transactionContext"]; ok {
@@ -13,3 +13,11 @@ func CreateBusinessBonusService(options map[string]interface{}) (service.Busines @@ -13,3 +13,11 @@ func CreateBusinessBonusService(options map[string]interface{}) (service.Busines
13 } 13 }
14 return domainService.NewBusinessBonusService(transactionContext), nil 14 return domainService.NewBusinessBonusService(transactionContext), nil
15 } 15 }
  16 +
  17 +func CreateOrderBonusService(options map[string]interface{}) (service.OrderBonusService, error) {
  18 + var transactionContext *transaction.TransactionContext
  19 + if value, ok := options["transactionContext"]; ok {
  20 + transactionContext = value.(*transaction.TransactionContext)
  21 + }
  22 + return domainService.NewOrderBonusService(transactionContext), nil
  23 +}
@@ -42,7 +42,7 @@ func CreateOrderGoodRepository(options map[string]interface{}) (domain.OrderGood @@ -42,7 +42,7 @@ func CreateOrderGoodRepository(options map[string]interface{}) (domain.OrderGood
42 return repository.NewOrderGoodRepository(transactionContext) 42 return repository.NewOrderGoodRepository(transactionContext)
43 } 43 }
44 44
45 -//CreateOrderGoodRepository 订单信息 45 +//CreateOrderGoodRepository 订单货品信息
46 func CreateUsersRepository(options map[string]interface{}) (domain.UsersRepository, error) { 46 func CreateUsersRepository(options map[string]interface{}) (domain.UsersRepository, error) {
47 var transactionContext *transaction.TransactionContext 47 var transactionContext *transaction.TransactionContext
48 if value, ok := options["transactionContext"]; ok { 48 if value, ok := options["transactionContext"]; ok {
@@ -77,3 +77,30 @@ func CreateBusinessBonusRepository(options map[string]interface{}) (domain.Busin @@ -77,3 +77,30 @@ func CreateBusinessBonusRepository(options map[string]interface{}) (domain.Busin
77 } 77 }
78 return repository.NewBusinessBonusRepository(transactionContext) 78 return repository.NewBusinessBonusRepository(transactionContext)
79 } 79 }
  80 +
  81 +//CreateOrderGoodBestshopRepository 小米(海鲜干货改)的订单商品信息
  82 +func CreateOrderGoodBestshopRepository(options map[string]interface{}) (domain.OrderGoodBestshopRepository, error) {
  83 + var transactionContext *transaction.TransactionContext
  84 + if value, ok := options["transactionContext"]; ok {
  85 + transactionContext = value.(*transaction.TransactionContext)
  86 + }
  87 + return repository.NewOrderGoodBestshopRepository(transactionContext)
  88 +}
  89 +
  90 +//CreateOrderGoodBestshopRepository 小米(海鲜干货改)订单信息
  91 +func CreateOrderBestshopRepository(options map[string]interface{}) (domain.OrderBestshopRepository, error) {
  92 + var transactionContext *transaction.TransactionContext
  93 + if value, ok := options["transactionContext"]; ok {
  94 + transactionContext = value.(*transaction.TransactionContext)
  95 + }
  96 + return repository.NewOrderBestshopRepository(transactionContext)
  97 +}
  98 +
  99 +//CreateOrderGoodBestshopRepository小米(海鲜干货改)订单信息
  100 +func CreateOrderLogRepository(options map[string]interface{}) (domain.OrderLogRepository, error) {
  101 + var transactionContext *transaction.TransactionContext
  102 + if value, ok := options["transactionContext"]; ok {
  103 + transactionContext = value.(*transaction.TransactionContext)
  104 + }
  105 + return repository.NewOrderLogRepository(transactionContext)
  106 +}
1 package command 1 package command
2 2
  3 +//创建订单
3 type CreateOrderCommand struct { 4 type CreateOrderCommand struct {
4 //订单类型 5 //订单类型
5 OrderType int `json:"orderType"` 6 OrderType int `json:"orderType"`
@@ -2,6 +2,7 @@ package command @@ -2,6 +2,7 @@ package command
2 2
3 import "time" 3 import "time"
4 4
  5 +//订单发货
5 type OrderDeliveryCommand struct { 6 type OrderDeliveryCommand struct {
6 OrderId int64 `json:"orderId"` 7 OrderId int64 `json:"orderId"`
7 DeliveryTime time.Time `json:"deliveryTime"` 8 DeliveryTime time.Time `json:"deliveryTime"`
1 package command 1 package command
2 2
3 -//更新订单的商品数字并更新分红的数据 3 +//UpdateGoodBouns 更新订单的商品数量,和支付状态 并更新分红的数据
4 type UpdateGoodBouns struct { 4 type UpdateGoodBouns struct {
5 Id int64 `json:"id"` //订单id 5 Id int64 `json:"id"` //订单id
6 GoodBouns []GoodBouns `json:"goodBouns"` 6 GoodBouns []GoodBouns `json:"goodBouns"`
1 package command 1 package command
2 2
3 -//UpdateOrderPurposeCommand 更新意向 3 +//UpdateOrderPurposeCommand 更新订单
4 type UpdateOrderCommand struct { 4 type UpdateOrderCommand struct {
5 Id int64 `json:"id"` 5 Id int64 `json:"id"`
6 //订单编号 6 //订单编号
@@ -10,9 +10,11 @@ type ListOrderBaseQuery struct { @@ -10,9 +10,11 @@ type ListOrderBaseQuery struct {
10 Offset int `json:"offset" ` 10 Offset int `json:"offset" `
11 // 查询限制 11 // 查询限制
12 Limit int `json:"limit"` 12 Limit int `json:"limit"`
13 - //订单类型  
14 - OrderType int `json:"orderType"`  
15 //发货单号 13 //发货单号
16 DeliveryCode string `json:"deliveryCode"` 14 DeliveryCode string `json:"deliveryCode"`
17 CompanyId int64 `json:"companyId"` 15 CompanyId int64 `json:"companyId"`
  16 +
  17 + //订单类型
  18 + OrderType int `json:"orderType"`
  19 + PartnerOrCode string `json:"partner_or_code"`
18 } 20 }
  1 +package query
  2 +
  3 +type ListOrderBonusQuery struct {
  4 + // 查询偏离量
  5 + Offset int `json:"offset" `
  6 + // 查询限制
  7 + Limit int `json:"limit"`
  8 + CompanyId int64 `json:"companyId"`
  9 + //订单类型
  10 + OrderType int `json:"orderType"`
  11 + PartnerOrCode string `json:"partner_or_code"`
  12 +}
@@ -2,19 +2,24 @@ package service @@ -2,19 +2,24 @@ package service
2 2
3 import ( 3 import (
4 "fmt" 4 "fmt"
  5 + "strings"
5 "time" 6 "time"
6 7
7 "github.com/astaxie/beego/logs" 8 "github.com/astaxie/beego/logs"
8 9
  10 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/event/subscriber"
9 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/factory" 11 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/factory"
10 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command" 12 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/command"
11 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query" 13 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/orderinfo/query"
12 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain" 14 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  15 + domainService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain/service"
13 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/dao" 16 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/dao"
  17 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
  18 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
14 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib" 19 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
15 ) 20 )
16 21
17 -//OrderService 管理员相关服务 22 +//OrderService 自建订单,意向单,实发订单
18 type OrderInfoService struct { 23 type OrderInfoService struct {
19 } 24 }
20 25
@@ -151,6 +156,7 @@ func (service OrderInfoService) GetOrderDetail(getOrderQuery query.GetOrderQuery @@ -151,6 +156,7 @@ func (service OrderInfoService) GetOrderDetail(getOrderQuery query.GetOrderQuery
151 return order, nil 156 return order, nil
152 } 157 }
153 158
  159 +//CreateNewOrder 创建订单
154 func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (*domain.OrderBase, error) { 160 func (service OrderInfoService) CreateNewOrder(cmd command.CreateOrderCommand) (*domain.OrderBase, error) {
155 var ( 161 var (
156 transactionContext, _ = factory.CreateTransactionContext(nil) 162 transactionContext, _ = factory.CreateTransactionContext(nil)
@@ -436,9 +442,11 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand) @@ -436,9 +442,11 @@ func (service OrderInfoService) UpdateOrderData(cmd command.UpdateOrderCommand)
436 oldOrderData.Goods = newOrderGoods 442 oldOrderData.Goods = newOrderGoods
437 //删不需要的订单总不需要的商品 443 //删不需要的订单总不需要的商品
438 delGoods = service.deleteOldOrderGoods(newOrderGoods, oldOrderGoods) 444 delGoods = service.deleteOldOrderGoods(newOrderGoods, oldOrderGoods)
439 - err = orderGoodRepository.Remove(oldOrderData.Id, cmd.CompanyId, delGoods...)  
440 - if err != nil {  
441 - return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("删除订单中的商品数据失败:%s", err)) 445 + if len(delGoods) > 0 {
  446 + err = orderGoodRepository.Remove(oldOrderData.Id, cmd.CompanyId, delGoods...)
  447 + if err != nil {
  448 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("删除订单中的商品数据失败:%s", err))
  449 + }
442 } 450 }
443 err = transactionContext.CommitTransaction() 451 err = transactionContext.CommitTransaction()
444 if err != nil { 452 if err != nil {
@@ -612,7 +620,7 @@ func (service OrderInfoService) DisableOrEnable(cmd command.DisableOrderCommand) @@ -612,7 +620,7 @@ func (service OrderInfoService) DisableOrEnable(cmd command.DisableOrderCommand)
612 return nil 620 return nil
613 } 621 }
614 622
615 -//UpdateGoodBouns 更新货品的分红相关的数值 623 +//UpdateGoodBouns 分红时,更新货品的分红相关的数值
616 func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) error { 624 func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) error {
617 var ( 625 var (
618 transactionContext, _ = factory.CreateTransactionContext(nil) 626 transactionContext, _ = factory.CreateTransactionContext(nil)
@@ -687,7 +695,7 @@ func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) err @@ -687,7 +695,7 @@ func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) err
687 } 695 }
688 } 696 }
689 oldOrderData.Goods = oldOrderGoods 697 oldOrderData.Goods = oldOrderGoods
690 - //变更订单类型 698 +
691 err = oldOrderData.Compute() 699 err = oldOrderData.Compute()
692 if err != nil { 700 if err != nil {
693 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err)) 701 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, fmt.Sprintf("核算订单中合计的数值失败:%s", err))
@@ -707,3 +715,466 @@ func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) err @@ -707,3 +715,466 @@ func (service OrderInfoService) UpdateGoodBouns(cmd command.UpdateGoodBouns) err
707 return nil 715 return nil
708 716
709 } 717 }
  718 +
  719 +//PageListOrderBouns 获取订单的分红列表
  720 +func (service OrderInfoService) PageListOrderBonus(listOrderQuery query.ListOrderBonusQuery) ([]map[string]interface{}, int, error) {
  721 + transactionContext, err := factory.CreateTransactionContext(nil)
  722 + if err != nil {
  723 + return nil, 0, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  724 + }
  725 + if err = transactionContext.StartTransaction(); err != nil {
  726 + return nil, 0, err
  727 + }
  728 + defer func() {
  729 + transactionContext.RollbackTransaction()
  730 + }()
  731 + var (
  732 + ordersM []models.OrderBase
  733 + orders []domain.OrderBase
  734 + cnt int
  735 + orderBaseDao *dao.OrderBaseDao
  736 + )
  737 +
  738 + if orderBaseDao, err = factory.CreateOrderBaseDao(map[string]interface{}{
  739 + "transactionContext": transactionContext,
  740 + }); err != nil {
  741 + return nil, cnt, lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  742 + }
  743 + ordersM, cnt, err = orderBaseDao.OrderBonusListByCondition(
  744 + listOrderQuery.CompanyId,
  745 + listOrderQuery.OrderType,
  746 + listOrderQuery.PartnerOrCode,
  747 + listOrderQuery.Limit,
  748 + listOrderQuery.Offset,
  749 + )
  750 + for _, orderModel := range ordersM {
  751 + order := domain.OrderBase{
  752 + Id: orderModel.Id, OrderType: orderModel.OrderType, OrderCode: orderModel.OrderCode,
  753 + DeliveryCode: orderModel.DeliveryCode, Buyer: orderModel.Buyer, RegionInfo: orderModel.RegionInfo,
  754 + PartnerId: orderModel.PartnerId, SalesmanBonusPercent: orderModel.SalesmanBonusPercent,
  755 + CreateTime: orderModel.CreateTime, DeliveryTime: orderModel.DeliveryTime, UpdateTime: orderModel.UpdateTime,
  756 + IsDisable: orderModel.IsDisable,
  757 + OrderCompute: domain.OrderCompute{
  758 + PlanPartnerBonus: orderModel.PlanPartnerBonus, UsePartnerBonus: orderModel.UsePartnerBonus,
  759 + PartnerBonusHas: orderModel.PartnerBonusHas, PartnerBonusNot: orderModel.PartnerBonusNot,
  760 + PartnerBonusExpense: orderModel.PartnerBonusExpense, SalesmanBonus: orderModel.SalesmanBonus,
  761 + PlanOrderCount: orderModel.PlanOrderCount, PlanOrderAmount: orderModel.PlanOrderAmount,
  762 + UseOrderCount: orderModel.UseOrderCount, UseOrderAmount: orderModel.UseOrderAmount,
  763 + },
  764 + PartnerInfo: domain.Partner{
  765 + Id: orderModel.PartnerId,
  766 + },
  767 + BonusStatus: orderModel.BonusStatus,
  768 + CompanyId: orderModel.CompanyId,
  769 + }
  770 + orders = append(orders, order)
  771 + }
  772 + var (
  773 + PartnerInfoRepository domain.PartnerInfoRepository
  774 + orderGoodRepository domain.OrderGoodRepository
  775 + )
  776 + if PartnerInfoRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  777 + "transactionContext": transactionContext,
  778 + }); err != nil {
  779 + return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  780 + }
  781 + if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
  782 + "transactionContext": transactionContext,
  783 + }); err != nil {
  784 + return nil, 0, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  785 + }
  786 + var resp = []map[string]interface{}{}
  787 + for i := range orders {
  788 + partnerData := &domain.PartnerInfo{}
  789 + partnerData, err = PartnerInfoRepository.FindOne(domain.PartnerFindOneQuery{
  790 + UserId: orders[i].PartnerId,
  791 + })
  792 + if err != nil {
  793 + logs.Error("获取合伙(id=%d)失败%s", orders[i].PartnerId, err)
  794 + } else {
  795 + orders[i].PartnerInfo = partnerData.Partner
  796 + }
  797 + var (
  798 + goods []domain.OrderGood
  799 + hasBonusPercent bool
  800 + )
  801 + goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orders[i].Id})
  802 + for ii := range goods {
  803 + if goods[ii].PartnerBonusPercent > 0 {
  804 + hasBonusPercent = true
  805 + }
  806 + }
  807 + listItem := map[string]interface{}{
  808 + "updateTime": orders[i].UpdateTime.Local().Format("2006-01-02 15:04:05"),
  809 + "id": orders[i].Id,
  810 + "shipmentsId": orders[i].DeliveryCode,
  811 + "partner": orders[i].PartnerInfo.PartnerName,
  812 + "dividendsReceivable": fmt.Sprint(orders[i].GetCurrentPartnerBonus()),
  813 + "dividendSpending": fmt.Sprint(orders[i].OrderCompute.PartnerBonusExpense),
  814 + "receiveDividends": fmt.Sprint(orders[i].OrderCompute.PartnerBonusHas),
  815 + "uncollectedDividends": fmt.Sprint(orders[i].OrderCompute.PartnerBonusNot),
  816 + "stateOfPayment": orders[i].BonusStatus,
  817 + "orderType": orders[i].OrderType,
  818 + "orderTypeName": domain.GetOrderBaseTypeName(orders[i].OrderType),
  819 + "orderNumber": orders[i].OrderCode,
  820 + }
  821 + if !hasBonusPercent {
  822 + listItem["receiveDividends"] = "-"
  823 + listItem["dividendsReceivable"] = "-"
  824 + listItem["dividendSpending"] = "-"
  825 + listItem["uncollectedDividends"] = "-"
  826 + }
  827 + resp = append(resp, listItem)
  828 + }
  829 + err = transactionContext.CommitTransaction()
  830 + if err != nil {
  831 + return resp, cnt, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  832 + }
  833 + return resp, cnt, nil
  834 +}
  835 +
  836 +//GetOrderBestshopInfo 获取来源于xiangmi订单的详情以及分红数据
  837 +func (service OrderInfoService) GetOrderBestshopInfoWithBonus(orderBaseId int64, companyId int64) (interface{}, error) {
  838 + var (
  839 + transactionContext, _ = factory.CreateTransactionContext(nil)
  840 + err error
  841 + )
  842 + if err = transactionContext.StartTransaction(); err != nil {
  843 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  844 + }
  845 + defer func() {
  846 + transactionContext.RollbackTransaction()
  847 + }()
  848 + var (
  849 + orderBaseRepository domain.OrderBaseRepository
  850 + orderGoodRepository domain.OrderGoodRepository
  851 + orderBestshopRepository domain.OrderBestshopRepository
  852 + orderGoodBestshopRepository domain.OrderGoodBestshopRepository
  853 + orderLogRepository domain.OrderLogRepository
  854 + partnerRepository domain.PartnerInfoRepository
  855 + )
  856 + if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
  857 + "transactionContext": transactionContext,
  858 + }); err != nil {
  859 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  860 + }
  861 + if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
  862 + "transactionContext": transactionContext,
  863 + }); err != nil {
  864 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  865 + }
  866 + if orderBestshopRepository, err = factory.CreateOrderBestshopRepository(map[string]interface{}{
  867 + "transactionContext": transactionContext,
  868 + }); err != nil {
  869 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  870 + }
  871 + if orderGoodBestshopRepository, err = factory.CreateOrderGoodBestshopRepository(map[string]interface{}{
  872 + "transactionContext": transactionContext,
  873 + }); err != nil {
  874 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  875 + }
  876 + if orderLogRepository, err = factory.CreateOrderLogRepository(map[string]interface{}{
  877 + "transactionContext": transactionContext,
  878 + }); err != nil {
  879 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  880 + }
  881 + if partnerRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  882 + "transactionContext": transactionContext,
  883 + }); err != nil {
  884 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  885 + }
  886 + var (
  887 + orderData *domain.OrderBase
  888 + orderGoods []domain.OrderGood
  889 + orderBestshopData *domain.OrderBestShop
  890 + orderGoodBestshop []domain.OrderGoodBestShop
  891 + orderLogs []domain.OrderLog
  892 + partnerInfo *domain.PartnerInfo
  893 + )
  894 +
  895 + orderData, err = orderBaseRepository.FindOne(domain.OrderBaseFindOneQuery{
  896 + OrderId: orderBaseId,
  897 + CompanyId: companyId,
  898 + })
  899 + if err != nil {
  900 + e := fmt.Sprintf("获取订单(order_base)数据失败,id=%d,company_id=%d,err=%s", orderBaseId, companyId, err)
  901 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  902 + }
  903 + if orderData.OrderType != domain.OrderTypeBestShop {
  904 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "获取的订单数据失败,OrderType err")
  905 + }
  906 + orderGoods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orderData.Id})
  907 + if err != nil {
  908 + e := fmt.Sprintf("获取订单的商品(order_good)数据失败,order_id=%d,err=%s", orderData.Id, err)
  909 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  910 + }
  911 + orderData.Goods = orderGoods
  912 + partnerInfo, err = partnerRepository.FindOne(domain.PartnerFindOneQuery{UserId: orderData.PartnerId})
  913 + if err != nil {
  914 + e := fmt.Sprintf("获取订单中的合伙人(partner)数据失败,id=%d,order_id=%d,err=%s", orderData.PartnerId, orderData.Id, err)
  915 + logs.Error(e)
  916 + }
  917 + orderData.PartnerInfo = partnerInfo.Partner
  918 + orderBestshopData, err = orderBestshopRepository.FindOne(domain.OrderBestshopFindOneQuery{OrderId: orderData.DataFrom.DataId})
  919 + if err != nil {
  920 + e := fmt.Sprintf("获取xiangmi订单(order_bestshop)数据失败,id=%d,err=%s", orderData.DataFrom.DataId, err)
  921 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  922 + }
  923 + orderGoodBestshop, err = orderGoodBestshopRepository.Find(domain.OrderGoodBestshopFindQuery{OrderId: orderBestshopData.Id})
  924 + if err != nil {
  925 + e := fmt.Sprintf("获取xiangmi订单货品(order_good_bestshop)数据失败,order_id=%d,err=%s", orderBestshopData.Id, err)
  926 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  927 + }
  928 + orderBestshopData.Goods = orderGoodBestshop
  929 + orderLogs, err = orderLogRepository.Find(domain.OrderLogFindQuery{OrderId: orderData.Id})
  930 + if err != nil {
  931 + e := fmt.Sprintf("获取订单的修改记录(order_log)失败,err=%s", err)
  932 + logs.Error(e)
  933 + }
  934 + err = transactionContext.CommitTransaction()
  935 + if err != nil {
  936 + return nil, lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  937 + }
  938 + result := service.buildOrderBestshopInfoData(orderData, orderBestshopData, orderLogs)
  939 + return result, nil
  940 +}
  941 +
  942 +//BuildOrderBestshopInfoData 构建前端需要的数据结构
  943 +func (service OrderInfoService) buildOrderBestshopInfoData(orderBase *domain.OrderBase,
  944 + orderBestshop *domain.OrderBestShop, orderLogs []domain.OrderLog) interface{} {
  945 + orderGoodBestshopMap := map[int64]*domain.OrderGoodBestShop{}
  946 + for i := range orderBestshop.Goods {
  947 + goodid := orderBestshop.Goods[i].Id
  948 + orderGoodBestshopMap[goodid] = &orderBestshop.Goods[i]
  949 + }
  950 + //订单中的商品
  951 + productDetail := []map[string]interface{}{}
  952 + var hasPartnerBonusPercent bool
  953 + for i := range orderBase.Goods {
  954 + detail := map[string]interface{}{
  955 + "commodityName": orderBase.Goods[i].GoodName,
  956 + "productCodes": "",
  957 + "commodityCode": "",
  958 + "univalence": orderBase.Goods[i].Price,
  959 + "orderNum": orderBase.Goods[i].GetCurrentGoodNumber(),
  960 + "commodityPrice": orderBase.Goods[i].GetCurrentAmount(),
  961 + "partnerDividends": "",
  962 + "productId": orderBase.Goods[i].Id,
  963 + "paymentStatus": orderBase.Goods[i].BonusStatus,
  964 + "partnerRatio": orderBase.Goods[i].PartnerBonusPercent,
  965 + }
  966 + if orderBase.Goods[i].PartnerBonusPercent >= 0 {
  967 + hasPartnerBonusPercent = true
  968 + detail["partnerDividends"] = fmt.Sprint(orderBase.Goods[i].GetCurrentPartnerBonus())
  969 + }
  970 + goodBestshopId := orderBase.Goods[i].DataFrom.DataId
  971 + if v, ok := orderGoodBestshopMap[goodBestshopId]; ok {
  972 + detail["productCodes"] = v.Sn
  973 + detail["commodityCode"] = v.Bn
  974 + }
  975 + productDetail = append(productDetail, detail)
  976 + }
  977 + product := map[string]interface{}{
  978 + "orderNumCount": orderBase.GetCurrentOrderCount(),
  979 + "partnerDividendsCount": "",
  980 + "orderAmountAdjustmentCount": orderBase.GetCurrentOrderAmount(),
  981 + "detail": productDetail,
  982 + }
  983 + if hasPartnerBonusPercent {
  984 + product["partnerDividendsCount"] = fmt.Sprint(orderBase.GetCurrentPartnerBonus())
  985 + }
  986 + //订单描述
  987 + order := map[string]interface{}{
  988 + "orderId": orderBase.Id,
  989 + "orderState": orderBestshop.OrderState,
  990 + "customers": orderBestshop.BuyerName,
  991 + "address": orderBestshop.BuyerAddress,
  992 + "remarks": orderBestshop.BuyerRemark,
  993 + "partner": orderBase.PartnerInfo.PartnerName,
  994 + "phone": orderBestshop.BuyerPhone,
  995 + "orderTime": orderBestshop.OrderTime,
  996 + "shippingStatus": orderBestshop.DeliveryState,
  997 + "partnerDividends": "",
  998 + "receivedDividends": "",
  999 + "notReceivedDividend": "",
  1000 + "dividendSpending": "",
  1001 + "orderNumber": orderBase.OrderCode,
  1002 + }
  1003 + if hasPartnerBonusPercent {
  1004 + order["partnerDividends"] = fmt.Sprint(orderBase.GetCurrentPartnerBonus())
  1005 + order["receivedDividends"] = fmt.Sprint(orderBase.OrderCompute.PartnerBonusHas)
  1006 + order["notReceivedDividend"] = fmt.Sprint(orderBase.OrderCompute.PartnerBonusNot)
  1007 + order["dividendSpending"] = fmt.Sprint(orderBase.OrderCompute.PartnerBonusExpense)
  1008 + }
  1009 + modifyLog := []map[string]interface{}{}
  1010 + for i := range orderLogs {
  1011 + m := map[string]interface{}{
  1012 + "title": orderLogs[i].LogAction,
  1013 + "time": orderLogs[i].AlterTime.Local().Format("2006-01-02 15:04:05"),
  1014 + "userName": orderLogs[i].Operator,
  1015 + "id": orderLogs[i].Id,
  1016 + }
  1017 + detail := []map[string]string{}
  1018 + for ii, vv := range orderLogs[i].Descript {
  1019 + d := map[string]string{
  1020 + "updateTitle": vv.Title,
  1021 + "id": fmt.Sprint(ii),
  1022 + "content": vv.Item,
  1023 + }
  1024 + if len(vv.Action) > 0 {
  1025 + d["content"] = vv.Item + ":" + strings.Join(vv.Action, ";")
  1026 + }
  1027 + detail = append(detail, d)
  1028 + }
  1029 + m["updateList"] = detail
  1030 + modifyLog = append(modifyLog, m)
  1031 + }
  1032 +
  1033 + result := map[string]interface{}{
  1034 + "order": order,
  1035 + "product": product,
  1036 + "modify": modifyLog,
  1037 + "remark": orderBase.Remark.RemarkBonus,
  1038 + }
  1039 + return result
  1040 +}
  1041 +
  1042 +//UpdateBounsWithGoodNumber 分红时,因修改订单中商品的数量发生分红变动
  1043 +func (service OrderInfoService) UpdateBonusByGoodNumber(orderId int64, goodId int64, adminId int64, goodNumber int, reason string) error {
  1044 + var (
  1045 + transactionContext, _ = factory.CreateTransactionContext(nil)
  1046 + err error
  1047 + )
  1048 + if err = transactionContext.StartTransaction(); err != nil {
  1049 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1050 + }
  1051 + defer func() {
  1052 + transactionContext.RollbackTransaction()
  1053 + }()
  1054 + var (
  1055 + orderBonuSrv domainService.OrderBonusService
  1056 + )
  1057 + orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
  1058 + "transactionContext": transactionContext,
  1059 + })
  1060 + if err != nil {
  1061 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1062 + }
  1063 + orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
  1064 + TransactionContext: transactionContext.(*transaction.TransactionContext),
  1065 + })
  1066 + err = orderBonuSrv.UpdateBounsByGoodNumber(orderId, adminId, goodId, goodNumber, reason)
  1067 + if err != nil {
  1068 + return err
  1069 + }
  1070 + err = transactionContext.CommitTransaction()
  1071 + if err != nil {
  1072 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1073 + }
  1074 + return nil
  1075 +}
  1076 +
  1077 +//UpdateBounsByPartnerBonusPercent 分红时,因修改订单中商品的合伙人分行比例发生分红变动
  1078 +func (service OrderInfoService) UpdateBonusByPartnerBonusPercent(orderId int64, goodId int64, adminId int64, percent float64, reason string) error {
  1079 + var (
  1080 + transactionContext, _ = factory.CreateTransactionContext(nil)
  1081 + err error
  1082 + )
  1083 + if err = transactionContext.StartTransaction(); err != nil {
  1084 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1085 + }
  1086 + defer func() {
  1087 + transactionContext.RollbackTransaction()
  1088 + }()
  1089 + var (
  1090 + orderBonuSrv domainService.OrderBonusService
  1091 + )
  1092 + orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
  1093 + "transactionContext": transactionContext,
  1094 + })
  1095 + if err != nil {
  1096 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1097 + }
  1098 + orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
  1099 + TransactionContext: transactionContext.(*transaction.TransactionContext),
  1100 + })
  1101 + err = orderBonuSrv.UpdateBounsByPartnerBonusPercent(orderId, adminId, goodId, percent, reason)
  1102 + if err != nil {
  1103 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1104 + }
  1105 + err = transactionContext.CommitTransaction()
  1106 + if err != nil {
  1107 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1108 + }
  1109 + return nil
  1110 +}
  1111 +
  1112 +//PayPartnerBonusWithOrderBestshop 支付分红,海鲜干货的订单 (orderType=domain.OrderTypeBestShop)
  1113 +func (service OrderInfoService) PayPartnerBonusWithOrderBestshop(orderId int64, goodId int64, adminId int64) error {
  1114 + var (
  1115 + transactionContext, _ = factory.CreateTransactionContext(nil)
  1116 + err error
  1117 + )
  1118 + if err = transactionContext.StartTransaction(); err != nil {
  1119 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1120 + }
  1121 + defer func() {
  1122 + transactionContext.RollbackTransaction()
  1123 + }()
  1124 + var (
  1125 + orderBonuSrv domainService.OrderBonusService
  1126 + )
  1127 + orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
  1128 + "transactionContext": transactionContext,
  1129 + })
  1130 + if err != nil {
  1131 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1132 + }
  1133 + orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
  1134 + TransactionContext: transactionContext.(*transaction.TransactionContext),
  1135 + })
  1136 + err = orderBonuSrv.PayOrderGoodBonus(orderId, goodId, adminId)
  1137 + if err != nil {
  1138 + return err
  1139 + }
  1140 + err = transactionContext.CommitTransaction()
  1141 + if err != nil {
  1142 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1143 + }
  1144 + return nil
  1145 +}
  1146 +
  1147 +//PayPartnerBonusWithOrderBestshop 支付分红,海鲜干货的订单 (orderType=domain.OrderTypeBestShop)
  1148 +func (service OrderInfoService) UpdateOrderRemarkBonus(orderId int64, adminId int64, remark string) error {
  1149 + var (
  1150 + transactionContext, _ = factory.CreateTransactionContext(nil)
  1151 + err error
  1152 + )
  1153 + if err = transactionContext.StartTransaction(); err != nil {
  1154 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  1155 + }
  1156 + defer func() {
  1157 + transactionContext.RollbackTransaction()
  1158 + }()
  1159 + var (
  1160 + orderBonuSrv domainService.OrderBonusService
  1161 + )
  1162 + orderBonuSrv, err = factory.CreateOrderBonusService(map[string]interface{}{
  1163 + "transactionContext": transactionContext,
  1164 + })
  1165 + if err != nil {
  1166 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1167 + }
  1168 + orderBonuSrv.Subscribe(&subscriber.OrderLogSubscriber{
  1169 + TransactionContext: transactionContext.(*transaction.TransactionContext),
  1170 + })
  1171 + err = orderBonuSrv.UpdateOrderRemarkBonus(orderId, adminId, remark)
  1172 + if err != nil {
  1173 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1174 + }
  1175 + err = transactionContext.CommitTransaction()
  1176 + if err != nil {
  1177 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  1178 + }
  1179 + return nil
  1180 +}
@@ -44,16 +44,16 @@ func (command CreatePartnerInfoCommand) ValidateCommand() error { @@ -44,16 +44,16 @@ func (command CreatePartnerInfoCommand) ValidateCommand() error {
44 if command.RegionInfo == nil { 44 if command.RegionInfo == nil {
45 return lib.ThrowError(lib.ARG_ERROR, "区域必填") 45 return lib.ThrowError(lib.ARG_ERROR, "区域必填")
46 } 46 }
47 - if len(command.Salesman) == 0 {  
48 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员必填")  
49 - }  
50 - for i := range command.Salesman {  
51 - if len(command.Salesman[i].Name) == 0 {  
52 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员名称必填")  
53 - }  
54 - if len(command.Salesman[i].Telephone) == 0 {  
55 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员电话必填")  
56 - }  
57 - } 47 + // if len(command.Salesman) == 0 {
  48 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员必填")
  49 + // }
  50 + // for i := range command.Salesman {
  51 + // if len(command.Salesman[i].Name) == 0 {
  52 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员名称必填")
  53 + // }
  54 + // if len(command.Salesman[i].Telephone) == 0 {
  55 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员电话必填")
  56 + // }
  57 + // }
58 return nil 58 return nil
59 } 59 }
@@ -31,19 +31,20 @@ func (command *UpdatePartnerInfoCommand) ValidateCommand() error { @@ -31,19 +31,20 @@ func (command *UpdatePartnerInfoCommand) ValidateCommand() error {
31 if command.RegionInfo == nil { 31 if command.RegionInfo == nil {
32 return lib.ThrowError(lib.ARG_ERROR, "区域必填") 32 return lib.ThrowError(lib.ARG_ERROR, "区域必填")
33 } 33 }
34 - if len(command.Salesman) == 0 {  
35 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员必填")  
36 - } 34 +
37 if command.Id == 0 { 35 if command.Id == 0 {
38 return lib.ThrowError(lib.ARG_ERROR, "合伙人id错误") 36 return lib.ThrowError(lib.ARG_ERROR, "合伙人id错误")
39 } 37 }
40 - for i := range command.Salesman {  
41 - if len(command.Salesman[i].Name) == 0 {  
42 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员名称必填")  
43 - }  
44 - if len(command.Salesman[i].Telephone) == 0 {  
45 - return lib.ThrowError(lib.ARG_ERROR, "关联业务员电话必填")  
46 - }  
47 - } 38 + // if len(command.Salesman) == 0 {
  39 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员必填")
  40 + // }
  41 + // for i := range command.Salesman {
  42 + // if len(command.Salesman[i].Name) == 0 {
  43 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员名称必填")
  44 + // }
  45 + // if len(command.Salesman[i].Telephone) == 0 {
  46 + // return lib.ThrowError(lib.ARG_ERROR, "关联业务员电话必填")
  47 + // }
  48 + // }
48 return nil 49 return nil
49 } 50 }
@@ -222,6 +222,7 @@ func (PartnerInfoService *PartnerInfoService) UpdatePartnerInfo(cmd *command.Upd @@ -222,6 +222,7 @@ func (PartnerInfoService *PartnerInfoService) UpdatePartnerInfo(cmd *command.Upd
222 }); err != nil { 222 }); err != nil {
223 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error()) 223 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
224 } 224 }
  225 + //TODO 修改为本地消息订阅
225 err = businessBonusSrv.EnableOrDisable(partnerInfo.Partner.Id) 226 err = businessBonusSrv.EnableOrDisable(partnerInfo.Partner.Id)
226 if err != nil { 227 if err != nil {
227 e := fmt.Sprintf("更新业务分红(partner_id=%d)数据失败:%s", partnerInfo.Partner.Id, err) 228 e := fmt.Sprintf("更新业务分红(partner_id=%d)数据失败:%s", partnerInfo.Partner.Id, err)
  1 +package command
  2 +
  3 +//接收海鲜干货的订单
  4 +type CreateOrderFromBestshop struct {
  5 + //订单编号
  6 + OrderCode string `json:"orderCode"`
  7 + //下单时间
  8 + OrderTime string `json:"orderTime"`
  9 + //公司id
  10 + CompanyId int64 `json:"companyId"`
  11 + //订单状态
  12 + OrderState int8 `json:"orderState"`
  13 + //发货状态
  14 + DeliveryState int8 `json:"deliveryState"`
  15 + //买家名称
  16 + BuyerName string `json:"buyerName"`
  17 + BuyerId int64 `json:"buyerId"`
  18 + //买家电话
  19 + BuyerPhone string `json:"buyerPhone"`
  20 + //买家地址
  21 + BuyerAddress string `json:"buyerAddress"`
  22 + //买家备注
  23 + BuyerRemark string `json:"buyerRemark"`
  24 + //商品总数
  25 + OrderCount int `json:"orderCount"`
  26 + //d订单总额
  27 + OrderAmount float64 `json:"orderAmount"`
  28 + //发货时间
  29 + DeliveryTime string `json:"deliveryTime"`
  30 + PartnerId int64 `json:"partnerId"`
  31 + Goods []struct {
  32 + Id int64 `json:"id"`
  33 + //货品编号
  34 + Sn string `json:"sn"`
  35 + //商品编号
  36 + Bn string `json:"bn"`
  37 + //货品名称
  38 + Name string `json:"name"`
  39 + //单价
  40 + Price float64 `json:"price"`
  41 + //货品数量
  42 + Nums int `json:"nums"`
  43 + //订单总价
  44 + Amount float64 `json:"amount"`
  45 + } `json:"goods"`
  46 +}
  1 +package service
  2 +
  3 +import (
  4 + "fmt"
  5 + "time"
  6 +
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/dao"
  8 +
  9 + "github.com/astaxie/beego/logs"
  10 +
  11 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/factory"
  12 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/syncOrder/command"
  13 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  14 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
  15 +)
  16 +
  17 +//从其他系统接收订单数据
  18 +const (
  19 + BEST_SHOP_UNIONID string = "gh_18eb644002fb" //海鲜干货小程序原始id
  20 +)
  21 +
  22 +type SyncOrderService struct {
  23 +}
  24 +
  25 +func NewOrderInfoService(option map[string]interface{}) *SyncOrderService {
  26 + newService := new(SyncOrderService)
  27 + return newService
  28 +}
  29 +
  30 +//SyncOrderFromBestshop 接收来源于xiangmi小程序的订单数据
  31 +func (s SyncOrderService) SyncOrderFromBestshop(cmd command.CreateOrderFromBestshop) error {
  32 + var (
  33 + transactionContext, _ = factory.CreateTransactionContext(nil)
  34 + err error
  35 + )
  36 + if err = transactionContext.StartTransaction(); err != nil {
  37 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  38 + }
  39 + defer func() {
  40 + transactionContext.RollbackTransaction()
  41 + }()
  42 +
  43 + //检查账号是否存在
  44 + var (
  45 + orderBestshopDao *dao.OrderBestshopDao
  46 + orderExist bool
  47 + partnerRepository domain.PartnerInfoRepository
  48 + partnerData *domain.PartnerInfo
  49 + )
  50 + if orderBestshopDao, err = factory.CreateOrderBestshopDao(map[string]interface{}{
  51 + "transactionContext": transactionContext,
  52 + }); err != nil {
  53 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  54 + }
  55 + orderExist, err = orderBestshopDao.OrderExist(cmd.OrderCode)
  56 + if err != nil {
  57 + return lib.ThrowError(lib.TRANSACTION_ERROR, "orderBestshopDao.OrderExist err:"+err.Error())
  58 + }
  59 + //数据检查
  60 + if partnerRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  61 + "transactionContext": transactionContext,
  62 + }); err != nil {
  63 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  64 + }
  65 + partnerData, err = partnerRepository.FindOne(domain.PartnerFindOneQuery{UserId: cmd.PartnerId})
  66 + if err != nil {
  67 + e := fmt.Sprintf("未找到指定的合伙人(id=%d)数据,%s", cmd.PartnerId, err)
  68 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  69 + }
  70 + if partnerData.CompanyId != cmd.CompanyId {
  71 + e := fmt.Sprintf("合伙人(partnerId)的公司(companyId=%d)和传递的参数中的companyId 不一致", partnerData.CompanyId)
  72 + logs.Warning(e)
  73 + }
  74 + err = transactionContext.CommitTransaction()
  75 + if err != nil {
  76 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  77 + }
  78 + if orderExist {
  79 + //
  80 + logs.Warning("订单数据已存在:order_code=%s", cmd.OrderCode)
  81 + } else {
  82 + err = s.CreateOrderFromBestshop(cmd)
  83 + }
  84 + return err
  85 +}
  86 +
  87 +func (s SyncOrderService) CreateOrderFromBestshop(cmd command.CreateOrderFromBestshop) error {
  88 + var (
  89 + transactionContext, _ = factory.CreateTransactionContext(nil)
  90 + err error
  91 + )
  92 + if err = transactionContext.StartTransaction(); err != nil {
  93 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  94 + }
  95 + defer func() {
  96 + transactionContext.RollbackTransaction()
  97 + }()
  98 + var (
  99 + orderBestshopRepository domain.OrderBestshopRepository
  100 + orderGoodBestshopRepository domain.OrderGoodBestshopRepository
  101 + )
  102 + if orderBestshopRepository, err = factory.CreateOrderBestshopRepository(map[string]interface{}{
  103 + "transactionContext": transactionContext,
  104 + }); err != nil {
  105 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  106 + }
  107 + if orderGoodBestshopRepository, err = factory.CreateOrderGoodBestshopRepository(map[string]interface{}{
  108 + "transactionContext": transactionContext,
  109 + }); err != nil {
  110 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  111 + }
  112 + order := domain.OrderBestShop{
  113 + OrderCode: cmd.OrderCode,
  114 + OrderTime: cmd.OrderTime,
  115 + OrderState: cmd.OrderState,
  116 + OrderCount: cmd.OrderCount,
  117 + OrderAmount: cmd.OrderAmount,
  118 + CreateTime: time.Now(),
  119 + PartnerId: cmd.PartnerId,
  120 + BuyerName: cmd.BuyerName,
  121 + BuyerPhone: cmd.BuyerPhone,
  122 + BuyerAddress: cmd.BuyerAddress,
  123 + BuyerRemark: cmd.BuyerRemark,
  124 + BuyerId: cmd.BuyerId,
  125 + DeliveryState: cmd.DeliveryState,
  126 + DeliveryTime: cmd.DeliveryTime,
  127 + IsCopy: false,
  128 + CompanyId: cmd.CompanyId,
  129 + }
  130 + err = orderBestshopRepository.Add(&order)
  131 + if err != nil {
  132 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "添加order_bestshop失败:"+err.Error())
  133 + }
  134 + goods := []domain.OrderGoodBestShop{}
  135 + for i := range cmd.Goods {
  136 + good := domain.OrderGoodBestShop{
  137 + Id: cmd.Goods[i].Id,
  138 + OrderId: order.Id,
  139 + Sn: cmd.Goods[i].Sn,
  140 + Bn: cmd.Goods[i].Bn,
  141 + Name: cmd.Goods[i].Name,
  142 + Price: cmd.Goods[i].Price,
  143 + Nums: cmd.Goods[i].Nums,
  144 + Amount: cmd.Goods[i].Amount,
  145 + }
  146 + err = orderGoodBestshopRepository.Add(&good)
  147 + if err != nil {
  148 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "添加order_good失败:"+err.Error())
  149 + }
  150 + goods = append(goods, good)
  151 + }
  152 + order.Goods = goods
  153 + err = transactionContext.CommitTransaction()
  154 + if err != nil {
  155 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  156 + }
  157 + if cmd.PartnerId <= 0 {
  158 + logs.Info("[SyncOrderFromBestshop] PartnerId<=0 ,不复制订单数据")
  159 + return nil
  160 + }
  161 + err = s.copyOrderBestshopToOrderBase(&order)
  162 + return err
  163 +}
  164 +
  165 +//copyOrderBestshopToOrderBase 复制数据
  166 +func (s SyncOrderService) copyOrderBestshopToOrderBase(orderBestshop *domain.OrderBestShop) error {
  167 + var (
  168 + transactionContext, _ = factory.CreateTransactionContext(nil)
  169 + err error
  170 + )
  171 + if err = transactionContext.StartTransaction(); err != nil {
  172 + return lib.ThrowError(lib.TRANSACTION_ERROR, err.Error())
  173 + }
  174 + defer func() {
  175 + transactionContext.RollbackTransaction()
  176 + }()
  177 + var (
  178 + orderBaseRepository domain.OrderBaseRepository
  179 + orderGoodRepository domain.OrderGoodRepository
  180 + orderBestshopRepository domain.OrderBestshopRepository
  181 + partnerRepository domain.PartnerInfoRepository
  182 + companyRepository domain.CompanyRepository
  183 + )
  184 + if orderBaseRepository, err = factory.CreateOrderBaseRepository(map[string]interface{}{
  185 + "transactionContext": transactionContext,
  186 + }); err != nil {
  187 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  188 + }
  189 + if orderGoodRepository, err = factory.CreateOrderGoodRepository(map[string]interface{}{
  190 + "transactionContext": transactionContext,
  191 + }); err != nil {
  192 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  193 + }
  194 + if partnerRepository, err = factory.CreatePartnerInfoRepository(map[string]interface{}{
  195 + "transactionContext": transactionContext,
  196 + }); err != nil {
  197 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  198 + }
  199 + if companyRepository, err = factory.CreateCompanyRepository(map[string]interface{}{
  200 + "transactionContext": transactionContext,
  201 + }); err != nil {
  202 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  203 + }
  204 + if orderBestshopRepository, err = factory.CreateOrderBestshopRepository(map[string]interface{}{
  205 + "transactionContext": transactionContext,
  206 + }); err != nil {
  207 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  208 + }
  209 + var (
  210 + partnerData *domain.PartnerInfo
  211 + companyData domain.Company
  212 + canCopyOrder bool
  213 + )
  214 + partnerData, err = partnerRepository.FindOne(domain.PartnerFindOneQuery{UserId: orderBestshop.PartnerId})
  215 + if err != nil {
  216 + e := fmt.Sprintf("未找到指定的合伙人(id=%d)数据,%s", orderBestshop.PartnerId, err)
  217 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  218 + }
  219 + companyData, err = companyRepository.FindOne(domain.CompanyFindOneOptions{
  220 + Id: partnerData.CompanyId,
  221 + })
  222 + if err != nil {
  223 + e := fmt.Sprintf("未找到指定的合伙人的公司(partner_id=%d,company_id=%d)数据,%s", orderBestshop.PartnerId, partnerData.CompanyId, err)
  224 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  225 + }
  226 + for _, v := range companyData.Applets {
  227 + if v.Id == BEST_SHOP_UNIONID {
  228 + canCopyOrder = true
  229 + }
  230 + }
  231 + if !canCopyOrder {
  232 + logs.Warning("公司未设置xiangmi小程序原始id; order_bestshop.id=%d", orderBestshop.Id)
  233 + return nil
  234 + }
  235 + var (
  236 + orderbase domain.OrderBase
  237 + ordergoods []domain.OrderGood
  238 + )
  239 + //TODO 添加orderBase
  240 + orderBestshop.CopyToOrderBase(&orderbase)
  241 + orderbase.CompanyId = companyData.Id
  242 + for i := range orderBestshop.Goods {
  243 + good := domain.NewOrderGood()
  244 + orderBestshop.Goods[i].CopyToOrderGood(&good)
  245 + good.CompanyId = partnerData.CompanyId
  246 + good.Compute()
  247 + good.CurrentBonusStatus.WartPayPartnerBonus(&good)
  248 + ordergoods = append(ordergoods, good)
  249 + }
  250 + orderbase.Goods = ordergoods
  251 + orderbase.PartnerId = partnerData.Partner.Id
  252 + orderbase.CompanyId = partnerData.CompanyId
  253 + orderbase.Compute()
  254 + err = orderBaseRepository.Save(&orderbase)
  255 + if err != nil {
  256 + e := fmt.Sprintf("添加order_base数据失败%s", err)
  257 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  258 + }
  259 + for i := range ordergoods {
  260 + ordergoods[i].OrderId = orderbase.Id
  261 + }
  262 + // 添加goods
  263 + err = orderGoodRepository.Save(ordergoods)
  264 + if err != nil {
  265 + e := fmt.Sprintf("添加order_good数据失败%s", err)
  266 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  267 + }
  268 + // 更新isCopy
  269 + orderBestshop.IsCopy = true
  270 + err = orderBestshopRepository.Edit(orderBestshop)
  271 + if err != nil {
  272 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  273 + }
  274 + err = transactionContext.CommitTransaction()
  275 + if err != nil {
  276 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  277 + }
  278 + return nil
  279 +}
  280 +
  281 +func (s SyncOrderService) UpdateOrderFromBestshop(cmd command.CreateOrderFromBestshop) error {
  282 + var (
  283 + transactionContext, _ = factory.CreateTransactionContext(nil)
  284 + err error
  285 + )
  286 + if err = transactionContext.StartTransaction(); err != nil {
  287 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  288 + }
  289 + defer func() {
  290 + transactionContext.RollbackTransaction()
  291 + }()
  292 + var (
  293 + orderBestshopRepository domain.OrderBestshopRepository
  294 + orderGoodBestshopRepository domain.OrderGoodBestshopRepository
  295 + )
  296 + if orderBestshopRepository, err = factory.CreateOrderBestshopRepository(map[string]interface{}{
  297 + "transactionContext": transactionContext,
  298 + }); err != nil {
  299 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  300 + }
  301 + if orderGoodBestshopRepository, err = factory.CreateOrderGoodBestshopRepository(map[string]interface{}{
  302 + "transactionContext": transactionContext,
  303 + }); err != nil {
  304 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  305 + }
  306 + var (
  307 + orderData *domain.OrderBestShop
  308 + orderGoods []domain.OrderGoodBestShop
  309 + )
  310 + orderData, err = orderBestshopRepository.FindOne(domain.OrderBestshopFindOneQuery{
  311 + OrderCode: cmd.OrderCode,
  312 + })
  313 + if err != nil {
  314 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "获取orderBestshop(order_code=%s)数据失败,err=%s", cmd.OrderCode, err.Error())
  315 + }
  316 +
  317 + orderData.OrderCode = cmd.OrderCode
  318 + orderData.OrderTime = cmd.OrderTime
  319 + orderData.OrderState = cmd.OrderState
  320 + orderData.OrderCount = cmd.OrderCount
  321 + orderData.OrderAmount = cmd.OrderAmount
  322 + orderData.PartnerId = cmd.PartnerId
  323 + orderData.BuyerName = cmd.BuyerName
  324 + orderData.BuyerPhone = cmd.BuyerPhone
  325 + orderData.BuyerAddress = cmd.BuyerAddress
  326 + orderData.BuyerRemark = cmd.BuyerRemark
  327 + orderData.BuyerId = cmd.BuyerId
  328 + orderData.DeliveryState = cmd.DeliveryState
  329 + orderData.DeliveryTime = cmd.DeliveryTime
  330 + orderData.CompanyId = cmd.CompanyId
  331 + err = orderBestshopRepository.Edit(orderData)
  332 + if err != nil {
  333 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "编辑order_bestshop失败:"+err.Error())
  334 + }
  335 + orderGoods, err = orderGoodBestshopRepository.Find(domain.OrderGoodBestshopFindQuery{
  336 + OrderId: orderData.Id,
  337 + })
  338 + if err != nil {
  339 + e := fmt.Sprintf("获取orderGoodBestshop(order_id=%d)数据失败,err=%s", orderData.Id, err.Error())
  340 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  341 + }
  342 +
  343 + for i := range orderGoods {
  344 + var updated bool
  345 + for ii := range cmd.Goods {
  346 + if cmd.Goods[ii].Id != orderGoods[i].Id {
  347 + continue
  348 + }
  349 + orderGoods[i].Sn = cmd.Goods[ii].Sn
  350 + orderGoods[i].Bn = cmd.Goods[ii].Bn
  351 + orderGoods[i].Name = cmd.Goods[ii].Name
  352 + orderGoods[i].Price = cmd.Goods[ii].Price
  353 + orderGoods[i].Nums = cmd.Goods[ii].Nums
  354 + orderGoods[i].Amount = cmd.Goods[ii].Amount
  355 + updated = true
  356 + }
  357 + if updated {
  358 + err = orderGoodBestshopRepository.Edit(&orderGoods[i])
  359 + if err != nil {
  360 + logs.Error("更新order_good_bestshop失败:" + err.Error())
  361 + }
  362 + }
  363 + }
  364 + err = transactionContext.CommitTransaction()
  365 + if err != nil {
  366 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  367 + }
  368 + return nil
  369 +}
@@ -16,14 +16,21 @@ type SyncCompanyService struct{} @@ -16,14 +16,21 @@ type SyncCompanyService struct{}
16 16
17 var _ SyncAction = (*SyncCompanyService)(nil) 17 var _ SyncAction = (*SyncCompanyService)(nil)
18 18
  19 +type CompanyBaseApplet struct {
  20 + Name string `json:"name"`
  21 + URL string `json:"url"`
  22 + Id string `json:"id"`
  23 +}
  24 +
19 //企业平台的公司基础数据 25 //企业平台的公司基础数据
20 type CompanyBase struct { 26 type CompanyBase struct {
21 - Id int64 `json:"id"` //id  
22 - Name string `json:"name"` //公司名称名称  
23 - AdminCompanyId int `json:"admin_company_id"` //总后台的公司id  
24 - Logo string `json:"logo"` //公司图标  
25 - Remarks string `json:"remarks"` //备注  
26 - Abbreviation string `json:"abbreviation"` 27 + Id int64 `json:"id"` //id
  28 + Name string `json:"name"` //公司名称名称
  29 + AdminCompanyId int `json:"admin_company_id"` //总后台的公司id
  30 + Logo string `json:"logo"` //公司图标
  31 + Remarks string `json:"remarks"` //备注
  32 + Abbreviation string `json:"abbreviation"` //公司简称
  33 + Applets []CompanyBaseApplet `json:"applets"` //公司对接的小程序
27 } 34 }
28 35
29 // CompanytData 企业平台发送过来的公司数据数据 36 // CompanytData 企业平台发送过来的公司数据数据
@@ -104,6 +111,15 @@ func (service SyncCompanyService) addCompany(data CompanytData) error { @@ -104,6 +111,15 @@ func (service SyncCompanyService) addCompany(data CompanytData) error {
104 }); err != nil { 111 }); err != nil {
105 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error()) 112 return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
106 } 113 }
  114 + applets := []domain.CompanyApplets{}
  115 + for _, v := range data.Company.Applets {
  116 + app := domain.CompanyApplets{
  117 + Name: v.Name,
  118 + URL: v.URL,
  119 + Id: v.Id,
  120 + }
  121 + applets = append(applets, app)
  122 + }
107 comany := domain.Company{ 123 comany := domain.Company{
108 Id: data.Company.Id, 124 Id: data.Company.Id,
109 Name: data.Company.Name, 125 Name: data.Company.Name,
@@ -114,7 +130,9 @@ func (service SyncCompanyService) addCompany(data CompanytData) error { @@ -114,7 +130,9 @@ func (service SyncCompanyService) addCompany(data CompanytData) error {
114 //Status: data.Company.Status, 130 //Status: data.Company.Status,
115 Enable: domain.CompanyEnableYes, //默认初始化值 131 Enable: domain.CompanyEnableYes, //默认初始化值
116 Abbreviation: data.Company.Abbreviation, 132 Abbreviation: data.Company.Abbreviation,
  133 + Applets: applets,
117 } 134 }
  135 +
118 err = companyRespository.Add(&comany) 136 err = companyRespository.Add(&comany)
119 if err != nil { 137 if err != nil {
120 return fmt.Errorf("添加公司数据失败,%s", err) 138 return fmt.Errorf("添加公司数据失败,%s", err)
@@ -186,12 +204,22 @@ func (service SyncCompanyService) updateCompany(data CompanytData) error { @@ -186,12 +204,22 @@ func (service SyncCompanyService) updateCompany(data CompanytData) error {
186 newUser, err = userRespository.FindOne(domain.UsersFindOneQuery{ 204 newUser, err = userRespository.FindOne(domain.UsersFindOneQuery{
187 Id: data.User.Id, 205 Id: data.User.Id,
188 }) 206 })
  207 + applets := []domain.CompanyApplets{}
  208 + for _, v := range data.Company.Applets {
  209 + app := domain.CompanyApplets{
  210 + Name: v.Name,
  211 + URL: v.URL,
  212 + Id: v.Id,
  213 + }
  214 + applets = append(applets, app)
  215 + }
189 oldCompany.Update(map[string]interface{}{ 216 oldCompany.Update(map[string]interface{}{
190 "Name": data.Company.Name, 217 "Name": data.Company.Name,
191 "Logo": data.Company.Logo, 218 "Logo": data.Company.Logo,
192 "Remarks": data.Company.Remarks, 219 "Remarks": data.Company.Remarks,
193 "AdminCompanyId": data.Company.AdminCompanyId, 220 "AdminCompanyId": data.Company.AdminCompanyId,
194 "Abbreviation": data.Company.Abbreviation, 221 "Abbreviation": data.Company.Abbreviation,
  222 + "Applets": applets,
195 }) 223 })
196 for i := range oldCompanyAdmins { 224 for i := range oldCompanyAdmins {
197 oldCompanyAdmins[i].Update(map[string]interface{}{ 225 oldCompanyAdmins[i].Update(map[string]interface{}{
  1 +package constant
  2 +
  3 +import (
  4 + "os"
  5 + "strings"
  6 +)
  7 +
  8 +type KafkaConfig struct {
  9 + Servers []string `json:"servers"`
  10 + ConsumerId string `json:"consumerGroup"`
  11 +}
  12 +
  13 +var KafkaCfg KafkaConfig
  14 +
  15 +func init() {
  16 + KafkaCfg = KafkaConfig{
  17 + Servers: []string{"192.168.190.136:9092"},
  18 + ConsumerId: "partnermg_local",
  19 + }
  20 + if os.Getenv("KAFKA_HOST") != "" {
  21 + kafkaHost := os.Getenv("KAFKA_HOST")
  22 + KafkaCfg.Servers = strings.Split(kafkaHost, ";")
  23 + }
  24 + if os.Getenv("KAFKA_CONSUMER_ID") != "" {
  25 + consumerId := os.Getenv("KAFKA_CONSUMER_ID")
  26 + KafkaCfg.ConsumerId = consumerId
  27 + }
  28 +}
  29 +
  30 +// "192.168.190.136:9092",
  31 +// "106.52.15.41:9092"
@@ -17,6 +17,12 @@ const ( @@ -17,6 +17,12 @@ const (
17 CompanyEnableNo int8 = 2 17 CompanyEnableNo int8 = 2
18 ) 18 )
19 19
  20 +type CompanyApplets struct {
  21 + Name string `json:"name"`
  22 + URL string `json:"url"`
  23 + Id string `json:"id"`
  24 +}
  25 +
20 // 公司信息 26 // 公司信息
21 type Company struct { 27 type Company struct {
22 // 唯一标识 28 // 唯一标识
@@ -40,13 +46,10 @@ type Company struct { @@ -40,13 +46,10 @@ type Company struct {
40 // 更新时间 46 // 更新时间
41 UpdateAt time.Time `json:"updateAt"` 47 UpdateAt time.Time `json:"updateAt"`
42 // 删除时间 48 // 删除时间
43 - DeleteAt time.Time `json:"deleteAt"` 49 + DeleteAt time.Time `json:"deleteAt"`
  50 + Applets []CompanyApplets `json:"applets"`
44 } 51 }
45 52
46 -// func (c Company) StatusIsOk() bool {  
47 -// return c.Status == companyStatusUsable  
48 -// }  
49 -  
50 func (c Company) EnableIsOk() bool { 53 func (c Company) EnableIsOk() bool {
51 return c.Enable == CompanyEnableYes 54 return c.Enable == CompanyEnableYes
52 } 55 }
@@ -76,6 +79,9 @@ func (c *Company) Update(m map[string]interface{}) error { @@ -76,6 +79,9 @@ func (c *Company) Update(m map[string]interface{}) error {
76 if v, ok := m["Abbreviation"]; ok { 79 if v, ok := m["Abbreviation"]; ok {
77 c.Abbreviation = v.(string) 80 c.Abbreviation = v.(string)
78 } 81 }
  82 + if v, ok := m["Applets"]; ok {
  83 + c.Applets = v.([]CompanyApplets)
  84 + }
79 return nil 85 return nil
80 } 86 }
81 87
  1 +package event
  2 +
  3 +const (
  4 + //订单分红因为货品的数量变动而发送改变
  5 + UPDATE_BONUS_BY_GOOD_NUMBER_EVENT string = "UpdateBonusByGoodNumber"
  6 + //订单分红因为合伙人分红比例变动而发送改变
  7 + UPDATE_BONUS_BY_PARTENT_BONUS_PERCENT_EVENT string = "UpdateBounsByPartnerBonusPercent"
  8 + //更新订单的备注
  9 + UPDATE_ORDER_REMARK string = "UpdateOrderRemark"
  10 +)
  11 +
  12 +//UpdateBonusByGoodNumber
  13 +//订单分红因为货品的数量变动而发送改变
  14 +type UpdateBonusByGoodNumber struct {
  15 + //订单id
  16 + OrderId int64
  17 + //管理员id
  18 + AdminId int64
  19 + //货品id
  20 + GoodId int64
  21 + //货品名称
  22 + GoodName string
  23 + //旧的货品数量
  24 + FormerNumber string
  25 + //新的货品数量
  26 + NewNumber string
  27 + //旧的货品总额
  28 + FormerAmount string
  29 + //新的货品总额
  30 + NewAmount string
  31 +}
  32 +
  33 +//EventType 事件名称
  34 +func (m UpdateBonusByGoodNumber) EventType() string {
  35 + return UPDATE_BONUS_BY_GOOD_NUMBER_EVENT
  36 +}
  37 +
  38 +//UpdateBounsByPartnerBonusPercent
  39 +//订单分红因为合伙人分红比例变动而发送改变
  40 +type UpdateBounsByPartnerBonusPercent struct {
  41 + //订单id
  42 + OrderId int64
  43 + //管理员id
  44 + AdminId int64
  45 + //货品id
  46 + GoodId int64
  47 + //货品名称
  48 + GoodName string
  49 + //旧的合伙人分红比例
  50 + FormerPartnerBonusPercent string
  51 + //新的合伙人分红比例
  52 + NewPartnerBonusPercent string
  53 + //旧的合伙人分红
  54 + FormerPartnerBonus string
  55 + //新的合伙人分红
  56 + NewPartnerBonus string
  57 +}
  58 +
  59 +//EventType 事件名称
  60 +func (m UpdateBounsByPartnerBonusPercent) EventType() string {
  61 + return UPDATE_BONUS_BY_PARTENT_BONUS_PERCENT_EVENT
  62 +}
  63 +
  64 +//UpdateOrderRemark 更新订单的备注
  65 +type UpdateOrderRemark struct {
  66 + //订单id
  67 + OrderId int64
  68 + //管理员id
  69 + AdminId int64
  70 + //旧的备注
  71 + FormerRemark string
  72 + //新的备注
  73 + NewRemark string
  74 +}
  75 +
  76 +//EventType 事件名称
  77 +func (m UpdateOrderRemark) EventType() string {
  78 + return UPDATE_ORDER_REMARK
  79 +}
  1 +package event
  2 +
  3 +const (
  4 + //支付订单中货品的分红
  5 + PAY_ORDER_GOOD_BONUS_EVENT string = "PayOrderGoodBonus"
  6 +)
  7 +
  8 +//PayOrderGoodBonus
  9 +//事件:支付订单中货品的分红
  10 +type PayOrderGoodBonus struct {
  11 + //订单id
  12 + OrderId int64
  13 + //货品名称
  14 + GoodName string
  15 + //订单中的货品id
  16 + GoodId int64
  17 + //管理员id
  18 + AdminId int64
  19 + //
  20 + PartnerBonus float64
  21 +}
  22 +
  23 +func (p PayOrderGoodBonus) EventType() string {
  24 + return PAY_ORDER_GOOD_BONUS_EVENT
  25 +}
@@ -7,10 +7,24 @@ import ( @@ -7,10 +7,24 @@ import (
7 ) 7 )
8 8
9 const ( 9 const (
10 - OrderReal = iota + 1 //实发订单  
11 - OrderIntention //意向订单 10 + OrderReal = iota + 1 //实发订单
  11 + OrderIntention //意向订单
  12 + OrderTypeBestShop //来自小程序海鲜干货的订单
12 ) 13 )
13 14
  15 +func GetOrderBaseTypeName(orderType int) string {
  16 + var name string
  17 + switch orderType {
  18 + case OrderReal:
  19 + name = "自建订单"
  20 + case OrderTypeBestShop:
  21 + name = "小程序订单"
  22 + case OrderIntention:
  23 + name = "意向订单"
  24 + }
  25 + return name
  26 +}
  27 +
14 const ( 28 const (
15 OrderDisableNot = iota //订单未关闭 29 OrderDisableNot = iota //订单未关闭
16 OrderDisableYes //订单已关闭 30 OrderDisableYes //订单已关闭
@@ -24,6 +38,41 @@ type Buyer struct { @@ -24,6 +38,41 @@ type Buyer struct {
24 ContactInfo string `json:"contactInfo"` 38 ContactInfo string `json:"contactInfo"`
25 //收获地址 39 //收获地址
26 ShippingAddress string `json:"shippingAddress"` 40 ShippingAddress string `json:"shippingAddress"`
  41 + //买家备注
  42 + Remark string `json:"remark"`
  43 +}
  44 +
  45 +type OrderCompute struct {
  46 + //合伙人应收分红
  47 + PlanPartnerBonus float64 `json:"planPartnerBonus"`
  48 + //调整后的合伙人应收分红 (初始值=-1);
  49 + //业务判定时0是有效值,
  50 + //所以用空串表示无值,转换到数据库中为负值
  51 + UsePartnerBonus float64 `json:"usePartnerBonus"`
  52 + //合伙人已收分红
  53 + PartnerBonusHas float64 `json:"partnerBonusHas"`
  54 + //合伙人未收分红
  55 + PartnerBonusNot float64 `json:"partnerBonusNot"`
  56 + //合伙人分红支出
  57 + PartnerBonusExpense float64 `json:"partnerBonusExpense"`
  58 + //业务员抽成
  59 + SalesmanBonus float64 `json:"salesmanBonus"`
  60 + //预计的订单内货品总数
  61 + PlanOrderCount int `json:"planOrderCount"`
  62 + //预计的订单的总金额
  63 + PlanOrderAmount float64 `json:"planOrderAmount"`
  64 + //按需使用的订单内货品总数 (初始值=-1)
  65 + //业务判定时0是有效值,
  66 + //所以用空串表示无值,转换到数据库中为负值
  67 + UseOrderCount int `json:"useOrderCount"`
  68 + //按需使用的订单内货总金额 (初始值=-1)
  69 + //业务判定时0是有效值,
  70 + //所以用空串表示无值,转换到数据库中为负值
  71 + UseOrderAmount float64 `json:"useOrderAmount"`
  72 +}
  73 +
  74 +type OrderBaseRemark struct {
  75 + RemarkBonus string `json:"remarkBonus"`
27 } 76 }
28 77
29 //OrderBase 订单基础 78 //OrderBase 订单基础
@@ -61,35 +110,87 @@ type OrderBase struct { @@ -61,35 +110,87 @@ type OrderBase struct {
61 BonusStatus int `json:"bonusStatus"` 110 BonusStatus int `json:"bonusStatus"`
62 //公司 111 //公司
63 CompanyId int64 `json:"companyId"` 112 CompanyId int64 `json:"companyId"`
  113 + //数据来源
  114 + DataFrom OrderDataFrom `json:"dataFrom"`
  115 + //备注
  116 + Remark OrderBaseRemark `json:"remark"`
64 } 117 }
65 118
66 -type OrderCompute struct {  
67 - //合伙人应收分红  
68 - PlanPartnerBonus float64 `json:"planPartnerBonus"`  
69 - //调整后的合伙人应收分红 (初始值=-1);  
70 - //业务判定时0是有效值,  
71 - //所以用空串表示无值,转换到数据库中为负值  
72 - UsePartnerBonus float64 `json:"usePartnerBonus"`  
73 - //合伙人已收分红  
74 - PartnerBonusHas float64 `json:"partnerBonusHas"`  
75 - //合伙人未收分红  
76 - PartnerBonusNot float64 `json:"partnerBonusNot"`  
77 - //合伙人分红支出  
78 - PartnerBonusExpense float64 `json:"partnerBonusExpense"`  
79 - //业务员抽成  
80 - SalesmanBonus float64 `json:"salesmanBonus"`  
81 - //预计的订单内货品总数  
82 - PlanOrderCount int `json:"planOrderCount"`  
83 - //预计的订单的总金额  
84 - PlanOrderAmount float64 `json:"planOrderAmount"`  
85 - //按需使用的订单内货品总数 (初始值=-1)  
86 - //业务判定时0是有效值,  
87 - //所以用空串表示无值,转换到数据库中为负值  
88 - UseOrderCount int `json:"useOrderCount"`  
89 - //按需使用的订单内货总金额 (初始值=-1)  
90 - //业务判定时0是有效值,  
91 - //所以用空串表示无值,转换到数据库中为负值  
92 - UseOrderAmount float64 `json:"useOrderAmount"` 119 +//GetCurrentPartnerBonus 获取当前合伙人应收分红
  120 +func (order *OrderBase) GetCurrentPartnerBonus() float64 {
  121 + if order.OrderCompute.UsePartnerBonus >= 0 {
  122 + return order.OrderCompute.UsePartnerBonus
  123 + }
  124 + return order.OrderCompute.PlanPartnerBonus
  125 +}
  126 +
  127 +//GetCurrentOrderCount 获取当前订单商品总数
  128 +func (order *OrderBase) GetCurrentOrderCount() int {
  129 + if order.OrderCompute.UseOrderCount >= 0 {
  130 + return order.OrderCompute.UseOrderCount
  131 + }
  132 + return order.OrderCompute.PlanOrderCount
  133 +}
  134 +
  135 +// GetCurrentOrderAmount 获取当前订单的总额
  136 +func (order *OrderBase) GetCurrentOrderAmount() float64 {
  137 + if order.OrderCompute.UseOrderAmount >= 0 {
  138 + return order.OrderCompute.UseOrderAmount
  139 + }
  140 + return order.OrderCompute.PlanOrderAmount
  141 +}
  142 +
  143 +//Update 更新订单数据
  144 +//orderData 订单数据
  145 +//goodsMap 货品的数据,以货品的id做键,map[id]map[string]interface{}
  146 +func (order *OrderBase) Update(orderData map[string]interface{}, goodsMap map[int64]map[string]interface{}) error {
  147 + if v, ok := orderData["OrderCode"]; ok {
  148 + order.OrderCode = v.(string)
  149 + }
  150 + if v, ok := orderData["DeliveryCode"]; ok {
  151 + order.DeliveryCode = v.(string)
  152 + }
  153 + if v, ok := orderData["Buyer"]; ok {
  154 + order.Buyer = v.(Buyer)
  155 + }
  156 + if v, ok := orderData["SalesmanBonusPercent"]; ok {
  157 + order.SalesmanBonusPercent = v.(float64)
  158 + }
  159 + if v, ok := orderData["DeliveryTime"]; ok {
  160 + order.DeliveryTime = v.(time.Time)
  161 + }
  162 + if v, ok := orderData["IsDisable"]; ok {
  163 + order.IsDisable = v.(int)
  164 + }
  165 + for i := range order.Goods {
  166 + goodId := order.Goods[i].Id
  167 + if _, ok := goodsMap[goodId]; !ok {
  168 + continue
  169 + }
  170 + if err := order.Goods[i].Update(goodsMap[goodId]); err != nil {
  171 + return err
  172 + }
  173 + }
  174 + err := order.Compute()
  175 + return err
  176 +}
  177 +
  178 +func (order *OrderBase) AddGoods(goods []OrderGood) {
  179 + order.Goods = append(order.Goods, goods...)
  180 + order.Compute()
  181 +}
  182 +
  183 +func (order *OrderBase) DeleteGoods(goodIds []int64) {
  184 + var newGoods []OrderGood
  185 + for i := range order.Goods {
  186 + for _, goodId := range goodIds {
  187 + order.Goods[i].Id = goodId
  188 + continue
  189 + }
  190 + newGoods = append(newGoods, order.Goods[i])
  191 + }
  192 + order.Goods = newGoods
  193 + order.Compute()
93 } 194 }
94 195
95 //Compute 数据汇总核算 196 //Compute 数据汇总核算
  1 +package domain
  2 +
  3 +import "time"
  4 +
  5 +//OrderBestShop 来源海鲜干货的订单
  6 +type OrderBestShop struct {
  7 + Id int64 `json:"id"`
  8 + //订单编号
  9 + OrderCode string `json:"orderCode"`
  10 + //下单时间
  11 + OrderTime string `json:"orderTime"`
  12 + //订单状态
  13 + OrderState int8 `json:"orderState"`
  14 + //发货状态
  15 + DeliveryState int8 `json:"deliveryState"`
  16 + //买家名称
  17 + BuyerName string `json:"buyerName"`
  18 + //买家电话
  19 + BuyerPhone string `json:"buyerPhone"`
  20 + //买家地址
  21 + BuyerAddress string `json:"buyerAddress"`
  22 + //买家备注
  23 + BuyerRemark string `json:"buyerRemark"`
  24 + //
  25 + BuyerId int64 `json:"buyerId"`
  26 + //商品总数
  27 + OrderCount int `json:"orderCount"`
  28 + //d订单总额
  29 + OrderAmount float64 `json:"orderAmount"`
  30 + //发货时间
  31 + DeliveryTime string `json:"deliveryTime"`
  32 + //创建时间
  33 + CreateTime time.Time `json:"createTime"`
  34 + PartnerId int64 `json:"partnerId"`
  35 + Goods []OrderGoodBestShop `json:"goods"`
  36 + //是否将数据同步到 order_base ,order_good
  37 + IsCopy bool `json:"isCopy"`
  38 + CompanyId int64 `json:"companyId"`
  39 +}
  40 +
  41 +func (order OrderBestShop) CopyToOrderBase(o *OrderBase) {
  42 + o.Buyer = Buyer{
  43 + BuyerName: order.BuyerName,
  44 + ContactInfo: order.BuyerPhone,
  45 + ShippingAddress: order.BuyerAddress,
  46 + Remark: order.BuyerRemark,
  47 + }
  48 + o.DataFrom = OrderDataFrom{
  49 + Platform: OrderDataFromBestShop,
  50 + DataId: order.Id,
  51 + }
  52 + o.OrderType = OrderTypeBestShop
  53 + o.OrderCode = order.OrderCode
  54 + o.OrderCompute.PlanOrderAmount = order.OrderAmount
  55 + o.OrderCompute.PlanOrderCount = order.OrderCount
  56 + o.DeliveryTime, _ = time.Parse("2006-01-02 15:04:05", order.DeliveryTime)
  57 + return
  58 +}
  59 +
  60 +type OrderBestshopFindOneQuery struct {
  61 + OrderId int64
  62 + OrderCode string
  63 +}
  64 +
  65 +type OrderBestshopRepository interface {
  66 + Add(order *OrderBestShop) error
  67 + Edit(order *OrderBestShop) error
  68 + FindOne(qureyOptions OrderBestshopFindOneQuery) (*OrderBestShop, error)
  69 +}
  70 +
  71 +//OrderGoodBestShop 订单明细
  72 +type OrderGoodBestShop struct {
  73 + Id int64 `json:"id"`
  74 + //订单id
  75 + OrderId int64 `json:"orderId"`
  76 + //货品编号
  77 + Sn string `json:"sn"`
  78 + //商品编号
  79 + Bn string `json:"bn"`
  80 + //货品名称
  81 + Name string `json:"name"`
  82 + //单价
  83 + Price float64 `json:"price"`
  84 + //货品数量
  85 + Nums int `json:"nums"`
  86 + //订单总价
  87 + Amount float64 `json:"amount"`
  88 +}
  89 +
  90 +func (good OrderGoodBestShop) CopyToOrderGood(g *OrderGood) {
  91 + g.DataFrom = OrderDataFrom{
  92 + Platform: OrderDataFromBestShop,
  93 + DataId: good.Id,
  94 + }
  95 + g.GoodName = good.Name
  96 + g.Price = good.Price
  97 + g.PlanGoodNumber = good.Nums
  98 + g.GoodCompute.PlanAmount = good.Amount
  99 + g.BonusStatus = OrderGoodWaitPay
  100 + g.CurrentBonusStatus = OrderGoodBonusWaitPay{}
  101 +
  102 + return
  103 +}
  104 +
  105 +type OrderGoodBestshopFindQuery struct {
  106 + OrderId int64
  107 +}
  108 +
  109 +type OrderGoodBestshopRepository interface {
  110 + Add(order *OrderGoodBestShop) error
  111 + Edit(good *OrderGoodBestShop) error
  112 + Find(qureyOptions OrderGoodBestshopFindQuery) ([]OrderGoodBestShop, error)
  113 +}
  1 +package domain
  2 +
  3 +const (
  4 + //海鲜干货订单
  5 + OrderDataFromBestShop string = "bestshop"
  6 +)
  7 +
  8 +//OrderDataFrom 订单数据来源
  9 +type OrderDataFrom struct {
  10 + Platform string `json:"platform"` //订单数据来源平台
  11 + DataId int64 `json:"dataId"` //订单数据id标识
  12 +}
@@ -22,6 +22,32 @@ const ( @@ -22,6 +22,32 @@ const (
22 OrderGoodHasPay int = 2 22 OrderGoodHasPay int = 2
23 ) 23 )
24 24
  25 +//GoodCompute 货品中计算值
  26 +type GoodCompute struct {
  27 + //预计的货品总额
  28 + PlanAmount float64 `json:"planAmount"`
  29 + //调整后的货品总额 (初始值=-1)
  30 + //业务判定时0是有效值,
  31 + //所以用空串表示无值,转换到数据库中为负值
  32 + UseAmount float64 `json:"useAmount"`
  33 + //预计的合伙人分红
  34 + PlanPartnerBonus float64 `json:"planPartnerBonus"`
  35 + //合伙人应收分红调整 (初始值=-1),
  36 + //业务判定时0是有效值,
  37 + //所以用空串表示无值,转换到数据库中为负值
  38 + UsePartnerBonus float64 `json:"usePartnerBonus"`
  39 + //合伙人已收分红
  40 + PartnerBonusHas float64 `json:"partnerBonusHas"`
  41 + //合伙人未收分红
  42 + PartnerBonusNot float64 `json:"partnerBonusNot"`
  43 + //合伙人分红支出
  44 + PartnerBonusExpense float64 `json:"partnerBonusExpense"`
  45 +}
  46 +type OrderGoodRemarkReason struct {
  47 + ModifyGoodNumber string `json:"modifyGoodNumber"` //货品数量变更的理由
  48 + ModifyPartnerBonusPercent string `json:"modifyPartnerBonusPercent"` //合伙人分红比例变更的理由
  49 +}
  50 +
25 //OrderGood 订单中的货品 51 //OrderGood 订单中的货品
26 type OrderGood struct { 52 type OrderGood struct {
27 //货品id 53 //货品id
@@ -49,28 +75,61 @@ type OrderGood struct { @@ -49,28 +75,61 @@ type OrderGood struct {
49 ///核算订单相关数据 75 ///核算订单相关数据
50 GoodCompute GoodCompute `json:"goodCompute"` 76 GoodCompute GoodCompute `json:"goodCompute"`
51 //公司 77 //公司
52 - CompanyId int64 78 + CompanyId int64 `json:"companyId"`
  79 + //原因备注
  80 + RemarkReason OrderGoodRemarkReason `json:"remarkReason"`
  81 + DataFrom OrderDataFrom `json:"data_from"`
53 } 82 }
54 83
55 -type GoodCompute struct {  
56 - //预计的货品总额  
57 - PlanAmount float64 `json:"planAmount"`  
58 - //调整后的货品总额 (初始值=-1)  
59 - //业务判定时0是有效值,  
60 - //所以用空串表示无值,转换到数据库中为负值  
61 - UseAmount float64 `json:"useAmount"`  
62 - //预计的合伙人分红  
63 - PlanPartnerBonus float64 `json:"planPartnerBonus"`  
64 - //合伙人应收分红调整 (初始值=-1),  
65 - //业务判定时0是有效值,  
66 - //所以用空串表示无值,转换到数据库中为负值  
67 - UsePartnerBonus float64 `json:"usePartnerBonus"`  
68 - //合伙人已收分红  
69 - PartnerBonusHas float64 `json:"partnerBonusHas"`  
70 - //合伙人未收分红  
71 - PartnerBonusNot float64 `json:"partnerBonusNot"`  
72 - //合伙人分红支出  
73 - PartnerBonusExpense float64 `json:"partnerBonusExpense"` 84 +//GetCurrentGoodNumber 获取当前的商品数量
  85 +func (good OrderGood) GetCurrentGoodNumber() int {
  86 + if good.UseGoodNumber >= 0 {
  87 + return good.UseGoodNumber
  88 + }
  89 + return good.PlanGoodNumber
  90 +}
  91 +
  92 +//GetCurrentAmount 获取当前的商品总额
  93 +func (good OrderGood) GetCurrentAmount() float64 {
  94 + if good.GoodCompute.UseAmount >= 0 {
  95 + return good.GoodCompute.UseAmount
  96 + }
  97 + return good.GoodCompute.PlanAmount
  98 +}
  99 +
  100 +//GetCurrentAmount 获取当前的商品合伙人分红
  101 +func (good OrderGood) GetCurrentPartnerBonus() float64 {
  102 + if good.GoodCompute.UsePartnerBonus >= 0 {
  103 + return good.GoodCompute.UsePartnerBonus
  104 + }
  105 + return good.GoodCompute.PlanPartnerBonus
  106 +}
  107 +
  108 +//Update 更新商品相关的数据
  109 +func (good *OrderGood) Update(m map[string]interface{}) error {
  110 + if v, ok := m["GoodName"]; ok {
  111 + good.GoodName = v.(string)
  112 + }
  113 + if v, ok := m["PlanGoodNumber"]; ok {
  114 + good.PlanGoodNumber = v.(int)
  115 + }
  116 + if v, ok := m["UseGoodNumber"]; ok {
  117 + good.UseGoodNumber = v.(int)
  118 + }
  119 + if v, ok := m["Price"]; ok {
  120 + good.Price = v.(float64)
  121 + }
  122 + if v, ok := m["PartnerBonusPercent"]; ok {
  123 + good.PartnerBonusPercent = v.(float64)
  124 + }
  125 + if v, ok := m["Remark"]; ok {
  126 + good.Remark = v.(string)
  127 + }
  128 + if v, ok := m["RemarkReason"]; ok {
  129 + good.RemarkReason = v.(OrderGoodRemarkReason)
  130 + }
  131 + err := good.Compute()
  132 + return err
74 } 133 }
75 134
76 //OrderGoodBonusWaitPay 货品分红待支付 135 //OrderGoodBonusWaitPay 货品分红待支付
@@ -95,6 +154,7 @@ func (waitPay OrderGoodBonusWaitPay) WartPayPartnerBonus(good *OrderGood) error @@ -95,6 +154,7 @@ func (waitPay OrderGoodBonusWaitPay) WartPayPartnerBonus(good *OrderGood) error
95 good.GoodCompute.PartnerBonusNot = good.GoodCompute.UsePartnerBonus 154 good.GoodCompute.PartnerBonusNot = good.GoodCompute.UsePartnerBonus
96 } 155 }
97 good.CurrentBonusStatus = OrderGoodBonusWaitPay{} 156 good.CurrentBonusStatus = OrderGoodBonusWaitPay{}
  157 + good.BonusStatus = OrderGoodWaitPay
98 return nil 158 return nil
99 } 159 }
100 160
@@ -112,6 +172,7 @@ func (waitPay OrderGoodBonusWaitPay) PayPartnerBonus(good *OrderGood) error { @@ -112,6 +172,7 @@ func (waitPay OrderGoodBonusWaitPay) PayPartnerBonus(good *OrderGood) error {
112 good.GoodCompute.PartnerBonusExpense = 0 172 good.GoodCompute.PartnerBonusExpense = 0
113 good.GoodCompute.PartnerBonusNot = 0 173 good.GoodCompute.PartnerBonusNot = 0
114 good.CurrentBonusStatus = OrderGoodBonusHasPay{} 174 good.CurrentBonusStatus = OrderGoodBonusHasPay{}
  175 + good.BonusStatus = OrderGoodHasPay
115 return nil 176 return nil
116 } 177 }
117 178
@@ -125,6 +186,7 @@ func (hasPay OrderGoodBonusHasPay) PayPartnerBonus(good *OrderGood) error { @@ -125,6 +186,7 @@ func (hasPay OrderGoodBonusHasPay) PayPartnerBonus(good *OrderGood) error {
125 good.GoodCompute.PartnerBonusExpense = good.GoodCompute.PartnerBonusHas - good.GoodCompute.UsePartnerBonus 186 good.GoodCompute.PartnerBonusExpense = good.GoodCompute.PartnerBonusHas - good.GoodCompute.UsePartnerBonus
126 } 187 }
127 good.CurrentBonusStatus = OrderGoodBonusHasPay{} 188 good.CurrentBonusStatus = OrderGoodBonusHasPay{}
  189 + good.BonusStatus = OrderGoodHasPay
128 return nil 190 return nil
129 } 191 }
130 192
@@ -135,8 +197,9 @@ func (hasPay OrderGoodBonusHasPay) WartPayPartnerBonus(good *OrderGood) error { @@ -135,8 +197,9 @@ func (hasPay OrderGoodBonusHasPay) WartPayPartnerBonus(good *OrderGood) error {
135 //NewOrderGood 初始值设定 197 //NewOrderGood 初始值设定
136 func NewOrderGood() OrderGood { 198 func NewOrderGood() OrderGood {
137 return OrderGood{ 199 return OrderGood{
138 - UseGoodNumber: -1,  
139 - BonusStatus: OrderGoodWaitPay, 200 + UseGoodNumber: -1,
  201 + BonusStatus: OrderGoodWaitPay,
  202 + PartnerBonusPercent: -1,
140 GoodCompute: GoodCompute{ 203 GoodCompute: GoodCompute{
141 UsePartnerBonus: -1, 204 UsePartnerBonus: -1,
142 UseAmount: -1, 205 UseAmount: -1,
@@ -150,9 +213,19 @@ func (good *OrderGood) Compute() error { @@ -150,9 +213,19 @@ func (good *OrderGood) Compute() error {
150 //计算预计货品总值 213 //计算预计货品总值
151 //计算预计合伙人分红 214 //计算预计合伙人分红
152 price := decimal.NewFromFloat(good.Price) 215 price := decimal.NewFromFloat(good.Price)
153 - planamount := price.Mul(decimal.NewFromInt(int64(good.PlanGoodNumber))) //price*planGoodNumber 216 + planGoodNumber := good.PlanGoodNumber
  217 + if good.PlanGoodNumber < 0 {
  218 + planGoodNumber = 0
  219 + }
  220 + planamount := price.Mul(decimal.NewFromInt(int64(planGoodNumber))) //price*planGoodNumber
  221 + var partnerBonusPercent float64
  222 + if good.PartnerBonusPercent < 0 {
  223 + partnerBonusPercent = 0
  224 + } else {
  225 + partnerBonusPercent = good.PartnerBonusPercent
  226 + }
154 //price*useGoodNumber 227 //price*useGoodNumber
155 - planPartnerBonus := planamount.Mul(decimal.NewFromFloat(good.PartnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*planGoodNumber*PartnerBonusPercent 228 + planPartnerBonus := planamount.Mul(decimal.NewFromFloat(partnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*planGoodNumber*PartnerBonusPercent
156 good.GoodCompute.PlanAmount, _ = planamount.Round(2).BigFloat().Float64() 229 good.GoodCompute.PlanAmount, _ = planamount.Round(2).BigFloat().Float64()
157 good.GoodCompute.PlanPartnerBonus, _ = planPartnerBonus.Round(2).BigFloat().Float64() 230 good.GoodCompute.PlanPartnerBonus, _ = planPartnerBonus.Round(2).BigFloat().Float64()
158 if good.UseGoodNumber < 0 { 231 if good.UseGoodNumber < 0 {
@@ -162,8 +235,8 @@ func (good *OrderGood) Compute() error { @@ -162,8 +235,8 @@ func (good *OrderGood) Compute() error {
162 } else { 235 } else {
163 //计算调整后的货品总值 236 //计算调整后的货品总值
164 //计算调整后的合伙人分红 237 //计算调整后的合伙人分红
165 - useamount := price.Mul(decimal.NewFromInt(int64(good.UseGoodNumber))) //price*useGoodNumber/price*useGoodNumber  
166 - usePartnerBonus := useamount.Mul(decimal.NewFromFloat(good.PartnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*useGoodNumber*PartnerBonusPercent 238 + useamount := price.Mul(decimal.NewFromInt(int64(good.UseGoodNumber))) //price*useGoodNumber/price*useGoodNumber
  239 + usePartnerBonus := useamount.Mul(decimal.NewFromFloat(partnerBonusPercent)).Div(decimal.NewFromInt(100)) //price*useGoodNumber*PartnerBonusPercent
167 good.GoodCompute.UsePartnerBonus, _ = usePartnerBonus.Round(2).BigFloat().Float64() 240 good.GoodCompute.UsePartnerBonus, _ = usePartnerBonus.Round(2).BigFloat().Float64()
168 good.GoodCompute.UseAmount, _ = useamount.Round(2).BigFloat().Float64() 241 good.GoodCompute.UseAmount, _ = useamount.Round(2).BigFloat().Float64()
169 } 242 }
@@ -177,9 +250,12 @@ type OrderGoodFindQuery struct { @@ -177,9 +250,12 @@ type OrderGoodFindQuery struct {
177 Limit int 250 Limit int
178 CompanyId int64 251 CompanyId int64
179 } 252 }
180 - 253 +type OrderGoodFindOneQuery struct {
  254 + GoodId int64
  255 +}
181 type OrderGoodRepository interface { 256 type OrderGoodRepository interface {
182 Save(order []OrderGood) error 257 Save(order []OrderGood) error
183 Find(queryOptions OrderGoodFindQuery) ([]OrderGood, int, error) 258 Find(queryOptions OrderGoodFindQuery) ([]OrderGood, int, error)
  259 + FindOne(queryOptions OrderGoodFindOneQuery) (OrderGood, error)
184 Remove(orderid int64, companyId int64, ids ...int64) error 260 Remove(orderid int64, companyId int64, ids ...int64) error
185 } 261 }
  1 +package domain
  2 +
  3 +import "time"
  4 +
  5 +// 日志数据来源
  6 +const (
  7 + //管理后台
  8 + ORDER_LOG_FROM string = "web_admin"
  9 +)
  10 +
  11 +//操作人员的类型
  12 +const (
  13 + //操作人类型
  14 + ORDER_LOG_OPERATOR_ADMIN string = "admin"
  15 +)
  16 +
  17 +//OrderLogDescript 描述日志内容
  18 +type OrderLogDescript struct {
  19 + Title string `json:"title"` //标题
  20 + Item string `json:"item"` //修改的项目
  21 + Action []string `json:"action"` //执行的操作
  22 +}
  23 +
  24 +//OrderLog 订单修改记录
  25 +type OrderLog struct {
  26 + Id int64
  27 + OrderId int64 `json:"orderId"` //订单id
  28 + GoodId int64 `json:"goodId"`
  29 + AlterTime time.Time `json:"alterTime"` //时间
  30 + Operator string `json:"operator"` //操作人员
  31 + OperatorId int64 `json:"operatorId"` //操作人员Id
  32 + OperatorType string `json:"operatorType"` //操作人员的类型
  33 + LogAction string `json:"logAction"` //执行动作
  34 + Descript []OrderLogDescript `json:"descript"` //描述日志内容
  35 + DataFrom string `json:"dataFrom"` //修改操作的来源:"web_admin"
  36 +}
  37 +
  38 +type OrderLogFindQuery struct {
  39 + OrderId int64 `json:"orderId"`
  40 +}
  41 +
  42 +type OrderLogRepository interface {
  43 + Add(*OrderLog) error
  44 + Find(queryOptions OrderLogFindQuery) ([]OrderLog, error)
  45 +}
  1 +package domain
  2 +
  3 +import (
  4 + "errors"
  5 + "fmt"
  6 +)
  7 +
  8 +//类型为(orderType=OrderTypeBestShop) 海鲜干货的订单分红
  9 +//因页面上的对于该类型的订单分红状态处理方式 有别于原有的其他类型(OrderReal),所以单独提取出来
  10 +
  11 +// OrderGoodWithBestshopBonusStatus 支付状态
  12 +type OrderGoodWithBestshopBonusStatus interface {
  13 + OrderGoodBonusStatus
  14 + UpdateOrderGoodNumber(good *OrderGood, number int) error
  15 + UpdatePertnerBonusPercent(good *OrderGood, percent float64) error
  16 +}
  17 +
  18 +//OrderGoodWithBestshop 处理订单中商品的分红相关数据
  19 +type OrderGoodWithBestshop struct {
  20 + currentBonusStatus OrderGoodWithBestshopBonusStatus
  21 +}
  22 +
  23 +func (o *OrderGoodWithBestshop) UpdateBonusByGoodNumber(good *OrderGood, number int) error {
  24 + o.reset(good)
  25 + if good.PlanGoodNumber < number {
  26 + return fmt.Errorf("修改商品数量的值不能大于初始值%d", good.PlanGoodNumber)
  27 + }
  28 + err := o.currentBonusStatus.UpdateOrderGoodNumber(good, number)
  29 + return err
  30 +}
  31 +
  32 +func (o *OrderGoodWithBestshop) UpdateBonusByPertnerBonusPercent(good *OrderGood, percent float64) error {
  33 + o.reset(good)
  34 + err := o.currentBonusStatus.UpdatePertnerBonusPercent(good, percent)
  35 + return err
  36 +}
  37 +
  38 +func (o *OrderGoodWithBestshop) PayPartnerBonus(good *OrderGood) error {
  39 + o.currentBonusStatus = OrderGoodBonusBestshopHasPay{}
  40 + err := good.Compute()
  41 + if err != nil {
  42 + return errors.New("核算商品数据失败" + err.Error())
  43 + }
  44 + err = good.CurrentBonusStatus.PayPartnerBonus(good)
  45 + return err
  46 +}
  47 +
  48 +func (o *OrderGoodWithBestshop) reset(good *OrderGood) {
  49 + switch good.BonusStatus {
  50 + case OrderGoodWaitPay:
  51 + o.currentBonusStatus = OrderGoodBonusBestshopWaitPay{}
  52 + case OrderGoodHasPay:
  53 + o.currentBonusStatus = OrderGoodBonusBestshopHasPay{}
  54 + }
  55 + return
  56 +}
  57 +
  58 +//OrderGoodBonusBestshopWaitPay 货品支付状态:待支付
  59 +type OrderGoodBonusBestshopWaitPay struct {
  60 + OrderGoodBonusWaitPay
  61 +}
  62 +
  63 +var _ OrderGoodWithBestshopBonusStatus = (*OrderGoodBonusBestshopWaitPay)(nil)
  64 +
  65 +func (waitPay OrderGoodBonusBestshopWaitPay) UpdateOrderGoodNumber(good *OrderGood, number int) error {
  66 + good.UseGoodNumber = number
  67 + //待支付状态计算
  68 + err := good.Compute()
  69 + if err != nil {
  70 + return errors.New("核算商品数据失败" + err.Error())
  71 + }
  72 + err = good.CurrentBonusStatus.WartPayPartnerBonus(good)
  73 + return err
  74 +}
  75 +
  76 +func (waitPay OrderGoodBonusBestshopWaitPay) UpdatePertnerBonusPercent(good *OrderGood, percent float64) error {
  77 + good.PartnerBonusPercent = percent
  78 + //待支付状态计算
  79 + err := good.Compute()
  80 + if err != nil {
  81 + return errors.New("核算商品数据失败" + err.Error())
  82 + }
  83 + err = good.CurrentBonusStatus.WartPayPartnerBonus(good)
  84 + return err
  85 +}
  86 +
  87 +//OrderGoodBonusBestshopHasPay 货品支付状态:已支付
  88 +type OrderGoodBonusBestshopHasPay struct {
  89 + OrderGoodBonusHasPay
  90 +}
  91 +
  92 +var _ OrderGoodWithBestshopBonusStatus = (*OrderGoodBonusBestshopHasPay)(nil)
  93 +
  94 +func (hasPay OrderGoodBonusBestshopHasPay) UpdateOrderGoodNumber(good *OrderGood, number int) error {
  95 + return errors.New("已支付分红的货品订单,不能修改货品数量")
  96 +}
  97 +
  98 +func (hasPay OrderGoodBonusBestshopHasPay) UpdatePertnerBonusPercent(good *OrderGood, percent float64) error {
  99 + return errors.New("已支付分红的货品订单,不能修改合伙人分红比例")
  100 +}
  1 +package service
  2 +
  3 +import (
  4 + coreDomain "github.com/linmadan/egglib-go/core/domain"
  5 +)
  6 +
  7 +type OrderBonusService interface {
  8 + coreDomain.DomainEventPublisher
  9 + UpdateBounsByGoodNumber(orderId int64, adminId int64, goodid int64, goodWithNumber int, reason string) error
  10 + UpdateBounsByPartnerBonusPercent(orderId int64, adminId int64, goodId int64, partnerPercent float64, reason string) error
  11 + UpdateOrderRemarkBonus(orderId int64, adminId int64, remark string) error
  12 + PayOrderGoodBonus(orderId int64, goodId int64, adminId int64) error
  13 +}
@@ -3,6 +3,9 @@ package dao @@ -3,6 +3,9 @@ package dao
3 import ( 3 import (
4 "fmt" 4 "fmt"
5 5
  6 + "github.com/go-pg/pg/v10/orm"
  7 +
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
6 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models" 9 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
7 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction" 10 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
8 ) 11 )
@@ -22,7 +25,7 @@ func NewOrderBaseDao(transactionContext *transaction.TransactionContext) (*Order @@ -22,7 +25,7 @@ func NewOrderBaseDao(transactionContext *transaction.TransactionContext) (*Order
22 } 25 }
23 26
24 func (dao OrderBaseDao) OrderCodeExist(code string, notId ...int64) (bool, error) { 27 func (dao OrderBaseDao) OrderCodeExist(code string, notId ...int64) (bool, error) {
25 - tx := dao.transactionContext.PgDd 28 + tx := dao.transactionContext.GetDB()
26 m := &models.OrderBase{} 29 m := &models.OrderBase{}
27 query := tx.Model(m).Where("order_code=?", code) 30 query := tx.Model(m).Where("order_code=?", code)
28 if len(notId) > 0 { 31 if len(notId) > 0 {
@@ -33,7 +36,7 @@ func (dao OrderBaseDao) OrderCodeExist(code string, notId ...int64) (bool, error @@ -33,7 +36,7 @@ func (dao OrderBaseDao) OrderCodeExist(code string, notId ...int64) (bool, error
33 } 36 }
34 37
35 func (dao OrderBaseDao) DeliveryCodeExist(code string, companyId int64, notId ...int64) (bool, error) { 38 func (dao OrderBaseDao) DeliveryCodeExist(code string, companyId int64, notId ...int64) (bool, error) {
36 - tx := dao.transactionContext.PgDd 39 + tx := dao.transactionContext.GetDB()
37 m := &models.OrderBase{} 40 m := &models.OrderBase{}
38 query := tx.Model(m).Where("delivery_code=?", code).Where("company_id=?", companyId) 41 query := tx.Model(m).Where("delivery_code=?", code).Where("company_id=?", companyId)
39 if len(notId) > 0 { 42 if len(notId) > 0 {
@@ -42,3 +45,32 @@ func (dao OrderBaseDao) DeliveryCodeExist(code string, companyId int64, notId .. @@ -42,3 +45,32 @@ func (dao OrderBaseDao) DeliveryCodeExist(code string, companyId int64, notId ..
42 ok, err := query.Exists() 45 ok, err := query.Exists()
43 return ok, err 46 return ok, err
44 } 47 }
  48 +
  49 +//OrderListByCondition 根据条件获取订单分红列表
  50 +//orderType 订单类型
  51 +//partnerOrCode 合伙人姓名或订单号或发货单号
  52 +func (dao OrderBaseDao) OrderBonusListByCondition(companyId int64, orderType int, partnerOrCode string, limit, offset int) ([]models.OrderBase, int, error) {
  53 + tx := dao.transactionContext.GetDB()
  54 + var orders []models.OrderBase
  55 + query := tx.Model(&orders).Where("order_base.company_id=?", companyId)
  56 + if orderType > 0 {
  57 + query = query.Where("order_base.order_type=?", orderType)
  58 + } else {
  59 + query = query.Where("order_base.order_type<>?", domain.OrderIntention)
  60 + }
  61 + if len(partnerOrCode) > 0 {
  62 + query = query.Join("LEFT JOIN partner_info as p ON order_base.partner_id=p.id").
  63 + WhereGroup(func(q *orm.Query) (*orm.Query, error) {
  64 + q = q.WhereOr("order_base.order_code like ? ", "%"+partnerOrCode+"%").
  65 + WhereOr("order_base.delivery_code like ? ", "%"+partnerOrCode+"%").
  66 + WhereOr("p.partner_name like ? ", "%"+partnerOrCode+"%")
  67 + return q, nil
  68 + })
  69 + }
  70 + query = query.Order("order_base.update_time DESC").
  71 + Offset(offset).
  72 + Limit(limit)
  73 +
  74 + cnt, err := query.SelectAndCount()
  75 + return orders, cnt, err
  76 +}
  1 +package dao
  2 +
  3 +import (
  4 + "fmt"
  5 +
  6 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  8 +)
  9 +
  10 +type OrderBestshopDao struct {
  11 + transactionContext *transaction.TransactionContext
  12 +}
  13 +
  14 +func NewOrderBestshopDao(transactionContext *transaction.TransactionContext) (*OrderBestshopDao, error) {
  15 + if transactionContext == nil {
  16 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  17 + } else {
  18 + return &OrderBestshopDao{
  19 + transactionContext: transactionContext,
  20 + }, nil
  21 + }
  22 +}
  23 +
  24 +func (dao OrderBestshopDao) OrderExist(orderCode string) (bool, error) {
  25 + tx := dao.transactionContext.GetDB()
  26 + m := models.OrderBestshop{}
  27 + query := tx.Model(&m).Where("order_code=?", orderCode)
  28 + ok, err := query.Exists()
  29 + return ok, err
  30 +}
@@ -16,6 +16,7 @@ func NewBusinessBonusService(tcx *transaction.TransactionContext) *BusinessBonus @@ -16,6 +16,7 @@ func NewBusinessBonusService(tcx *transaction.TransactionContext) *BusinessBonus
16 transactionContext: tcx, 16 transactionContext: tcx,
17 } 17 }
18 } 18 }
  19 +
19 func (srv BusinessBonusService) EnableOrDisable(parntnerId int64) error { 20 func (srv BusinessBonusService) EnableOrDisable(parntnerId int64) error {
20 var ( 21 var (
21 bonusDao, _ = dao.NewBusinessBonusDao(srv.transactionContext) 22 bonusDao, _ = dao.NewBusinessBonusDao(srv.transactionContext)
  1 +package domainService
  2 +
  3 +import (
  4 + "errors"
  5 + "fmt"
  6 +
  7 + coreDomain "github.com/linmadan/egglib-go/core/domain"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  9 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain/event"
  10 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain/service"
  11 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  12 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/repository"
  13 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/lib"
  14 +)
  15 +
  16 +//OrderBonusServices 处理订单分红的相关操作
  17 +type OrderBonusService struct {
  18 + coreDomain.BaseEventPublisher
  19 + transactionContext *transaction.TransactionContext
  20 +}
  21 +
  22 +var _ service.OrderBonusService = (*OrderBonusService)(nil)
  23 +
  24 +func NewOrderBonusService(tcx *transaction.TransactionContext) *OrderBonusService {
  25 + return &OrderBonusService{
  26 + transactionContext: tcx,
  27 + }
  28 +}
  29 +
  30 +//UpdateBounsWithGoodNumber 分红时,因修改订单中商品的数量发生分红变动
  31 +//目前只处理 xiangmi的订单 即 order_type = OrderTypeBestShop (3)
  32 +func (serve *OrderBonusService) UpdateBounsByGoodNumber(orderId int64, adminId int64, goodId int64, goodWithNumber int, reason string) error {
  33 + var (
  34 + userRepository domain.UsersRepository
  35 + orderBaseReponsitory domain.OrderBaseRepository
  36 + orderGoodRepository domain.OrderGoodRepository
  37 + oldOrder *domain.OrderBase
  38 + adminUser domain.Users
  39 + err error
  40 + )
  41 + if orderGoodRepository, err = repository.NewOrderGoodRepository(serve.transactionContext); err != nil {
  42 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  43 + }
  44 + if orderBaseReponsitory, err = repository.NewOrderBaseRepository(serve.transactionContext); err != nil {
  45 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  46 + }
  47 + if userRepository, err = repository.NewUsersRepository(serve.transactionContext); err != nil {
  48 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  49 + }
  50 + oldOrder, err = orderBaseReponsitory.FindOne(domain.OrderBaseFindOneQuery{OrderId: orderId})
  51 + if err != nil {
  52 + e := fmt.Sprintf("获取订单(id=%d)数据失败,%s", orderId, err)
  53 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  54 + }
  55 + if oldOrder.OrderType != domain.OrderTypeBestShop {
  56 + return lib.ThrowError(lib.BUSINESS_ERROR, "订单类型错误")
  57 + }
  58 + oldOrder.Goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orderId})
  59 + if err != nil {
  60 + e := fmt.Sprintf("获取订单(id=%d)中的货品数据失败,%s", orderId, err)
  61 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  62 + }
  63 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: adminId})
  64 + if err != nil {
  65 + e := fmt.Sprintf("获取管理员用户(id=%d)数据失败,%s", adminId, err)
  66 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  67 + }
  68 + if ok := adminUser.InCompany(oldOrder.CompanyId); !ok {
  69 + return lib.ThrowError(lib.BUSINESS_ERROR, "用户不能更新非自己公司的订单")
  70 + }
  71 + var (
  72 + updateGood domain.OrderGood
  73 + formerNumber int
  74 + formerAmount float64
  75 + newAmount float64
  76 + goodExist bool
  77 + )
  78 + for i := range oldOrder.Goods {
  79 + if oldOrder.Goods[i].Id != goodId {
  80 + continue
  81 + }
  82 + updateGood = oldOrder.Goods[i]
  83 + formerNumber = updateGood.GetCurrentGoodNumber()
  84 + formerAmount = updateGood.GetCurrentAmount()
  85 + err := new(domain.OrderGoodWithBestshop).
  86 + UpdateBonusByGoodNumber(&updateGood, goodWithNumber)
  87 + if err != nil {
  88 + return lib.ThrowError(lib.BUSINESS_ERROR, err.Error())
  89 + }
  90 + updateGood.RemarkReason.ModifyGoodNumber = reason
  91 + newAmount = updateGood.GetCurrentAmount()
  92 + goodExist = true
  93 + oldOrder.Goods[i] = updateGood
  94 + }
  95 + if !goodExist {
  96 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "未找到指定的货品")
  97 + }
  98 + if err := oldOrder.Compute(); err != nil {
  99 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "核算订单数据失败"+err.Error())
  100 + }
  101 + //更新商品数据
  102 + err = orderGoodRepository.Save([]domain.OrderGood{updateGood})
  103 + if err != nil {
  104 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "更新商品数据失败,"+err.Error())
  105 + }
  106 + //更新订单数据
  107 + err = orderBaseReponsitory.Save(oldOrder)
  108 + if err != nil {
  109 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "更新订单数据失败,"+err.Error())
  110 + }
  111 + if formerNumber != goodWithNumber {
  112 + // 事件发布
  113 + modifyEvent := event.UpdateBonusByGoodNumber{
  114 + OrderId: oldOrder.Id,
  115 + AdminId: adminId,
  116 + GoodId: oldOrder.Id,
  117 + GoodName: updateGood.GoodName,
  118 + FormerNumber: fmt.Sprint(formerNumber),
  119 + NewNumber: fmt.Sprint(goodWithNumber),
  120 + FormerAmount: fmt.Sprint(formerAmount),
  121 + NewAmount: fmt.Sprint(newAmount),
  122 + }
  123 + if err = serve.Publish(modifyEvent); err != nil {
  124 + return err
  125 + }
  126 + }
  127 + return nil
  128 +}
  129 +
  130 +//UpdateBounsByPartnerBonusPercent 分红时,因修改订单中商品的合伙人分行比例发生分红变动
  131 +////目前只处理 xiangmi的订单 即 order_type = OrderTypeBestShop (3)
  132 +func (serve *OrderBonusService) UpdateBounsByPartnerBonusPercent(orderId int64, adminId int64, goodId int64, partnerPercent float64, reason string) error {
  133 + var (
  134 + userRepository domain.UsersRepository
  135 + orderBaseReponsitory domain.OrderBaseRepository
  136 + orderGoodRepository domain.OrderGoodRepository
  137 + oldOrder *domain.OrderBase
  138 + adminUser domain.Users
  139 + err error
  140 + )
  141 + if orderGoodRepository, err = repository.NewOrderGoodRepository(serve.transactionContext); err != nil {
  142 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  143 + }
  144 + if orderBaseReponsitory, err = repository.NewOrderBaseRepository(serve.transactionContext); err != nil {
  145 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  146 + }
  147 + if userRepository, err = repository.NewUsersRepository(serve.transactionContext); err != nil {
  148 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  149 + }
  150 + oldOrder, err = orderBaseReponsitory.FindOne(domain.OrderBaseFindOneQuery{OrderId: orderId})
  151 + if err != nil {
  152 + e := fmt.Sprintf("获取订单(id=%d)数据失败,%s", orderId, err)
  153 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  154 + }
  155 + if oldOrder.OrderType != domain.OrderTypeBestShop {
  156 + return lib.ThrowError(lib.BUSINESS_ERROR, "订单类型错误")
  157 + }
  158 + oldOrder.Goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orderId})
  159 + if err != nil {
  160 + e := fmt.Sprintf("获取订单中(id=%d)的货品数据失败,%s", orderId, err)
  161 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  162 + }
  163 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: adminId})
  164 + if err != nil {
  165 + e := fmt.Sprintf("获取管理员用户(id=%d)数据失败,%s", adminId, err)
  166 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  167 + }
  168 + if ok := adminUser.InCompany(oldOrder.CompanyId); !ok {
  169 + return lib.ThrowError(lib.BUSINESS_ERROR, "用户不能更新非自己公司的订单")
  170 + }
  171 + var (
  172 + updateGood domain.OrderGood
  173 + formerPartnerBonusPercent float64
  174 + formerPartnerBonus float64
  175 + newPartnerBonus float64
  176 + goodExist bool
  177 + )
  178 + for i := range oldOrder.Goods {
  179 + if oldOrder.Goods[i].Id != goodId {
  180 + continue
  181 + }
  182 + updateGood = oldOrder.Goods[i]
  183 + formerPartnerBonusPercent = updateGood.PartnerBonusPercent
  184 + formerPartnerBonus = updateGood.GetCurrentPartnerBonus()
  185 + err := new(domain.OrderGoodWithBestshop).
  186 + UpdateBonusByPertnerBonusPercent(&updateGood, partnerPercent)
  187 + if err != nil {
  188 + return lib.ThrowError(lib.BUSINESS_ERROR, err.Error())
  189 + }
  190 + updateGood.RemarkReason.ModifyPartnerBonusPercent = reason
  191 + newPartnerBonus = updateGood.GetCurrentPartnerBonus()
  192 + goodExist = true
  193 + oldOrder.Goods[i] = updateGood
  194 + }
  195 + if !goodExist {
  196 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "未找到指定的货品")
  197 + }
  198 + if err := oldOrder.Compute(); err != nil {
  199 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "核算订单数据失败"+err.Error())
  200 + }
  201 + //更新商品数据
  202 + err = orderGoodRepository.Save([]domain.OrderGood{updateGood})
  203 + if err != nil {
  204 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "更新商品数据失败,"+err.Error())
  205 + }
  206 + //更新订单数据
  207 + err = orderBaseReponsitory.Save(oldOrder)
  208 + if err != nil {
  209 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "更新订单数据失败,"+err.Error())
  210 + }
  211 + //事件发布
  212 + modifyEvent := event.UpdateBounsByPartnerBonusPercent{
  213 + OrderId: oldOrder.Id,
  214 + AdminId: adminUser.Id,
  215 + GoodId: updateGood.Id,
  216 + GoodName: updateGood.GoodName,
  217 + FormerPartnerBonusPercent: fmt.Sprint(formerPartnerBonusPercent),
  218 + NewPartnerBonusPercent: fmt.Sprint(partnerPercent),
  219 + FormerPartnerBonus: fmt.Sprint(formerPartnerBonus),
  220 + NewPartnerBonus: fmt.Sprint(newPartnerBonus),
  221 + }
  222 + if formerPartnerBonusPercent < 0 {
  223 + modifyEvent.FormerPartnerBonus = "-"
  224 + modifyEvent.FormerPartnerBonusPercent = "-"
  225 + }
  226 + if err = serve.Publish(modifyEvent); err != nil {
  227 + return err
  228 + }
  229 + return nil
  230 +}
  231 +
  232 +//PayOrderGoodBonus 支付订单中货品的分红
  233 +//目前只处理 海鲜干货的订单 即 order_type = OrderTypeBestShop (3)
  234 +func (serve *OrderBonusService) PayOrderGoodBonus(orderId int64, goodId int64, adminId int64) error {
  235 + var (
  236 + userRepository domain.UsersRepository
  237 + orderBaseReponsitory domain.OrderBaseRepository
  238 + orderGoodRepository domain.OrderGoodRepository
  239 + oldOrder *domain.OrderBase
  240 + adminUser domain.Users
  241 + err error
  242 + )
  243 + if orderGoodRepository, err = repository.NewOrderGoodRepository(serve.transactionContext); err != nil {
  244 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  245 + }
  246 + if orderBaseReponsitory, err = repository.NewOrderBaseRepository(serve.transactionContext); err != nil {
  247 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  248 + }
  249 + if userRepository, err = repository.NewUsersRepository(serve.transactionContext); err != nil {
  250 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  251 + }
  252 + oldOrder, err = orderBaseReponsitory.FindOne(domain.OrderBaseFindOneQuery{OrderId: orderId})
  253 + if err != nil {
  254 + e := fmt.Sprintf("获取订单(id=%d)数据失败,%s", orderId, err)
  255 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  256 + }
  257 + if oldOrder.OrderType != domain.OrderTypeBestShop {
  258 + return lib.ThrowError(lib.BUSINESS_ERROR, "订单类型错误")
  259 + }
  260 + oldOrder.Goods, _, err = orderGoodRepository.Find(domain.OrderGoodFindQuery{OrderId: orderId})
  261 + if err != nil {
  262 + e := fmt.Sprintf("获取订单中(id=%d)的货品数据失败,%s", orderId, err)
  263 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  264 + }
  265 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: adminId})
  266 + if err != nil {
  267 + e := fmt.Sprintf("获取管理员用户(id=%d)数据失败,%s", adminId, err)
  268 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  269 + }
  270 + if ok := adminUser.InCompany(oldOrder.CompanyId); !ok {
  271 + return lib.ThrowError(lib.BUSINESS_ERROR, "用户不能更新非自己公司的订单")
  272 + }
  273 + var (
  274 + updateGood domain.OrderGood
  275 + goodExist bool
  276 + )
  277 + for i := range oldOrder.Goods {
  278 + if oldOrder.Goods[i].Id != goodId {
  279 + continue
  280 + }
  281 + updateGood = oldOrder.Goods[i]
  282 + err := new(domain.OrderGoodWithBestshop).PayPartnerBonus(&updateGood)
  283 + if err != nil {
  284 + return lib.ThrowError(lib.BUSINESS_ERROR, err.Error())
  285 + }
  286 + goodExist = true
  287 + oldOrder.Goods[i] = updateGood
  288 + }
  289 + if !goodExist {
  290 + return errors.New("未找到指定的货品")
  291 + }
  292 + //计算订单的总数据
  293 + if err := oldOrder.Compute(); err != nil {
  294 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, "核算订单数据失败"+err.Error())
  295 + }
  296 + //更新商品数据
  297 + err = orderGoodRepository.Save([]domain.OrderGood{updateGood})
  298 + if err != nil {
  299 + return fmt.Errorf("更新商品数据失败,%s", err)
  300 + }
  301 + //更新订单数据
  302 + err = orderBaseReponsitory.Save(oldOrder)
  303 + if err != nil {
  304 + return fmt.Errorf("更新订单数据失败,%s", err)
  305 + }
  306 + //
  307 + payEvent := event.PayOrderGoodBonus{
  308 + OrderId: orderId,
  309 + GoodId: goodId,
  310 + AdminId: adminId,
  311 + GoodName: updateGood.GoodName,
  312 + PartnerBonus: updateGood.GetCurrentPartnerBonus(),
  313 + }
  314 + if err = serve.Publish(payEvent); err != nil {
  315 + return err
  316 + }
  317 + return nil
  318 +}
  319 +
  320 +//UpdateOrderRemarkBonus 更新备注
  321 +//目前只处理 海鲜干货的订单 即 order_type = OrderTypeBestShop (3)
  322 +func (serve *OrderBonusService) UpdateOrderRemarkBonus(orderId int64, adminId int64, remark string) error {
  323 + var (
  324 + userRepository domain.UsersRepository
  325 + orderBaseReponsitory domain.OrderBaseRepository
  326 + oldOrder *domain.OrderBase
  327 + adminUser domain.Users
  328 + err error
  329 + )
  330 + if orderBaseReponsitory, err = repository.NewOrderBaseRepository(serve.transactionContext); err != nil {
  331 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  332 + }
  333 + if userRepository, err = repository.NewUsersRepository(serve.transactionContext); err != nil {
  334 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, err.Error())
  335 + }
  336 + oldOrder, err = orderBaseReponsitory.FindOne(domain.OrderBaseFindOneQuery{OrderId: orderId})
  337 + if err != nil {
  338 + e := fmt.Sprintf("获取订单(id=%d)数据失败,%s", orderId, err)
  339 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  340 + }
  341 + if oldOrder.OrderType != domain.OrderTypeBestShop {
  342 + return lib.ThrowError(lib.BUSINESS_ERROR, "订单类型错误")
  343 + }
  344 + adminUser, err = userRepository.FindOne(domain.UsersFindOneQuery{Id: adminId})
  345 + if err != nil {
  346 + e := fmt.Sprintf("获取管理员用户(id=%d)数据失败,%s", adminId, err)
  347 + return lib.ThrowError(lib.INTERNAL_SERVER_ERROR, e)
  348 + }
  349 + if ok := adminUser.InCompany(oldOrder.CompanyId); !ok {
  350 + return lib.ThrowError(lib.BUSINESS_ERROR, "用户不能更新非自己公司的订单")
  351 + }
  352 + formerRemark := oldOrder.Remark.RemarkBonus
  353 + oldOrder.Remark.RemarkBonus = remark
  354 + //更新订单数据
  355 + err = orderBaseReponsitory.Save(oldOrder)
  356 + if err != nil {
  357 + return fmt.Errorf("更新订单数据失败,%s", err)
  358 + }
  359 + if formerRemark != remark {
  360 + //事件发布
  361 + modifyEvent := event.UpdateOrderRemark{
  362 + OrderId: oldOrder.Id,
  363 + AdminId: adminUser.Id,
  364 + FormerRemark: formerRemark,
  365 + NewRemark: remark,
  366 + }
  367 + if err = serve.Publish(modifyEvent); err != nil {
  368 + return err
  369 + }
  370 + }
  371 +
  372 + return nil
  373 +}
@@ -5,6 +5,7 @@ import ( @@ -5,6 +5,7 @@ import (
5 "time" 5 "time"
6 6
7 "github.com/go-pg/pg/v10" 7 "github.com/go-pg/pg/v10"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
8 ) 9 )
9 10
10 // 公司信息 11 // 公司信息
@@ -34,6 +35,8 @@ type Company struct { @@ -34,6 +35,8 @@ type Company struct {
34 UpdateAt time.Time 35 UpdateAt time.Time
35 // 删除时间 36 // 删除时间
36 DeleteAt time.Time 37 DeleteAt time.Time
  38 +
  39 + Applets []domain.CompanyApplets
37 } 40 }
38 41
39 var _ pg.BeforeUpdateHook = (*Company)(nil) 42 var _ pg.BeforeUpdateHook = (*Company)(nil)
@@ -63,6 +63,10 @@ type OrderBase struct { @@ -63,6 +63,10 @@ type OrderBase struct {
63 //分红支付状态 63 //分红支付状态
64 BonusStatus int 64 BonusStatus int
65 CompanyId int64 65 CompanyId int64
  66 + //数据来源
  67 + DataFrom domain.OrderDataFrom ``
  68 + //备注
  69 + Remark domain.OrderBaseRemark ``
66 } 70 }
67 71
68 var _ pg.BeforeUpdateHook = (*OrderBase)(nil) 72 var _ pg.BeforeUpdateHook = (*OrderBase)(nil)
  1 +package models
  2 +
  3 +import "time"
  4 +
  5 +type OrderBestshop struct {
  6 + tableName struct{} `pg:"order_bestshop"`
  7 + Id int64
  8 + //订单编号
  9 + OrderCode string
  10 + //下单时间
  11 + OrderTime string
  12 + //订单状态
  13 + OrderState int8
  14 + //发货状态
  15 + DeliveryState int8
  16 + //买家名称
  17 + BuyerName string
  18 + //买家电话
  19 + BuyerPhone string
  20 + //买家地址
  21 + BuyerAddress string
  22 + //买家备注
  23 + BuyerRemark string
  24 + //
  25 + BuyerId int64
  26 + //订单总数
  27 + OrderCount int
  28 + //d订单总额
  29 + OrderAmount float64
  30 + //发货时间
  31 + DeliveryTime string
  32 + //创建时间
  33 + CreateTime time.Time
  34 + PartnerId int64
  35 + //是否将数据同步到 order_base ,order_good
  36 + IsCopy bool `pg:",use_zero"`
  37 + CompanyId int64
  38 +}
1 package models 1 package models
2 2
  3 +import "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  4 +
3 //OrderGood 订单中的货品 5 //OrderGood 订单中的货品
4 type OrderGood struct { 6 type OrderGood struct {
5 tableName struct{} `pg:"order_good"` 7 tableName struct{} `pg:"order_good"`
@@ -36,6 +38,11 @@ type OrderGood struct { @@ -36,6 +38,11 @@ type OrderGood struct {
36 //分红状态 38 //分红状态
37 BonusStatus int 39 BonusStatus int
38 //备注信息 40 //备注信息
39 - Remark string 41 + Remark string
  42 + //公司id
40 CompanyId int64 43 CompanyId int64
  44 + //原因备注
  45 + RemarkReason domain.OrderGoodRemarkReason ``
  46 +
  47 + DataFrom domain.OrderDataFrom ``
41 } 48 }
  1 +package models
  2 +
  3 +type OrderGoodBestshop struct {
  4 + tableName struct{} `pg:"order_good_bestshop"`
  5 + Id int64
  6 + //订单id
  7 + OrderId int64
  8 + //货品编号
  9 + Sn string
  10 + //商品编号
  11 + Bn string
  12 + //货品名称
  13 + Name string
  14 + //单价
  15 + Price float64
  16 + //货品数量
  17 + Nums int
  18 + //订单总价
  19 + Amount float64
  20 +}
  1 +package models
  2 +
  3 +import (
  4 + "context"
  5 + "time"
  6 +
  7 + "github.com/go-pg/pg/v10"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  9 +)
  10 +
  11 +//OrderLog 订单修改记录
  12 +type OrderLog struct {
  13 + tableName struct{} `pg:"order_log"`
  14 + Id int64
  15 + OrderId int64 `` //订单id
  16 + AlterTime time.Time `` //时间
  17 + Operator string `` //操作人员
  18 + OperatorId int64 `` //操作人员Id
  19 + OperatorType string `` //操作人员的类型
  20 + LogAction string `` //执行动作
  21 + Descript []domain.OrderLogDescript `` //描述日志内容
  22 + DataFrom string `` //修改操作的来源:"web_admin"
  23 +}
  24 +
  25 +var _ pg.BeforeInsertHook = (*OrderBase)(nil)
  26 +
  27 +func (l *OrderLog) BeforeInsert(ctx context.Context) (context.Context, error) {
  28 + l.AlterTime = time.Now()
  29 + return ctx, nil
  30 +}
@@ -36,6 +36,7 @@ func (repository CompanyRepository) transformPgModelToDomainModel(m *models.Comp @@ -36,6 +36,7 @@ func (repository CompanyRepository) transformPgModelToDomainModel(m *models.Comp
36 CreateAt: m.CreateAt, 36 CreateAt: m.CreateAt,
37 UpdateAt: m.UpdateAt, 37 UpdateAt: m.UpdateAt,
38 Abbreviation: m.Abbreviation, 38 Abbreviation: m.Abbreviation,
  39 + Applets: m.Applets,
39 }, nil 40 }, nil
40 } 41 }
41 42
@@ -55,6 +56,7 @@ func (reponsitory CompanyRepository) Add(m *domain.Company) error { @@ -55,6 +56,7 @@ func (reponsitory CompanyRepository) Add(m *domain.Company) error {
55 CreateAt: m.CreateAt, 56 CreateAt: m.CreateAt,
56 UpdateAt: m.UpdateAt, 57 UpdateAt: m.UpdateAt,
57 Abbreviation: m.Abbreviation, 58 Abbreviation: m.Abbreviation,
  59 + Applets: m.Applets,
58 } 60 }
59 _, err = tx.Model(&companyModel).Insert() 61 _, err = tx.Model(&companyModel).Insert()
60 return err 62 return err
@@ -77,6 +79,7 @@ func (reponsitory CompanyRepository) Edit(m *domain.Company) error { @@ -77,6 +79,7 @@ func (reponsitory CompanyRepository) Edit(m *domain.Company) error {
77 DeleteAt: m.DeleteAt, 79 DeleteAt: m.DeleteAt,
78 UpdateAt: m.UpdateAt, 80 UpdateAt: m.UpdateAt,
79 Abbreviation: m.Abbreviation, 81 Abbreviation: m.Abbreviation,
  82 + Applets: m.Applets,
80 } 83 }
81 _, err = tx.Model(&companyModel).WherePK().Update() 84 _, err = tx.Model(&companyModel).WherePK().Update()
82 return err 85 return err
@@ -42,6 +42,8 @@ func (reponsitory OrderBaseRepository) transformPgModelToDomainModel(orderModel @@ -42,6 +42,8 @@ func (reponsitory OrderBaseRepository) transformPgModelToDomainModel(orderModel
42 }, 42 },
43 BonusStatus: orderModel.BonusStatus, 43 BonusStatus: orderModel.BonusStatus,
44 CompanyId: orderModel.CompanyId, 44 CompanyId: orderModel.CompanyId,
  45 + DataFrom: orderModel.DataFrom,
  46 + Remark: orderModel.Remark,
45 } 47 }
46 return order, nil 48 return order, nil
47 } 49 }
@@ -62,7 +64,8 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error { @@ -62,7 +64,8 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error {
62 PartnerBonusHas: orderInfo.OrderCompute.PartnerBonusHas, PartnerBonusNot: orderInfo.OrderCompute.PartnerBonusNot, 64 PartnerBonusHas: orderInfo.OrderCompute.PartnerBonusHas, PartnerBonusNot: orderInfo.OrderCompute.PartnerBonusNot,
63 PartnerBonusExpense: orderInfo.OrderCompute.PartnerBonusExpense, IsDisable: orderInfo.IsDisable, 65 PartnerBonusExpense: orderInfo.OrderCompute.PartnerBonusExpense, IsDisable: orderInfo.IsDisable,
64 CreateTime: orderInfo.CreateTime, BonusStatus: orderInfo.BonusStatus, 66 CreateTime: orderInfo.CreateTime, BonusStatus: orderInfo.BonusStatus,
65 - CompanyId: orderInfo.CompanyId, 67 + CompanyId: orderInfo.CompanyId, DataFrom: orderInfo.DataFrom,
  68 + Remark: orderInfo.Remark,
66 } 69 }
67 if m.Id == 0 { 70 if m.Id == 0 {
68 _, err = tx.Model(m). 71 _, err = tx.Model(m).
@@ -82,7 +85,7 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error { @@ -82,7 +85,7 @@ func (repository OrderBaseRepository) Save(orderInfo *domain.OrderBase) error {
82 } 85 }
83 86
84 func (repository OrderBaseRepository) Find(queryOption domain.OrderBaseFindQuery) ([]domain.OrderBase, int, error) { 87 func (repository OrderBaseRepository) Find(queryOption domain.OrderBaseFindQuery) ([]domain.OrderBase, int, error) {
85 - db := repository.transactionContext.PgDd 88 + db := repository.transactionContext.GetDB()
86 orderModels := []models.OrderBase{} 89 orderModels := []models.OrderBase{}
87 query := db.Model(&orderModels) 90 query := db.Model(&orderModels)
88 if queryOption.PartnerId > 0 { 91 if queryOption.PartnerId > 0 {
  1 +package repository
  2 +
  3 +import (
  4 + "fmt"
  5 + "time"
  6 +
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
  9 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  10 +)
  11 +
  12 +type OrderBestshopRepository struct {
  13 + transactionContext *transaction.TransactionContext
  14 +}
  15 +
  16 +var (
  17 + _ domain.OrderBestshopRepository = (*OrderBestshopRepository)(nil)
  18 +)
  19 +
  20 +func NewOrderBestshopRepository(transactionContext *transaction.TransactionContext) (*OrderBestshopRepository, error) {
  21 + if transactionContext == nil {
  22 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  23 + }
  24 + return &OrderBestshopRepository{transactionContext: transactionContext}, nil
  25 +}
  26 +
  27 +func (respository OrderBestshopRepository) transformPgModelToDomainModel(orderModel *models.OrderBestshop) (order domain.OrderBestShop, err error) {
  28 + return domain.OrderBestShop{
  29 + Id: orderModel.Id,
  30 + OrderCode: orderModel.OrderCode,
  31 + OrderTime: orderModel.OrderTime,
  32 + OrderState: orderModel.OrderState,
  33 + DeliveryState: orderModel.DeliveryState,
  34 + BuyerName: orderModel.BuyerName,
  35 + BuyerPhone: orderModel.BuyerPhone,
  36 + BuyerAddress: orderModel.BuyerAddress,
  37 + BuyerRemark: orderModel.BuyerRemark,
  38 + BuyerId: orderModel.BuyerId,
  39 + OrderCount: orderModel.OrderCount,
  40 + OrderAmount: orderModel.OrderAmount,
  41 + DeliveryTime: orderModel.DeliveryTime,
  42 + CreateTime: orderModel.CreateTime,
  43 + PartnerId: orderModel.PartnerId,
  44 + IsCopy: orderModel.IsCopy,
  45 + CompanyId: orderModel.CompanyId,
  46 + }, nil
  47 +}
  48 +
  49 +func (respository OrderBestshopRepository) Add(order *domain.OrderBestShop) error {
  50 + tx := respository.transactionContext.GetDB()
  51 + m := models.OrderBestshop{
  52 + OrderCode: order.OrderCode,
  53 + OrderTime: order.OrderTime,
  54 + OrderState: order.OrderState,
  55 + DeliveryState: order.DeliveryState,
  56 + BuyerName: order.BuyerName,
  57 + BuyerPhone: order.BuyerPhone,
  58 + BuyerAddress: order.BuyerAddress,
  59 + BuyerRemark: order.BuyerRemark,
  60 + BuyerId: order.BuyerId,
  61 + OrderCount: order.OrderCount,
  62 + OrderAmount: order.OrderAmount,
  63 + DeliveryTime: order.DeliveryTime,
  64 + CreateTime: time.Now(),
  65 + PartnerId: order.PartnerId,
  66 + IsCopy: order.IsCopy,
  67 + CompanyId: order.CompanyId,
  68 + }
  69 + _, err := tx.Model(&m).Insert()
  70 + order.Id = m.Id
  71 + return err
  72 +}
  73 +
  74 +func (respository OrderBestshopRepository) Edit(order *domain.OrderBestShop) error {
  75 + tx := respository.transactionContext.GetDB()
  76 + m := models.OrderBestshop{
  77 + Id: order.Id,
  78 + OrderCode: order.OrderCode,
  79 + OrderTime: order.OrderTime,
  80 + OrderState: order.OrderState,
  81 + DeliveryState: order.DeliveryState,
  82 + BuyerName: order.BuyerName,
  83 + BuyerPhone: order.BuyerPhone,
  84 + BuyerAddress: order.BuyerAddress,
  85 + BuyerRemark: order.BuyerRemark,
  86 + BuyerId: order.BuyerId,
  87 + OrderCount: order.OrderCount,
  88 + OrderAmount: order.OrderAmount,
  89 + DeliveryTime: order.DeliveryTime,
  90 + CreateTime: order.CreateTime,
  91 + PartnerId: order.PartnerId,
  92 + IsCopy: order.IsCopy,
  93 + CompanyId: order.CompanyId,
  94 + }
  95 + _, err := tx.Model(&m).Where("id=?", order.Id).Update()
  96 + order.Id = m.Id
  97 + return err
  98 +}
  99 +
  100 +func (respository OrderBestshopRepository) FindOne(queryOption domain.OrderBestshopFindOneQuery) (*domain.OrderBestShop, error) {
  101 + tx := respository.transactionContext.GetDB()
  102 + m := models.OrderBestshop{}
  103 + err := tx.Model(&m).
  104 + Where("id=?", queryOption.OrderId).
  105 + First()
  106 + if err != nil {
  107 + return nil, err
  108 + }
  109 + var order domain.OrderBestShop
  110 + order, err = respository.transformPgModelToDomainModel(&m)
  111 + if err != nil {
  112 + return nil, fmt.Errorf("OrderBestshop domain 数据结构转换失败:%s", err)
  113 + }
  114 + return &order, nil
  115 +}
  1 +package repository
  2 +
  3 +import (
  4 + "fmt"
  5 +
  6 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  9 +)
  10 +
  11 +type OrderGoodBestshopRepository struct {
  12 + transactionContext *transaction.TransactionContext
  13 +}
  14 +
  15 +var (
  16 + _ domain.OrderGoodBestshopRepository = (*OrderGoodBestshopRepository)(nil)
  17 +)
  18 +
  19 +func NewOrderGoodBestshopRepository(transactionContext *transaction.TransactionContext) (*OrderGoodBestshopRepository, error) {
  20 + if transactionContext == nil {
  21 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  22 + }
  23 + return &OrderGoodBestshopRepository{transactionContext: transactionContext}, nil
  24 +}
  25 +
  26 +func (respository OrderGoodBestshopRepository) transformPgModelToDomainModel(orderGoodModel *models.OrderGoodBestshop) (orderGood domain.OrderGoodBestShop, err error) {
  27 + return domain.OrderGoodBestShop{
  28 + Id: orderGoodModel.Id,
  29 + OrderId: orderGoodModel.OrderId,
  30 + Sn: orderGoodModel.Sn,
  31 + Bn: orderGoodModel.Bn,
  32 + Name: orderGoodModel.Name,
  33 + Price: orderGoodModel.Price,
  34 + Nums: orderGoodModel.Nums,
  35 + Amount: orderGoodModel.Amount,
  36 + }, nil
  37 +}
  38 +
  39 +func (respository OrderGoodBestshopRepository) Add(good *domain.OrderGoodBestShop) error {
  40 + tx := respository.transactionContext.GetDB()
  41 + m := models.OrderGoodBestshop{
  42 + Id: good.Id,
  43 + OrderId: good.OrderId,
  44 + Sn: good.Sn,
  45 + Bn: good.Bn,
  46 + Name: good.Name,
  47 + Price: good.Price,
  48 + Nums: good.Nums,
  49 + Amount: good.Amount,
  50 + }
  51 + _, err := tx.Model(&m).Insert()
  52 + good.Id = m.Id
  53 + return err
  54 +}
  55 +
  56 +func (respository OrderGoodBestshopRepository) Edit(good *domain.OrderGoodBestShop) error {
  57 + tx := respository.transactionContext.GetDB()
  58 + m := models.OrderGoodBestshop{
  59 + Id: good.Id,
  60 + OrderId: good.OrderId,
  61 + Sn: good.Sn,
  62 + Bn: good.Bn,
  63 + Name: good.Name,
  64 + Price: good.Price,
  65 + Nums: good.Nums,
  66 + Amount: good.Amount,
  67 + }
  68 + _, err := tx.Model(&m).Update()
  69 + return err
  70 +}
  71 +
  72 +func (respository OrderGoodBestshopRepository) Find(queryOption domain.OrderGoodBestshopFindQuery) ([]domain.OrderGoodBestShop, error) {
  73 + tx := respository.transactionContext.GetDB()
  74 + goodModels := []models.OrderGoodBestshop{}
  75 + query := tx.Model(&goodModels)
  76 + if queryOption.OrderId > 0 {
  77 + query = query.Where("order_id=?", queryOption.OrderId)
  78 + }
  79 + query = query.Limit(1000)
  80 + err := query.Select()
  81 + if err != nil {
  82 + return nil, err
  83 + }
  84 + goods := []domain.OrderGoodBestShop{}
  85 + for i := range goodModels {
  86 + g, _ := respository.transformPgModelToDomainModel(&goodModels[i])
  87 + goods = append(goods, g)
  88 + }
  89 + return goods, nil
  90 +}
1 package repository 1 package repository
2 2
3 import ( 3 import (
  4 + "errors"
4 "fmt" 5 "fmt"
5 6
6 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain" 7 "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
@@ -38,7 +39,9 @@ func (reponsitory OrderGoodRepository) transformPgModelToDomainModel(orderModel @@ -38,7 +39,9 @@ func (reponsitory OrderGoodRepository) transformPgModelToDomainModel(orderModel
38 PartnerBonusNot: orderModel.PartnerBonusNot, 39 PartnerBonusNot: orderModel.PartnerBonusNot,
39 PartnerBonusExpense: orderModel.PartnerBonusExpense, 40 PartnerBonusExpense: orderModel.PartnerBonusExpense,
40 }, 41 },
41 - CompanyId: orderModel.CompanyId, 42 + CompanyId: orderModel.CompanyId,
  43 + RemarkReason: orderModel.RemarkReason,
  44 + DataFrom: orderModel.DataFrom,
42 } 45 }
43 switch orderModel.BonusStatus { 46 switch orderModel.BonusStatus {
44 case domain.OrderGoodWaitPay: 47 case domain.OrderGoodWaitPay:
@@ -63,8 +66,9 @@ func (repository OrderGoodRepository) Save(data []domain.OrderGood) error { @@ -63,8 +66,9 @@ func (repository OrderGoodRepository) Save(data []domain.OrderGood) error {
63 PlanPartnerBonus: v.GoodCompute.PlanPartnerBonus, UsePartnerBonus: v.GoodCompute.UsePartnerBonus, 66 PlanPartnerBonus: v.GoodCompute.PlanPartnerBonus, UsePartnerBonus: v.GoodCompute.UsePartnerBonus,
64 PartnerBonusHas: v.GoodCompute.PartnerBonusHas, PartnerBonusNot: v.GoodCompute.PartnerBonusNot, 67 PartnerBonusHas: v.GoodCompute.PartnerBonusHas, PartnerBonusNot: v.GoodCompute.PartnerBonusNot,
65 PartnerBonusExpense: v.GoodCompute.PartnerBonusExpense, BonusStatus: v.BonusStatus, 68 PartnerBonusExpense: v.GoodCompute.PartnerBonusExpense, BonusStatus: v.BonusStatus,
66 - Remark: v.Remark,  
67 - CompanyId: v.CompanyId, 69 + Remark: v.Remark, CompanyId: v.CompanyId,
  70 + RemarkReason: v.RemarkReason,
  71 + DataFrom: v.DataFrom,
68 } 72 }
69 if v.Id == 0 { 73 if v.Id == 0 {
70 _, err = tx.Model(m). 74 _, err = tx.Model(m).
@@ -138,3 +142,27 @@ func (repository OrderGoodRepository) Remove(orderId int64, companyId int64, goo @@ -138,3 +142,27 @@ func (repository OrderGoodRepository) Remove(orderId int64, companyId int64, goo
138 _, err = query.Delete() 142 _, err = query.Delete()
139 return err 143 return err
140 } 144 }
  145 +
  146 +func (repository OrderGoodRepository) FindOne(queryOption domain.OrderGoodFindOneQuery) (domain.OrderGood, error) {
  147 + var (
  148 + good domain.OrderGood
  149 + goodModel models.OrderGood
  150 + err error
  151 + hasCondition bool
  152 + )
  153 + tx := repository.transactionContext.GetDB()
  154 + query := tx.Model(&goodModel)
  155 + if queryOption.GoodId > 0 {
  156 + query = query.Where("id=?", queryOption.GoodId)
  157 + hasCondition = true
  158 + }
  159 + if !hasCondition {
  160 + return good, errors.New("OrderGoodRepository.FindOne 必须使用查询条件")
  161 + }
  162 + err = query.First()
  163 + if err != nil {
  164 + return good, fmt.Errorf("获取订单的货品数据失败,%s", err)
  165 + }
  166 + good, err = repository.transformPgModelToDomainModel(&goodModel)
  167 + return good, err
  168 +}
  1 +package repository
  2 +
  3 +import (
  4 + "fmt"
  5 +
  6 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/models"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/infrastructure/pg/transaction"
  9 +)
  10 +
  11 +//订单日志
  12 +type OrderLogRepository struct {
  13 + transactionContext *transaction.TransactionContext
  14 +}
  15 +
  16 +var _ domain.OrderLogRepository = (*OrderLogRepository)(nil)
  17 +
  18 +func NewOrderLogRepository(transactionContext *transaction.TransactionContext) (*OrderLogRepository, error) {
  19 + if transactionContext == nil {
  20 + return nil, fmt.Errorf("transactionContext参数不能为nil")
  21 + }
  22 + return &OrderLogRepository{transactionContext: transactionContext}, nil
  23 +}
  24 +
  25 +func (repository OrderLogRepository) transformPgModelToDomainModel(m *models.OrderLog) (data domain.OrderLog, err error) {
  26 + return domain.OrderLog{
  27 + Id: m.Id,
  28 + OrderId: m.OrderId,
  29 + Operator: m.Operator,
  30 + OperatorId: m.OperatorId,
  31 + OperatorType: m.OperatorType,
  32 + AlterTime: m.AlterTime,
  33 + LogAction: m.LogAction,
  34 + Descript: m.Descript,
  35 + DataFrom: m.DataFrom,
  36 + }, nil
  37 +}
  38 +
  39 +func (repository OrderLogRepository) Add(data *domain.OrderLog) error {
  40 + db := repository.transactionContext.GetDB()
  41 + m := models.OrderLog{
  42 + OrderId: data.OrderId,
  43 + Operator: data.Operator,
  44 + OperatorId: data.OperatorId,
  45 + OperatorType: data.OperatorType,
  46 + LogAction: data.LogAction,
  47 + Descript: data.Descript,
  48 + DataFrom: data.DataFrom,
  49 + }
  50 + _, err := db.Model(&m).Insert()
  51 + data.AlterTime = m.AlterTime
  52 + return err
  53 +}
  54 +
  55 +func (repository OrderLogRepository) Find(queryOptions domain.OrderLogFindQuery) ([]domain.OrderLog, error) {
  56 + db := repository.transactionContext.GetDB()
  57 + logModels := []models.OrderLog{}
  58 + var err error
  59 + query := db.Model(&logModels)
  60 + if queryOptions.OrderId > 0 {
  61 + query = query.Where("order_id=?", queryOptions.OrderId)
  62 + }
  63 + query = query.Order("order_log.id")
  64 + query = query.Limit(1000)
  65 + err = query.Select()
  66 + if err != nil {
  67 + return nil, err
  68 + }
  69 + logReturn := []domain.OrderLog{}
  70 + for i := range logModels {
  71 + domainLog, err := repository.transformPgModelToDomainModel(&logModels[i])
  72 + if err != nil {
  73 + return logReturn, err
  74 + }
  75 + logReturn = append(logReturn, domainLog)
  76 + }
  77 + return logReturn, nil
  78 +}
@@ -141,7 +141,7 @@ func (reponsitory UsersRepository) FindOne(queryOptions domain.UsersFindOneQuery @@ -141,7 +141,7 @@ func (reponsitory UsersRepository) FindOne(queryOptions domain.UsersFindOneQuery
141 query = query.Where("open_id=?", queryOptions.OpenId) 141 query = query.Where("open_id=?", queryOptions.OpenId)
142 } 142 }
143 if !hasCondition { 143 if !hasCondition {
144 - return domain.Users{}, errors.New("FindOne 必须要有查询条件") 144 + return domain.Users{}, errors.New("UsersRepository.FindOne 必须要有查询条件")
145 } 145 }
146 err = query.First() 146 err = query.First()
147 if err != nil { 147 if err != nil {
@@ -5,6 +5,7 @@ import ( @@ -5,6 +5,7 @@ import (
5 categoryService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerCategory/service" 5 categoryService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerCategory/service"
6 partnerQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/query" 6 partnerQuery "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/query"
7 partnerInfoService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/service" 7 partnerInfoService "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/partnerInfo/service"
  8 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/domain"
8 ) 9 )
9 10
10 type CommonController struct { 11 type CommonController struct {
@@ -64,3 +65,18 @@ func (c *CommonController) GetPartnerCategory() { @@ -64,3 +65,18 @@ func (c *CommonController) GetPartnerCategory() {
64 } 65 }
65 c.ResponseData(resp) 66 c.ResponseData(resp)
66 } 67 }
  68 +
  69 +// GetOrderType 下拉选项数据通用接口,获取订单类型列表
  70 +func (c *CommonController) GetOrderType() {
  71 + resp := []map[string]interface{}{
  72 + map[string]interface{}{
  73 + "id": domain.OrderReal,
  74 + "name": domain.GetOrderBaseTypeName(domain.OrderReal),
  75 + },
  76 + map[string]interface{}{
  77 + "id": domain.OrderTypeBestShop,
  78 + "name": domain.GetOrderBaseTypeName(domain.OrderTypeBestShop),
  79 + },
  80 + }
  81 + c.ResponseData(resp)
  82 +}
@@ -31,8 +31,8 @@ func (c *OrderDividendController) Prepare() { @@ -31,8 +31,8 @@ func (c *OrderDividendController) Prepare() {
31 //PageListOrderDividend 获取实发订单分红列表 31 //PageListOrderDividend 获取实发订单分红列表
32 func (c *OrderDividendController) PageListOrderDividend() { 32 func (c *OrderDividendController) PageListOrderDividend() {
33 type Parameter struct { 33 type Parameter struct {
34 - SearchText string `json:"searchText"`  
35 - Partner int64 `json:"partner"` 34 + SearchWord string `json:"searchWord"`
  35 + OrderType int `json:"orderType"`
36 PageSize int `json:"pageSize"` 36 PageSize int `json:"pageSize"`
37 PageNumber int `json:"pageNumber"` 37 PageNumber int `json:"pageNumber"`
38 } 38 }
@@ -45,6 +45,12 @@ func (c *OrderDividendController) PageListOrderDividend() { @@ -45,6 +45,12 @@ func (c *OrderDividendController) PageListOrderDividend() {
45 c.ResponseError(errors.New("json数据解析失败")) 45 c.ResponseError(errors.New("json数据解析失败"))
46 return 46 return
47 } 47 }
  48 + if !(param.OrderType == 0 ||
  49 + param.OrderType == domain.OrderReal ||
  50 + param.OrderType == domain.OrderTypeBestShop) {
  51 + c.ResponseError(errors.New("参数异常"))
  52 + return
  53 + }
48 if param.PageNumber == 0 { 54 if param.PageNumber == 0 {
49 param.PageNumber = 1 55 param.PageNumber = 1
50 } 56 }
@@ -53,38 +59,18 @@ func (c *OrderDividendController) PageListOrderDividend() { @@ -53,38 +59,18 @@ func (c *OrderDividendController) PageListOrderDividend() {
53 } 59 }
54 companyId := c.GetUserCompany() 60 companyId := c.GetUserCompany()
55 orderSrv := orderService.NewOrderInfoService(nil) 61 orderSrv := orderService.NewOrderInfoService(nil)
56 - orderinfos, cnt, err := orderSrv.PageListOrderBase(orderQuery.ListOrderBaseQuery{  
57 - PartnerId: param.Partner,  
58 - DeliveryCode: param.SearchText,  
59 - OrderType: domain.OrderReal,  
60 - Limit: param.PageSize,  
61 - Offset: (param.PageNumber - 1) * param.PageSize,  
62 - CompanyId: companyId, 62 + resp, cnt, err := orderSrv.PageListOrderBonus(orderQuery.ListOrderBonusQuery{
  63 + OrderType: param.OrderType,
  64 + PartnerOrCode: param.SearchWord,
  65 + Limit: param.PageSize,
  66 + Offset: (param.PageNumber - 1) * param.PageSize,
  67 + CompanyId: companyId,
63 }) 68 })
64 if err != nil { 69 if err != nil {
65 c.ResponseError(err) 70 c.ResponseError(err)
66 return 71 return
67 } 72 }
68 - rsp := []map[string]interface{}{}  
69 - for i := range orderinfos {  
70 - orderinfo := orderinfos[i]  
71 - m := map[string]interface{}{  
72 - "updateTime": orderinfo.UpdateTime.Local().Format("2006-01-02 15:04:05"),  
73 - "id": orderinfo.Id,  
74 - "shipmentsId": orderinfo.DeliveryCode,  
75 - "partner": orderinfo.PartnerInfo.PartnerName,  
76 - "dividendsReceivable": orderinfo.OrderCompute.PlanPartnerBonus,  
77 - "dividendSpending": orderinfo.OrderCompute.PartnerBonusExpense,  
78 - "receiveDividends": orderinfo.OrderCompute.PartnerBonusHas,  
79 - "uncollectedDividends": orderinfo.OrderCompute.PartnerBonusNot,  
80 - "stateOfPayment": orderinfo.BonusStatus,  
81 - }  
82 - if orderinfo.OrderCompute.UsePartnerBonus >= 0 {  
83 - m["dividendsReceivable"] = orderinfo.OrderCompute.UsePartnerBonus  
84 - }  
85 - rsp = append(rsp, m)  
86 - }  
87 - c.ResponsePageList(rsp, cnt, param.PageNumber) 73 + c.ResponsePageList(resp, cnt, param.PageNumber)
88 return 74 return
89 } 75 }
90 76
@@ -269,3 +255,147 @@ func (c *OrderDividendController) EditOrderDividend() { @@ -269,3 +255,147 @@ func (c *OrderDividendController) EditOrderDividend() {
269 c.ResponseData(nil) 255 c.ResponseData(nil)
270 return 256 return
271 } 257 }
  258 +
  259 +//OrderDividendDetailForBestshop 海鲜干货的订单分红详情
  260 +func (c *OrderDividendController) OrderDividendDetailForBestshop() {
  261 + type Parameter struct {
  262 + Id string `json:"id"`
  263 + }
  264 + var (
  265 + param Parameter
  266 + err error
  267 + )
  268 + if err = c.BindJsonData(&param); err != nil {
  269 + logs.Error(err)
  270 + c.ResponseError(errors.New("json数据解析失败"))
  271 + return
  272 + }
  273 + orderid, _ := strconv.ParseInt(param.Id, 10, 64)
  274 + if orderid == 0 {
  275 + c.ResponseError(errors.New("参数错误"))
  276 + return
  277 + }
  278 + companyId := c.GetUserCompany()
  279 + orderSrv := orderService.NewOrderInfoService(nil)
  280 + respData, err := orderSrv.GetOrderBestshopInfoWithBonus(orderid, companyId)
  281 + if err != nil {
  282 + c.ResponseError(err)
  283 + return
  284 + }
  285 + c.ResponseData(respData)
  286 + return
  287 +}
  288 +
  289 +//EditOrderForBestshop 编辑海鲜干货的订单 中的 货品数量和分红比例
  290 +func (c *OrderDividendController) EditOrderDividendForBestshop() {
  291 + type Parameter struct {
  292 + State int `json:"state"`
  293 + OrderId string `json:"orderId"`
  294 + ProductId string `json:"productId"`
  295 + Reason string `json:"reason"`
  296 + GoodNumber int `json:"goodNumber"`
  297 + PartnerBonusPercent float64 `json:"partnerBonusPercent"`
  298 + }
  299 + var (
  300 + param Parameter
  301 + err error
  302 + )
  303 + if err = c.BindJsonData(&param); err != nil {
  304 + logs.Error(err)
  305 + c.ResponseError(errors.New("json数据解析失败"))
  306 + return
  307 + }
  308 + orderid, _ := strconv.ParseInt(param.OrderId, 10, 64)
  309 + if orderid == 0 {
  310 + c.ResponseError(errors.New("参数错误"))
  311 + return
  312 + }
  313 + productId, _ := strconv.ParseInt(param.ProductId, 10, 64)
  314 + if productId == 0 {
  315 + c.ResponseError(errors.New("参数错误"))
  316 + return
  317 + }
  318 + adminId := c.GetUserId()
  319 + orderSrv := orderService.NewOrderInfoService(nil)
  320 +
  321 + switch param.State {
  322 + case 1:
  323 + err = orderSrv.UpdateBonusByGoodNumber(orderid, productId, adminId, param.GoodNumber, param.Reason)
  324 + case 2:
  325 + err = orderSrv.UpdateBonusByPartnerBonusPercent(orderid, productId, adminId, param.PartnerBonusPercent, param.Reason)
  326 + }
  327 + if err != nil {
  328 + c.ResponseError(err)
  329 + return
  330 + }
  331 + c.ResponseData(nil)
  332 + return
  333 +}
  334 +
  335 +//PayOrderGoodBonusForBestshop 支付海鲜干货订单中的分红
  336 +func (c *OrderDividendController) PayOrderGoodBonusForBestshop() {
  337 + type Parameter struct {
  338 + OrderId string `json:"orderId"`
  339 + ProductId string `json:"productId"`
  340 + }
  341 + var (
  342 + param Parameter
  343 + err error
  344 + )
  345 + if err = c.BindJsonData(&param); err != nil {
  346 + logs.Error(err)
  347 + c.ResponseError(errors.New("json数据解析失败"))
  348 + return
  349 + }
  350 + orderid, _ := strconv.ParseInt(param.OrderId, 10, 64)
  351 + if orderid == 0 {
  352 + c.ResponseError(errors.New("参数错误"))
  353 + return
  354 + }
  355 + productId, _ := strconv.ParseInt(param.ProductId, 10, 64)
  356 + if productId == 0 {
  357 + c.ResponseError(errors.New("参数错误"))
  358 + return
  359 + }
  360 + adminId := c.GetUserId()
  361 + orderSrv := orderService.NewOrderInfoService(nil)
  362 + err = orderSrv.PayPartnerBonusWithOrderBestshop(orderid, productId, adminId)
  363 + if err != nil {
  364 + c.ResponseError(err)
  365 + return
  366 + }
  367 + c.ResponseData(nil)
  368 + return
  369 +}
  370 +
  371 +//EditOrderRemarkBonusForBestshop 编辑海鲜干货订单中的备注
  372 +func (c *OrderDividendController) EditOrderRemarkBonusForBestshop() {
  373 + type Parameter struct {
  374 + OrderId string `json:"orderId"`
  375 + Remark string `json:"remark"`
  376 + }
  377 + var (
  378 + param Parameter
  379 + err error
  380 + )
  381 + if err = c.BindJsonData(&param); err != nil {
  382 + logs.Error(err)
  383 + c.ResponseError(errors.New("json数据解析失败"))
  384 + return
  385 + }
  386 + orderid, _ := strconv.ParseInt(param.OrderId, 10, 64)
  387 + if orderid == 0 {
  388 + c.ResponseError(errors.New("参数错误"))
  389 + return
  390 + }
  391 +
  392 + adminId := c.GetUserId()
  393 + orderSrv := orderService.NewOrderInfoService(nil)
  394 + err = orderSrv.UpdateOrderRemarkBonus(orderid, adminId, param.Remark)
  395 + if err != nil {
  396 + c.ResponseError(err)
  397 + return
  398 + }
  399 + c.ResponseData(nil)
  400 + return
  401 +}
@@ -68,13 +68,15 @@ func (c *PartnerInfoController) CreatePartnerInfo() { @@ -68,13 +68,15 @@ func (c *PartnerInfoController) CreatePartnerInfo() {
68 Status: param.State, 68 Status: param.State,
69 PartnerCategory: param.PartnerType, 69 PartnerCategory: param.PartnerType,
70 CooperateTime: cooperateTime, 70 CooperateTime: cooperateTime,
71 - Salesman: []domain.Salesman{ 71 + CompanyId: companyId,
  72 + }
  73 + if len(param.SalesmanName) > 0 || len(param.Phone) > 0 {
  74 + cmd.Salesman = []domain.Salesman{
72 domain.Salesman{ 75 domain.Salesman{
73 Name: param.SalesmanName, 76 Name: param.SalesmanName,
74 Telephone: param.Phone, 77 Telephone: param.Phone,
75 }, 78 },
76 - },  
77 - CompanyId: companyId, 79 + }
78 } 80 }
79 if len(param.Area) > 0 { 81 if len(param.Area) > 0 {
80 cmd.RegionInfo = &domain.RegionInfo{ 82 cmd.RegionInfo = &domain.RegionInfo{
@@ -29,6 +29,10 @@ func init() { @@ -29,6 +29,10 @@ func init() {
29 beego.NSRouter("/list", &controllers.OrderDividendController{}, "POST:PageListOrderDividend"), 29 beego.NSRouter("/list", &controllers.OrderDividendController{}, "POST:PageListOrderDividend"),
30 beego.NSRouter("/edit", &controllers.OrderDividendController{}, "POST:EditOrderDividend"), 30 beego.NSRouter("/edit", &controllers.OrderDividendController{}, "POST:EditOrderDividend"),
31 beego.NSRouter("/detail", &controllers.OrderDividendController{}, "POST:OrderDividendDetail"), 31 beego.NSRouter("/detail", &controllers.OrderDividendController{}, "POST:OrderDividendDetail"),
  32 + beego.NSRouter("/mini-program/detail", &controllers.OrderDividendController{}, "POST:OrderDividendDetailForBestshop"),
  33 + beego.NSRouter("/mini-program/modify", &controllers.OrderDividendController{}, "POST:EditOrderDividendForBestshop"),
  34 + beego.NSRouter("/mini-program/payDividends", &controllers.OrderDividendController{}, "POST:PayOrderGoodBonusForBestshop"),
  35 + beego.NSRouter("/mini-program/remarks", &controllers.OrderDividendController{}, "POST:EditOrderRemarkBonusForBestshop"),
32 36
33 beego.NSRouter("/business/detail", &controllers.BusinessBonusController{}, "POST:GetBusinessBonus"), 37 beego.NSRouter("/business/detail", &controllers.BusinessBonusController{}, "POST:GetBusinessBonus"),
34 beego.NSRouter("/business/edit", &controllers.BusinessBonusController{}, "POST:UpdateBusinessBonus"), 38 beego.NSRouter("/business/edit", &controllers.BusinessBonusController{}, "POST:UpdateBusinessBonus"),
@@ -50,6 +54,7 @@ func init() { @@ -50,6 +54,7 @@ func init() {
50 beego.NSNamespace("/common", 54 beego.NSNamespace("/common",
51 beego.NSRouter("/partner", &controllers.CommonController{}, "POST:GetPartnerList"), 55 beego.NSRouter("/partner", &controllers.CommonController{}, "POST:GetPartnerList"),
52 beego.NSRouter("/partnerType", &controllers.CommonController{}, "POST:GetPartnerCategory"), 56 beego.NSRouter("/partnerType", &controllers.CommonController{}, "POST:GetPartnerCategory"),
  57 + beego.NSRouter("/orderType", &controllers.CommonController{}, "POST:GetOrderType"),
53 ), 58 ),
54 59
55 beego.NSNamespace("/enterprises", 60 beego.NSNamespace("/enterprises",
  1 +package configs
  2 +
  3 +import (
  4 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/constant"
  5 +)
  6 +
  7 +type MqConfig struct {
  8 + Servers []string `json:"servers"`
  9 + ConsumerId string `json:"consumerGroup"`
  10 +}
  11 +
  12 +var Cfg = MqConfig{
  13 + Servers: constant.KafkaCfg.Servers,
  14 + ConsumerId: constant.KafkaCfg.ConsumerId,
  15 +}
  16 +
  17 +// "192.168.190.136:9092",
  18 +// "106.52.15.41:9092"
  1 +package consumer
  2 +
  3 +import (
  4 + "context"
  5 + "errors"
  6 + "fmt"
  7 + "time"
  8 +
  9 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/consumer/configs"
  10 +
  11 + "github.com/Shopify/sarama"
  12 + "github.com/astaxie/beego/logs"
  13 + cluster "github.com/bsm/sarama-cluster"
  14 +)
  15 +
  16 +//MessageConsumer 消息消费者
  17 +type MessageConsumer struct {
  18 + ready chan struct{}
  19 + kafkaHosts []string
  20 + groupId string
  21 + topics []string
  22 + topicsHandles map[string]TopicHandle
  23 + // beforeHandles []TopicHandle
  24 + // afterHandles []TopicHandle
  25 +}
  26 +
  27 +//实现对应的接口
  28 +var _ sarama.ConsumerGroupHandler = (*MessageConsumer)(nil)
  29 +
  30 +func (c *MessageConsumer) Setup(groupSession sarama.ConsumerGroupSession) error {
  31 + close(c.ready)
  32 + return nil
  33 +}
  34 +
  35 +func (c *MessageConsumer) Cleanup(groupSession sarama.ConsumerGroupSession) error {
  36 + return nil
  37 +}
  38 +
  39 +func (c *MessageConsumer) ConsumeClaim(groupSession sarama.ConsumerGroupSession,
  40 + groupClaim sarama.ConsumerGroupClaim) error {
  41 + var (
  42 + topicHandle TopicHandle
  43 + err error
  44 + )
  45 + for message := range groupClaim.Messages() {
  46 + logs.Debug("Done Message claimed: timestamp = %v, topic = %s offset = %v value = %v \n",
  47 + message.Timestamp, message.Topic, message.Offset, string(message.Value))
  48 + if topicHandle, err = c.FindTopichandle(groupClaim.Topic()); err != nil {
  49 + logs.Error("FindTopichandle err:%s \n", err)
  50 + continue
  51 + }
  52 + if err = topicHandle(message); err != nil {
  53 + logs.Error("Message claimed: kafka消息处理错误 topic =", message.Topic, message.Offset, err)
  54 + }
  55 + groupSession.MarkMessage(message, "")
  56 + }
  57 + return nil
  58 +}
  59 +
  60 +func (c *MessageConsumer) FindTopichandle(topic string) (TopicHandle, error) {
  61 + if v, ok := c.topicsHandles[topic]; ok {
  62 + return v, nil
  63 + }
  64 + return nil, errors.New("TopicHandle not found")
  65 +}
  66 +
  67 +type Runer struct {
  68 + msgConsumer *MessageConsumer
  69 + consumerGroup sarama.ConsumerGroup
  70 + Consumer *cluster.Consumer
  71 +}
  72 +
  73 +func NewRuner() *Runer {
  74 + topics := []string{}
  75 + for key := range TopicHandleRouters {
  76 + topics = append(topics, key)
  77 + }
  78 + r := &Runer{
  79 + msgConsumer: &MessageConsumer{
  80 + ready: make(chan struct{}),
  81 + kafkaHosts: configs.Cfg.Servers,
  82 + groupId: configs.Cfg.ConsumerId,
  83 + topicsHandles: TopicHandleRouters,
  84 + topics: topics,
  85 + },
  86 + }
  87 + logs.Debug("kafka_host=%v; topic=%v;groupid=%s ", r.msgConsumer.kafkaHosts,
  88 + r.msgConsumer.topics, r.msgConsumer.groupId)
  89 + return r
  90 +}
  91 +
  92 +func (r *Runer) InitConsumer() error {
  93 + config := sarama.NewConfig()
  94 + //config.Consumer.Group.Rebalance.Strategy = sarama.BalanceStrategyRoundRobin
  95 + config.Consumer.Offsets.Initial = sarama.OffsetNewest
  96 + config.Version = sarama.V0_10_2_1
  97 + if err := config.Validate(); err != nil {
  98 + msg := fmt.Sprintf("Kafka producer config invalidate. config: %v. err: %v", configs.Cfg, err)
  99 + logs.Error(msg)
  100 + panic(msg)
  101 + }
  102 +
  103 + consumerGroup, err := sarama.NewConsumerGroup(r.msgConsumer.kafkaHosts, r.msgConsumer.groupId, config)
  104 + if err != nil {
  105 + return err
  106 + }
  107 + r.consumerGroup = consumerGroup
  108 + return nil
  109 +}
  110 +
  111 +// func (r *Runer) InitConsumer() error {
  112 +// clusterCfg := cluster.NewConfig()
  113 +// clusterCfg.Consumer.Return.Errors = true
  114 +// clusterCfg.Consumer.Offsets.Initial = sarama.OffsetOldest
  115 +// clusterCfg.Group.Return.Notifications = true
  116 +// clusterCfg.Version = sarama.V0_10_2_1
  117 +// // khosts := []string{"192.168.0.252:9092", "192.168.0.251:9092", "192.168.0.250:9092"}
  118 +// // groupid := "partnermg_dev"
  119 +// // topic := []string{"topic_test"}
  120 +// logs.Debug(r.msgConsumer.kafkaHosts, r.msgConsumer.groupId, r.msgConsumer.topics)
  121 +// consumer, err := cluster.NewConsumer(r.msgConsumer.kafkaHosts, r.msgConsumer.groupId, r.msgConsumer.topics, clusterCfg)
  122 +// // consumer, err := cluster.NewConsumer(khosts, groupid, topic, clusterCfg)
  123 +// if err != nil {
  124 +// msg := fmt.Sprintf("Create kafka consumer error: %v. config: %v", err, clusterCfg)
  125 +// logs.Error(msg)
  126 +// panic(msg)
  127 +// }
  128 +// r.Consumer = consumer
  129 +// return nil
  130 +// }
  131 +
  132 +func (r *Runer) Start(ctx context.Context) {
  133 + defer func() {
  134 + if e := recover(); e != nil {
  135 + logs.Error(e)
  136 + }
  137 + }()
  138 + if len(r.msgConsumer.topics) == 0 {
  139 + logs.Error("there has no topics")
  140 + return
  141 + }
  142 + for {
  143 + select {
  144 + case <-ctx.Done():
  145 + logs.Warning("ctx cancel;consumerGroup.Close()")
  146 + r.consumerGroup.Close()
  147 + return
  148 + default:
  149 + if err := r.consumerGroup.Consume(ctx, r.msgConsumer.topics, r.msgConsumer); err != nil {
  150 + logs.Error("consumerGroup err:%s \n", err)
  151 + //等待重试
  152 + timer := time.NewTimer(5 * time.Second)
  153 + <-timer.C
  154 + }
  155 + r.msgConsumer.ready = make(chan struct{})
  156 + }
  157 +
  158 + }
  159 +}
  160 +
  161 +// func (r *Runer) Start(ctx context.Context) {
  162 +// for {
  163 +// select {
  164 +// case msg, more := <-r.Consumer.Messages():
  165 +// if more {
  166 +// logs.Info("Partition:%d, Offset:%d, Key:%s, Value:%s Timestamp:%s\n", msg.Partition, msg.Offset, string(msg.Key), string(msg.Value), msg.Timestamp)
  167 +// r.Consumer.MarkOffset(msg, "") // mark message as processed
  168 +// }
  169 +// case err, more := <-r.Consumer.Errors():
  170 +// if more {
  171 +// logs.Info("Kafka consumer error: %v", err.Error())
  172 +// }
  173 +// case ntf, more := <-r.Consumer.Notifications():
  174 +// if more {
  175 +// logs.Info("Kafka consumer rebalance: %v", ntf)
  176 +// }
  177 +// case <-ctx.Done():
  178 +// logs.Info("Stop consumer server...")
  179 +// r.Consumer.Close()
  180 +// return
  181 +// }
  182 +// }
  183 +// }
  184 +
  185 +func (r *Runer) IsReady() <-chan struct{} {
  186 + return r.msgConsumer.ready
  187 +}
  1 +package handles
  2 +
  3 +import "encoding/json"
  4 +
  5 +type DataFromMessage struct {
  6 + Module string `json:"module"`
  7 + Action string `json:"action"`
  8 + Data json.RawMessage `json:"data"`
  9 +}
  1 +package handles
  2 +
  3 +import (
  4 + "encoding/json"
  5 + "fmt"
  6 +
  7 + "github.com/Shopify/sarama"
  8 + "github.com/astaxie/beego/logs"
  9 + syncOrderCmd "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/syncOrder/command"
  10 + syncOrderSrv "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/application/syncOrder/service"
  11 +)
  12 +
  13 +func DataFromXiangMi(message *sarama.ConsumerMessage) error {
  14 + logs.Info("Done Message claimed: timestamp = %v, topic = %s offset = %v value = %v \n",
  15 + message.Timestamp, message.Topic, message.Offset, string(message.Value))
  16 + var (
  17 + msgData DataFromMessage
  18 + err error
  19 + )
  20 + err = json.Unmarshal(message.Value, &msgData)
  21 + if err != nil {
  22 + return fmt.Errorf("[Consumer][SyncBestshopOrder] 解析kafka数据失败;%s", err)
  23 + }
  24 + dataAction := msgData.Module + "/" + msgData.Action
  25 + switch dataAction {
  26 + case "xiangmi.order/ship":
  27 + err = syncBestshopOrder(msgData.Data)
  28 + if err != nil {
  29 + e := fmt.Errorf("[Consumer][SyncBestshopOrder] %s", err)
  30 + return e
  31 + }
  32 + default:
  33 + logs.Error("未找到执行动作:Module=%s,Action=%s", msgData.Module, msgData.Action)
  34 + }
  35 + return nil
  36 +}
  37 +
  38 +//SyncBestshopOrder 同步
  39 +func syncBestshopOrder(data []byte) error {
  40 + var (
  41 + cmd syncOrderCmd.CreateOrderFromBestshop
  42 + err error
  43 + )
  44 + err = json.Unmarshal(data, &cmd)
  45 + if err != nil {
  46 + return fmt.Errorf("[Consumer][syncBestshopOrder] 解析kafka数据失败;%s", err)
  47 + }
  48 + if cmd.PartnerId <= 0 {
  49 + logs.Info("[Consumer][syncBestshopOrder] PartnerId<=0 ,不处理消息")
  50 + return nil
  51 + }
  52 + srv := syncOrderSrv.NewOrderInfoService(nil)
  53 + err = srv.SyncOrderFromBestshop(cmd)
  54 + if err != nil {
  55 + e := fmt.Errorf("[Consumer][syncBestshopOrder] %s", err)
  56 + return e
  57 + }
  58 + return err
  59 +}
  1 +package consumer
  2 +
  3 +import (
  4 + "os"
  5 +
  6 + "github.com/Shopify/sarama"
  7 + "gitlab.fjmaimaimai.com/mmm-go/partnermg/pkg/port/consumer/handles"
  8 +)
  9 +
  10 +//TopicHandle 处理kafka中得消息
  11 +type TopicHandle func(*sarama.ConsumerMessage) error
  12 +
  13 +//TopicHandleRouters 根据topic区分消息并进行处理
  14 +var TopicHandleRouters = map[string]TopicHandle{
  15 + // "topic_test": func(message *sarama.ConsumerMessage) error {
  16 + // logs.Info("Done Message claimed: timestamp = %v, topic = %s offset = %v value = %v \n",
  17 + // message.Timestamp, message.Topic, message.Offset, string(message.Value))
  18 + // return nil
  19 + // },
  20 +}
  21 +
  22 +func init() {
  23 + var runEnv string
  24 + if os.Getenv("KAFKA_CONSUMER_ID") != "" {
  25 + runEnv = os.Getenv("KAFKA_CONSUMER_ID")
  26 + }
  27 + if runEnv == "partnermg_test" {
  28 + initHandleRoutersTest()
  29 + }
  30 + if runEnv == "partnermg_prd" {
  31 + initHandleRoutersProd()
  32 + }
  33 +}
  34 +
  35 +func initHandleRoutersTest() {
  36 + TopicHandleRouters["xiangmi_project_test"] = handles.DataFromXiangMi
  37 +}
  38 +
  39 +func initHandleRoutersProd() {
  40 + TopicHandleRouters["xiangmi_project"] = handles.DataFromXiangMi
  41 +}
  1 +dist: xenial
  2 +language: go
  3 +
  4 +go:
  5 + - 1.10.x
  6 + - 1.11.x
  7 + - 1.12.x
  8 +
  9 +os:
  10 + - linux
  11 + - osx
  12 +
  13 +matrix:
  14 + include:
  15 + name: "Go 1.11.x CentOS 32bits"
  16 + language: go
  17 + go: 1.11.x
  18 + os: linux
  19 + services:
  20 + - docker
  21 + script:
  22 + # Please update Go version in travis_test_32 as needed
  23 + - "docker run -i -v \"${PWD}:/zstd\" toopher/centos-i386:centos6 /bin/bash -c \"linux32 --32bit i386 /zstd/travis_test_32.sh\""
  24 +
  25 +install:
  26 + - "wget https://github.com/DataDog/zstd/files/2246767/mr.zip"
  27 + - "unzip mr.zip"
  28 +script:
  29 + - "go build"
  30 + - "PAYLOAD=`pwd`/mr go test -v"
  31 + - "PAYLOAD=`pwd`/mr go test -bench ."
  1 +Simplified BSD License
  2 +
  3 +Copyright (c) 2016, Datadog <info@datadoghq.com>
  4 +All rights reserved.
  5 +
  6 +Redistribution and use in source and binary forms, with or without
  7 +modification, are permitted provided that the following conditions are met:
  8 +
  9 + * Redistributions of source code must retain the above copyright notice,
  10 + this list of conditions and the following disclaimer.
  11 + * Redistributions in binary form must reproduce the above copyright notice,
  12 + this list of conditions and the following disclaimer in the documentation
  13 + and/or other materials provided with the distribution.
  14 + * Neither the name of the copyright holder nor the names of its contributors
  15 + may be used to endorse or promote products derived from this software
  16 + without specific prior written permission.
  17 +
  18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
  22 +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23 +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  24 +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  25 +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  26 +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1 +# Zstd Go Wrapper
  2 +
  3 +[C Zstd Homepage](https://github.com/Cyan4973/zstd)
  4 +
  5 +The current headers and C files are from *v1.3.8* (Commit
  6 +[470344d](https://github.com/facebook/zstd/releases/tag/v1.3.8)).
  7 +
  8 +## Usage
  9 +
  10 +There are two main APIs:
  11 +
  12 +* simple Compress/Decompress
  13 +* streaming API (io.Reader/io.Writer)
  14 +
  15 +The compress/decompress APIs mirror that of lz4, while the streaming API was
  16 +designed to be a drop-in replacement for zlib.
  17 +
  18 +### Simple `Compress/Decompress`
  19 +
  20 +
  21 +```go
  22 +// Compress compresses the byte array given in src and writes it to dst.
  23 +// If you already have a buffer allocated, you can pass it to prevent allocation
  24 +// If not, you can pass nil as dst.
  25 +// If the buffer is too small, it will be reallocated, resized, and returned bu the function
  26 +// If dst is nil, this will allocate the worst case size (CompressBound(src))
  27 +Compress(dst, src []byte) ([]byte, error)
  28 +```
  29 +
  30 +```go
  31 +// CompressLevel is the same as Compress but you can pass another compression level
  32 +CompressLevel(dst, src []byte, level int) ([]byte, error)
  33 +```
  34 +
  35 +```go
  36 +// Decompress will decompress your payload into dst.
  37 +// If you already have a buffer allocated, you can pass it to prevent allocation
  38 +// If not, you can pass nil as dst (allocates a 4*src size as default).
  39 +// If the buffer is too small, it will retry 3 times by doubling the dst size
  40 +// After max retries, it will switch to the slower stream API to be sure to be able
  41 +// to decompress. Currently switches if compression ratio > 4*2**3=32.
  42 +Decompress(dst, src []byte) ([]byte, error)
  43 +```
  44 +
  45 +### Stream API
  46 +
  47 +```go
  48 +// NewWriter creates a new object that can optionally be initialized with
  49 +// a precomputed dictionary. If dict is nil, compress without a dictionary.
  50 +// The dictionary array should not be changed during the use of this object.
  51 +// You MUST CALL Close() to write the last bytes of a zstd stream and free C objects.
  52 +NewWriter(w io.Writer) *Writer
  53 +NewWriterLevel(w io.Writer, level int) *Writer
  54 +NewWriterLevelDict(w io.Writer, level int, dict []byte) *Writer
  55 +
  56 +// Write compresses the input data and write it to the underlying writer
  57 +(w *Writer) Write(p []byte) (int, error)
  58 +
  59 +// Close flushes the buffer and frees C zstd objects
  60 +(w *Writer) Close() error
  61 +```
  62 +
  63 +```go
  64 +// NewReader returns a new io.ReadCloser that will decompress data from the
  65 +// underlying reader. If a dictionary is provided to NewReaderDict, it must
  66 +// not be modified until Close is called. It is the caller's responsibility
  67 +// to call Close, which frees up C objects.
  68 +NewReader(r io.Reader) io.ReadCloser
  69 +NewReaderDict(r io.Reader, dict []byte) io.ReadCloser
  70 +```
  71 +
  72 +### Benchmarks (benchmarked with v0.5.0)
  73 +
  74 +The author of Zstd also wrote lz4. Zstd is intended to occupy a speed/ratio
  75 +level similar to what zlib currently provides. In our tests, the can always
  76 +be made to be better than zlib by chosing an appropriate level while still
  77 +keeping compression and decompression time faster than zlib.
  78 +
  79 +You can run the benchmarks against your own payloads by using the Go benchmarks tool.
  80 +Just export your payload filepath as the `PAYLOAD` environment variable and run the benchmarks:
  81 +
  82 +```go
  83 +go test -bench .
  84 +```
  85 +
  86 +Compression of a 7Mb pdf zstd (this wrapper) vs [czlib](https://github.com/DataDog/czlib):
  87 +```
  88 +BenchmarkCompression 5 221056624 ns/op 67.34 MB/s
  89 +BenchmarkDecompression 100 18370416 ns/op 810.32 MB/s
  90 +
  91 +BenchmarkFzlibCompress 2 610156603 ns/op 24.40 MB/s
  92 +BenchmarkFzlibDecompress 20 81195246 ns/op 183.33 MB/s
  93 +```
  94 +
  95 +Ratio is also better by a margin of ~20%.
  96 +Compression speed is always better than zlib on all the payloads we tested;
  97 +However, [czlib](https://github.com/DataDog/czlib) has optimisations that make it
  98 +faster at decompressiong small payloads:
  99 +
  100 +```
  101 +Testing with size: 11... czlib: 8.97 MB/s, zstd: 3.26 MB/s
  102 +Testing with size: 27... czlib: 23.3 MB/s, zstd: 8.22 MB/s
  103 +Testing with size: 62... czlib: 31.6 MB/s, zstd: 19.49 MB/s
  104 +Testing with size: 141... czlib: 74.54 MB/s, zstd: 42.55 MB/s
  105 +Testing with size: 323... czlib: 155.14 MB/s, zstd: 99.39 MB/s
  106 +Testing with size: 739... czlib: 235.9 MB/s, zstd: 216.45 MB/s
  107 +Testing with size: 1689... czlib: 116.45 MB/s, zstd: 345.64 MB/s
  108 +Testing with size: 3858... czlib: 176.39 MB/s, zstd: 617.56 MB/s
  109 +Testing with size: 8811... czlib: 254.11 MB/s, zstd: 824.34 MB/s
  110 +Testing with size: 20121... czlib: 197.43 MB/s, zstd: 1339.11 MB/s
  111 +Testing with size: 45951... czlib: 201.62 MB/s, zstd: 1951.57 MB/s
  112 +```
  113 +
  114 +zstd starts to shine with payloads > 1KB
  115 +
  116 +### Stability - Current state: STABLE
  117 +
  118 +The C library seems to be pretty stable and according to the author has been tested and fuzzed.
  119 +
  120 +For the Go wrapper, the test cover most usual cases and we have succesfully tested it on all staging and prod data.
  1 +BSD License
  2 +
  3 +For Zstandard software
  4 +
  5 +Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
  6 +
  7 +Redistribution and use in source and binary forms, with or without modification,
  8 +are permitted provided that the following conditions are met:
  9 +
  10 + * Redistributions of source code must retain the above copyright notice, this
  11 + list of conditions and the following disclaimer.
  12 +
  13 + * Redistributions in binary form must reproduce the above copyright notice,
  14 + this list of conditions and the following disclaimer in the documentation
  15 + and/or other materials provided with the distribution.
  16 +
  17 + * Neither the name Facebook nor the names of its contributors may be used to
  18 + endorse or promote products derived from this software without specific
  19 + prior written permission.
  20 +
  21 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  22 +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  23 +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  24 +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
  25 +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  26 +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  27 +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  28 +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30 +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1 +/* ******************************************************************
  2 + bitstream
  3 + Part of FSE library
  4 + Copyright (C) 2013-present, Yann Collet.
  5 +
  6 + BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
  7 +
  8 + Redistribution and use in source and binary forms, with or without
  9 + modification, are permitted provided that the following conditions are
  10 + met:
  11 +
  12 + * Redistributions of source code must retain the above copyright
  13 + notice, this list of conditions and the following disclaimer.
  14 + * Redistributions in binary form must reproduce the above
  15 + copyright notice, this list of conditions and the following disclaimer
  16 + in the documentation and/or other materials provided with the
  17 + distribution.
  18 +
  19 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  20 + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  21 + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  22 + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  23 + OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  24 + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  25 + LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  26 + DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  27 + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  28 + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  29 + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  30 +
  31 + You can contact the author at :
  32 + - Source repository : https://github.com/Cyan4973/FiniteStateEntropy
  33 +****************************************************************** */
  34 +#ifndef BITSTREAM_H_MODULE
  35 +#define BITSTREAM_H_MODULE
  36 +
  37 +#if defined (__cplusplus)
  38 +extern "C" {
  39 +#endif
  40 +
  41 +/*
  42 +* This API consists of small unitary functions, which must be inlined for best performance.
  43 +* Since link-time-optimization is not available for all compilers,
  44 +* these functions are defined into a .h to be included.
  45 +*/
  46 +
  47 +/*-****************************************
  48 +* Dependencies
  49 +******************************************/
  50 +#include "mem.h" /* unaligned access routines */
  51 +#include "debug.h" /* assert(), DEBUGLOG(), RAWLOG() */
  52 +#include "error_private.h" /* error codes and messages */
  53 +
  54 +
  55 +/*=========================================
  56 +* Target specific
  57 +=========================================*/
  58 +#if defined(__BMI__) && defined(__GNUC__)
  59 +# include <immintrin.h> /* support for bextr (experimental) */
  60 +#endif
  61 +
  62 +#define STREAM_ACCUMULATOR_MIN_32 25
  63 +#define STREAM_ACCUMULATOR_MIN_64 57
  64 +#define STREAM_ACCUMULATOR_MIN ((U32)(MEM_32bits() ? STREAM_ACCUMULATOR_MIN_32 : STREAM_ACCUMULATOR_MIN_64))
  65 +
  66 +
  67 +/*-******************************************
  68 +* bitStream encoding API (write forward)
  69 +********************************************/
  70 +/* bitStream can mix input from multiple sources.
  71 + * A critical property of these streams is that they encode and decode in **reverse** direction.
  72 + * So the first bit sequence you add will be the last to be read, like a LIFO stack.
  73 + */
  74 +typedef struct {
  75 + size_t bitContainer;
  76 + unsigned bitPos;
  77 + char* startPtr;
  78 + char* ptr;
  79 + char* endPtr;
  80 +} BIT_CStream_t;
  81 +
  82 +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC, void* dstBuffer, size_t dstCapacity);
  83 +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
  84 +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC);
  85 +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC);
  86 +
  87 +/* Start with initCStream, providing the size of buffer to write into.
  88 +* bitStream will never write outside of this buffer.
  89 +* `dstCapacity` must be >= sizeof(bitD->bitContainer), otherwise @return will be an error code.
  90 +*
  91 +* bits are first added to a local register.
  92 +* Local register is size_t, hence 64-bits on 64-bits systems, or 32-bits on 32-bits systems.
  93 +* Writing data into memory is an explicit operation, performed by the flushBits function.
  94 +* Hence keep track how many bits are potentially stored into local register to avoid register overflow.
  95 +* After a flushBits, a maximum of 7 bits might still be stored into local register.
  96 +*
  97 +* Avoid storing elements of more than 24 bits if you want compatibility with 32-bits bitstream readers.
  98 +*
  99 +* Last operation is to close the bitStream.
  100 +* The function returns the final size of CStream in bytes.
  101 +* If data couldn't fit into `dstBuffer`, it will return a 0 ( == not storable)
  102 +*/
  103 +
  104 +
  105 +/*-********************************************
  106 +* bitStream decoding API (read backward)
  107 +**********************************************/
  108 +typedef struct {
  109 + size_t bitContainer;
  110 + unsigned bitsConsumed;
  111 + const char* ptr;
  112 + const char* start;
  113 + const char* limitPtr;
  114 +} BIT_DStream_t;
  115 +
  116 +typedef enum { BIT_DStream_unfinished = 0,
  117 + BIT_DStream_endOfBuffer = 1,
  118 + BIT_DStream_completed = 2,
  119 + BIT_DStream_overflow = 3 } BIT_DStream_status; /* result of BIT_reloadDStream() */
  120 + /* 1,2,4,8 would be better for bitmap combinations, but slows down performance a bit ... :( */
  121 +
  122 +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize);
  123 +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits);
  124 +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD);
  125 +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* bitD);
  126 +
  127 +
  128 +/* Start by invoking BIT_initDStream().
  129 +* A chunk of the bitStream is then stored into a local register.
  130 +* Local register size is 64-bits on 64-bits systems, 32-bits on 32-bits systems (size_t).
  131 +* You can then retrieve bitFields stored into the local register, **in reverse order**.
  132 +* Local register is explicitly reloaded from memory by the BIT_reloadDStream() method.
  133 +* A reload guarantee a minimum of ((8*sizeof(bitD->bitContainer))-7) bits when its result is BIT_DStream_unfinished.
  134 +* Otherwise, it can be less than that, so proceed accordingly.
  135 +* Checking if DStream has reached its end can be performed with BIT_endOfDStream().
  136 +*/
  137 +
  138 +
  139 +/*-****************************************
  140 +* unsafe API
  141 +******************************************/
  142 +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC, size_t value, unsigned nbBits);
  143 +/* faster, but works only if value is "clean", meaning all high bits above nbBits are 0 */
  144 +
  145 +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC);
  146 +/* unsafe version; does not check buffer overflow */
  147 +
  148 +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits);
  149 +/* faster, but works only if nbBits >= 1 */
  150 +
  151 +
  152 +
  153 +/*-**************************************************************
  154 +* Internal functions
  155 +****************************************************************/
  156 +MEM_STATIC unsigned BIT_highbit32 (U32 val)
  157 +{
  158 + assert(val != 0);
  159 + {
  160 +# if defined(_MSC_VER) /* Visual */
  161 + unsigned long r=0;
  162 + _BitScanReverse ( &r, val );
  163 + return (unsigned) r;
  164 +# elif defined(__GNUC__) && (__GNUC__ >= 3) /* Use GCC Intrinsic */
  165 + return 31 - __builtin_clz (val);
  166 +# else /* Software version */
  167 + static const unsigned DeBruijnClz[32] = { 0, 9, 1, 10, 13, 21, 2, 29,
  168 + 11, 14, 16, 18, 22, 25, 3, 30,
  169 + 8, 12, 20, 28, 15, 17, 24, 7,
  170 + 19, 27, 23, 6, 26, 5, 4, 31 };
  171 + U32 v = val;
  172 + v |= v >> 1;
  173 + v |= v >> 2;
  174 + v |= v >> 4;
  175 + v |= v >> 8;
  176 + v |= v >> 16;
  177 + return DeBruijnClz[ (U32) (v * 0x07C4ACDDU) >> 27];
  178 +# endif
  179 + }
  180 +}
  181 +
  182 +/*===== Local Constants =====*/
  183 +static const unsigned BIT_mask[] = {
  184 + 0, 1, 3, 7, 0xF, 0x1F,
  185 + 0x3F, 0x7F, 0xFF, 0x1FF, 0x3FF, 0x7FF,
  186 + 0xFFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF, 0x1FFFF,
  187 + 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF,
  188 + 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF,
  189 + 0x3FFFFFFF, 0x7FFFFFFF}; /* up to 31 bits */
  190 +#define BIT_MASK_SIZE (sizeof(BIT_mask) / sizeof(BIT_mask[0]))
  191 +
  192 +/*-**************************************************************
  193 +* bitStream encoding
  194 +****************************************************************/
  195 +/*! BIT_initCStream() :
  196 + * `dstCapacity` must be > sizeof(size_t)
  197 + * @return : 0 if success,
  198 + * otherwise an error code (can be tested using ERR_isError()) */
  199 +MEM_STATIC size_t BIT_initCStream(BIT_CStream_t* bitC,
  200 + void* startPtr, size_t dstCapacity)
  201 +{
  202 + bitC->bitContainer = 0;
  203 + bitC->bitPos = 0;
  204 + bitC->startPtr = (char*)startPtr;
  205 + bitC->ptr = bitC->startPtr;
  206 + bitC->endPtr = bitC->startPtr + dstCapacity - sizeof(bitC->bitContainer);
  207 + if (dstCapacity <= sizeof(bitC->bitContainer)) return ERROR(dstSize_tooSmall);
  208 + return 0;
  209 +}
  210 +
  211 +/*! BIT_addBits() :
  212 + * can add up to 31 bits into `bitC`.
  213 + * Note : does not check for register overflow ! */
  214 +MEM_STATIC void BIT_addBits(BIT_CStream_t* bitC,
  215 + size_t value, unsigned nbBits)
  216 +{
  217 + MEM_STATIC_ASSERT(BIT_MASK_SIZE == 32);
  218 + assert(nbBits < BIT_MASK_SIZE);
  219 + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
  220 + bitC->bitContainer |= (value & BIT_mask[nbBits]) << bitC->bitPos;
  221 + bitC->bitPos += nbBits;
  222 +}
  223 +
  224 +/*! BIT_addBitsFast() :
  225 + * works only if `value` is _clean_,
  226 + * meaning all high bits above nbBits are 0 */
  227 +MEM_STATIC void BIT_addBitsFast(BIT_CStream_t* bitC,
  228 + size_t value, unsigned nbBits)
  229 +{
  230 + assert((value>>nbBits) == 0);
  231 + assert(nbBits + bitC->bitPos < sizeof(bitC->bitContainer) * 8);
  232 + bitC->bitContainer |= value << bitC->bitPos;
  233 + bitC->bitPos += nbBits;
  234 +}
  235 +
  236 +/*! BIT_flushBitsFast() :
  237 + * assumption : bitContainer has not overflowed
  238 + * unsafe version; does not check buffer overflow */
  239 +MEM_STATIC void BIT_flushBitsFast(BIT_CStream_t* bitC)
  240 +{
  241 + size_t const nbBytes = bitC->bitPos >> 3;
  242 + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
  243 + MEM_writeLEST(bitC->ptr, bitC->bitContainer);
  244 + bitC->ptr += nbBytes;
  245 + assert(bitC->ptr <= bitC->endPtr);
  246 + bitC->bitPos &= 7;
  247 + bitC->bitContainer >>= nbBytes*8;
  248 +}
  249 +
  250 +/*! BIT_flushBits() :
  251 + * assumption : bitContainer has not overflowed
  252 + * safe version; check for buffer overflow, and prevents it.
  253 + * note : does not signal buffer overflow.
  254 + * overflow will be revealed later on using BIT_closeCStream() */
  255 +MEM_STATIC void BIT_flushBits(BIT_CStream_t* bitC)
  256 +{
  257 + size_t const nbBytes = bitC->bitPos >> 3;
  258 + assert(bitC->bitPos < sizeof(bitC->bitContainer) * 8);
  259 + MEM_writeLEST(bitC->ptr, bitC->bitContainer);
  260 + bitC->ptr += nbBytes;
  261 + if (bitC->ptr > bitC->endPtr) bitC->ptr = bitC->endPtr;
  262 + bitC->bitPos &= 7;
  263 + bitC->bitContainer >>= nbBytes*8;
  264 +}
  265 +
  266 +/*! BIT_closeCStream() :
  267 + * @return : size of CStream, in bytes,
  268 + * or 0 if it could not fit into dstBuffer */
  269 +MEM_STATIC size_t BIT_closeCStream(BIT_CStream_t* bitC)
  270 +{
  271 + BIT_addBitsFast(bitC, 1, 1); /* endMark */
  272 + BIT_flushBits(bitC);
  273 + if (bitC->ptr >= bitC->endPtr) return 0; /* overflow detected */
  274 + return (bitC->ptr - bitC->startPtr) + (bitC->bitPos > 0);
  275 +}
  276 +
  277 +
  278 +/*-********************************************************
  279 +* bitStream decoding
  280 +**********************************************************/
  281 +/*! BIT_initDStream() :
  282 + * Initialize a BIT_DStream_t.
  283 + * `bitD` : a pointer to an already allocated BIT_DStream_t structure.
  284 + * `srcSize` must be the *exact* size of the bitStream, in bytes.
  285 + * @return : size of stream (== srcSize), or an errorCode if a problem is detected
  286 + */
  287 +MEM_STATIC size_t BIT_initDStream(BIT_DStream_t* bitD, const void* srcBuffer, size_t srcSize)
  288 +{
  289 + if (srcSize < 1) { memset(bitD, 0, sizeof(*bitD)); return ERROR(srcSize_wrong); }
  290 +
  291 + bitD->start = (const char*)srcBuffer;
  292 + bitD->limitPtr = bitD->start + sizeof(bitD->bitContainer);
  293 +
  294 + if (srcSize >= sizeof(bitD->bitContainer)) { /* normal case */
  295 + bitD->ptr = (const char*)srcBuffer + srcSize - sizeof(bitD->bitContainer);
  296 + bitD->bitContainer = MEM_readLEST(bitD->ptr);
  297 + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
  298 + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0; /* ensures bitsConsumed is always set */
  299 + if (lastByte == 0) return ERROR(GENERIC); /* endMark not present */ }
  300 + } else {
  301 + bitD->ptr = bitD->start;
  302 + bitD->bitContainer = *(const BYTE*)(bitD->start);
  303 + switch(srcSize)
  304 + {
  305 + case 7: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[6]) << (sizeof(bitD->bitContainer)*8 - 16);
  306 + /* fall-through */
  307 +
  308 + case 6: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[5]) << (sizeof(bitD->bitContainer)*8 - 24);
  309 + /* fall-through */
  310 +
  311 + case 5: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[4]) << (sizeof(bitD->bitContainer)*8 - 32);
  312 + /* fall-through */
  313 +
  314 + case 4: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[3]) << 24;
  315 + /* fall-through */
  316 +
  317 + case 3: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[2]) << 16;
  318 + /* fall-through */
  319 +
  320 + case 2: bitD->bitContainer += (size_t)(((const BYTE*)(srcBuffer))[1]) << 8;
  321 + /* fall-through */
  322 +
  323 + default: break;
  324 + }
  325 + { BYTE const lastByte = ((const BYTE*)srcBuffer)[srcSize-1];
  326 + bitD->bitsConsumed = lastByte ? 8 - BIT_highbit32(lastByte) : 0;
  327 + if (lastByte == 0) return ERROR(corruption_detected); /* endMark not present */
  328 + }
  329 + bitD->bitsConsumed += (U32)(sizeof(bitD->bitContainer) - srcSize)*8;
  330 + }
  331 +
  332 + return srcSize;
  333 +}
  334 +
  335 +MEM_STATIC size_t BIT_getUpperBits(size_t bitContainer, U32 const start)
  336 +{
  337 + return bitContainer >> start;
  338 +}
  339 +
  340 +MEM_STATIC size_t BIT_getMiddleBits(size_t bitContainer, U32 const start, U32 const nbBits)
  341 +{
  342 + U32 const regMask = sizeof(bitContainer)*8 - 1;
  343 + /* if start > regMask, bitstream is corrupted, and result is undefined */
  344 + assert(nbBits < BIT_MASK_SIZE);
  345 + return (bitContainer >> (start & regMask)) & BIT_mask[nbBits];
  346 +}
  347 +
  348 +MEM_STATIC size_t BIT_getLowerBits(size_t bitContainer, U32 const nbBits)
  349 +{
  350 + assert(nbBits < BIT_MASK_SIZE);
  351 + return bitContainer & BIT_mask[nbBits];
  352 +}
  353 +
  354 +/*! BIT_lookBits() :
  355 + * Provides next n bits from local register.
  356 + * local register is not modified.
  357 + * On 32-bits, maxNbBits==24.
  358 + * On 64-bits, maxNbBits==56.
  359 + * @return : value extracted */
  360 +MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
  361 +{
  362 + /* arbitrate between double-shift and shift+mask */
  363 +#if 1
  364 + /* if bitD->bitsConsumed + nbBits > sizeof(bitD->bitContainer)*8,
  365 + * bitstream is likely corrupted, and result is undefined */
  366 + return BIT_getMiddleBits(bitD->bitContainer, (sizeof(bitD->bitContainer)*8) - bitD->bitsConsumed - nbBits, nbBits);
  367 +#else
  368 + /* this code path is slower on my os-x laptop */
  369 + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
  370 + return ((bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> 1) >> ((regMask-nbBits) & regMask);
  371 +#endif
  372 +}
  373 +
  374 +/*! BIT_lookBitsFast() :
  375 + * unsafe version; only works if nbBits >= 1 */
  376 +MEM_STATIC size_t BIT_lookBitsFast(const BIT_DStream_t* bitD, U32 nbBits)
  377 +{
  378 + U32 const regMask = sizeof(bitD->bitContainer)*8 - 1;
  379 + assert(nbBits >= 1);
  380 + return (bitD->bitContainer << (bitD->bitsConsumed & regMask)) >> (((regMask+1)-nbBits) & regMask);
  381 +}
  382 +
  383 +MEM_STATIC void BIT_skipBits(BIT_DStream_t* bitD, U32 nbBits)
  384 +{
  385 + bitD->bitsConsumed += nbBits;
  386 +}
  387 +
  388 +/*! BIT_readBits() :
  389 + * Read (consume) next n bits from local register and update.
  390 + * Pay attention to not read more than nbBits contained into local register.
  391 + * @return : extracted value. */
  392 +MEM_STATIC size_t BIT_readBits(BIT_DStream_t* bitD, unsigned nbBits)
  393 +{
  394 + size_t const value = BIT_lookBits(bitD, nbBits);
  395 + BIT_skipBits(bitD, nbBits);
  396 + return value;
  397 +}
  398 +
  399 +/*! BIT_readBitsFast() :
  400 + * unsafe version; only works only if nbBits >= 1 */
  401 +MEM_STATIC size_t BIT_readBitsFast(BIT_DStream_t* bitD, unsigned nbBits)
  402 +{
  403 + size_t const value = BIT_lookBitsFast(bitD, nbBits);
  404 + assert(nbBits >= 1);
  405 + BIT_skipBits(bitD, nbBits);
  406 + return value;
  407 +}
  408 +
  409 +/*! BIT_reloadDStream() :
  410 + * Refill `bitD` from buffer previously set in BIT_initDStream() .
  411 + * This function is safe, it guarantees it will not read beyond src buffer.
  412 + * @return : status of `BIT_DStream_t` internal register.
  413 + * when status == BIT_DStream_unfinished, internal register is filled with at least 25 or 57 bits */
  414 +MEM_STATIC BIT_DStream_status BIT_reloadDStream(BIT_DStream_t* bitD)
  415 +{
  416 + if (bitD->bitsConsumed > (sizeof(bitD->bitContainer)*8)) /* overflow detected, like end of stream */
  417 + return BIT_DStream_overflow;
  418 +
  419 + if (bitD->ptr >= bitD->limitPtr) {
  420 + bitD->ptr -= bitD->bitsConsumed >> 3;
  421 + bitD->bitsConsumed &= 7;
  422 + bitD->bitContainer = MEM_readLEST(bitD->ptr);
  423 + return BIT_DStream_unfinished;
  424 + }
  425 + if (bitD->ptr == bitD->start) {
  426 + if (bitD->bitsConsumed < sizeof(bitD->bitContainer)*8) return BIT_DStream_endOfBuffer;
  427 + return BIT_DStream_completed;
  428 + }
  429 + /* start < ptr < limitPtr */
  430 + { U32 nbBytes = bitD->bitsConsumed >> 3;
  431 + BIT_DStream_status result = BIT_DStream_unfinished;
  432 + if (bitD->ptr - nbBytes < bitD->start) {
  433 + nbBytes = (U32)(bitD->ptr - bitD->start); /* ptr > start */
  434 + result = BIT_DStream_endOfBuffer;
  435 + }
  436 + bitD->ptr -= nbBytes;
  437 + bitD->bitsConsumed -= nbBytes*8;
  438 + bitD->bitContainer = MEM_readLEST(bitD->ptr); /* reminder : srcSize > sizeof(bitD->bitContainer), otherwise bitD->ptr == bitD->start */
  439 + return result;
  440 + }
  441 +}
  442 +
  443 +/*! BIT_endOfDStream() :
  444 + * @return : 1 if DStream has _exactly_ reached its end (all bits consumed).
  445 + */
  446 +MEM_STATIC unsigned BIT_endOfDStream(const BIT_DStream_t* DStream)
  447 +{
  448 + return ((DStream->ptr == DStream->start) && (DStream->bitsConsumed == sizeof(DStream->bitContainer)*8));
  449 +}
  450 +
  451 +#if defined (__cplusplus)
  452 +}
  453 +#endif
  454 +
  455 +#endif /* BITSTREAM_H_MODULE */
  1 +/*
  2 + * Copyright (c) 2016-present, Yann Collet, Facebook, Inc.
  3 + * All rights reserved.
  4 + *
  5 + * This source code is licensed under both the BSD-style license (found in the
  6 + * LICENSE file in the root directory of this source tree) and the GPLv2 (found
  7 + * in the COPYING file in the root directory of this source tree).
  8 + * You may select, at your option, one of the above-listed licenses.
  9 + */
  10 +
  11 +#ifndef ZSTD_COMPILER_H
  12 +#define ZSTD_COMPILER_H
  13 +
  14 +/*-*******************************************************
  15 +* Compiler specifics
  16 +*********************************************************/
  17 +/* force inlining */
  18 +
  19 +#if !defined(ZSTD_NO_INLINE)
  20 +#if defined (__GNUC__) || defined(__cplusplus) || defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* C99 */
  21 +# define INLINE_KEYWORD inline
  22 +#else
  23 +# define INLINE_KEYWORD
  24 +#endif
  25 +
  26 +#if defined(__GNUC__)
  27 +# define FORCE_INLINE_ATTR __attribute__((always_inline))
  28 +#elif defined(_MSC_VER)
  29 +# define FORCE_INLINE_ATTR __forceinline
  30 +#else
  31 +# define FORCE_INLINE_ATTR
  32 +#endif
  33 +
  34 +#else
  35 +
  36 +#define INLINE_KEYWORD
  37 +#define FORCE_INLINE_ATTR
  38 +
  39 +#endif
  40 +
  41 +/**
  42 + * FORCE_INLINE_TEMPLATE is used to define C "templates", which take constant
  43 + * parameters. They must be inlined for the compiler to elimininate the constant
  44 + * branches.
  45 + */
  46 +#define FORCE_INLINE_TEMPLATE static INLINE_KEYWORD FORCE_INLINE_ATTR
  47 +/**
  48 + * HINT_INLINE is used to help the compiler generate better code. It is *not*
  49 + * used for "templates", so it can be tweaked based on the compilers
  50 + * performance.
  51 + *
  52 + * gcc-4.8 and gcc-4.9 have been shown to benefit from leaving off the
  53 + * always_inline attribute.
  54 + *
  55 + * clang up to 5.0.0 (trunk) benefit tremendously from the always_inline
  56 + * attribute.
  57 + */
  58 +#if !defined(__clang__) && defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8 && __GNUC__ < 5
  59 +# define HINT_INLINE static INLINE_KEYWORD
  60 +#else
  61 +# define HINT_INLINE static INLINE_KEYWORD FORCE_INLINE_ATTR
  62 +#endif
  63 +
  64 +/* force no inlining */
  65 +#ifdef _MSC_VER
  66 +# define FORCE_NOINLINE static __declspec(noinline)
  67 +#else
  68 +# ifdef __GNUC__
  69 +# define FORCE_NOINLINE static __attribute__((__noinline__))
  70 +# else
  71 +# define FORCE_NOINLINE static
  72 +# endif
  73 +#endif
  74 +
  75 +/* target attribute */
  76 +#ifndef __has_attribute
  77 + #define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */
  78 +#endif
  79 +#if defined(__GNUC__)
  80 +# define TARGET_ATTRIBUTE(target) __attribute__((__target__(target)))
  81 +#else
  82 +# define TARGET_ATTRIBUTE(target)
  83 +#endif
  84 +
  85 +/* Enable runtime BMI2 dispatch based on the CPU.
  86 + * Enabled for clang & gcc >=4.8 on x86 when BMI2 isn't enabled by default.
  87 + */
  88 +#ifndef DYNAMIC_BMI2
  89 + #if ((defined(__clang__) && __has_attribute(__target__)) \
  90 + || (defined(__GNUC__) \
  91 + && (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)))) \
  92 + && (defined(__x86_64__) || defined(_M_X86)) \
  93 + && !defined(__BMI2__)
  94 + # define DYNAMIC_BMI2 1
  95 + #else
  96 + # define DYNAMIC_BMI2 0
  97 + #endif
  98 +#endif
  99 +
  100 +/* prefetch
  101 + * can be disabled, by declaring NO_PREFETCH build macro */
  102 +#if defined(NO_PREFETCH)
  103 +# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
  104 +# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
  105 +#else
  106 +# if defined(_MSC_VER) && (defined(_M_X64) || defined(_M_I86)) /* _mm_prefetch() is not defined outside of x86/x64 */
  107 +# include <mmintrin.h> /* https://msdn.microsoft.com/fr-fr/library/84szxsww(v=vs.90).aspx */
  108 +# define PREFETCH_L1(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T0)
  109 +# define PREFETCH_L2(ptr) _mm_prefetch((const char*)(ptr), _MM_HINT_T1)
  110 +# elif defined(__GNUC__) && ( (__GNUC__ >= 4) || ( (__GNUC__ == 3) && (__GNUC_MINOR__ >= 1) ) )
  111 +# define PREFETCH_L1(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 3 /* locality */)
  112 +# define PREFETCH_L2(ptr) __builtin_prefetch((ptr), 0 /* rw==read */, 2 /* locality */)
  113 +# else
  114 +# define PREFETCH_L1(ptr) (void)(ptr) /* disabled */
  115 +# define PREFETCH_L2(ptr) (void)(ptr) /* disabled */
  116 +# endif
  117 +#endif /* NO_PREFETCH */
  118 +
  119 +#define CACHELINE_SIZE 64
  120 +
  121 +#define PREFETCH_AREA(p, s) { \
  122 + const char* const _ptr = (const char*)(p); \
  123 + size_t const _size = (size_t)(s); \
  124 + size_t _pos; \
  125 + for (_pos=0; _pos<_size; _pos+=CACHELINE_SIZE) { \
  126 + PREFETCH_L2(_ptr + _pos); \
  127 + } \
  128 +}
  129 +
  130 +/* disable warnings */
  131 +#ifdef _MSC_VER /* Visual Studio */
  132 +# include <intrin.h> /* For Visual 2005 */
  133 +# pragma warning(disable : 4100) /* disable: C4100: unreferenced formal parameter */
  134 +# pragma warning(disable : 4127) /* disable: C4127: conditional expression is constant */
  135 +# pragma warning(disable : 4204) /* disable: C4204: non-constant aggregate initializer */
  136 +# pragma warning(disable : 4214) /* disable: C4214: non-int bitfields */
  137 +# pragma warning(disable : 4324) /* disable: C4324: padded structure */
  138 +#endif
  139 +
  140 +#endif /* ZSTD_COMPILER_H */