using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using Edu.Cache.WeChat;
using Edu.Common;
using Edu.Common.API;
using Edu.Common.Enum.Finance;
using Edu.Common.Plugin;
using Edu.Model.CacheModel;
using Edu.Model.ViewModel.User;
using Edu.Model.ViewModel.WeChat;
using Edu.Repository.User;
using Edu.Repository.WeChat;
using Edu.ThirdCore.QYWinXin;
using Edu.ThirdCore.QYWinXin.Model;
using Newtonsoft.Json.Linq;
using Senparc.Weixin.Work.AdvancedAPIs.OAuth2;
using VT.FW.DB;
namespace Edu.Module.QYWeChat
{
///
/// 企业微信处理类
///
public class QYWeChatModule
{
///
/// 微信配置
///
private readonly RB_WeChat_ConfigRepository weChat_ConfigRepository = new RB_WeChat_ConfigRepository();
///
/// 部门
///
private readonly RB_DepartmentRepository departmentRepository = new RB_DepartmentRepository();
///
/// 账号列表
///
private readonly RB_AccountRepository accountRepository = new RB_AccountRepository();
///
/// 素材
///
private readonly RB_WeChat_MediumRepository weChat_MediumRepository = new RB_WeChat_MediumRepository();
///
/// 素材分组
///
private readonly RB_WeChat_MediumGroupRepository weChat_MediumGroupRepository = new RB_WeChat_MediumGroupRepository();
///
/// 欢迎语
///
private readonly RB_WeChat_WelcomesRepository weChat_WelcomesRepository = new RB_WeChat_WelcomesRepository();
///
/// 客户标签
///
private readonly RB_WeChat_LableRepository weChat_LableRepository = new RB_WeChat_LableRepository();
///
/// 渠道分组
///
private readonly RB_WeChat_ChannelGroupRepository weChat_ChannelGroupRepository = new RB_WeChat_ChannelGroupRepository();
///
/// 人员添加上限
///
private readonly RB_WeChat_ChannelLimitRepository weChat_ChannelLimitRepository = new RB_WeChat_ChannelLimitRepository();
///
/// 渠道活码
///
private readonly RB_WeChat_ChannelRepository weChat_ChannelRepository = new RB_WeChat_ChannelRepository();
///
/// 活码周期
///
private readonly RB_WeChat_ChannelWeekRepository weChat_ChannelWeekRepository = new RB_WeChat_ChannelWeekRepository();
///
/// 周期欢迎语
///
private readonly RB_WeChat_ChannelWelcomeRepository weChat_ChannelWelcomeRepository = new RB_WeChat_ChannelWelcomeRepository();
///
/// 添加客户记录
///
private readonly RB_WeChat_ChannelRecordRepository weChat_ChannelRecordRepository = new RB_WeChat_ChannelRecordRepository();
///
/// 渠道码日志
///
private readonly RB_WeChat_ChannelLogRepository weChat_ChannelLogRepository = new RB_WeChat_ChannelLogRepository();
#region 微信配置
///
/// 获取企业微信配置
///
///
///
public WorkChatConfig GetWeChatConfigModel(RB_WeChat_Config_ViewModel model)
{
//var dmodel = weChat_ConfigRepository.GetList(model).FirstOrDefault();
//if (dmodel == null) { dmodel = new RB_WeChat_Config_ViewModel(); }
return WeChatReidsCache.GetWorkChatConfig(model.Group_Id);
}
///
/// 新增/修改企业微信配置
///
///
///
public string SetWeChatConfig(RB_WeChat_Config_ViewModel demdoel)
{
if (demdoel.Enable == 1)
{
#region 通讯录
var TelToken = QYWeiXinHelper.GetToken(demdoel.WX_CorpId, demdoel.Employee_Secret);
if (TelToken.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
WeChatReidsCache.TokenSet(Cache.CacheKey.QYWeChat_TelToken_Key + demdoel.Group_Id, TelToken.access_token, TelToken.expires_in - 1);
}
else
{
return "token请求失败";
}
#endregion
#region 外部人员
var EmpToken = QYWeiXinHelper.GetToken(demdoel.WX_CorpId, demdoel.Contact_Secret);
if (EmpToken.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
WeChatReidsCache.TokenSet(Cache.CacheKey.QYWeChat_EmpToken_Key + demdoel.Group_Id, EmpToken.access_token, EmpToken.expires_in - 1);
}
else
{
return "token请求失败";
}
#endregion
}
if (demdoel.Id > 0)
{
Dictionary keyValues = new Dictionary() {
{ nameof(RB_WeChat_Config_ViewModel.Name),demdoel.Name},
{ nameof(RB_WeChat_Config_ViewModel.WX_CorpId),demdoel.WX_CorpId},
{ nameof(RB_WeChat_Config_ViewModel.Employee_Secret),demdoel.Employee_Secret},
{ nameof(RB_WeChat_Config_ViewModel.Contact_Secret),demdoel.Contact_Secret},
{ nameof(RB_WeChat_Config_ViewModel.TelEvent_CallBack),demdoel.TelEvent_CallBack},
{ nameof(RB_WeChat_Config_ViewModel.EmpEvent_CallBack),demdoel.EmpEvent_CallBack},
{ nameof(RB_WeChat_Config_ViewModel.Token),demdoel.Token},
{ nameof(RB_WeChat_Config_ViewModel.Encoding_Aes_Key),demdoel.Encoding_Aes_Key},
{ nameof(RB_WeChat_Config_ViewModel.Enable),demdoel.Enable},
{ nameof(RB_WeChat_Config_ViewModel.UpdateBy),demdoel.UpdateBy},
{ nameof(RB_WeChat_Config_ViewModel.UpdateTime),demdoel.UpdateTime},
};
List wheres = new List() {
new WhereHelper(){
FiledName=nameof(RB_WeChat_Config_ViewModel.Id),
FiledValue=demdoel.Id,
OperatorEnum=OperatorEnum.Equal
}
};
bool flag = false;
if (weChat_ConfigRepository.Update(keyValues, wheres))
{
flag = true;
//更新缓存
WeChatReidsCache.UpdateConfig(demdoel.Id);
}
return flag ? "" : "出错了,请联系管理员";
}
else {
var id = weChat_ConfigRepository.Insert(demdoel);
bool flag = false;
if (id > 0)
{
flag = true;
//更新缓存
WeChatReidsCache.UpdateConfig(id);
}
return flag ? "" : "出错了,请联系管理员";
}
}
#endregion
#region 同步部门人员
///
/// 同步部门
///
///
///
public string SetSyncEduDepartment(UserInfo userInfo)
{
var configmodel = weChat_ConfigRepository.GetList(new RB_WeChat_Config_ViewModel() { Group_Id = userInfo.Group_Id, Enable = 1 }).FirstOrDefault();
if (configmodel == null || configmodel.Enable != 1) { return "未启用企业微信,无法同步"; }
string token = GetEmployeeToken(userInfo.Group_Id, configmodel);
if (string.IsNullOrEmpty(token)) { return "token获取失败"; }
//获取教育部门列表
var dlist = departmentRepository.GetDepartmentListRepository(new RB_Department_ViewModel() { Group_Id = userInfo.Group_Id });
//树形结构遍历
var firstList = dlist.Where(x => x.ParentId == 0).ToList();
foreach (var item in firstList) {
if (item.WorkDepartId <= 0)
{
//需在微信端创建
var CDModle = QYWeiXinHelper.CreateDepartment(token, item.DeptName, 1, item.DeptSort);
if (CDModle.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
item.WorkDepartId = Convert.ToInt32(CDModle.id);
//更新原部门微信部门Id绑定
Dictionary keyValues = new Dictionary() {
{ nameof(RB_Department_ViewModel.WorkDepartId),item.WorkDepartId}
};
List wheres = new List() {
new WhereHelper(){
FiledName=nameof(RB_Department_ViewModel.DeptId),
FiledValue=item.DeptId,
OperatorEnum=OperatorEnum.Equal
}
};
departmentRepository.Update(keyValues, wheres);
}
else {
LogHelper.Write("企业微信部门创建失败DeptId:" + item.DeptId + " 消息:" + CDModle.errmsg);
return "出问题咯";
}
}
//开始遍历下级
SyncEduDepartmentChildList(item.DeptId, item.WorkDepartId, dlist, token);
}
LogHelper.WriteInfo("用户" + userInfo.AccountName + "(" + userInfo.Id + ") 操作同步部门至企业微信");
return "";
}
///
/// 递归处理下级
///
///
///
public void SyncEduDepartmentChildList(int parentId, int parentWorkDepartId, List dlist, string token) {
var childList = dlist.Where(x => x.ParentId == parentId).ToList();
foreach (var item in childList) {
if (item.WorkDepartId <= 0)
{
//需在微信端创建
var CDModle = QYWeiXinHelper.CreateDepartment(token, item.DeptName, parentWorkDepartId, item.DeptSort);
if (CDModle.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
item.WorkDepartId = Convert.ToInt32(CDModle.id);
//更新原部门微信部门Id绑定
Dictionary keyValues = new Dictionary() {
{ nameof(RB_Department_ViewModel.WorkDepartId),item.WorkDepartId}
};
List wheres = new List() {
new WhereHelper(){
FiledName=nameof(RB_Department_ViewModel.DeptId),
FiledValue=item.DeptId,
OperatorEnum=OperatorEnum.Equal
}
};
departmentRepository.Update(keyValues, wheres);
}
else
{
LogHelper.Write("企业微信部门创建失败DeptId:" + item.DeptId + " 消息:" + CDModle.errmsg);
return;
}
}
//开始遍历下级
SyncEduDepartmentChildList(item.DeptId, item.WorkDepartId, dlist, token);
}
}
///
/// 同步人员
///
///
///
public string SetSynvEduEmployee(UserInfo userInfo)
{
var configmodel = weChat_ConfigRepository.GetList(new RB_WeChat_Config_ViewModel() { Group_Id = userInfo.Group_Id, Enable = 1 }).FirstOrDefault();
if (configmodel == null || configmodel.Enable != 1) { return "未启用企业微信,无法同步"; }
string token = GetEmployeeToken(userInfo.Group_Id, configmodel);
if (string.IsNullOrEmpty(token)) { return "token获取失败"; }
//获取企业微信端所有的部门人员
var WeiXinEmpList = QYWeiXinHelper.GetDepartmentMemberInfo(token, 1, 1);
if (WeiXinEmpList.errcode != Senparc.Weixin.ReturnCode_Work.请求成功) {
LogHelper.Write("获取企业微信部门下人员失败:" + WeiXinEmpList.errmsg);
return "获取企业微信部门下人员失败";
}
var wxEmpList = WeiXinEmpList.userlist;
//获取所有的部门
var dlist = departmentRepository.GetDepartmentListRepository(new RB_Department_ViewModel() { Group_Id = userInfo.Group_Id });
//获取所有的人员
var elist = accountRepository.GetEmployeeListRepository(new Employee_ViewModel() { Group_Id = userInfo.Group_Id, IsLeave = 1 });//.Take(10);//;;;;;;;;;;;;;;注意
foreach (var item in elist.Where(x=> string.IsNullOrEmpty(x.WorkUserId))) {
var dmodel = dlist.Where(x => x.DeptId == item.Dept_Id).FirstOrDefault();
int wxDeptId = dmodel?.WorkDepartId ?? 1;
string WorkUserId = "";
//根据手机号码 强验证
var wxModel = wxEmpList.Where(x => x.mobile == item.Account).FirstOrDefault();
if (wxModel == null)
{
//成员UserID。对应管理端的帐号,企业内必须唯一。不区分大小写,长度为1~64个字节。只能由数字、字母和“_-@.”四种字符组成,且第一个字符必须是数字或字母。
string userId = item.Id + "_" + DateTime.Now.ToString("yyyyMMddHHmmssffff@") + (new Random().Next(1000, 9999));//规则生成
//新增用户
var inserMember = new Senparc.Weixin.Work.AdvancedAPIs.MailList.Member.MemberCreateRequest()
{
to_invite = true,
alias = "",
userid = userId,
name = item.EmployeeName,
english_name = "",
mobile = item.Account,
department = new long[] { wxDeptId },
order = new long[] { 0 },
position = item.PostName,
gender = (item.Sex + 1).ToString(),
email = "",
enable = 1,
avatar_mediaid = "",
telephone = "",
address = "",
};
var cmodel = QYWeiXinHelper.CreateMember(token, inserMember);
if (cmodel.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
WorkUserId = userId;
}
else {
LogHelper.Write("员工 " + item.EmployeeName + "(" + item.Id + ") 创建失败;" + cmodel.errmsg);
return "员工 " + item.EmployeeName + "(" + item.Id + ") 创建失败;" + cmodel.errmsg;
}
}
else {
//修改用户
WorkUserId = wxModel.userid;
//string new_userId = item.Id + "_" + DateTime.Now.ToString("yyyyMMddHHmmssffff@") + (new Random().Next(1000, 9999));//规则生成
//执行更新用户名称 设置新的userId (微信自动生成的userId 只能修改一次用户信息)
var updateMember = new Senparc.Weixin.Work.AdvancedAPIs.MailList.Member.MemberUpdateRequest()
{
new_userid="",
alias = "",
userid = wxModel.userid,
name = item.EmployeeName,
english_name = wxModel.english_name,
mobile = wxModel.mobile,
department = new long[] { wxDeptId },
order = new long[] { 0 },
position = item.PostName,
gender = (item.Sex + 1).ToString(),
email = wxModel.email,
enable = 1,
avatar_mediaid = wxModel.avatar,
telephone = "",
address = "",
};
var upmodel = QYWeiXinHelper.UpdateMember(token, updateMember);
if (upmodel.errcode != Senparc.Weixin.ReturnCode_Work.请求成功) {
LogHelper.Write("员工 " + item.EmployeeName + "(" + item.Id + ") 更新失败;" + upmodel.errmsg);
return "员工 " + item.EmployeeName + "(" + item.Id + ") 更新失败;" + upmodel.errmsg;
}
}
//更新用户表 企业微信用户id
Dictionary keyValues = new Dictionary() {
{ nameof(RB_Account_ViewModel.WorkUserId),WorkUserId}
};
List wheres = new List() {
new WhereHelper(){
FiledName=nameof(RB_Account_ViewModel.Id),
FiledValue=item.Id,
OperatorEnum=OperatorEnum.Equal
}
};
accountRepository.Update(keyValues, wheres);
}
LogHelper.WriteInfo("用户" + userInfo.AccountName + "(" + userInfo.Id + ") 操作同步人员至企业微信");
return "";
}
///
/// 获取通讯录token
///
///
///
///
private string GetEmployeeToken(int Group_Id, RB_WeChat_Config_ViewModel configmodel)
{
string token = WeChatReidsCache.GetToken(Cache.CacheKey.QYWeChat_TelToken_Key + Group_Id);
if (string.IsNullOrEmpty(token))
{
var TelToken = QYWeiXinHelper.GetToken(configmodel.WX_CorpId, configmodel.Employee_Secret);
if (TelToken.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
WeChatReidsCache.TokenSet(Cache.CacheKey.QYWeChat_TelToken_Key + Group_Id, TelToken.access_token, TelToken.expires_in - 1);
token = TelToken.access_token;
}
else
{
LogHelper.Write("token获取失败 GetEmployeeToken");
return "";
}
}
return token;
}
#endregion
#region 用户客户
///
/// 转移客户
///
///
///
///
///
public string SetUserCoustomerTransfer(int transferUserId, int receiveUserId, int customerTransfer, int channelTransfer, UserInfo userInfo)
{
var configmodel = weChat_ConfigRepository.GetList(new RB_WeChat_Config_ViewModel() { Group_Id = userInfo.Group_Id, Enable = 1 }).FirstOrDefault();
if (configmodel == null || configmodel.Enable != 1) { return "未启用企业微信,无法同步"; }
string token = GetContactToken(userInfo.Group_Id, configmodel);
if (string.IsNullOrEmpty(token)) { return "token获取失败"; }
var transferModel = accountRepository.GetEmployeeInfo(transferUserId);
var receiveModel = accountRepository.GetEmployeeInfo(receiveUserId);
if (transferModel == null || receiveModel == null) { return "用户不存在"; }
if (string.IsNullOrEmpty(transferModel.WorkUserId) || string.IsNullOrEmpty(receiveModel.WorkUserId)) { return "关联企业微信Id不存在,请核实用户后再试"; }
string msg = "";
if (customerTransfer == 1)
{
List CoustomerList = new List();
try
{
var excontact = QYWeiXinHelper.GetExternalContactList(token, transferModel.WorkUserId);
if (excontact.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
if (excontact.external_userid != null && excontact.external_userid.Any())
{
CoustomerList = excontact.external_userid;
}
}
else
{
return "企业微信获取客户列表失败";
}
}
catch (Exception ex)
{
if (!ex.Message.Contains("84061"))
{
return "当前用户不存在外部联系人的关系";
}
}
if (CoustomerList.Any())
{
int pageIndex = (int)Math.Ceiling(Convert.ToDecimal(CoustomerList.Count()) / 100);
int pageSize = 100;//微信只支持单次100条数据
bool uflag = false;
for (int index = 1; index <= pageIndex; index++)
{
//开始转移
var clist = CoustomerList.Skip((index - 1) * pageSize).Take(pageSize).ToList();
if (clist.Any())
{
string Robj = QYWeiXinHelper.TransferCostomer(token, clist, transferModel.WorkUserId, receiveModel.WorkUserId);
if (!string.IsNullOrEmpty(Robj))
{
JObject parms = JObject.Parse(Robj);
int errcode = parms.GetInt("errcode", -1);
if (errcode == 0)
{
uflag = true;
}
else
{
//失败
return "转移客户失败,请联系管理员后再试";
}
}
else
{
return "请求失败,请联系管理员";
}
}
}
if (uflag)
{
//成功
Dictionary keyValues = new Dictionary() {
{ nameof(RB_Account_ViewModel.IsWorkTransfer),1 }
};
List wheres = new List() {
new WhereHelper(){
FiledName=nameof(RB_Account_ViewModel.Id),
FiledValue=transferModel.Id,
OperatorEnum=OperatorEnum.Equal
}
};
bool flag = accountRepository.Update(keyValues, wheres);
msg = flag ? "" : "出错了,请联系管理员";
}
}
}
#region 转移渠道码配置用户
if (channelTransfer == 1)
{
msg += TransferChannelUser(transferUserId, receiveUserId, userInfo);
}
#endregion
LogHelper.WriteInfo("用户" + userInfo.AccountName + "(" + userInfo.Id + ") 操作在职客户转移,由" + transferUserId + "=>" + receiveUserId);
return msg;
}
///
/// 获取外部联系人token
///
///
///
///
private string GetContactToken(int Group_Id, RB_WeChat_Config_ViewModel configmodel) {
string token = WeChatReidsCache.GetToken(Cache.CacheKey.QYWeChat_EmpToken_Key + Group_Id);
if (string.IsNullOrEmpty(token))
{
var TelToken = QYWeiXinHelper.GetToken(configmodel.WX_CorpId, configmodel.Contact_Secret);
if (TelToken.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
WeChatReidsCache.TokenSet(Cache.CacheKey.QYWeChat_EmpToken_Key + Group_Id, TelToken.access_token, TelToken.expires_in - 1);
token = TelToken.access_token;
}
else
{
LogHelper.Write("token获取失败," + TelToken.errmsg);
return "";
}
}
return token;
}
///
/// 定时器中获取外部联系人token
///
///
///
///
private string GetContactTokenForTimer(int Group_Id, RB_WeChat_Config_ViewModel configmodel) {
string token = WeChatReidsCache.GetToken(Cache.CacheKey.QYWeChat_EmpToken_Key + Group_Id);
if (string.IsNullOrEmpty(token))
{
token = GetTokenForServer(configmodel.WX_CorpId, configmodel.Contact_Secret, out int expires_in);
if (string.IsNullOrEmpty(token))
{
LogHelper.Write("token获取失败 GetTokenForServer");
return "";
}
WeChatReidsCache.TokenSet(Cache.CacheKey.QYWeChat_EmpToken_Key + Group_Id, token, expires_in - 1);
}
return token;
}
///
/// 获取离职员工客户列表
///
///
///
public object GetLeaveUserClientList(UserInfo userInfo)
{
var configmodel = weChat_ConfigRepository.GetList(new RB_WeChat_Config_ViewModel() { Group_Id = userInfo.Group_Id, Enable = 1 }).FirstOrDefault();
if (configmodel == null || configmodel.Enable != 1) { return "未启用企业微信,无法同步"; }
string token = GetContactToken(userInfo.Group_Id, configmodel);
if (string.IsNullOrEmpty(token)) { return "token获取失败"; }
List list = new List();
for (int i = 0; i < 50; i++)
{
var rmsg = QYWeiXinHelper.GetUnassignedList(token, i);
if (rmsg.errcode == Senparc.Weixin.ReturnCode_Work.请求成功)
{
list.AddRange(rmsg.info);
if (rmsg.is_last)
{
break;
}
}
else {
LogHelper.Write("获取离职员工客户列表失败:" + rmsg.errmsg);
break;
}
}
#region 分组查询员工信息
List