Exemple #1
0
        public async Task OnGetAsync()
        {
            var allMpAccounts = await _mpAccountService.GetFullListAsync(z => true);

            MpAccountDtos = allMpAccounts.Select(z => _mpAccountService.Mapper.Map <MpAccountDto>(z)).ToList();

            AccessTokenBags          = new List <AccessTokenBag>();
            RegisteredMpAccountCount = 0;
            foreach (var mpAccount in allMpAccounts)
            {
                if (await AccessTokenContainer.CheckRegisteredAsync(mpAccount.AppId))
                {
                    var bag = await AccessTokenContainer.TryGetItemAsync(mpAccount.AppId);

                    if (bag.AccessTokenResult != null && !bag.AccessTokenResult.access_token.IsNullOrEmpty())
                    {
                        RegisteredMpAccountCount++;
                    }
                    AccessTokenBags.Add(bag);
                }
            }

            WeixinUserCount = await _weixinUserService.GetCountAsync(z => true);

            TodayWeixinUserCount = await _weixinUserService.GetCountAsync(z => z.AddTime >= DateTime.Today);
        }
Exemple #2
0
        public async Task <IActionResult> OnGetSyncUserAsync(int mpId, SyncType syncType)
        {
            var mpAccount = await _mpAccountService.GetObjectAsync(z => z.Id == mpId);

            if (mpAccount == null)
            {
                return(RenderError("公众号配置不存在:" + mpId));
            }

            SenparcTrace.SendCustomLog("开始公众号用户同步", mpAccount.Name);
            //List<WeixinUserDto> weixinUserDtos = new List<WeixinUserDto>();
            string        lastOpenId = null;
            List <string> openIds    = new List <string>()
            {
                //"olPjZjsbk4WzEbbGDkWWHuwhpg1M"//测试ID
                //"oxRg0uLsnpHjb8o93uVnwMK_WAVw"
            };

            while (true)
            {
                var result = await Senparc.Weixin.MP.AdvancedAPIs.UserApi.GetAsync(mpAccount.AppId, lastOpenId);

                if (result.data != null)
                {
                    SenparcTrace.SendCustomLog("获取到OpenId", $"{result.data.openid.Count} 个");
                    openIds.AddRange(result.data.openid);
                }

                if (result.next_openid.IsNullOrEmpty())
                {
                    break;
                }
                lastOpenId = result.next_openid;
            }

            //更新Tag
            var weixinTagDto  = new UserTag_CreateOrUpdateDto();
            var allDbUserTags = await _userTagService.GetFullListAsync(z => z.MpAccountId == mpId);

            SenparcTrace.SendCustomLog("当前已经存储UserTags", $"{allDbUserTags.Count} 个\r\n{string.Join(",", allDbUserTags.Select(z => z.Name).ToArray())}");

            var tagInfo = await Senparc.Weixin.MP.AdvancedAPIs.UserTagApi.GetAsync(mpAccount.AppId);

            SenparcTrace.SendCustomLog("微信账号存储UerTag", $"{tagInfo.tags.Count} 个\r\n{string.Join(",", tagInfo.tags.Select(z => z.name).ToArray())}");

            //添加或更新 UserTag
            foreach (var tag in tagInfo.tags)
            {
                var dbUserTag = allDbUserTags.FirstOrDefault(z => z.TagId == tag.id);

                UserTag_CreateOrUpdateDto tagDto;
                tagDto = dbUserTag == null
                    ? _userTagService.Mapper.Map <UserTag_CreateOrUpdateDto>(tag)       //创建新tag
                    : _userTagService.Mapper.Map <UserTag_CreateOrUpdateDto>(dbUserTag) //从数据库获取
                ;

                tagDto.MpAccountId = mpId;
                tagDto.TagId       = tag.id;//名称不一致,手动填充

                var changed = false;

                if (dbUserTag == null)
                {
                    SenparcTrace.SendCustomLog("新增UserTag", $"{tagDto.TagId}:{tagDto.Name}");
                    dbUserTag = _userTagService.Mapper.Map <UserTag>(tagDto);
                    //await _userTagService.SaveObjectAsync(dbUserTag);
                    allDbUserTags.Add(dbUserTag);
                    changed = true;
                }
                else
                {
                    SenparcTrace.SendCustomLog("更新UserTag", $"{tagDto.TagId}:{tagDto.Name}");
                    changed = dbUserTag.Update(tagDto);
                }

                if (changed)
                {
                    await _userTagService.SaveObjectAsync(dbUserTag);
                }
            }

            //检测删除的 Tag
            var tobeRemoveTags = allDbUserTags.Where(z => !tagInfo.tags.Exists(t => t.name == z.Name));

            if (tobeRemoveTags.Count() > 0)
            {
                await _userTagService.DeleteAllAsync(tobeRemoveTags);
            }

            var allUsers = await _weixinUserService.GetFullListAsync(z => z.MpAccountId == mpId,
                                                                     z => z.Include(p => p.UserTags_WeixinUsers), null);

            ConcurrentBag <Models.WeixinUser> allToSaveWeixinUsers = new ConcurrentBag <Models.WeixinUser>();
            ConcurrentBag <Models.WeixinUser> newWeixinUsers       = new ConcurrentBag <Models.WeixinUser>();

            ConcurrentDictionary <int, Task> tasks = new ConcurrentDictionary <int, Task>();
            var maxThreadsCount = 300;//最大拉取线程数

            SenparcTrace.SendCustomLog("开始同步用户信息", $"共 {openIds.Count} 个");
            for (int i = 0; i < openIds.Count; i++)
            {
                var  index  = i;
                var  openId = openIds[index];
                Task task   = Task.Run(async() =>
                {
                    var weixinUser = allUsers.FirstOrDefault(z => z.OpenId == openId);
                    if (weixinUser == null || syncType == SyncType.all)
                    {
                        //需要新增或尝试更新用户
                        var user                  = await Senparc.Weixin.MP.AdvancedAPIs.UserApi.InfoAsync(mpAccount.AppId, openId);
                        var weixinUserDto         = _weixinUserService.Mapper.Map <WeixinUser_UpdateFromApiDto>(user);
                        weixinUserDto.MpAccountId = mpId;
                        if (weixinUser != null)
                        {
                            //查看已有项更新,两个数据进行对比
                            var newApiWeixinUserJson = weixinUserDto.ToJson(false, new Newtonsoft.Json.JsonSerializerSettings()
                            {
                                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                            });
                            var oldDbWeixinUserDto        = _weixinUserService.Mapper.Map <Models.WeixinUser_UpdateFromApiDto>(weixinUser);
                            oldDbWeixinUserDto.Tagid_List = weixinUser.UserTags_WeixinUsers.Select(z => z.UserTag.TagId).ToArray();
                            var oldDbWeixinUserJson       = oldDbWeixinUserDto.ToJson(false, new Newtonsoft.Json.JsonSerializerSettings()
                            {
                                ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
                            });
                            if (newApiWeixinUserJson != oldDbWeixinUserJson)
                            {
                                SenparcTrace.SendCustomLog("WeixinUserJson 更新", $"旧:{oldDbWeixinUserJson}\r\n新:{newApiWeixinUserJson}");
                                _weixinUserService.Mapper.Map(weixinUserDto, weixinUser);

                                //SenparcTrace.SendCustomLog("weixinUser 实体信息", $"{weixinUser.ToJson(false, new Newtonsoft.Json.JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore })}");
                                weixinUser.UpdateTime();
                                allToSaveWeixinUsers.Add(weixinUser);//更新
                            }

                            //添加或删除个人的 Tag
                            foreach (var weixinTagId in user.tagid_list)
                            {
                                var userTag = allDbUserTags.FirstOrDefault(z => z.TagId == weixinTagId);
                                if (userTag == null)
                                {
                                    SenparcTrace.SendCustomLog("匹配到未同步的 TagId", "TagId:" + weixinTagId);//正常情况不会存在
                                }

                                //查找未添加的Tag
                                var userTags_WeixinUsers = weixinUser.UserTags_WeixinUsers
                                                           .FirstOrDefault(z => /*z.WeixinUserId == weixinUser.Id &&*/ z.UserTagId == userTag.Id);
                                if (userTags_WeixinUsers == null)
                                {
                                    SenparcTrace.SendCustomLog("创建新Tag关联", $"WeixinUser:{weixinUser.NickName} -> TagName:{userTag.Name}");

                                    var userTag_Weixinuser = new UserTag_WeixinUser(userTag.Id, weixinUser.Id);
                                    userTag_Weixinuser.UpdateTime();
                                    weixinUser.UserTags_WeixinUsers.Add(userTag_Weixinuser);
                                }
                            }

                            //查找需要删除的Tag
                            var tobeRemoveTagList = weixinUser.UserTags_WeixinUsers.Where(z =>
                            {
                                var dbUserTag = allDbUserTags.FirstOrDefault(t => t.Id == z.UserTagId);
                                return(!user.tagid_list.Contains(dbUserTag.TagId));
                            });

                            foreach (var userTags_WeixinUsers in tobeRemoveTagList)
                            {
                                SenparcTrace.SendCustomLog("删除Tag关联", $"WeixinUser:{weixinUser.NickName} -> UserTag.Id:{userTags_WeixinUsers.UserTagId}");
                                weixinUser.UserTags_WeixinUsers.Remove(userTags_WeixinUsers);
                            }
                        }
                        else
                        {
                            weixinUser = _weixinUserService.Mapper.Map <Models.WeixinUser>(weixinUserDto);//新增
                            weixinUser.UpdateTime();
                            newWeixinUsers.Add(weixinUser);
                            allToSaveWeixinUsers.Add(weixinUser);
                        }

                        //TODO:更新group信息
                    }
                });

                tasks[index] = task;

                if (index % maxThreadsCount == 0 || index == openIds.Count - 1)
                {
                    //只允许N个线程,否则等待
                    Task.WaitAll(tasks.Values.ToArray());
                    //记录异常
                    foreach (var item in tasks.Values.Where(z => z.Exception != null))
                    {
                        SenparcTrace.BaseExceptionLog(item.Exception);
                    }
                    //清除已完成的线程
                    tasks.Clear();
                }
            }

            SenparcTrace.SendCustomLog("保存用户信息", $"{allToSaveWeixinUsers.Count} 个");
            try
            {
                var saveWeixinusers = allToSaveWeixinUsers.OrderBy(z => z.Subscribe_Time);
                await _weixinUserService.SaveObjectListAsync(saveWeixinusers);
            }
            catch (Exception ex)
            {
                SenparcTrace.BaseExceptionLog(ex);
                SenparcTrace.BaseExceptionLog(ex.InnerException);
            }

            //base.SetMessager(Ncf.Core.Enums.MessageType.success, "更新成功!");
            //return RedirectToPage("./Index", new { uid = Uid, mpId = mpId });
            return(Ok(new { uid = Uid, mpId }));
        }
Exemple #3
0
        public async Task <IActionResult> OnPostAccessTokenStatusAsync([FromBody] int[] ids)
        {
            var data          = new List <AccessTokenData>();
            var allMpAccounts = await _mpAccountService.GetFullListAsync(z => true);

            foreach (var id in ids)
            {
                var mpAccount = allMpAccounts.FirstOrDefault(z => z.Id == id);
                if (mpAccount == null)
                {
                    continue;
                }
                var            appId       = mpAccount.AppId;
                string         status      = null;
                double         leftSeconds = 0;
                AccessTokenBag bag         = null;
                if (!appId.IsNullOrEmpty())
                {
                    if (await AccessTokenContainer.CheckRegisteredAsync(appId))
                    {
                        bag = await AccessTokenContainer.TryGetItemAsync(appId);

                        if (bag.AccessTokenResult != null && !bag.AccessTokenResult.access_token.IsNullOrEmpty())
                        {
                            leftSeconds = (bag.AccessTokenExpireTime - SystemTime.Now).TotalSeconds;
                            if (leftSeconds > 9999)
                            {
                                leftSeconds = 0;
                                status      = "未启动";
                            }
                            else if (leftSeconds > 0)
                            {
                                status = "有效";
                            }
                            else //leftSeconds <= 0
                            {
                                leftSeconds = 0;
                                status      = "已过期";
                            }
                        }
                        else
                        {
                            status = "未启动";
                        }
                    }
                    else
                    {
                        status = "未注册";
                    }
                }
                else
                {
                    status = "AppId无效";
                }

                var totalSeconds = bag?.AccessTokenResult.expires_in ?? 0;
                var leftPercent  = bag?.AccessTokenResult != null && totalSeconds != 0 ? Math.Round(leftSeconds / bag.AccessTokenResult.expires_in * 100, 1) : 0;
                data.Add(new AccessTokenData()
                {
                    Id           = id,
                    AppId        = appId,
                    Status       = status,
                    LeftPercent  = leftPercent,
                    TotalSeconds = totalSeconds,
                });
            }
            return(Ok(data));
        }