Browse Source

1.微信加好友两个接口使用同一套API界面和逻辑,只是验证方式不同 
2.参数支持多微信ID和多手机同时添加,并且有随机对齐补全功能

liwei 4 ngày trước cách đây
mục cha
commit
8d2b6ec6b8

+ 4 - 3
desc/openapi/chat.api

@@ -5,10 +5,11 @@ type (
     
 	//add_friend_by_phone api接口请求值
 	AddFriendByPhoneReq {
-		Type int `json:"type"`
-		WeChatId string `json:"WeChatId"`
-		Phone string `json:"phone"`
+		Type int `json:"type,options=1|3,default=1"`
+		WeChatIds []string `json:"wechat_ids,optional,omitempty"`
+		Phones []string `json:"phones"`
 		Message string `json:"message"`
+		CallbackURL string `json:"callback_url,optional"`
 	}
 
 	//以下是API请求类型

+ 2 - 11
desc/wechat/add_wechat_friend_log.api

@@ -1,15 +1,6 @@
 import "../base.api"
+import "../openapi/chat.api"
 
-type (
-    
-    //add_friend_by_phone api接口请求值
-    AddWechatFriendLogInfo {
-        Type int `json:"type"`
-        WeChatIds []string `json:"WeChatIds,optional,omitempty"`
-        Phone string `json:"phone"`
-        Message string `json:"message"`
-    }
-)
 
 @server(
     jwt: Auth
@@ -20,5 +11,5 @@ type (
 service Wechat {
     // 手机号加好友接口
     @handler AddFriendByPhone
-    post /add_friend/add_friend_by_phone (AddWechatFriendLogInfo) returns (BaseMsgResp)
+    post /add_friend/add_friend_by_phone (AddFriendByPhoneReq) returns (BaseMsgResp)
 } 

+ 1 - 1
internal/handler/add_friend/add_friend_by_phone_handler.go

@@ -27,7 +27,7 @@ import (
 
 func AddFriendByPhoneHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
 	return func(w http.ResponseWriter, r *http.Request) {
-		var req types.AddWechatFriendLogInfo
+		var req types.AddFriendByPhoneReq
 		if err := httpx.Parse(r, &req, true); err != nil {
 			httpx.ErrorCtx(r.Context(), w, err)
 			return

+ 3 - 49
internal/logic/add_friend/add_friend_by_phone_logic.go

@@ -4,12 +4,9 @@ import (
 	"context"
 
 	"wechat-api/internal/logic/chat"
-	"wechat-api/internal/service/addfriend"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 
-	"github.com/suyuan32/simple-admin-common/enum/errorcode"
-	"github.com/suyuan32/simple-admin-common/msg/errormsg"
 	"github.com/zeromicro/go-zero/core/logx"
 )
 
@@ -26,52 +23,9 @@ func NewAddFriendByPhoneLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
 		svcCtx: svcCtx}
 }
 
-/*
-func getWeChatIds(ids any) []string {
-	nids := []string{}
-	switch rv := ids.(type) {
-	case []string:
-		nids = rv
-	case string:
-		nids = append(nids, rv)
-	}
-	return nids
-}
-*/
-
-func (l *AddFriendByPhoneLogic) AddFriendByPhone(req *types.AddWechatFriendLogInfo) (resp *types.BaseMsgResp, err error) {
+func (l *AddFriendByPhoneLogic) AddFriendByPhone(req *types.AddFriendByPhoneReq) (resp *types.BaseMsgResp, err error) {
 	// todo: add your logic here and delete this line
 
-	if req.Type != 2 {
-		req.Type = 1
-	}
-	if len(req.WeChatIds) == 0 {
-		req.WeChatIds = append(req.WeChatIds, "")
-	}
-	for _, wechatId := range req.WeChatIds {
-		nreq := &types.AddFriendByPhoneReq{Type: req.Type, WeChatId: wechatId, Phone: req.Phone, Message: req.Message}
-		//fmt.Println(typekit.PrettyPrint(nreq))
-		id, err := chat.AppendWechaFriendAddLog(l.ctx, l.svcCtx, nreq)
-		if err != nil {
-			logx.Errorf("chat.AppendWechaFriendAddLog err : %s", err)
-			continue
-		}
-		logx.Infof("chat.AppendWechaFriendAddLog succ,get id:%d",
-			id)
-
-		if req.Type != 1 {
-			continue //企微忽略后面
-		}
-		ret := addfriend.NewAddWechatFriendService(l.ctx, l.svcCtx).
-			FindFriendByContent(wechatId, req.Phone)
-		if ret {
-			logx.Infof("call addfriend.NewAddWechatFriendService.FindFriendByContent('%s','%s') maybe succ", wechatId, req.Phone)
-		}
-	}
-	resp = &types.BaseMsgResp{
-		Msg:  errormsg.Success,
-		Code: errorcode.OK,
-	}
-
-	return resp, nil
+	chatLogic := chat.NewAddFriendByPhoneLogic(l.ctx, l.svcCtx)
+	return chatLogic.AddFriendByPhone(req)
 }

+ 137 - 34
internal/logic/chat/add_friend_by_phone_logic.go

@@ -5,10 +5,12 @@ import (
 	"errors"
 
 	"wechat-api/ent"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/wx"
 	"wechat-api/internal/service/addfriend"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
-	"wechat-api/internal/utils/contextkey"
+	"wechat-api/internal/utils/typekit"
 
 	"github.com/suyuan32/simple-admin-common/enum/errorcode"
 	"github.com/suyuan32/simple-admin-common/msg/errormsg"
@@ -28,47 +30,157 @@ func NewAddFriendByPhoneLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
 		svcCtx: svcCtx}
 }
 
+func GetRandWxid(idList []string) string {
+	id := ""
+	if len(idList) > 0 {
+		typekit.ShuffleList(idList)
+		id = idList[0]
+	}
+	return id
+}
+
+func (l *AddFriendByPhoneLogic) getWxInfoList(preds ...predicate.Wx) ([]*ent.Wx, error) {
+	preds = append(preds, wx.StatusEQ(1))
+	return l.svcCtx.DB.Wx.Query().Where(preds...).All(l.ctx)
+}
+
+func (l *AddFriendByPhoneLogic) getWxIdListByOid(Oid uint64, Type uint64) ([]string, error) {
+	preds := []predicate.Wx{}
+	preds = append(preds, wx.OrganizationIDEQ(Oid))
+	if Type == 1 || Type == 3 {
+		preds = append(preds, wx.CtypeEQ(Type))
+	}
+	wxIdList := []string{}
+	wxInfoList, err := l.getWxInfoList(preds...)
+	if err == nil {
+		for _, wxInfo := range wxInfoList {
+			wxIdList = append(wxIdList, wxInfo.Wxid)
+		}
+	}
+	return wxIdList, err
+}
+
+type AddFriendByPhoneInfo struct {
+	Type        int    `json:"type"`
+	WeChatId    string `json:"wechat_id"`
+	Phone       string `json:"phone"`
+	Message     string `json:"message"`
+	CallbackURL string `json:"callback_url"`
+}
+
+func (l *AddFriendByPhoneLogic) rebuildAddFriendByPhoneInfos(req *types.AddFriendByPhoneReq,
+	Oid uint64) ([]AddFriendByPhoneInfo, error) {
+
+	var err error
+	_, req.WeChatIds, req.Phones, err = l.alignWxidsAndPhones(Oid,
+		uint64(req.Type), req.WeChatIds, req.Phones)
+	if err != nil {
+		return nil, err
+	}
+	infos := []AddFriendByPhoneInfo{}
+	for idx, weChatid := range req.WeChatIds {
+		info := AddFriendByPhoneInfo{Type: req.Type, WeChatId: weChatid,
+			Phone: req.Phones[idx], Message: req.Message, CallbackURL: req.CallbackURL}
+		infos = append(infos, info)
+	}
+	return infos, nil
+}
+
+func (l *AddFriendByPhoneLogic) alignWxidsAndPhones(Oid uint64, CType uint64,
+	weChatIds []string, phones []string) (bool, []string, []string, error) {
+
+	lenWechatIds := len(weChatIds)
+	lenPhones := len(phones)
+	//case1: 输入的wxids和phones大小一样,不需要对齐
+	if lenWechatIds == lenPhones {
+		return true, weChatIds, phones, nil
+	}
+	//case2: 输入的wxids比phones小或者空
+	if lenWechatIds < lenPhones {
+		allWxIds, err := l.getWxIdListByOid(Oid, CType)
+		if err != nil {
+			return false, weChatIds, phones, err
+		}
+		if len(allWxIds) == 0 {
+			if len(weChatIds) == 0 {
+				err = errors.New("db wxIds empty")
+			}
+			return false, weChatIds, phones, err
+		}
+		for i := 0; i < lenPhones-lenWechatIds; i++ {
+			weChatIds = append(weChatIds, GetRandWxid(allWxIds))
+		}
+	} else { //case 3: 输入的wxids比phones大
+		for i := 0; i < lenWechatIds-lenPhones; i++ {
+			phones = append(phones, GetRandWxid(phones))
+		}
+	}
+	return true, weChatIds, phones, nil
+}
+
 func (l *AddFriendByPhoneLogic) AddFriendByPhone(req *types.AddFriendByPhoneReq) (resp *types.BaseMsgResp, err error) {
 	// todo: add your logic here and delete this line
 
-	var (
-		apiKeyObj *ent.ApiKey
-		ok        bool
-	)
+	if len(req.Phones) == 0 {
+		return nil, errors.New("miss phone")
+	}
 
-	//从上下文中获取鉴权中间件埋下的apiAuthInfo
-	apiKeyObj, ok = contextkey.AuthTokenInfoKey.GetValue(l.ctx)
-	if !ok {
-		return nil, errors.New("content get auth info err")
+	orgID, ok := l.ctx.Value("organizationId").(uint64)
+	if !ok || orgID == 0 {
+		return nil, errors.New("content get oid info err")
 	}
-	err = l.AppendWechaFriendAddReq(apiKeyObj, req)
+
+	//fmt.Println("before weChatIds:", req.WeChatIds)
+	//fmt.Println("before phones:", req.Phones)
+	//apiKeyObj.OrganizationID = 1
+
+	if req.Type != 3 {
+		req.Type = 1
+	}
+	infos, err := l.rebuildAddFriendByPhoneInfos(req, orgID)
 	if err != nil {
 		return nil, err
 	}
-	//addfriend.NewAddWechatFriendService(l.ctx, l.svcCtx).AddNewFriend(req.WeChatId, req.Phone, req.Message)
-	addfriend.NewAddWechatFriendService(l.ctx, l.svcCtx).FindFriendByContent(req.WeChatId, req.Phone)
+	//fmt.Println("after weChatIds:", req.WeChatIds)
+	//fmt.Println("after phones:", req.Phones)
+	//fmt.Println(typekit.PrettyPrint(infos))
 
-	resp = &types.BaseMsgResp{
-		Msg:  errormsg.Success,
-		Code: errorcode.OK,
-	}
+	var id int64
+	for _, info := range infos {
+		id, err = l.AppendWechaFriendAddInfo(&info)
+		if err != nil {
+			logx.Errorf("chat.AppendWechaFriendAddLog err : %s", err)
+			return nil, err
+		}
+		logx.Infof("chat.AppendWechaFriendAddLog succ,get id:%d", id)
 
-	return resp, nil
+		if req.Type != 1 {
+			continue //企微忽略后面
+		}
+		ret := addfriend.NewAddWechatFriendService(l.ctx, l.svcCtx).
+			FindFriendByContent(info.WeChatId, info.Phone)
+		retStr := "fail"
+		if ret {
+			retStr = "succ"
+		}
+		logx.Infof("call addfriend.NewAddWechatFriendService.FindFriendByContent('%s','%s') maybe %s", info.WeChatId, info.Phone, retStr)
+	}
+	return &types.BaseMsgResp{Msg: errormsg.Success, Code: errorcode.OK}, nil
 }
 
-func AppendWechaFriendAddLog(ctx context.Context, svcCtx *svc.ServiceContext, addLog *types.AddFriendByPhoneReq) (int64, error) {
+func (l *AddFriendByPhoneLogic) AppendWechaFriendAddInfo(addInfo *AddFriendByPhoneInfo) (int64, error) {
 
 	isCanAdd := 0
-	if addLog.Type != 1 {
+	if addInfo.Type != 1 {
 		isCanAdd = 1
 	}
-	res, err := svcCtx.DB.AddWechatFriendLog.Create().
-		SetNotNilOwnerWxID(&addLog.WeChatId).
-		SetNotNilOwnerWxType(&addLog.Type).
-		SetNotNilFindContent(&addLog.Phone).
-		SetNotNilMessage(&addLog.Message).
+	res, err := l.svcCtx.DB.AddWechatFriendLog.Create().
+		SetNotNilOwnerWxID(&addInfo.WeChatId).
+		SetNotNilOwnerWxType(&addInfo.Type).
+		SetNotNilFindContent(&addInfo.Phone).
+		SetNotNilMessage(&addInfo.Message).
 		SetIsCanAdd(isCanAdd).
-		Save(ctx)
+		Save(l.ctx)
 
 	id := int64(0)
 	if err == nil {
@@ -76,12 +188,3 @@ func AppendWechaFriendAddLog(ctx context.Context, svcCtx *svc.ServiceContext, ad
 	}
 	return id, err
 }
-
-func (l *AddFriendByPhoneLogic) AppendWechaFriendAddReq(apiKeyObj *ent.ApiKey, req *types.AddFriendByPhoneReq) error {
-
-	id, err := AppendWechaFriendAddLog(l.ctx, l.svcCtx, req)
-	if err == nil {
-		logx.Infof("AppendWechaFriendAddReq succ,get id:%d", id)
-	}
-	return err
-}

+ 1 - 0
internal/middleware/openauthority_middleware.go

@@ -153,6 +153,7 @@ func (m *OpenAuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc
 		}
 
 		ctx = contextkey.AuthTokenInfoKey.WithValue(ctx, apiKeyObj)
+		ctx = context.WithValue(ctx, "organizationId", apiKeyObj.OrganizationID) //兼容awt中间件的方式
 
 		newReq := r.WithContext(ctx)
 		// Passthrough to next handler if need

+ 5 - 13
internal/types/types.go

@@ -1986,10 +1986,11 @@ type WxidReq struct {
 // add_friend_by_phone api接口请求值
 // swagger:model AddFriendByPhoneReq
 type AddFriendByPhoneReq struct {
-	Type     int    `json:"type"`
-	WeChatId string `json:"WeChatId"`
-	Phone    string `json:"phone"`
-	Message  string `json:"message"`
+	Type        int      `json:"type,options=1|3,default=1"`
+	WeChatIds   []string `json:"wechat_ids,optional,omitempty"`
+	Phones      []string `json:"phones"`
+	Message     string   `json:"message"`
+	CallbackURL string   `json:"callback_url,optional"`
 }
 
 // 以下是API请求类型
@@ -4711,12 +4712,3 @@ type LoginResp struct {
 	// The log in information | 登陆返回的数据信息
 	Data LoginInfo `json:"data"`
 }
-
-// add_friend_by_phone api接口请求值
-// swagger:model AddWechatFriendLogInfo
-type AddWechatFriendLogInfo struct {
-	Type      int      `json:"type"`
-	WeChatIds []string `json:"WeChatIds,optional,omitempty"`
-	Phone     string   `json:"phone"`
-	Message   string   `json:"message"`
-}

+ 16 - 0
internal/utils/typekit/list.go

@@ -0,0 +1,16 @@
+package typekit
+
+import "math/rand/v2"
+
+/*
+* 随机打乱一个泛型列表
+*
+*  tl1 := []string{"a", "b", "c"}
+*  tl1 := []int{1,2,3}
+*  ShuffleList(tl1)
+ */
+func ShuffleList[T any](list []T) {
+	rand.Shuffle(len(list), func(i, j int) {
+		list[i], list[j] = list[j], list[i]
+	})
+}