正在显示
65 个修改的文件
包含
4053 行增加
和
145 行删除
@@ -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 | +} |
@@ -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"` |
@@ -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 | } |
@@ -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{}{ |
pkg/constant/kafka.go
0 → 100644
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 |
pkg/domain/event/modifyOrderGoodBonus.go
0 → 100644
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 | +} |
pkg/domain/event/payOrderGoodBonus.go
0 → 100644
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 数据汇总核算 |
pkg/domain/order_bestshop.go
0 → 100644
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 | +} |
pkg/domain/order_data_from.go
0 → 100644
@@ -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 | } |
pkg/domain/order_log.go
0 → 100644
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 | +} |
pkg/domain/order_with_bestshop.go
0 → 100644
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 | +} |
pkg/domain/service/order_bonus.go
0 → 100644
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 | +} |
pkg/infrastructure/dao/pg_order_bestshop.go
0 → 100644
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 | +} |
pkg/infrastructure/pg/models/order_log.go
0 → 100644
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(¶m); 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(¶m); 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(¶m); 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(¶m); 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", |
pkg/port/consumer/configs/config.go
0 → 100644
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" |
pkg/port/consumer/consumer.go
0 → 100644
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 | +} |
pkg/port/consumer/handles/messageValue.go
0 → 100644
pkg/port/consumer/handles/xiangmi.go
0 → 100644
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 | +} |
pkg/port/consumer/topic_handle_router.go
0 → 100644
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 | +} |
vendor/github.com/DataDog/zstd/.travis.yml
0 → 100644
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 ." |
vendor/github.com/DataDog/zstd/LICENSE
0 → 100644
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. |
vendor/github.com/DataDog/zstd/README.md
0 → 100644
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. |
vendor/github.com/DataDog/zstd/ZSTD_LICENSE
0 → 100644
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. |
vendor/github.com/DataDog/zstd/bitstream.h
0 → 100644
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 */ |
vendor/github.com/DataDog/zstd/compiler.h
0 → 100644
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 */ |
-
请 注册 或 登录 后发表评论