正在显示
18 个修改的文件
包含
816 行增加
和
3 行删除
@@ -67,6 +67,11 @@ func Login(header *protocol.RequestHeader, request *protocol.LoginRequest) (rsp | @@ -67,6 +67,11 @@ func Login(header *protocol.RequestHeader, request *protocol.LoginRequest) (rsp | ||
67 | break | 67 | break |
68 | } | 68 | } |
69 | rsp.AuthCode, _ = utils.GenerateToken(partnerInfo.Id, protocol.AuthCodeExpire*time.Second) | 69 | rsp.AuthCode, _ = utils.GenerateToken(partnerInfo.Id, protocol.AuthCodeExpire*time.Second) |
70 | + | ||
71 | + if err = InitOrUpdateUserIMInfo(partnerInfo, transactionContext); err != nil { | ||
72 | + log.Error(err) | ||
73 | + return | ||
74 | + } | ||
70 | err = transactionContext.CommitTransaction() | 75 | err = transactionContext.CommitTransaction() |
71 | return | 76 | return |
72 | } | 77 | } |
pkg/application/auth/im.go
0 → 100644
1 | +package auth | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/log" | ||
6 | + "strconv" | ||
7 | + "time" | ||
8 | + | ||
9 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/application/factory" | ||
10 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain" | ||
11 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/im" | ||
12 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/transaction" | ||
13 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/utils" | ||
14 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/protocol" | ||
15 | +) | ||
16 | + | ||
17 | +// 更新用户 IM INFO | ||
18 | +func InitOrUpdateUserIMInfo(partnerInfo *domain.PartnerInfo, ctx *transaction.TransactionContext) (err error) { | ||
19 | + var ( | ||
20 | + ImInfoRepository, _ = factory.CreateImInfoRepository(ctx) | ||
21 | + checkImRequest *protocol.CheckImRequest = &protocol.CheckImRequest{} | ||
22 | + IsCreated = false | ||
23 | + checkImResponse *protocol.CheckImResponse | ||
24 | + ) | ||
25 | + imInfo, e := ImInfoRepository.FindOne(map[string]interface{}{"user_id": partnerInfo.Id}) | ||
26 | + // 异常 | ||
27 | + if e != nil && e != domain.QueryNoRow { | ||
28 | + err = e | ||
29 | + return | ||
30 | + } | ||
31 | + // 不存在 | ||
32 | + if e == domain.QueryNoRow { | ||
33 | + imInfo = &domain.ImInfo{ | ||
34 | + UserId: partnerInfo.Id, | ||
35 | + CreateTime: time.Now(), | ||
36 | + } | ||
37 | + } | ||
38 | + // 已存在 | ||
39 | + if e == nil && imInfo != nil { | ||
40 | + IsCreated = true | ||
41 | + } | ||
42 | + | ||
43 | + if len(imInfo.ImId) == 0 { | ||
44 | + id, _ := utils.NewSnowflakeId() | ||
45 | + imInfo.ImId = fmt.Sprintf("%v", id) | ||
46 | + } | ||
47 | + checkImRequest = &protocol.CheckImRequest{ | ||
48 | + UserId: imInfo.UserId, | ||
49 | + ImId: imInfo.ImId, | ||
50 | + Uname: partnerInfo.PartnerName, | ||
51 | + CustomerImId: fmt.Sprintf("%v", imInfo.CustomerImId), | ||
52 | + IsCreated: IsCreated, | ||
53 | + } | ||
54 | + if checkImResponse, err = CheckIm(checkImRequest); err != nil { | ||
55 | + return | ||
56 | + } | ||
57 | + if imInfo.CustomerImId == 0 { | ||
58 | + imInfo.CustomerImId = getRandomCustomerAccount(partnerInfo.Id, ctx) | ||
59 | + } | ||
60 | + imInfo.ImToken = checkImResponse.ImToken | ||
61 | + imInfo.UpdateTime = time.Now() | ||
62 | + if _, err = ImInfoRepository.Save(imInfo); err != nil { | ||
63 | + return | ||
64 | + } | ||
65 | + return | ||
66 | +} | ||
67 | + | ||
68 | +// 检查ImToken | ||
69 | +func CheckIm(request *protocol.CheckImRequest) (rsp *protocol.CheckImResponse, err error) { | ||
70 | + var () | ||
71 | + rsp = &protocol.CheckImResponse{} | ||
72 | + if !request.IsCreated { | ||
73 | + if err = imCreate(request, rsp); err != nil { | ||
74 | + return | ||
75 | + } | ||
76 | + } else { | ||
77 | + if err = imUpdate(request, rsp); err != nil { | ||
78 | + return | ||
79 | + } | ||
80 | + } | ||
81 | + if err = imRefreshToken(request, rsp); err != nil { | ||
82 | + return | ||
83 | + } | ||
84 | + return | ||
85 | +} | ||
86 | + | ||
87 | +//create | ||
88 | +func imCreate(request *protocol.CheckImRequest, rsp *protocol.CheckImResponse) (err error) { | ||
89 | + var ( | ||
90 | + param im.UserCreate = im.UserCreate{ | ||
91 | + Accid: request.ImId, | ||
92 | + Name: request.Uname, | ||
93 | + Icon: request.Icon, | ||
94 | + } | ||
95 | + out *im.UserTokenResult | ||
96 | + ) | ||
97 | + if out, err = im.CallCreate(param); err != nil { | ||
98 | + return | ||
99 | + } | ||
100 | + if out.Code != 200 || (out.Info.Accid != request.ImId) { | ||
101 | + return im.ErrorFailCall | ||
102 | + } | ||
103 | + rsp.ImToken = out.Info.Token | ||
104 | + return | ||
105 | +} | ||
106 | + | ||
107 | +//update user info | ||
108 | +func imUpdate(request *protocol.CheckImRequest, rsp *protocol.CheckImResponse) (err error) { | ||
109 | + var ( | ||
110 | + param im.UserUpdate = im.UserUpdate{ | ||
111 | + Accid: request.ImId, | ||
112 | + Name: request.Uname, | ||
113 | + Icon: request.Icon, | ||
114 | + } | ||
115 | + out *im.BaseResp | ||
116 | + ) | ||
117 | + if out, err = im.CallUpdate(param); err != nil { | ||
118 | + return | ||
119 | + } | ||
120 | + if out.Code != 200 { | ||
121 | + return im.ErrorFailCall | ||
122 | + } | ||
123 | + return | ||
124 | +} | ||
125 | + | ||
126 | +//refresh token | ||
127 | +func imRefreshToken(request *protocol.CheckImRequest, rsp *protocol.CheckImResponse) (err error) { | ||
128 | + var ( | ||
129 | + param im.UserRefreshToken = im.UserRefreshToken{ | ||
130 | + Accid: request.ImId, | ||
131 | + } | ||
132 | + out *im.UserTokenResult | ||
133 | + ) | ||
134 | + if out, err = im.CallRefreshToken(param); err != nil { | ||
135 | + return | ||
136 | + } | ||
137 | + if out.Code != 200 || (out.Info.Accid != request.ImId) { | ||
138 | + return im.ErrorFailCall | ||
139 | + } | ||
140 | + rsp.ImToken = out.Info.Token | ||
141 | + return | ||
142 | +} | ||
143 | + | ||
144 | +// 获取客服id | ||
145 | +func getRandomCustomerAccount(userId int64, ctx *transaction.TransactionContext) (acid int64) { | ||
146 | + CustomerServiceRepository, _ := factory.CreateCustomerServiceRepository(ctx) | ||
147 | + total, customers, err := CustomerServiceRepository.Find(map[string]interface{}{"sortById": domain.ASC}) | ||
148 | + if err != nil { | ||
149 | + log.Error(err) | ||
150 | + return 0 | ||
151 | + } | ||
152 | + if total == 0 { | ||
153 | + return 0 | ||
154 | + } | ||
155 | + index := userId % total | ||
156 | + if int(index) < len(customers) { | ||
157 | + acid, _ = strconv.ParseInt(customers[index].ImId, 10, 64) | ||
158 | + return | ||
159 | + } | ||
160 | + acid, _ = strconv.ParseInt(customers[0].ImId, 10, 64) | ||
161 | + return | ||
162 | +} |
@@ -46,3 +46,13 @@ func CreateOrderBaseRepository(transactionContext *transaction.TransactionContex | @@ -46,3 +46,13 @@ func CreateOrderBaseRepository(transactionContext *transaction.TransactionContex | ||
46 | func CreateOrderGoodRepository(transactionContext *transaction.TransactionContext) (domain.OrderGoodRepository, error) { | 46 | func CreateOrderGoodRepository(transactionContext *transaction.TransactionContext) (domain.OrderGoodRepository, error) { |
47 | return repository.NewOrderGoodRepository(transactionContext) | 47 | return repository.NewOrderGoodRepository(transactionContext) |
48 | } | 48 | } |
49 | + | ||
50 | +//CreateImInfoRepository Im信息 | ||
51 | +func CreateImInfoRepository(transactionContext *transaction.TransactionContext) (domain.ImInfoRepository, error) { | ||
52 | + return repository.NewImInfoRepository(transactionContext) | ||
53 | +} | ||
54 | + | ||
55 | +//CreateImInfoRepository Im信息 | ||
56 | +func CreateCustomerServiceRepository(transactionContext *transaction.TransactionContext) (domain.CustomerServiceRepository, error) { | ||
57 | + return repository.NewCustomerServiceRepository(transactionContext) | ||
58 | +} |
@@ -81,9 +81,10 @@ func orderProducts(order *domain.OrderBase) interface{} { | @@ -81,9 +81,10 @@ func orderProducts(order *domain.OrderBase) interface{} { | ||
81 | item["orderCount"] = good.PlanGoodNumber | 81 | item["orderCount"] = good.PlanGoodNumber |
82 | item["orderAmount"] = good.PlanAmount | 82 | item["orderAmount"] = good.PlanAmount |
83 | item["dividendPercent"] = good.PartnerBonusPercent | 83 | item["dividendPercent"] = good.PartnerBonusPercent |
84 | - item["dividendReceivable"] = good.PartnerBonusHas | ||
85 | - item["dividendUnReceive"] = good.PartnerBonusNot | ||
86 | - item["dividendExpend"] = good.PartnerBonusExpense | 84 | + item["dividendReceivable"] = good.PlanPartnerBonus //已收分红 |
85 | + item["dividendReceived"] = good.PartnerBonusHas //已收分红 | ||
86 | + item["dividendUnReceive"] = good.PartnerBonusNot // 未收分红 | ||
87 | + item["dividendExpend"] = good.PartnerBonusExpense //分红支出 | ||
87 | if len(good.Remark) > 0 { | 88 | if len(good.Remark) > 0 { |
88 | item["orderUpdateReason"] = good.Remark | 89 | item["orderUpdateReason"] = good.Remark |
89 | } | 90 | } |
pkg/constant/im.go
0 → 100644
1 | +package constant | ||
2 | + | ||
3 | +import "os" | ||
4 | + | ||
5 | +var ( | ||
6 | + IM_SERVICE_ADDRESS = "https://api.netease.im/nimserver" | ||
7 | + IM_APP_KEY = "ebf3ae278ee1b346773b99be5080f6a9" | ||
8 | + IM_APP_SECRET = "67ea92e1ea45" | ||
9 | +) | ||
10 | + | ||
11 | +func init() { | ||
12 | + if os.Getenv("IM_APP_KEY") != "" { | ||
13 | + IM_APP_KEY = os.Getenv("IM_APP_KEY") | ||
14 | + } | ||
15 | + if os.Getenv("IM_APP_SECRET") != "" { | ||
16 | + IM_APP_SECRET = os.Getenv("IM_APP_SECRET") | ||
17 | + } | ||
18 | +} |
pkg/domain/customer_service.go
0 → 100644
1 | +package domain | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +type CustomerService struct { | ||
6 | + // id | ||
7 | + Id int64 | ||
8 | + // 用户id(合伙人Id) | ||
9 | + UserId int64 | ||
10 | + // IM唯一id | ||
11 | + ImId string | ||
12 | + // IM颁发的token | ||
13 | + ImToken string | ||
14 | + // 创建时间 | ||
15 | + CreateTime time.Time | ||
16 | + // 更新时间 | ||
17 | + UpdateTime time.Time | ||
18 | +} | ||
19 | + | ||
20 | +type CustomerServiceRepository interface { | ||
21 | + Save(dm *CustomerService) (*CustomerService, error) | ||
22 | + Remove(dm *CustomerService) (*CustomerService, error) | ||
23 | + FindOne(queryOptions map[string]interface{}) (*CustomerService, error) | ||
24 | + Find(queryOptions map[string]interface{}) (int64, []*CustomerService, error) | ||
25 | +} | ||
26 | + | ||
27 | +func (m *CustomerService) Identify() interface{} { | ||
28 | + if m.Id == 0 { | ||
29 | + return nil | ||
30 | + } | ||
31 | + return m.Id | ||
32 | +} |
1 | package domain | 1 | package domain |
2 | 2 | ||
3 | +import "fmt" | ||
4 | + | ||
3 | //查询参数 | 5 | //查询参数 |
4 | const ( | 6 | const ( |
5 | ASC = "ASC" | 7 | ASC = "ASC" |
@@ -15,3 +17,7 @@ const ( | @@ -15,3 +17,7 @@ const ( | ||
15 | BonusWaitPay = iota + 1 //等待支付分红 | 17 | BonusWaitPay = iota + 1 //等待支付分红 |
16 | BonusPaid //已经支付分红 | 18 | BonusPaid //已经支付分红 |
17 | ) | 19 | ) |
20 | + | ||
21 | +var ( | ||
22 | + QueryNoRow = fmt.Errorf("not row found") | ||
23 | +) |
pkg/domain/im_info.go
0 → 100644
1 | +package domain | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +type ImInfo struct { | ||
6 | + tableName struct{} `pg:"im_info"` | ||
7 | + // id | ||
8 | + Id int64 | ||
9 | + // 合伙人Id | ||
10 | + UserId int64 | ||
11 | + // IM唯一id | ||
12 | + ImId string | ||
13 | + // IM颁发的token | ||
14 | + ImToken string | ||
15 | + // 客服IM编号 | ||
16 | + CustomerImId int64 | ||
17 | + // 是否是客服 true:是 false:否 | ||
18 | + //IsCustomer bool | ||
19 | + // 创建时间 | ||
20 | + CreateTime time.Time | ||
21 | + // 更新时间 | ||
22 | + UpdateTime time.Time | ||
23 | +} | ||
24 | + | ||
25 | +type ImInfoRepository interface { | ||
26 | + Save(dm *ImInfo) (*ImInfo, error) | ||
27 | + Remove(dm *ImInfo) (*ImInfo, error) | ||
28 | + FindOne(queryOptions map[string]interface{}) (*ImInfo, error) | ||
29 | + Find(queryOptions map[string]interface{}) (int64, []*ImInfo, error) | ||
30 | +} | ||
31 | + | ||
32 | +func (m *ImInfo) Identify() interface{} { | ||
33 | + if m.Id == 0 { | ||
34 | + return nil | ||
35 | + } | ||
36 | + return m.Id | ||
37 | +} |
pkg/infrastructure/im/im.go
0 → 100644
1 | +package im | ||
2 | + | ||
3 | +import ( | ||
4 | + "encoding/json" | ||
5 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/constant" | ||
6 | +) | ||
7 | + | ||
8 | +func init() { | ||
9 | + InitImClient(constant.IM_SERVICE_ADDRESS, constant.IM_APP_KEY, constant.IM_APP_SECRET) | ||
10 | +} | ||
11 | + | ||
12 | +type RequestParam interface { | ||
13 | + Format() map[string]string | ||
14 | + GetPath() string | ||
15 | + Valid() error | ||
16 | +} | ||
17 | + | ||
18 | +//接口 | ||
19 | +func CallCreate(v UserCreate) (*UserTokenResult, error) { | ||
20 | + var result UserTokenResult | ||
21 | + btData, err := DefaultImClient.Call(v) | ||
22 | + if err != nil { | ||
23 | + return nil, err | ||
24 | + } | ||
25 | + err = json.Unmarshal(btData, &result) | ||
26 | + if err != nil { | ||
27 | + return nil, err | ||
28 | + } | ||
29 | + return &result, nil | ||
30 | +} | ||
31 | +func CallRefreshToken(v UserRefreshToken) (*UserTokenResult, error) { | ||
32 | + var result UserTokenResult | ||
33 | + btData, err := DefaultImClient.Call(v) | ||
34 | + if err != nil { | ||
35 | + return nil, err | ||
36 | + } | ||
37 | + err = json.Unmarshal(btData, &result) | ||
38 | + if err != nil { | ||
39 | + return nil, err | ||
40 | + } | ||
41 | + return &result, nil | ||
42 | +} | ||
43 | +func CallUpdate(v UserUpdate) (*BaseResp, error) { | ||
44 | + var result BaseResp | ||
45 | + btData, err := DefaultImClient.Call(v) | ||
46 | + if err != nil { | ||
47 | + return nil, err | ||
48 | + } | ||
49 | + err = json.Unmarshal(btData, &result) | ||
50 | + if err != nil { | ||
51 | + return nil, err | ||
52 | + } | ||
53 | + return &result, nil | ||
54 | +} |
pkg/infrastructure/im/im_test.go
0 → 100644
1 | +package im | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/constant" | ||
5 | + "testing" | ||
6 | +) | ||
7 | + | ||
8 | +func TestCallCreate(t *testing.T) { | ||
9 | + InitImClient(constant.IM_SERVICE_ADDRESS, constant.IM_APP_KEY, constant.IM_APP_SECRET) | ||
10 | + token, err := CallCreate(UserCreate{Accid: "1"}) | ||
11 | + if err != nil { | ||
12 | + t.Fatal(err) | ||
13 | + } | ||
14 | + if token == nil { | ||
15 | + t.Fatal("token is nil") | ||
16 | + } | ||
17 | + t.Log(token.Code, token.Info) | ||
18 | +} | ||
19 | + | ||
20 | +func TestCallRefreshToken(t *testing.T) { | ||
21 | + InitImClient(constant.IM_SERVICE_ADDRESS, constant.IM_APP_KEY, constant.IM_APP_SECRET) | ||
22 | + token, err := CallRefreshToken(UserRefreshToken{Accid: "1"}) | ||
23 | + if err != nil { | ||
24 | + t.Fatal(err) | ||
25 | + } | ||
26 | + if token == nil { | ||
27 | + t.Fatal("token is nil") | ||
28 | + } | ||
29 | + t.Log(token.Code, token.Info) | ||
30 | +} | ||
31 | + | ||
32 | +func TestCallUpdate(t *testing.T) { | ||
33 | + InitImClient(constant.IM_SERVICE_ADDRESS, constant.IM_APP_KEY, constant.IM_APP_SECRET) | ||
34 | + token, err := CallUpdate(UserUpdate{Accid: "1", Name: "tip tok"}) | ||
35 | + if err != nil { | ||
36 | + t.Fatal(err) | ||
37 | + } | ||
38 | + if token == nil { | ||
39 | + t.Fatal("token is nil") | ||
40 | + } | ||
41 | + t.Log(token.Code) | ||
42 | +} |
pkg/infrastructure/im/netease.go
0 → 100644
1 | +package im | ||
2 | + | ||
3 | +import ( | ||
4 | + "crypto/sha1" | ||
5 | + "encoding/hex" | ||
6 | + "fmt" | ||
7 | + "io/ioutil" | ||
8 | + "math/rand" | ||
9 | + "net/http" | ||
10 | + "net/url" | ||
11 | + "strconv" | ||
12 | + "strings" | ||
13 | + "time" | ||
14 | +) | ||
15 | + | ||
16 | +var DefaultImClient Client | ||
17 | + | ||
18 | +var ErrorFailCall = fmt.Errorf(" imclient call failed") | ||
19 | + | ||
20 | +func InitImClient(baseUrl, appKey, appSecret string) { | ||
21 | + DefaultImClient = Client{ | ||
22 | + baseUrl: baseUrl, | ||
23 | + appKey: appKey, | ||
24 | + appSecret: appSecret, | ||
25 | + } | ||
26 | +} | ||
27 | + | ||
28 | +type Client struct { | ||
29 | + baseUrl string | ||
30 | + appKey string | ||
31 | + appSecret string | ||
32 | +} | ||
33 | + | ||
34 | +func (i Client) Call(param RequestParam) ([]byte, error) { | ||
35 | + return i.httpDo(param.GetPath(), param.Format()) | ||
36 | +} | ||
37 | +func (i Client) buildHeader() http.Header { | ||
38 | + var h = http.Header{} | ||
39 | + curTime := strconv.FormatInt(time.Now().Unix(), 10) | ||
40 | + nonce := strconv.FormatInt(time.Now().Unix()+rand.Int63n(5000), 10) | ||
41 | + checkSum := buildCheckSum(i.appSecret, nonce, curTime) | ||
42 | + h.Set("Content-Type", "application/x-www-form-urlencoded") | ||
43 | + h.Set("AppKey", i.appKey) | ||
44 | + h.Set("Nonce", nonce) | ||
45 | + h.Set("CurTime", curTime) | ||
46 | + h.Set("CheckSum", checkSum) | ||
47 | + return h | ||
48 | +} | ||
49 | +func (i Client) httpDo(path string, posts map[string]string) ([]byte, error) { | ||
50 | + client := http.Client{ | ||
51 | + Timeout: 5 * time.Second, //请求超时时间5秒 | ||
52 | + } | ||
53 | + reqURL := i.baseUrl + path | ||
54 | + params := url.Values{} | ||
55 | + for k, v := range posts { | ||
56 | + params.Add(k, v) | ||
57 | + } | ||
58 | + req, err := http.NewRequest("POST", reqURL, strings.NewReader(params.Encode())) | ||
59 | + if err != nil { | ||
60 | + return nil, err | ||
61 | + } | ||
62 | + req.Header = i.buildHeader() | ||
63 | + resp, err := client.Do(req) | ||
64 | + if err != nil { | ||
65 | + return nil, err | ||
66 | + } | ||
67 | + defer resp.Body.Close() | ||
68 | + | ||
69 | + body, err := ioutil.ReadAll(resp.Body) | ||
70 | + if err != nil { | ||
71 | + return nil, err | ||
72 | + } | ||
73 | + | ||
74 | + return body, nil | ||
75 | +} | ||
76 | + | ||
77 | +func buildCheckSum(appSecret string, nonce string, curTime string) string { | ||
78 | + str := []byte(appSecret + nonce + curTime) | ||
79 | + sh := sha1.New() | ||
80 | + sh.Write(str) | ||
81 | + result := hex.EncodeToString(sh.Sum(nil)) | ||
82 | + return strings.ToLower(result) | ||
83 | +} |
pkg/infrastructure/im/netease_request.go
0 → 100644
1 | +package im | ||
2 | + | ||
3 | +import ( | ||
4 | + "fmt" | ||
5 | +) | ||
6 | + | ||
7 | +var ( | ||
8 | + _ RequestParam = UserCreate{} | ||
9 | + _ RequestParam = UserUpdate{} | ||
10 | + _ RequestParam = UserRefreshToken{} | ||
11 | +) | ||
12 | + | ||
13 | +type BaseResp struct { | ||
14 | + Code int `json:"code"` | ||
15 | +} | ||
16 | + | ||
17 | +// TokenInfo 云通信Token | ||
18 | +type TokenInfo struct { | ||
19 | + Token string `json:"token"` | ||
20 | + Accid string `json:"accid"` | ||
21 | + Name string `json:"name"` | ||
22 | +} | ||
23 | +type UserTokenResult struct { | ||
24 | + BaseResp | ||
25 | + Info TokenInfo `json:"info"` | ||
26 | +} | ||
27 | + | ||
28 | +// 创建网易云通信ID | ||
29 | +type UserCreate struct { | ||
30 | + Accid string //网易云通信ID,最大长度32字符 | ||
31 | + Name string //ID昵称,最大长度64字符。 | ||
32 | + Props string //json属性,开发者可选填,最大长度1024字符 | ||
33 | + Icon string //ID头像URL,开发者可选填,最大长度1024字符 | ||
34 | + /** | ||
35 | + 云通信ID可以指定登录token值,最大长度128字符, | ||
36 | + 并更新,如果未指定,会自动生成token,并在 | ||
37 | + 创建成功后返回 | ||
38 | + **/ | ||
39 | + Token string | ||
40 | + Sign string //签名 | ||
41 | + Email string | ||
42 | + Birth string | ||
43 | + Mobile string | ||
44 | + Gender int //0未知,1男,2女 | ||
45 | + Ex string //扩展字段 | ||
46 | +} | ||
47 | + | ||
48 | +func (p UserCreate) Format() map[string]string { | ||
49 | + return map[string]string{ | ||
50 | + "accid": p.Accid, | ||
51 | + "name": p.Name, | ||
52 | + "props": p.Props, | ||
53 | + "icon": p.Icon, | ||
54 | + "token": p.Token, | ||
55 | + "sign": p.Sign, | ||
56 | + "email": p.Email, | ||
57 | + "birth": p.Birth, | ||
58 | + "mobile": p.Mobile, | ||
59 | + "gender": fmt.Sprintf("%d", p.Gender), | ||
60 | + "ex": p.Ex, | ||
61 | + } | ||
62 | +} | ||
63 | +func (p UserCreate) GetPath() string { | ||
64 | + return "/user/create.action" | ||
65 | +} | ||
66 | +func (p UserCreate) Valid() error { | ||
67 | + return nil | ||
68 | +} | ||
69 | + | ||
70 | +// 重置网易云通信token | ||
71 | +type UserRefreshToken struct { | ||
72 | + Accid string //网易云通信ID,最大长度32字符,必须保证一个 APP内唯一 | ||
73 | +} | ||
74 | + | ||
75 | +func (p UserRefreshToken) Format() map[string]string { | ||
76 | + return map[string]string{ | ||
77 | + "accid": p.Accid, | ||
78 | + } | ||
79 | +} | ||
80 | +func (p UserRefreshToken) GetPath() string { | ||
81 | + return "/user/refreshToken.action" | ||
82 | +} | ||
83 | +func (p UserRefreshToken) Valid() error { | ||
84 | + return nil | ||
85 | +} | ||
86 | + | ||
87 | +// 更新网易云通信token | ||
88 | +type UserUpdate struct { | ||
89 | + Accid string | ||
90 | + Name string //这边网易云要有昵称以手机号码为昵称 | ||
91 | + Icon string //icon默认头像 | ||
92 | + Sign string //签名 | ||
93 | + Email string | ||
94 | + Birth string | ||
95 | + Mobile string | ||
96 | + Gender int //0未知,1男,2女 | ||
97 | + Ex string //扩展字段 | ||
98 | +} | ||
99 | + | ||
100 | +func (u UserUpdate) Format() map[string]string { | ||
101 | + return map[string]string{ | ||
102 | + "accid": u.Accid, | ||
103 | + "name": u.Name, | ||
104 | + "icon": u.Icon, | ||
105 | + "sign": u.Sign, | ||
106 | + "email": u.Email, | ||
107 | + "birth": u.Birth, | ||
108 | + "mobile": u.Mobile, | ||
109 | + "gender": fmt.Sprintf("%d", u.Gender), | ||
110 | + "ex": u.Ex, | ||
111 | + } | ||
112 | +} | ||
113 | +func (u UserUpdate) GetPath() string { | ||
114 | + return "/user/refreshToken.action" | ||
115 | +} | ||
116 | +func (u UserUpdate) Valid() error { | ||
117 | + return nil | ||
118 | +} |
@@ -33,6 +33,8 @@ func init() { | @@ -33,6 +33,8 @@ func init() { | ||
33 | (*models.Company)(nil), | 33 | (*models.Company)(nil), |
34 | (*models.OrderBase)(nil), | 34 | (*models.OrderBase)(nil), |
35 | (*models.OrderGood)(nil), | 35 | (*models.OrderGood)(nil), |
36 | + (*models.ImInfo)(nil), | ||
37 | + (*models.CustomerService)(nil), | ||
36 | } { | 38 | } { |
37 | err := DB.CreateTable(model, &orm.CreateTableOptions{ | 39 | err := DB.CreateTable(model, &orm.CreateTableOptions{ |
38 | Temp: false, | 40 | Temp: false, |
1 | +package models | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +type CustomerService struct { | ||
6 | + tableName struct{} `pg:"customer_service"` | ||
7 | + // id | ||
8 | + Id int64 | ||
9 | + // 用户id(合伙人Id) | ||
10 | + UserId int64 | ||
11 | + // IM唯一id | ||
12 | + ImId string | ||
13 | + // IM颁发的token | ||
14 | + ImToken string | ||
15 | + // 创建时间 | ||
16 | + CreateTime time.Time | ||
17 | + // 更新时间 | ||
18 | + UpdateTime time.Time | ||
19 | +} |
pkg/infrastructure/pg/models/im_info.go
0 → 100644
1 | +package models | ||
2 | + | ||
3 | +import "time" | ||
4 | + | ||
5 | +type ImInfo struct { | ||
6 | + tableName struct{} `pg:"im_info"` | ||
7 | + // id | ||
8 | + Id int64 | ||
9 | + // 合伙人Id | ||
10 | + UserId int64 | ||
11 | + // IM唯一id | ||
12 | + ImId string | ||
13 | + // IM颁发的token | ||
14 | + ImToken string | ||
15 | + // 客服IM编号 | ||
16 | + CustomerImId int64 | ||
17 | + // 是否是客服 true:是 false:否 | ||
18 | + //IsCustomer bool | ||
19 | + // 创建时间 | ||
20 | + CreateTime time.Time | ||
21 | + // 更新时间 | ||
22 | + UpdateTime time.Time | ||
23 | +} |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain" | ||
5 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/models" | ||
6 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/transaction" | ||
7 | + . "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/utils" | ||
8 | +) | ||
9 | + | ||
10 | +type CustomerServiceRepository struct { | ||
11 | + transactionContext *transaction.TransactionContext | ||
12 | +} | ||
13 | + | ||
14 | +func (repository *CustomerServiceRepository) Save(dm *domain.CustomerService) (*domain.CustomerService, error) { | ||
15 | + var ( | ||
16 | + err error | ||
17 | + m = &models.CustomerService{} | ||
18 | + tx = repository.transactionContext.PgTx | ||
19 | + ) | ||
20 | + if err = GobModelTransform(m, dm); err != nil { | ||
21 | + return nil, err | ||
22 | + } | ||
23 | + if dm.Identify() == nil { | ||
24 | + if err = tx.Insert(m); err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + return dm, nil | ||
28 | + } | ||
29 | + if err = tx.Update(m); err != nil { | ||
30 | + return nil, err | ||
31 | + } | ||
32 | + return dm, nil | ||
33 | +} | ||
34 | + | ||
35 | +func (repository *CustomerServiceRepository) Remove(CustomerService *domain.CustomerService) (*domain.CustomerService, error) { | ||
36 | + var ( | ||
37 | + tx = repository.transactionContext.PgTx | ||
38 | + CustomerServiceModel = &models.CustomerService{Id: CustomerService.Identify().(int64)} | ||
39 | + ) | ||
40 | + if _, err := tx.Model(CustomerServiceModel).Where("id = ?", CustomerService.Id).Delete(); err != nil { | ||
41 | + return CustomerService, err | ||
42 | + } | ||
43 | + return CustomerService, nil | ||
44 | +} | ||
45 | + | ||
46 | +func (repository *CustomerServiceRepository) FindOne(queryOptions map[string]interface{}) (*domain.CustomerService, error) { | ||
47 | + tx := repository.transactionContext.PgTx | ||
48 | + CustomerServiceModel := new(models.CustomerService) | ||
49 | + query := NewQuery(tx.Model(CustomerServiceModel), queryOptions) | ||
50 | + query.SetWhere("id = ?", "id") | ||
51 | + query.SetWhere("user_id = ?", "user_id") | ||
52 | + if err := query.First(); err != nil { | ||
53 | + return nil, domain.QueryNoRow | ||
54 | + } | ||
55 | + if CustomerServiceModel.Id == 0 { | ||
56 | + return nil, domain.QueryNoRow | ||
57 | + } | ||
58 | + return repository.transformPgModelToDomainModel(CustomerServiceModel) | ||
59 | +} | ||
60 | + | ||
61 | +func (repository *CustomerServiceRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.CustomerService, error) { | ||
62 | + tx := repository.transactionContext.PgTx | ||
63 | + var CustomerServiceModels []*models.CustomerService | ||
64 | + CustomerServices := make([]*domain.CustomerService, 0) | ||
65 | + query := NewQuery(tx.Model(&CustomerServiceModels), queryOptions). | ||
66 | + SetOrder("create_time", "sortByCreateTime"). | ||
67 | + SetOrder("update_time", "sortByUpdateTime"). | ||
68 | + SetOrder("id", "sortById") | ||
69 | + var err error | ||
70 | + if query.AffectRow, err = query.SelectAndCount(); err != nil { | ||
71 | + return 0, CustomerServices, err | ||
72 | + } | ||
73 | + for _, CustomerServiceModel := range CustomerServiceModels { | ||
74 | + if CustomerService, err := repository.transformPgModelToDomainModel(CustomerServiceModel); err != nil { | ||
75 | + return 0, CustomerServices, err | ||
76 | + } else { | ||
77 | + CustomerServices = append(CustomerServices, CustomerService) | ||
78 | + } | ||
79 | + } | ||
80 | + return int64(query.AffectRow), CustomerServices, nil | ||
81 | +} | ||
82 | + | ||
83 | +func (repository *CustomerServiceRepository) transformPgModelToDomainModel(CustomerServiceModel *models.CustomerService) (*domain.CustomerService, error) { | ||
84 | + m := &domain.CustomerService{} | ||
85 | + err := GobModelTransform(m, CustomerServiceModel) | ||
86 | + return m, err | ||
87 | +} | ||
88 | + | ||
89 | +func NewCustomerServiceRepository(transactionContext *transaction.TransactionContext) (*CustomerServiceRepository, error) { | ||
90 | + if transactionContext == nil { | ||
91 | + return nil, ERR_EMPTY_TC | ||
92 | + } | ||
93 | + return &CustomerServiceRepository{transactionContext: transactionContext}, nil | ||
94 | +} |
1 | +package repository | ||
2 | + | ||
3 | +import ( | ||
4 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/domain" | ||
5 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/models" | ||
6 | + "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/pg/transaction" | ||
7 | + . "gitlab.fjmaimaimai.com/mmm-go/partner/pkg/infrastructure/utils" | ||
8 | +) | ||
9 | + | ||
10 | +type ImInfoRepository struct { | ||
11 | + transactionContext *transaction.TransactionContext | ||
12 | +} | ||
13 | + | ||
14 | +func (repository *ImInfoRepository) Save(dm *domain.ImInfo) (*domain.ImInfo, error) { | ||
15 | + var ( | ||
16 | + err error | ||
17 | + m = &models.ImInfo{} | ||
18 | + tx = repository.transactionContext.PgTx | ||
19 | + ) | ||
20 | + if err = GobModelTransform(m, dm); err != nil { | ||
21 | + return nil, err | ||
22 | + } | ||
23 | + if dm.Identify() == nil { | ||
24 | + if err = tx.Insert(m); err != nil { | ||
25 | + return nil, err | ||
26 | + } | ||
27 | + return dm, nil | ||
28 | + } | ||
29 | + if err = tx.Update(m); err != nil { | ||
30 | + return nil, err | ||
31 | + } | ||
32 | + return dm, nil | ||
33 | +} | ||
34 | + | ||
35 | +func (repository *ImInfoRepository) Remove(ImInfo *domain.ImInfo) (*domain.ImInfo, error) { | ||
36 | + var ( | ||
37 | + tx = repository.transactionContext.PgTx | ||
38 | + ImInfoModel = &models.ImInfo{Id: ImInfo.Identify().(int64)} | ||
39 | + ) | ||
40 | + if _, err := tx.Model(ImInfoModel).Where("id = ?", ImInfo.Id).Delete(); err != nil { | ||
41 | + return ImInfo, err | ||
42 | + } | ||
43 | + return ImInfo, nil | ||
44 | +} | ||
45 | + | ||
46 | +func (repository *ImInfoRepository) FindOne(queryOptions map[string]interface{}) (*domain.ImInfo, error) { | ||
47 | + tx := repository.transactionContext.PgTx | ||
48 | + ImInfoModel := new(models.ImInfo) | ||
49 | + query := NewQuery(tx.Model(ImInfoModel), queryOptions) | ||
50 | + query.SetWhere("id = ?", "id") | ||
51 | + query.SetWhere("user_id = ?", "user_id") | ||
52 | + if err := query.First(); err != nil { | ||
53 | + return nil, domain.QueryNoRow | ||
54 | + } | ||
55 | + if ImInfoModel.Id == 0 { | ||
56 | + return nil, domain.QueryNoRow | ||
57 | + } | ||
58 | + return repository.transformPgModelToDomainModel(ImInfoModel) | ||
59 | +} | ||
60 | + | ||
61 | +func (repository *ImInfoRepository) Find(queryOptions map[string]interface{}) (int64, []*domain.ImInfo, error) { | ||
62 | + tx := repository.transactionContext.PgTx | ||
63 | + var ImInfoModels []*models.ImInfo | ||
64 | + ImInfos := make([]*domain.ImInfo, 0) | ||
65 | + query := NewQuery(tx.Model(&ImInfoModels), queryOptions). | ||
66 | + SetOrder("im_info.create_time", "sortByCreateTime"). | ||
67 | + SetOrder("im_info.update_time", "sortByUpdateTime") | ||
68 | + var err error | ||
69 | + if query.AffectRow, err = query.SelectAndCount(); err != nil { | ||
70 | + return 0, ImInfos, err | ||
71 | + } | ||
72 | + for _, ImInfoModel := range ImInfoModels { | ||
73 | + if ImInfo, err := repository.transformPgModelToDomainModel(ImInfoModel); err != nil { | ||
74 | + return 0, ImInfos, err | ||
75 | + } else { | ||
76 | + ImInfos = append(ImInfos, ImInfo) | ||
77 | + } | ||
78 | + } | ||
79 | + return int64(query.AffectRow), ImInfos, nil | ||
80 | +} | ||
81 | + | ||
82 | +func (repository *ImInfoRepository) transformPgModelToDomainModel(ImInfoModel *models.ImInfo) (*domain.ImInfo, error) { | ||
83 | + m := &domain.ImInfo{} | ||
84 | + err := GobModelTransform(m, ImInfoModel) | ||
85 | + return m, err | ||
86 | +} | ||
87 | + | ||
88 | +func NewImInfoRepository(transactionContext *transaction.TransactionContext) (*ImInfoRepository, error) { | ||
89 | + if transactionContext == nil { | ||
90 | + return nil, ERR_EMPTY_TC | ||
91 | + } | ||
92 | + return &ImInfoRepository{transactionContext: transactionContext}, nil | ||
93 | +} |
@@ -91,3 +91,17 @@ type AuthCheckSmsCodeRequest struct { | @@ -91,3 +91,17 @@ type AuthCheckSmsCodeRequest struct { | ||
91 | type AuthCheckSmsCodeResponse struct { | 91 | type AuthCheckSmsCodeResponse struct { |
92 | CaptchaCertificate string `json:"captchaCertificate"` //短信验证码通过凭证 | 92 | CaptchaCertificate string `json:"captchaCertificate"` //短信验证码通过凭证 |
93 | } | 93 | } |
94 | + | ||
95 | +/*CheckIm */ | ||
96 | +type CheckImRequest struct { | ||
97 | + UserId int64 | ||
98 | + ImId string | ||
99 | + Uname string | ||
100 | + Icon string | ||
101 | + CustomerImId string | ||
102 | + IsCreated bool | ||
103 | +} | ||
104 | +type CheckImResponse struct { | ||
105 | + ImToken string //net im token | ||
106 | + CsAccount int64 //客服id | ||
107 | +} |
-
请 注册 或 登录 后发表评论