Przeglądaj źródła

企业微信API 添加员工

leiy 1 rok temu
rodzic
commit
4e5e962491

+ 39 - 2
OASystem/OASystem.Api/Controllers/AuthController.cs

@@ -8,6 +8,11 @@ using Serilog.Parsing;
 using OASystem.Domain.Dtos.System;
 using System.Drawing.Drawing2D;
 using System.Collections;
+using OASystem.API.OAMethodLib.JuHeAPI;
+using OASystem.API.OAMethodLib.QiYeWeChatAPI;
+using OASystem.Domain.Dtos.QiYeWeChat;
+using OASystem.Domain.Entities.System;
+using TinyPinyin;
 
 namespace OASystem.API.Controllers
 {
@@ -22,14 +27,18 @@ namespace OASystem.API.Controllers
         private readonly LoginRepository _loginRep;
         private readonly MessageRepository _message;
         private readonly SystemMenuPermissionRepository _SystemMenuPermissionRepository;
+
+        private readonly IQiYeWeChatApiService _qiYeWeChatApiServic;
+
         public AuthController(IConfiguration config, LoginRepository loginRep, IMapper mapper,MessageRepository message,
-            SystemMenuPermissionRepository systemMenuPermissionRepository)
+            SystemMenuPermissionRepository systemMenuPermissionRepository, IQiYeWeChatApiService qiYeWeChatApiService)
         {
             _config = config;
             _loginRep = loginRep;
             _mapper = mapper;
             _message = message;
             _SystemMenuPermissionRepository = systemMenuPermissionRepository;
+            _qiYeWeChatApiServic = qiYeWeChatApiService;
         }
 
         /// <summary>
@@ -121,11 +130,36 @@ namespace OASystem.API.Controllers
         /// </summary>
         /// <param name="dto"></param>
         /// <returns></returns>
-        [Authorize]
+        //[Authorize]
         [HttpPost]
         [Route("register")]
         public async Task<IActionResult> Register(RegisterDto dto)
         {
+            #region 企业微信添加员工
+
+            string lastName = dto.CnName.Substring(0, 1);
+            string lastNamePy = string.Empty;
+            if (PinyinHelper.IsChinese(Convert.ToChar(lastName)))
+            {
+                lastNamePy = PinyinHelper.GetPinyin(lastName);
+            }
+
+            string userId = string.Format("{0}.{1}", dto.EnName, lastNamePy.ToLower());
+            Create_Request request = new Create_Request()
+            {
+                userid = userId,
+                name = dto.CnName,
+                mobile = dto.Phone,
+                department = new List<long>() { dto.DepId },
+                position = dto.JobPostId.ToString(),
+                gender = dto.Sex == 0 ? 1 : dto.Sex == 1 ? 2 : 1,
+                biz_mail = dto.Email
+            };
+
+            var qiYeWeChatCreateData = await _qiYeWeChatApiServic.CreateAsync(request);
+            #endregion
+
+
             var userData = _loginRep.Register(_loginRep, dto);
             if (userData.Result.Code != 0)
             {
@@ -134,6 +168,9 @@ namespace OASystem.API.Controllers
                 return Ok(JsonView(false, "注册失败!"));
             }
 
+           
+
+
             return Ok(new { Code = 0, Msg = userData.Result.Msg });
         }
 

+ 16 - 10
OASystem/OASystem.Api/Controllers/TencentOCRController.cs

@@ -52,7 +52,7 @@ namespace OASystem.API.Controllers
                 return Ok(JsonView("图片不能大于7M!"));
             }
 
-            var gbData = TencentOCRTools.GetOCR((int)TencentOCREnum.GeneralBasic, dto);
+            var gbData =  TencentOCRTools.GetOCR((int)TencentOCREnum.GeneralBasic, dto);
 
             if (gbData.Code != 0)
             {
@@ -468,19 +468,25 @@ namespace OASystem.API.Controllers
                 return Ok(JsonView("图片不能大于7M!"));
             }
 
-            var mlidpData = TencentOCRTools.GetOCR((int)TencentOCREnum.BusinessCard, dto);
-
-            if (mlidpData.Code != 0)
+            try
             {
-                return Ok(JsonView(mlidpData.Msg));
-            }
+                var mlidpData = TencentOCRTools.GetOCR((int)TencentOCREnum.BusinessCard, dto);
+                if (mlidpData.Code != 0)
+                {
+                    return Ok(JsonView(mlidpData.Msg));
+                }
 
-            if (mlidpData.Data == null)
+                if (mlidpData.Data == null)
+                {
+                    return Ok(JsonView(mlidpData.Msg));
+                }
+
+                return Ok(JsonView(mlidpData.Data));
+            }
+            catch (Exception ex)
             {
-                return Ok(JsonView(mlidpData.Msg));
+                return Ok(JsonView(false, ex.Message));
             }
-
-            return Ok(JsonView(mlidpData.Data));
         }
     }
 }

+ 32 - 0
OASystem/OASystem.Api/OAMethodLib/QiYeWeChatAPI/IQiYeWeChatApiService.cs

@@ -0,0 +1,32 @@
+using OASystem.Domain.Dtos.QiYeWeChat;
+using OASystem.Domain.ViewModels.QiYeWeChat;
+
+namespace OASystem.API.OAMethodLib.QiYeWeChatAPI
+{
+    /// <summary>
+    /// 企业微信Api 服务
+    /// </summary>
+    public interface IQiYeWeChatApiService
+    {
+
+        ///// <summary>
+        ///// 获取access_token
+        ///// </summary>
+        ///// <param name="applicationType">
+        ///// 1:人事助手 
+        ///// 2:打卡
+        ///// 3:邮件
+        ///// </param>
+        ///// <returns></returns>
+        //Task<Access_TokenView> GetToken(int applicationType);
+
+        /// <summary>
+        /// 创建员工
+        /// </summary>
+        /// <param name="create_Request"></param>
+        /// <returns></returns>
+        Task<ResponseBase> CreateAsync(Create_Request create_Request);
+
+
+    }
+}

+ 235 - 0
OASystem/OASystem.Api/OAMethodLib/QiYeWeChatAPI/QiYeWeChatApiService.cs

@@ -0,0 +1,235 @@
+using OASystem.Domain.Dtos.QiYeWeChat;
+using OASystem.Domain.ViewModels.JuHeExchangeRate;
+using OASystem.Domain.ViewModels.QiYeWeChat;
+using Org.BouncyCastle.Ocsp;
+using System.Text.Json;
+using Ubiety.Dns.Core;
+
+namespace OASystem.API.OAMethodLib.QiYeWeChatAPI
+{
+    /// <summary>
+    /// 聚合Api 服务
+    /// </summary>
+    public class QiYeWeChatApiService: IQiYeWeChatApiService
+    {
+        private readonly HttpClient _httpClient;
+        private readonly string CorpId = "wwe978bef5495a0728";   //企业Id
+        private readonly string PersonnelAssistant_AgentId = "3010011";   //人事助手Id
+        private readonly string PersonnelAssistant_Corpsecret = "ig--IJd6TxWDMJ1wT4e-RDRcRX12v5GjB359DNATwJ4"; //人事助手凭证密钥
+        private readonly string PunchCard_AgentId = "3010185";            //打卡Id
+        private readonly string PunchCard_Corpsecret = "Xhrl37GOqlAjsu0VzUSJECaJdjzkDXQLbvrzRsZQb8M";          //打卡凭证密钥
+        private readonly string Email_AgentId = "1000004";   //E-Mail Id
+        private readonly string Email_Corpsecret = "NA1zbJM15GmgjPYwDOqz59dIo1Wnug-MbU107MeUemc"; //E-Mail 凭证密钥
+        private readonly string AddressBook_Corpsecret = "Y1tnjh7j-BvbqAytAoXZPUbmDR6dqLTL6mXtc6PZ7fo";  //通讯录同步 凭证密钥
+        private readonly JobPostRepository _jobPostRep;
+
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <param name="clientFactory"></param>
+        /// <param name="jobPostRep"></param>
+        public QiYeWeChatApiService(IHttpClientFactory clientFactory, JobPostRepository jobPostRep) 
+        {
+            _httpClient = clientFactory.CreateClient("PublicQiYeWeChatApi"); ;
+            _jobPostRep = jobPostRep;
+        }
+
+        /// <summary>
+        /// 获取access_token
+        /// </summary>
+        /// <param name="applicationType">
+        /// 1:人事助手 
+        /// 2:打卡
+        /// 3:邮件
+        /// 4:通讯录同步
+        /// </param>
+        /// <returns></returns>
+        private async Task<Access_TokenView> GetTokenAsync(int applicationType)
+        {
+            Access_TokenView tokenResult = new Access_TokenView();
+            Access_Token_Request access_Token = new Access_Token_Request();
+            string cacheName = string.Empty;
+
+            if (applicationType == 1)
+            {
+                access_Token.corpsecret = PersonnelAssistant_Corpsecret; //人事助手
+                cacheName = "PersonnelAssistant_Access_Token";
+            }
+            else if (applicationType == 2)
+            {
+                access_Token.corpsecret = PunchCard_Corpsecret; //打卡
+                cacheName = "PunchCard_Access_Token";
+            }
+            else if (applicationType == 3)
+            {
+                access_Token.corpsecret = Email_Corpsecret; //E-Mail
+                cacheName = "Enail_Access_Token";
+            }
+            else if (applicationType == 4)
+            {
+                access_Token.corpsecret = AddressBook_Corpsecret; //通讯录同步
+                cacheName = "AddressBook_Access_Token";
+            }
+            else
+            {
+                tokenResult.errmsg = "未识别应用类型Id!";
+                return tokenResult;
+            }
+
+
+            string access_token = await RedisRepository.RedisFactory
+                                                    .CreateRedisRepository()
+                                                    .StringGetAsync<string>(cacheName);//string 取
+
+            if (string.IsNullOrEmpty(access_token))
+            {
+                string access_token_url = string.Format(@"/cgi-bin/gettoken?corpid={0}&corpsecret={1}", access_Token.corpid, access_Token.corpsecret);
+
+                var access_tokenReq = await _httpClient.GetAsync(access_token_url);
+                if (access_tokenReq.IsSuccessStatusCode) 
+                {
+                    var stringResponse = await access_tokenReq.Content.ReadAsStringAsync();
+
+                    tokenResult = System.Text.Json.JsonSerializer.Deserialize<Access_TokenView>(stringResponse,
+                        new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
+
+                    if (tokenResult.errcode == 0)
+                    {
+                        TimeSpan ts = DateTime.Now.AddMinutes(118) - DateTime.Now; //设置redis 过期时间 118分钟
+                        await RedisRepository
+                            .RedisFactory
+                            .CreateRedisRepository()
+                            .StringSetAsync<string>(cacheName, tokenResult.access_token, ts);//string 存
+                    }
+                }
+                else
+                {
+                    tokenResult.errmsg = "企业微信Token未获取到!";
+                }
+            }
+            else
+            {
+                tokenResult.errcode = 0;
+                tokenResult.access_token = access_token;
+            }
+
+            return tokenResult;
+        }
+
+        /// <summary>
+        /// 获取部门列表
+        /// </summary>
+        /// <param name="access_token"></param>
+        /// <returns></returns>
+        private async Task<DepartmentListView> GetDepartmentAsync(string access_token)
+        {
+            DepartmentListView result = new DepartmentListView();
+
+            string dep_url = string.Format("/cgi-bin/department/list?access_token={0}", access_token);
+
+
+            var depReq = await _httpClient.GetAsync(dep_url);
+            if (depReq.IsSuccessStatusCode)
+            {
+                var stringResponse = await depReq.Content.ReadAsStringAsync();
+
+                result = System.Text.Json.JsonSerializer.Deserialize<DepartmentListView>(stringResponse,
+                    new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
+
+
+            }
+            else
+            {
+                result.errcode = -1;
+                result.errmsg = "企业微信部门列表未获取到!";
+            }
+
+            return result;
+        }
+
+        /// <summary>
+        /// 创建员工
+        /// </summary>
+        /// <param name="create_Request"></param>
+        /// <returns></returns>
+        public async Task<ResponseBase> CreateAsync(Create_Request create_Request)
+        {
+            ResponseBase responseBase = new ResponseBase();
+
+            #region 职位
+            string depName = string.Empty,
+                   jobName = string.Empty;
+
+            List<Sys_JobPostI> jobs = await _jobPostRep.QueryJobPost(string.Empty);
+
+            Sys_JobPostI jobPost = jobs.Where(it => it.IsDel == 0 && it.Id == Convert.ToInt32(create_Request.position)).FirstOrDefault();
+
+            if (jobPost != null)
+            {
+                depName = jobPost.DepName; 
+                jobName = jobPost.JobName;
+            }
+            create_Request.position = jobName;
+
+            if (string.IsNullOrEmpty(create_Request.biz_mail))
+            {
+                create_Request.biz_mail = string.Format("{0}@pan-american-intl.com", create_Request.userid);
+            }
+
+            #endregion
+
+            Access_TokenView access_Token = new Access_TokenView();
+            access_Token = await GetTokenAsync(4);
+            if (access_Token.errcode == 0)
+            {
+                create_Request.access_token = access_Token.access_token;
+
+                #region 处理部门
+                DepartmentListView depData = await GetDepartmentAsync(access_Token.access_token);
+
+                if (depData.errcode == 0)
+                {
+                    var depData1 = depData.department.Where(x => x.name == depName).FirstOrDefault();
+                    if (depData1 != null) 
+                    {
+                        create_Request.department = new List<long> { depData1.id };
+                    }
+                    else
+                    {
+                        responseBase.errcode = -1;
+                        responseBase.errmsg = "未在企业微信上找到OA内设置的部门";
+                        return responseBase;
+                    }
+                }
+                else
+                {
+                    responseBase.errcode = depData.errcode;
+                    responseBase.errmsg = depData.errmsg;
+                    return responseBase;
+                }
+
+                #endregion
+
+                create_Request.access_token = access_Token.access_token;
+                string create_url = string.Format("/cgi-bin/user/create?access_token={0}", create_Request.access_token);
+
+                var json = System.Text.Json.JsonSerializer.Serialize(create_Request);
+                var content = new StringContent(json, Encoding.UTF8, "application/json");
+                var create_Req = await _httpClient.PostAsync(create_url, content);
+                var stringResponse = await create_Req.Content.ReadAsStringAsync();
+
+                responseBase = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
+                    new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
+
+
+            }
+            else
+            {
+                responseBase.errcode = access_Token.errcode;
+                responseBase.errmsg = access_Token.errmsg;
+            }
+
+            return responseBase;
+        }
+    }
+}

+ 1 - 0
OASystem/OASystem.Api/OASystem.API.csproj

@@ -37,6 +37,7 @@
     <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
     <PackageReference Include="TencentCloudSDK.Common" Version="3.0.734" />
     <PackageReference Include="TencentCloudSDK.Ocr" Version="3.0.734" />
+    <PackageReference Include="TinyPinyin.Net" Version="1.0.2" />
   </ItemGroup>
 
   <ItemGroup>

+ 9 - 0
OASystem/OASystem.Api/Program.cs

@@ -14,6 +14,7 @@ using Quartz.Spi;
 using Quartz;
 using QuzrtzJob.Factory;
 using System.Runtime.CompilerServices;
+using OASystem.API.OAMethodLib.QiYeWeChatAPI;
 
 var builder = WebApplication.CreateBuilder(args);
 var basePath = AppContext.BaseDirectory;
@@ -250,6 +251,14 @@ builder.Services.AddSingleton<IJuHeApiService, JuHeApiService>();
 builder.Services.AddHttpClient("PublicJuHeApi", c => c.BaseAddress = new Uri("http://web.juhe.cn"));
 #endregion
 
+#region Æóҵ΢ÐÅAPI ·þÎñ
+
+builder.Services.AddControllersWithViews();
+builder.Services.AddSingleton<IQiYeWeChatApiService, QiYeWeChatApiService>();
+builder.Services.AddHttpClient("PublicQiYeWeChatApi", c => c.BaseAddress = new Uri("https://qyapi.weixin.qq.com"));
+
+#endregion
+
 #region ÓеÀAPI ·þÎñ
 //builder.Services.AddControllersWithViews();
 //builder.Services.AddSingleton<IYouDaoApiService, YouDaoApiService>();

+ 26 - 0
OASystem/OASystem.Domain/Dtos/QiYeWeChat/Access_Token_Request.cs

@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Dtos.QiYeWeChat
+{
+    /// <summary>
+    /// 企业微信 
+    /// 请求 access_token dto
+    /// </summary>
+    public class Access_Token_Request
+    {
+        /// <summary>
+        /// 企业ID
+        /// </summary>
+        public string corpid { get; set; } = "wwe978bef5495a0728";
+
+        /// <summary>
+        /// 应用的凭证密钥
+        /// 每个应用有独立的secret,获取到的access_token只能本应用使用,所以每个应用的access_token应该分开来获取
+        /// </summary>
+        public string? corpsecret { get; set; }
+    }
+}

+ 61 - 0
OASystem/OASystem.Domain/Dtos/QiYeWeChat/Create_Request.cs

@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.Dtos.QiYeWeChat
+{
+    /// <summary>
+    /// 企业微信API
+    /// 添加员工
+    /// </summary>
+    public class Create_Request
+    {/// <summary>
+     /// 调用接口凭证
+     /// </summary>
+        public string? access_token { get; set; }
+
+        /// <summary>
+        /// 成员UserID。对应管理端的账号,企业内必须唯一。长度为1~64个字节。只能由数字、字母和“_-@.”四种字符组成,且第一个字符必须是数字或字母。系统进行唯一性检查时会忽略大小写
+        /// </summary>
+        public string? userid { get; set; }
+
+        /// <summary>
+        /// 成员名称。长度为1~64个utf8字符
+        /// </summary>
+        public string? name { get; set; }
+
+        /// <summary>
+        /// 手机号码。企业内必须唯一,mobile/email二者不能同时为空
+        /// </summary>
+        public string? mobile { get; set; }
+
+        /// <summary>
+        /// 成员所属部门id列表,不超过100个
+        /// </summary>
+        public List<long> department { get; set; }
+
+        /// <summary>
+        /// 职务信息。长度为0~128个字符
+        /// </summary>
+        public string? position { get; set; }
+
+        /// <summary>
+        /// 性别。1表示男性,2表示女性
+        /// </summary>
+        public int gender { get; set; }
+
+        /// <summary>
+        /// 企业邮箱。仅对开通企业邮箱的企业有效。长度6~64个字节,且为有效的企业邮箱格式。
+        /// 企业内必须唯一。
+        /// 未填写则系统会为用户生成默认企业邮箱(由系统生成的邮箱可修改一次,2022年4月25日之后创建的成员需通过企业管理后台-协作-邮件-邮箱管理-成员邮箱修改)
+        /// </summary>
+        public string? biz_mail { get; set; }
+
+        /// <summary>
+        /// 启用/禁用成员。1表示启用成员,0表示禁用成员
+        /// </summary>
+        public int enable { get; set; } = 1;
+    }
+}

+ 24 - 0
OASystem/OASystem.Domain/ViewModels/QiYeWeChat/Access_TokenView.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.ViewModels.QiYeWeChat
+{
+    /// <summary>
+    /// 企业微信 获取access_token
+    /// </summary>
+    public class Access_TokenView : ResponseBase
+    {
+        /// <summary>
+        /// 获取到的凭证,最长为512字节
+        /// </summary>
+        public string access_token { get; set; } = null;
+
+        /// <summary>
+        /// 凭证的有效时间(秒)
+        /// </summary>
+        public int expires_in { get; set; }
+    }
+}

+ 50 - 0
OASystem/OASystem.Domain/ViewModels/QiYeWeChat/DepartmentView.cs

@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.ViewModels.QiYeWeChat
+{
+    /// <summary>
+    /// 部门详情
+    /// </summary>
+    public class DepartmentView
+    {
+        /// <summary>
+        /// 部门Id
+        /// </summary>
+        public long id { get; set; }
+
+        /// <summary>
+        /// 部门名称
+        /// </summary>
+        public string? name { get; set; }
+
+        /// <summary>
+        /// 部门负责人的UserID;第三方仅通讯录应用可获取
+        /// </summary>
+        public List<string>? department_leader { get; set; }
+
+        /// <summary>
+        /// 父部门id。根部门为1
+        /// </summary>
+        public int parentid { get; set; }
+
+        /// <summary>
+        /// 在父部门中的次序值。order值大的排序靠前。值范围是[0, 2^32)
+        /// </summary>
+        public long order { get; set; }
+    }
+
+    /// <summary>
+    /// 部门列表
+    /// </summary>
+    public class DepartmentListView : ResponseBase
+    {
+        /// <summary>
+        /// 部门列表数据
+        /// </summary>
+        public List<DepartmentView>? department { get; set; }
+    }
+}

+ 24 - 0
OASystem/OASystem.Domain/ViewModels/QiYeWeChat/ResponseBase.cs

@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace OASystem.Domain.ViewModels.QiYeWeChat
+{
+    /// <summary>
+    /// 企业微信 响应基类
+    /// </summary>
+    public class ResponseBase
+    {
+        /// <summary>
+        /// 出错返回码,为0表示成功,非0表示调用失败
+        /// </summary>
+        public int errcode { get; set; } = -1;
+
+        /// <summary>
+        /// 返回码提示语
+        /// </summary>
+        public string errmsg { get; set; } = "企业API请求错误!";
+    }
+}

+ 2 - 0
OASystem/OASystem.Infrastructure/Repositories/Login/LoginRepository.cs

@@ -1,6 +1,7 @@
 
 using AutoMapper;
 using OASystem.Domain;
+using OASystem.Domain.Dtos.QiYeWeChat;
 using OASystem.Domain.Dtos.System;
 using OASystem.Domain.Dtos.UserDto;
 using OASystem.Domain.Entities.System;
@@ -139,6 +140,7 @@ namespace OASystem.Infrastructure.Repositories.Login
 
                 return result;
             }
+
             result.Code = 0;
             result.Msg = "申请成功!人事主管审核后且信息部经理分配了登录账号,可登录OA!";
             return result;