Browse Source

Merge branch 'task_526_lichangdong_250424' into debug

lichangdong 23 hours ago
parent
commit
ebd3b01bf4

+ 1 - 0
crontask/init.go

@@ -24,6 +24,7 @@ func NewCronTask(ctx context.Context, svcCtx *svc.ServiceContext) *CronTask {
 
 func ScheduleRun(c *cron.Cron, serverCtx *svc.ServiceContext) {
 
+	//除了fe环境任务关闭 其他环境任务要正常打开
 	l := NewCronTask(context.Background(), serverCtx)
 	c.AddFunc("* * * * *", func() {
 		l.sendMsg()

+ 10 - 4
desc/openapi/chat.api

@@ -1,14 +1,20 @@
 import "../base.api"
+import "../wechat/wxhook.api"
 
 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"`
+	}
+
+	NullReq {
+
 	}
 
 	//以下是API请求类型
@@ -202,7 +208,7 @@ type (
 service Wechat {
     
     @handler getAuth
-    get /chat/getauth () returns (BaseMsgResp)
+    get /chat/getauth (NullReq) returns (BaseMsgResp)
 }
 
 @server(

+ 52 - 4
desc/wechat/add_wechat_friend_log.api

@@ -4,10 +4,49 @@ type (
     
     //add_friend_by_phone api接口请求值
     AddWechatFriendLogInfo {
-        Type int `json:"type"`
-        WeChatIds []string `json:"WeChatId,optional,omitempty"`
-        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"`
+    }
+
+    AddFriendListReq {
+        PageInfo
+        OwnerWxId *string `json:"wxId,optional"`
+        OwnerWxType *int `json:"wxType,optional"`
+        FindContent *string `json:"phone,optional"`
+        status *int `json:"status,optional"`
+    }
+
+     AddFriendListResp {
+        BaseDataInfo
+        Data FriendListInfo `json:"data"`
+     }
+
+    FriendListInfo {
+        BaseListInfo
+        Data []FriendList `json:"data"`
+    }
+
+    FriendList{
+        Id int64 `json:"id,optional"`
+        // 微信id 公众号微信ID
+        OwnerWxId  *string `json:"wxId,optional"`
+        OwnerWxType  *string `json:"wxType,optional"`
+        FindContent  *string `json:"phone,optional"`
+        Status *string `json:"status,optional"`
+        ErrMessage  *string `json:"errMessage,optional"`
+        TaskCount  *int `json:"taskCount,optional"`
+        isShow  *int `json:"isShow,optional"`
+        // 微信昵称 群备注名称
+        Message  *string `json:"message,optional"`
+        CreateTime  *string `json:"createTime,optional"`
+        UpdateTime  *string `json:"updateTime,optional"`
+    }
+
+    CancelByIdsReq {
+        Ids []int64 `json:"ids" validate:"required,min=1"`
     }
 )
 
@@ -21,4 +60,13 @@ service Wechat {
     // 手机号加好友接口
     @handler AddFriendByPhone
     post /add_friend/add_friend_by_phone (AddWechatFriendLogInfo) returns (BaseMsgResp)
+
+    // 添加好友的列表接口
+    @handler AddFriendList
+    post /add_friend/add_friend_list (AddFriendListReq) returns (AddFriendListResp)
+
+    // cancel task add friend
+    @handler CancelByIds
+    post /add_friend/cancel_by_ids (CancelByIdsReq) returns (BaseMsgResp)
+
 } 

+ 2 - 2
ent/addwechatfriendlog.go

@@ -20,7 +20,7 @@ type AddWechatFriendLog struct {
 	ID int64 `json:"id,omitempty"`
 	// 属主的wxid
 	OwnerWxID string `json:"owner_wx_id,omitempty"`
-	// 属主的微信类型(1个微,2企微)
+	// 属主的微信类型(1个微,3企微)
 	OwnerWxType int `json:"owner_wx_type,omitempty"`
 	// 手机号
 	FindContent string `json:"find_content,omitempty"`
@@ -32,7 +32,7 @@ type AddWechatFriendLog struct {
 	FindResult map[string]interface{} `json:"find_result,omitempty"`
 	// 任务执行次数
 	IsCanAdd int `json:"is_can_add,omitempty"`
-	// 是否可以添加好友(与属主账号非好友且其数据查询正常时 0 不可以,1 可以 2成功添加申请
+	// 是否可以添加好友(与属主账号非好友且其数据查询正常时 0数据准备中,1 待执行 2成功添加申请 3timeout及其他错误 4用户不存在 5手动取消
 	TaskCount int `json:"task_count,omitempty"`
 	// 添加时候的请求体
 	TaskID int64 `json:"task_id,omitempty"`

+ 2 - 2
ent/schema/add_wechat_friend_log.go

@@ -30,7 +30,7 @@ func (AddWechatFriendLog) Fields() []ent.Field {
 
 		field.Int("owner_wx_type").
 			Default(1).
-			Comment("属主的微信类型(1个微,2企微)"),
+			Comment("属主的微信类型(1个微,3企微)"),
 
 		field.String("find_content").
 			Default("").
@@ -55,7 +55,7 @@ func (AddWechatFriendLog) Fields() []ent.Field {
 			Comment("任务执行次数"),
 		field.Int("task_count").
 			Default(0).
-			Comment("是否可以添加好友(与属主账号非好友且其数据查询正常时 0 不可以,1 可以 2成功添加申请)"),
+			Comment("是否可以添加好友(与属主账号非好友且其数据查询正常时 0数据准备中,1 待执行 2成功添加申请 3timeout及其他错误 4用户不存在 5手动取消 6已经是好友)"),
 		field.Int64("task_id").Default(0).Comment("添加时候的请求体"),
 		field.JSON("add_request", map[string]interface{}{}).
 			Optional().Comment("添加时候的请求体"),

+ 32 - 0
hook/contact.go

@@ -240,6 +240,38 @@ func (h *Hook) TriggerUserLabelTask(wxWxid string) error {
 	return nil
 }
 
+func (h *Hook) TriggerContactPushTask(wxWxid string) error {
+	conn, err := h.connWorkPhone()
+	if err != nil {
+		err = fmt.Errorf("TriggerContactPushTask failed")
+		return err
+	}
+	defer func(conn *websocket.Conn) {
+		err = conn.Close()
+		if err != nil {
+			err = fmt.Errorf("TriggerContactPushTask failed")
+		}
+	}(conn)
+
+	message := map[string]interface{}{
+		"MsgType": "TriggerContactPushTask",
+		"Content": map[string]interface{}{
+			"WxId": wxWxid,
+		},
+	}
+	transportMessageJSON, err := json.Marshal(message)
+	if err != nil {
+		return err
+	}
+	// 发送 JSON 消息
+	err = conn.WriteMessage(websocket.TextMessage, transportMessageJSON)
+	if err != nil {
+		return fmt.Errorf("failed to send message: %v", err)
+	}
+
+	return nil
+}
+
 func (h *Hook) AddFriendInChatRoom(ChatRoomId, wxWxid, friendId, desc string) error {
 	conn, err := h.connWorkPhone()
 	if err != nil {

+ 0 - 2
internal/handler/add_friend/add_friend_by_phone_handler.go

@@ -14,8 +14,6 @@ import (
 //
 // 手机号加好友接口
 //
-// 手机号加好友接口
-//
 // Parameters:
 //  + name: body
 //    require: true

+ 42 - 0
internal/handler/add_friend/add_friend_list_handler.go

@@ -0,0 +1,42 @@
+package add_friend
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/add_friend"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /add_friend/add_friend_list add_friend AddFriendList
+//
+// 添加好友的列表接口
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: AddFriendListReq
+//
+// Responses:
+//  200: AddFriendListResp
+
+func AddFriendListHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.AddFriendListReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := add_friend.NewAddFriendListLogic(r.Context(), svcCtx)
+		resp, err := l.AddFriendList(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 44 - 0
internal/handler/add_friend/cancel_by_ids_handler.go

@@ -0,0 +1,44 @@
+package add_friend
+
+import (
+	"net/http"
+
+	"github.com/zeromicro/go-zero/rest/httpx"
+
+	"wechat-api/internal/logic/add_friend"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+)
+
+// swagger:route post /add_friend/cancel_by_ids add_friend CancelByIds
+//
+// cancel task add friend
+//
+// cancel task add friend
+//
+// Parameters:
+//  + name: body
+//    require: true
+//    in: body
+//    type: CancelByIdsReq
+//
+// Responses:
+//  200: BaseMsgResp
+
+func CancelByIdsHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {
+	return func(w http.ResponseWriter, r *http.Request) {
+		var req types.CancelByIdsReq
+		if err := httpx.Parse(r, &req, true); err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+			return
+		}
+
+		l := add_friend.NewCancelByIdsLogic(r.Context(), svcCtx)
+		resp, err := l.CancelByIds(&req)
+		if err != nil {
+			httpx.ErrorCtx(r.Context(), w, err)
+		} else {
+			httpx.OkJsonCtx(r.Context(), w, resp)
+		}
+	}
+}

+ 10 - 0
internal/handler/routes.go

@@ -2371,6 +2371,16 @@ func RegisterHandlers(server *rest.Server, serverCtx *svc.ServiceContext) {
 					Path:    "/add_friend/add_friend_by_phone",
 					Handler: add_friend.AddFriendByPhoneHandler(serverCtx),
 				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/add_friend/add_friend_list",
+					Handler: add_friend.AddFriendListHandler(serverCtx),
+				},
+				{
+					Method:  http.MethodPost,
+					Path:    "/add_friend/cancel_by_ids",
+					Handler: add_friend.CancelByIdsHandler(serverCtx),
+				},
 			}...,
 		),
 		rest.WithJwt(serverCtx.Config.Auth.AccessSecret),

+ 3 - 2
internal/logic/Wxhook/get_friends_and_groups_logic.go

@@ -208,9 +208,10 @@ func (l *GetFriendsAndGroupsLogic) GetFriendsAndGroups(req *types.IDReq) (resp *
 
 		if wxInfo.Ctype == uint64(3) {
 			hookClient = hook.NewWecomHook("", "", "")
-			_ = hookClient.TriggerCustomerPushTask(wxInfo.Wxid)
+			_ = hookClient.TriggerCustomerPushTask(wxInfo.Wxid) //获取客户
 			_ = hookClient.TriggerConversationPushTask(wxInfo.Wxid)
-			_ = hookClient.TriggerUserLabelTask(wxInfo.Wxid)
+			_ = hookClient.TriggerUserLabelTask(wxInfo.Wxid)   //获取客户标签
+			_ = hookClient.TriggerContactPushTask(wxInfo.Wxid) //获取同事
 		} else {
 
 			data := map[string]interface{}{

+ 8 - 1
internal/logic/add_friend/add_friend_by_phone_logic.go

@@ -3,6 +3,7 @@ package add_friend
 import (
 	"context"
 
+	"wechat-api/internal/logic/chat"
 	"wechat-api/internal/svc"
 	"wechat-api/internal/types"
 
@@ -25,5 +26,11 @@ func NewAddFriendByPhoneLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
 func (l *AddFriendByPhoneLogic) AddFriendByPhone(req *types.AddWechatFriendLogInfo) (resp *types.BaseMsgResp, err error) {
 	// todo: add your logic here and delete this line
 
-	return
+	chatLogic := chat.NewAddFriendByPhoneLogic(l.ctx, l.svcCtx)
+	nreq := &types.AddFriendByPhoneReq{Type: req.Type,
+		WeChatIds:   req.WeChatIds,
+		Phones:      req.Phones,
+		Message:     req.Message,
+		CallbackURL: req.CallbackURL}
+	return chatLogic.AddFriendByPhone(nreq)
 }

+ 132 - 0
internal/logic/add_friend/add_friend_list_logic.go

@@ -0,0 +1,132 @@
+package add_friend
+
+import (
+	"context"
+	"github.com/suyuan32/simple-admin-common/msg/errormsg"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"github.com/zeromicro/go-zero/core/logx"
+	"wechat-api/ent/addwechatfriendlog"
+	"wechat-api/ent/predicate"
+	"wechat-api/ent/wx"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+	"wechat-api/internal/utils"
+)
+
+type AddFriendListLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewAddFriendListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *AddFriendListLogic {
+	return &AddFriendListLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *AddFriendListLogic) AddFriendList(req *types.AddFriendListReq) (resp *types.AddFriendListResp, err error) {
+	//获取上下文的组织id
+	organizationId := l.ctx.Value("organizationId").(uint64)
+	//通过organizationId去wx表拿微信机器人的数
+
+	query := l.svcCtx.DB.Wx.Query().Where(wx.OrganizationIDEQ(organizationId), wx.DeletedAtIsNil())
+	// 动态添加条件示例:假设 req.OwnerWxId 存在时添加额外的 Where 条件
+	if utils.IsNonEmptyString(req.OwnerWxId) {
+		query = query.Where(wx.WxidEQ(*req.OwnerWxId))
+	}
+	wxIds, err := query.Select(wx.FieldWxid).Strings(l.ctx)
+	if err != nil {
+		//数据库错误,不直接返回错误,防止暴露数据库错误
+		return nil, errorx.NewInvalidArgumentError("请联系管理员")
+	}
+	//机器人列表为空,直接返回
+	if len(wxIds) == 0 {
+		return nil, errorx.NewInvalidArgumentError("当前组织架构下,没有wx机器人")
+	}
+	var predicates []predicate.AddWechatFriendLog
+
+	predicates = append(predicates, addwechatfriendlog.OwnerWxIDIn(wxIds...))
+	ownerWxType := req.OwnerWxType
+	//查询企业微信机器人加的好友
+	if ownerWxType != nil && *ownerWxType > 0 {
+		predicates = append(predicates, addwechatfriendlog.OwnerWxTypeEQ(*ownerWxType))
+	}
+	//查找添加好友
+	if utils.IsNonEmptyString(req.FindContent) {
+		predicates = append(predicates, addwechatfriendlog.FindContent(*req.FindContent))
+	}
+
+	var IsCanAdd []int
+	if req.Status != nil {
+		switch *req.Status {
+		case 1:
+			IsCanAdd = append(IsCanAdd, 0, 1)
+		case 2:
+			IsCanAdd = append(IsCanAdd, 3, 4, 6)
+		case 3:
+			IsCanAdd = append(IsCanAdd, 2)
+		default:
+			IsCanAdd = append(IsCanAdd, 0, 1, 2, 3, 4, 5, 6)
+		}
+		if len(IsCanAdd) < 7 {
+			predicates = append(predicates, addwechatfriendlog.IsCanAddIn(IsCanAdd...))
+		}
+	}
+	data, err := l.svcCtx.DB.AddWechatFriendLog.Query().Where(predicates...).Page(l.ctx, req.Page, req.PageSize)
+	logx.Info("数据", data)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("请联系管理员")
+	}
+	resp = &types.AddFriendListResp{}
+	resp.Msg = errormsg.Success
+	resp.Data.Total = data.PageDetails.Total
+	for _, v := range data.List {
+		var wxString string
+		if v.OwnerWxType == 1 {
+			wxString = "个微"
+		} else {
+			wxString = "企微"
+		}
+		resp.Data.Data = append(resp.Data.Data,
+			types.FriendList{
+				Id:          v.ID,
+				OwnerWxId:   &v.OwnerWxID,
+				OwnerWxType: &wxString,
+				FindContent: &v.FindContent,
+				Status: func() *string {
+					statusMap := map[int]string{
+						0: "数据准备中",
+						1: "待执行",
+						2: "成功邀请",
+						3: "timeout及其他错误",
+						4: "用户不存在",
+						5: "后台取消",
+						6: "已是好友",
+					}
+					statusStr := statusMap[v.IsCanAdd]
+					return &statusStr
+				}(),
+				IsShow: func() *int {
+					statusMap := map[int]int{
+						0: 1,
+						1: 1,
+						2: 0,
+						3: 0,
+						4: 0,
+						5: 0,
+						6: 0,
+					}
+					isShow := statusMap[v.IsCanAdd]
+					return &isShow
+				}(),
+				TaskCount:  &v.TaskCount,
+				Message:    &v.Message,
+				CreateTime: utils.UnixTimeToBeijing(v.CreatedAt),
+				UpdateTime: utils.UnixTimeToBeijing(v.UpdatedAt),
+			},
+		)
+	}
+	return resp, nil
+}

+ 48 - 0
internal/logic/add_friend/cancel_by_ids_logic.go

@@ -0,0 +1,48 @@
+package add_friend
+
+import (
+	"context"
+	"github.com/zeromicro/go-zero/core/errorx"
+	"time"
+	"wechat-api/ent/addwechatfriendlog"
+	"wechat-api/internal/svc"
+	"wechat-api/internal/types"
+
+	"github.com/zeromicro/go-zero/core/logx"
+)
+
+type CancelByIdsLogic struct {
+	logx.Logger
+	ctx    context.Context
+	svcCtx *svc.ServiceContext
+}
+
+func NewCancelByIdsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CancelByIdsLogic {
+	return &CancelByIdsLogic{
+		Logger: logx.WithContext(ctx),
+		ctx:    ctx,
+		svcCtx: svcCtx}
+}
+
+func (l *CancelByIdsLogic) CancelByIds(req *types.CancelByIdsReq) (resp *types.BaseMsgResp, err error) {
+	if req.Ids == nil {
+		return nil, errorx.NewInvalidArgumentError("参数ids不能为空")
+	}
+	if len(req.Ids) == 0 {
+		return nil, errorx.NewInvalidArgumentError("参数ids不能为空")
+	}
+	var isCanAdd []int
+	isCanAdd = append(isCanAdd, 0, 1)
+	err = l.svcCtx.DB.AddWechatFriendLog.Update().
+		SetIsCanAdd(5).                  // 假设要将IsCanAdd字段设置为5
+		SetUpdatedAt(time.Now().Unix()). // 设置修改时间
+		Where(addwechatfriendlog.IDIn(req.Ids...), addwechatfriendlog.IsCanAddIn(isCanAdd...)).
+		Exec(l.ctx)
+	if err != nil {
+		return nil, errorx.NewInvalidArgumentError("取消失败")
+	}
+	return &types.BaseMsgResp{
+		Code: 0,
+		Msg:  "取消成功",
+	}, nil
+}

+ 144 - 24
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,45 +30,163 @@ 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, phone := range req.Phones {
+		info := AddFriendByPhoneInfo{Type: req.Type, WeChatId: req.WeChatIds[idx],
+			Phone: phone, 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")
+	}
+
+	orgID, ok := l.ctx.Value("organizationId").(uint64)
+	if !ok || orgID == 0 {
+		return nil, errors.New("content get oid info err")
+	}
+
+	//fmt.Println("before weChatIds:", req.WeChatIds)
+	//fmt.Println("before phones:", req.Phones)
+	//apiKeyObj.OrganizationID = 1
 
-	//从上下文中获取鉴权中间件埋下的apiAuthInfo
-	apiKeyObj, ok = contextkey.AuthTokenInfoKey.GetValue(l.ctx)
-	if !ok {
-		return nil, errors.New("content get auth info err")
+	if req.Type != 3 {
+		req.Type = 1
 	}
-	err = l.AppendWechaFriendAddReq(apiKeyObj, req)
+	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 (l *AddFriendByPhoneLogic) AppendWechaFriendAddReq(apiKeyObj *ent.ApiKey, req *types.AddFriendByPhoneReq) error {
+func (l *AddFriendByPhoneLogic) AppendWechaFriendAddInfo(addInfo *AddFriendByPhoneInfo) (int64, error) {
 
+	isCanAdd := 0
+	if addInfo.Type != 1 {
+		isCanAdd = 1
+	}
 	res, err := l.svcCtx.DB.AddWechatFriendLog.Create().
-		SetNotNilOwnerWxID(&req.WeChatId).
-		SetNotNilOwnerWxType(&req.Type).
-		SetNotNilFindContent(&req.Phone).
-		SetNotNilMessage(&req.Message).
+		SetNotNilOwnerWxID(&addInfo.WeChatId).
+		SetNotNilOwnerWxType(&addInfo.Type).
+		SetNotNilFindContent(&addInfo.Phone).
+		SetNotNilMessage(&addInfo.Message).
+		SetIsCanAdd(isCanAdd).
 		Save(l.ctx)
 
+	id := int64(0)
 	if err == nil {
-		logx.Infof("AppendWechaFriendAddReq succ,get id:%d", res.ID)
+		id = res.ID
 	}
-	return err
+	return id, err
 }

+ 4 - 3
internal/middleware/authority_middleware.go

@@ -3,11 +3,12 @@ package middleware
 import (
 	"context"
 	"errors"
-	"github.com/suyuan32/simple-admin-core/rpc/coreclient"
-	"github.com/suyuan32/simple-admin-core/rpc/types/core"
 	"net/http"
 	"strings"
 
+	"github.com/suyuan32/simple-admin-core/rpc/coreclient"
+	"github.com/suyuan32/simple-admin-core/rpc/types/core"
+
 	"github.com/casbin/casbin/v2"
 	"github.com/redis/go-redis/v9"
 	"github.com/suyuan32/simple-admin-common/config"
@@ -39,7 +40,7 @@ func (m *AuthorityMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
 		// get the method
 		act := r.Method
 		// get the role id
-		roleIds := r.Context().Value("roleId").(string)
+		roleIds, _ := r.Context().Value("roleId").(string)
 
 		// check jwt blacklist
 		jwtResult, err := m.Rds.Get(context.Background(), config.RedisTokenPrefix+jwt.StripBearerPrefixFromToken(r.Header.Get("Authorization"))).Result()

+ 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

+ 0 - 6
internal/pkg/util/strings.go

@@ -1,6 +0,0 @@
-package util
-
-// IsNonEmptyString 判断字符串指针不为 nil 且不为空
-func IsNonEmptyString(s *string) bool {
-	return s != nil && *s != ""
-}

+ 1 - 1
internal/service/MessageHandlers/find_contact_task_result_notice.go

@@ -90,7 +90,7 @@ func (f *FindContactTaskResultNoticeHandler) Handle(ctx context.Context, msg *we
 		SetUpdatedAt(time.Now().Unix())
 	if message.Success {
 		if message.IsFriend {
-			update = update.SetIsCanAdd(0)
+			update = update.SetIsCanAdd(6)
 		} else {
 			update = update.SetIsCanAdd(1)
 		}

+ 8 - 2
internal/service/MessageHandlers/task_result_notice.go

@@ -61,8 +61,14 @@ func (f *TaskResultNoticeHandler) Handle(ctx context.Context, msg *wechat_ws.Msg
 		SetAddResult(m).
 		SetUpdatedAt(time.Now().Unix())
 
-	if common.ErrMsg == "该用户不存在" {
-		update.SetIsCanAdd(0) // 重置添加为不能添加好友
+	if common.Code == "InternalError" {
+		if common.ErrMsg == "timeout" {
+			update.SetIsCanAdd(3) // 重置添加为不能添加好友
+		} else if common.ErrMsg == "该用户不存在" || common.ErrMsg == "用户不存在" {
+			update.SetIsCanAdd(4) // 重置添加为不能添加好友
+		} else {
+			update.SetIsCanAdd(3)
+		} // 重置添加为不能添加好友
 	}
 
 	if common.Success {

+ 2 - 2
internal/service/addfriend/add_wechat_friend_log.go

@@ -60,7 +60,7 @@ func (l *AddWechatFriendService) FindFriendByContent(wechatId, content string) b
 
 func (l *AddWechatFriendService) AddNewFriend(wechatId, content, message string, wechatType int) bool {
 	//先记录请求
-	if wechatType != 1 && wechatType != 2 {
+	if wechatType != 1 && wechatType != 3 {
 		return false
 	}
 	node, err := snowflake.NewNode(1) // 1 是节点 ID,根据需要设置
@@ -77,7 +77,7 @@ func (l *AddWechatFriendService) AddNewFriend(wechatId, content, message string,
 	case 1:
 		hookClient = hook.NewHook("", "", "")
 		result, err = hookClient.AddFriendTask(wechatId, content, message, taskId.Int64())
-	case 2:
+	case 3:
 		hookClient = hook.NewWecomHook("", "", "")
 		result, err = hookClient.AddWecomCustomerFromSearchTask(wechatId, content, message, taskId.Int64())
 	default:

+ 58 - 8
internal/types/types.go

@@ -2040,10 +2040,15 @@ 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"`
+}
+
+// swagger:model NullReq
+type NullReq struct {
 }
 
 // 以下是API请求类型
@@ -4769,8 +4774,53 @@ type LoginResp struct {
 // add_friend_by_phone api接口请求值
 // swagger:model AddWechatFriendLogInfo
 type AddWechatFriendLogInfo struct {
-	Type      int      `json:"type"`
-	WeChatIds []string `json:"WeChatId,optional,omitempty"`
-	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"`
+}
+
+// swagger:model AddFriendListReq
+type AddFriendListReq struct {
+	PageInfo
+	OwnerWxId   *string `json:"wxId,optional"`
+	OwnerWxType *int    `json:"wxType,optional"`
+	FindContent *string `json:"phone,optional"`
+	Status      *int    `json:"status,optional"`
+}
+
+// swagger:model AddFriendListResp
+type AddFriendListResp struct {
+	BaseDataInfo
+	Data FriendListInfo `json:"data"`
+}
+
+// swagger:model FriendListInfo
+type FriendListInfo struct {
+	BaseListInfo
+	Data []FriendList `json:"data"`
+}
+
+type FriendList struct {
+	Id int64 `json:"id,optional"`
+	// 微信id 公众号微信ID
+	OwnerWxId   *string `json:"wxId,optional"`
+	OwnerWxType *string `json:"wxType,optional"`
+	FindContent *string `json:"phone,optional"`
+	Status      *string `json:"status,optional"`
+	ErrMessage  *string `json:"errMessage,optional"`
+	TaskCount   *int    `json:"taskCount,optional"`
+	IsShow      *int    `json:"isShow,optional"`
+	// 微信昵称 群备注名称
+	Message    *string `json:"message,optional"`
+	CreateTime *string `json:"createTime,optional"`
+	UpdateTime *string `json:"updateTime,optional"`
+}
+
+// swagger:model CancelByIdsReq
+type CancelByIdsReq struct {
+	// required : true
+	// min length : 1
+	Ids []int64 `json:"ids" validate:"required,min=1"`
 }

+ 32 - 0
internal/utils/strings.go

@@ -0,0 +1,32 @@
+package utils
+
+import "time"
+
+// IsNonEmptyString 判断字符串指针不为 nil 且不为空
+func IsNonEmptyString(s *string) bool {
+	return s != nil && *s != ""
+}
+
+// UnixTimeToBeijing 将 Unix 时间戳转换为北京时间字符串
+func UnixTimeToBeijing(i any) *string {
+	// 断言输入为 int64 类型
+	unixTime, ok := i.(int64)
+	if !ok {
+		return nil
+	}
+
+	// 当传入的时间为0值时,返回固定字符串"---"
+	if unixTime == 0 {
+		defaultTime := "--"
+		return &defaultTime
+	}
+
+	// 转换为北京时间(UTC+8)
+	beijingTime := time.Unix(unixTime, 0).In(time.FixedZone("CST", 8*3600))
+
+	// 格式化时间字符串
+	formattedTime := beijingTime.Format("2006-01-02 15:04:05")
+
+	// 返回字符串指针
+	return &formattedTime
+}

+ 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]
+	})
+}