備忘錄——C#建立釘釘OA審批例項

shanzm發表於2024-08-20

目錄
  • 1.釘釘介面文件及SDK
  • 2.釘釘中建立應用
  • 3.程式碼段
    • 3.1 獲取Token
    • 3.2 透過手機號獲取釘釘UserID等資訊
    • 3.3 建立流程審批例項

1.釘釘介面文件及SDK

  • 完整發起審批流程例項的步驟:https://open.dingtalk.com/document/orgapp/tutorial-creating-or-updating-an-approval-template
  • 呼叫本介面建立審批例項:https://open.dingtalk.com/document/isvapp/initiate-an-approval-process-without-a-process
  • SDK下載:https://open.dingtalk.com/document/resourcedownload/download-server-sdk?spm=ding_open_doc.document.0.0.72fb3336BiUuCT#title-dyi-gqb-z18

2.釘釘中建立應用

建立應用後,得到以下資訊,新增到專案檔案中

注意建立應用後,在開發配置->許可權管理:獲取使用者個人資訊的許可權

	<appSettings>
		<add key="appKey" value="ding3jfjmdaXXXXXXXX"/>
		<add key="appSecret" value="Xlw9Z3_XXXXXXXXXXX-XXXXXXXX-XXXXXXXXXXX"/>
		<add key="agentId" value="XXXXXXX"/>
	</appSettings>

3.程式碼段

3.1 獲取Token

    public class TokenModel
    {
        public DateTime CreateTime { get; set; }
        public string Token { get; set; }
        public int Expires { get; set; }
    }

    public static class TokenHelper
    {
        private static string _appKey = ConfigurationManager.AppSettings["appKey"];
        private static string _appSecret = ConfigurationManager.AppSettings["appSecret"];

        /// <summary>
        /// 從釘釘介面獲取Token
        /// </summary>
        /// <returns></returns>
        private  static TokenModel PostApplyToken()
        {
            DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
            OapiGettokenRequest request = new OapiGettokenRequest();
            request.Appkey = _appKey;
            request.Appsecret = _appSecret;
            request.SetHttpMethod("GET");
            OapiGettokenResponse response = client.Execute(request);
            string token = response.AccessToken;
            int expires = Convert.ToInt16(response.ExpiresIn);
            TokenModel tokenModel = new TokenModel() { CreateTime = DateTime.Now, Token = token, Expires = expires };
            return tokenModel;
        }

        /// <summary>
        /// 獲取Token
        /// </summary>
        /// <returns></returns>
        public static string  GetToken()
        {
            TokenModel tokenModel = new TokenModel ();
            MemoryCache tokenCache = MemoryCache.Default;
            CacheItemPolicy policy = new CacheItemPolicy() { AbsoluteExpiration = DateTimeOffset.Now.AddDays(1) };

            //快取中存在Token
            if (tokenCache.Contains("token"))
            {
                TokenModel tempTokenModel = tokenCache["token"] as TokenModel;
                bool isValidity = IsBetweenTimeSpan(DateTime.Now, tempTokenModel.CreateTime.AddSeconds(tokenModel.Expires));
                //Token過期
                if (!isValidity)
                {
                    //快取更新最新Token
                    tokenCache.Remove("token");
                    tokenModel = PostApplyToken();
                    tokenCache = MemoryCache.Default;
                    tokenCache.Add("token", tokenModel, policy);
                }

            }
            //快取中不存在Token
            else
            {
                //快取更新最新Token
                tokenModel = PostApplyToken();
                tokenCache = MemoryCache.Default;
                tokenCache.Add("token", tokenModel, policy);
            }
            TokenModel tokenModel1 = tokenCache["token"] as TokenModel;
            return tokenModel.Token;
        }

        /// <summary>
        /// datetime是否在endTime之前
        /// </summary>
        /// <param name="dateTime"></param>
        /// <param name="endTime"></param>
        /// <returns></returns>
        private static bool IsBetweenTimeSpan(DateTime dateTime, DateTime endTime)
        {
            int compNum2 = DateTime.Compare(dateTime, endTime);
            return compNum2 < 0;
        }

    }

3.2 透過手機號獲取釘釘UserID等資訊


    public static class UserInfoHelper
    {

        /// <summary>
        /// 透過手機號查詢UserId
        /// </summary>
        /// <param name="mobile">形如:18860912913</param>
        /// <returns>形如:17180664937558782</returns>
        public static string GetUserIdByPhone(string mobile = "18860912913")
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/getbymobile");
            OapiV2UserGetbymobileRequest req = new OapiV2UserGetbymobileRequest();
            req.Mobile = mobile;
            OapiV2UserGetbymobileResponse rsp = client.Execute(req, TokenHelper.GetToken());
            return rsp.Result.Userid;
        }

        /// <summary>
        /// 透過userId 查詢 部門ID
        /// </summary>
        /// <param name="userId">形如:17180664937558782</param>
        /// <returns>形如:481091344</returns>
        public static long GetDepByUserId(string userId)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
            OapiV2UserGetRequest req = new OapiV2UserGetRequest();
            req.Userid = userId;
            req.Language = "zh_CN";
            OapiV2UserGetResponse rsp = client.Execute(req, TokenHelper.GetToken());
            return Convert.ToInt64(rsp.Result.DeptOrderList[0].DeptId);
        }
    }

3.3 建立流程審批例項

  • 注意流程模板的ID在流程設計的基礎設定介面的最下面,形如:"PROC-38313682-235A-496F-9B64-0FFE9D0C18DC"
  • 注意檢視文件,流程中不是所有的的控制元件都支援透過介面建立
  • 注意明細行的表格是一行是一個陣列,之後在巢狀在一個陣列中
    public class ProcInstance
    {
        private static long _agentId = Convert.ToInt64(ConfigurationManager.AppSettings["agentId"]);
        public string processCode = "流程模板ID";

        /// <summary>
        /// 建立審批例項
        /// </summary>
        /// <returns></returns>
        public string CreateProcInstance()
        {
            try
            {
                IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/create");

                OapiProcessinstanceCreateRequest request = new OapiProcessinstanceCreateRequest();
                request.OriginatorUserId = UserInfoHelper.GetUserIdByPhone("手機號");
                request.DeptId = UserInfoHelper.GetDepByUserId(request.OriginatorUserId.ToString());
                request.AgentId = _agentId;
                request.ProcessCode = processCode;
                request.CcPosition = "START";

                OapiProcessinstanceCreateRequest.FormComponentValueVoDomain a = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();
                a.Name = "單行輸入框";
                a.Value = "123456789";

                OapiProcessinstanceCreateRequest.FormComponentValueVoDomain b = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();
                b.Name = "姓名";
                b.Value = "123456789";

                #region 表格
                OapiProcessinstanceCreateRequest.FormComponentValueVoDomain c = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();
                OapiProcessinstanceCreateRequest.FormComponentValueVoDomain item1 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();
                item1.Name = "檢驗專案";
                item1.Value = "啊啦啦啦啦";

                OapiProcessinstanceCreateRequest.FormComponentValueVoDomain item2 = new OapiProcessinstanceCreateRequest.FormComponentValueVoDomain();
                item2.Name = "型別";
                item2.Value = "啊啦啦啦啦";

                List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain> listItem = new List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain>() { item1, item2 };

                c.Name = "表格";
                c.Value = TopUtils.ObjectToJson(new List<List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain>>() { listItem });
                #endregion

                var d = new List<OapiProcessinstanceCreateRequest.FormComponentValueVoDomain>() { a, b, c };
                request.FormComponentValues = TopUtils.ObjectToJson(d);

                var token = TokenHelper.GetToken();
                OapiProcessinstanceCreateResponse rsp = client.Execute(request, token);
                if (rsp.IsError)
                {
                    return rsp.Errmsg;
                }
                else
                {
                    return rsp.ProcessInstanceId;
                }

            }
            catch (Exception ex)
            {

                return ex.Message;
            }
        }

        /// <summary>
        /// 透過審批例項ID查詢審批流程的資訊
        /// </summary>
        /// <param name="instanceId">流程例項ID,形如"OpYINCq5TUaKzy0MSfoIrg04411720693785"</param>
        /// <returns></returns>
        public string GetInstanceNoById(string instanceId)
        {
            IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/processinstance/get");
            OapiProcessinstanceGetRequest req = new OapiProcessinstanceGetRequest();
            //審批例項process_instance_id
            req.ProcessInstanceId = instanceId;
            OapiProcessinstanceGetResponse rsp = client.Execute(req, TokenHelper.GetToken());
            return rsp.ProcessInstance.BusinessId;
        }
    }

相關文章