欧美成人精品手机在线观看_69视频国产_动漫精品第一页_日韩中文字幕网 - 日本欧美一区二区

LOGO OA教程 ERP教程 模切知識(shí)交流 PMS教程 CRM教程 開(kāi)發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

[點(diǎn)晴永久免費(fèi)OA]C#獲取釘釘考勤機(jī)的打卡記錄并且解析

admin
2020年4月27日 17:29 本文熱度 3694

關(guān)注點(diǎn)

  • 1、釘釘AccessToken的獲取和防止過(guò)期
  • 2、使用TPL并行編程調(diào)用釘釘接口

需求詳解

公司前臺(tái)有個(gè)大屏,領(lǐng)導(dǎo)想顯示全部員工的考勤結(jié)果統(tǒng)計(jì)情況和車(chē)間的實(shí)時(shí)監(jiān)控視頻,還有車(chē)間的看板。簡(jiǎn)單說(shuō)就是把大屏分割成幾個(gè)區(qū)域。現(xiàn)在遇到的難題是釘釘獲取考勤結(jié)果的api是只有明細(xì)記錄,比如你公司1000人,那么可能回給你2000條考勤結(jié)果。分別是上班考勤和下班考勤的。沒(méi)有整個(gè)公司的,我就需要這么一條數(shù)據(jù)就行了。但人家沒(méi)有這樣的接口提供。卷起袖子,干!

趟坑過(guò)程

考勤打卡數(shù)據(jù)開(kāi)放

業(yè)務(wù)場(chǎng)景

該接口僅限企業(yè)接入使用,用于返回企業(yè)內(nèi)員工的實(shí)際打卡結(jié)果。比如,企業(yè)給一個(gè)員工設(shè)定的排班是上午9點(diǎn)和下午6點(diǎn)各打一次卡,即使員工在這期間打了多次,該接口也只會(huì)返回兩條記錄,包括上午的打卡結(jié)果和下午的打卡結(jié)果

考勤打卡數(shù)據(jù)開(kāi)放

請(qǐng)求說(shuō)明(ISV無(wú)調(diào)用權(quán)限)
如果你是ISV(應(yīng)用服務(wù)商,將開(kāi)發(fā)的應(yīng)用上架到釘釘應(yīng)用市場(chǎng),提供給釘釘其他企業(yè)用戶使用),則無(wú)調(diào)用權(quán)限
如果你是企業(yè)內(nèi)部開(kāi)發(fā)者(將自己公司的HR、OA、客戶管理、業(yè)務(wù)管理等系統(tǒng)接入釘釘),有權(quán)限調(diào)用
2017-10-16更新:新增用戶userId列表參數(shù)(userIdList)和分頁(yè)參數(shù)(offset,limit),提升接口穩(wěn)定性。

Https請(qǐng)求方式: POST

https://oapi.dingtalk.com/attendance/list?access_token=ACCESS_TOKEN

請(qǐng)求包結(jié)構(gòu)體
{
    "workDateFrom": "yyyy-MM-dd hh:mm:ss",
    "workDateTo": "yyyy-MM-dd hh:mm:ss",
    "userIdList":["員工UserId列表"],    // 必填,與offset和limit配合使用,不傳表示分頁(yè)獲取全員的數(shù)據(jù)
    "offset":0,    // 必填,第一次傳0,如果還有多余數(shù)據(jù),下次傳之前的offset加上limit的值
    "limit":1,     // 必填,表示數(shù)據(jù)條數(shù),最大不能超過(guò)50條
}

參數(shù)說(shuō)明
參數(shù)參數(shù)類(lèi)型必須說(shuō)明
access_tokenString調(diào)用接口憑證
workDateFromString查詢考勤打卡記錄的起始工作日
workDateToString查詢考勤打卡記錄的結(jié)束工作日
userIdListList員工在企業(yè)內(nèi)的UserID列表,企業(yè)用來(lái)唯一標(biāo)識(shí)用戶的字段
offsetLong表示獲取考勤數(shù)據(jù)的起始點(diǎn),第一次傳0,如果還有多余數(shù)據(jù),下次獲取傳的offset值為之前的offset+limit
limitLong表示獲取考勤數(shù)據(jù)的條數(shù),最大不能超過(guò)50條


1)獲取AccessToken

釘釘?shù)姆?wù)器很牛X可以并行訪問(wèn)的。但是獲取回來(lái)的數(shù)據(jù)集有點(diǎn)亂,其中有個(gè)關(guān)于分頁(yè)的參數(shù)需要順序讀取,就是“hasMore”還有沒(méi)有下一頁(yè)。所以最終沒(méi)有使用TPL。

        /// <summary>
        /// 獲取AccessToken
        /// </summary>
        /// <returns></returns>
        private AccessToken GetAccessToken()
        {
            string URL_GetToken = "https://oapi.dingtalk.com/gettoken?corpid={0}&corpsecret={1}";
            string fileName = AppDomain.CurrentDomain.BaseDirectory + "AccessToken.xml";
            if (!System.IO.File.Exists(fileName))
            {
                string respon = Program.HttpGetRequest(string.Format(URL_GetToken, Program.CorpId, Program.CorpSecret));
                DingTalkRespond obj = JsonConvert.DeserializeObject<DingTalkRespond>(respon);
                if (obj != null && obj.errcode == 0)
                {
                    var result = new AccessToken
                    {
                        access_token = obj.access_token,
                        expires_in = GetCurrentTimeStamp()
                    };
                    SerializerHelper.SerializerToXML(fileName, result);
                    return result;
                }
                else
                    return new AccessToken
                    {
                        access_token = obj.access_token,
                        expires_in = GetCurrentTimeStamp()
                    };
            }
            else
            {
                var fileResult = SerializerHelper.LoadFromXML<AccessToken>(fileName);
                long ts = (GetCurrentTimeStamp() - fileResult.expires_in) / 1000;
                if (ts >= 7200)
                {
                    string respon = Program.HttpGetRequest(string.Format(URL_GetToken, Program.CorpId, Program.CorpSecret));
                    DingTalkRespond obj = JsonConvert.DeserializeObject<DingTalkRespond>(respon);
                    if (obj != null && obj.errcode == 0)
                    {
                        fileResult.access_token = obj.access_token;
                        fileResult.expires_in = GetCurrentTimeStamp();
                        SerializerHelper.SerializerToXML(fileName, fileResult);
                    }
                }
                return fileResult;
            }
        }


2)獲取企業(yè)總?cè)藬?shù)

/// <summary>
        /// 獲取公司總?cè)藬?shù)
        /// </summary>
        /// <returns></returns>
        private int GetFactoryEmployeeCount(AccessToken token)
        {
            int result = 0;
            string url = string.Format("https://oapi.dingtalk.com/user/get_org_user_count?access_token={0}&onlyActive=0", token.access_token);
            string jsonObj = Program.HttpGetRequest(url);
            var objResult = JsonConvert.DeserializeObject<DingTalkRespond>(jsonObj);
            if (objResult != null && objResult.errcode == 0)
                result = objResult.count;
            return result;
        }


3)獲取全體員工的考勤結(jié)果

  /// <summary>
        /// 獲取指定頁(yè)的考勤結(jié)果
        /// </summary>
        /// <param name="offset"></param>
        /// <returns></returns>
        private void GetAttendance(AccessToken token)
        {
            EmployeeAttendanceList.Clear();
            string url = string.Format("https://oapi.dingtalk.com/attendance/list?access_token={0}", token.access_token);
            int offset = 0;
            bool bHasMore = true;
            while (bHasMore)
            {
                var request = new AttendanceRequest
                {
                    workDateFrom = DateTime.Now.ToString("yyyy-MM-dd") + " 00:00:00",
                    workDateTo = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    limit = 50,
                    userIdList = null,
                    offset = offset * 50
                };
                string jsonRequest = JsonConvert.SerializeObject(request).Replace("null", "[]");
                string jsonResult = Program.PostJsonData(url, jsonRequest);
                var objResult = JsonConvert.DeserializeObject<DingTalkRespond>(jsonResult);
                if (objResult != null && objResult.errcode == 0)
                {
                    foreach (var item in objResult.recordresult)
                    {
                        if (!EmployeeAttendanceList.Any(a => a.id == item.id))
                            EmployeeAttendanceList.Add(item);
                    }
                    offset++;
                    bHasMore = objResult.hasMore;
                }
                else
                    break;
            }
            EmployeeAttendanceList = EmployeeAttendanceList.Where(a => a.checkType == "OnDuty").OrderBy(e => e.id).ToList();
        }


private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
       {
           AccessToken token = GetAccessToken();
           GetAttendance(token);
           var report = from in EmployeeAttendanceList
                        group by q.timeResult into g
                        select new AttendanceReportItemDTO
                        {
                            TimeResult = g.Key,
                            PersonNumber = g.Count()
                        };
           BulletinBoardInit();
           #region 考勤統(tǒng)計(jì)
           attendanceReport.Total = GetFactoryEmployeeCount(token);
           var normalObj = report.Where(p => p.TimeResult == "正常").FirstOrDefault();
           attendanceReport.Normal = normalObj == null ? 0 : normalObj.PersonNumber;
           var lateObj = report.Where(p => p.TimeResult == "遲到").FirstOrDefault();
           attendanceReport.Late = lateObj == null ? 0 : lateObj.PersonNumber;
           var earlyObj = report.Where(p => p.TimeResult == "早退").FirstOrDefault();
           attendanceReport.Early = earlyObj == null ? 0 : earlyObj.PersonNumber;
           var seriousLateObj = report.Where(p => p.TimeResult == "嚴(yán)重遲到").FirstOrDefault();
           attendanceReport.SeriousLate = seriousLateObj == null ? 0 : seriousLateObj.PersonNumber;
           var absenteeismObj = report.Where(p => p.TimeResult == "曠工").FirstOrDefault();
           attendanceReport.Absenteeism = absenteeismObj == null ? 0 : absenteeismObj.PersonNumber;
           int total_temp = report.Sum(p => p.PersonNumber);
           var notSignedObj = report.Where(p => p.TimeResult == "未打卡").FirstOrDefault();
           attendanceReport.NotSigned = notSignedObj == null ? 0 : notSignedObj.PersonNumber;
           attendanceReport.NotSigned = attendanceReport.NotSigned + (attendanceReport.Total - total_temp);
           #endregion
           #region 判斷有沒(méi)有公告信息
           if (BulletinImages != null && BulletinImages.Length > 0)
           {
               if (BulletinImages.Length == 1)
               {
                   pbxNotity.Image = Image.FromFile(BulletinImages[0]);
               }
               if (BulletinImages.Length > 1)
               {
                   if (notifyShowIndex == BulletinImages.Length - 1)
                   {
                       notifyShowIndex = 0;
                   }
                   pbxNotity.Image = Image.FromFile(BulletinImages[notifyShowIndex]);
                   notifyShowIndex++;
               }
           }
           else
           {
               Action task = () =>
               {
                   BulletinBoardInit();
               };
               task.BeginInvoke(nullnull);
               string dir = AppDomain.CurrentDomain.BaseDirectory + "公告欄圖片\\";
               if (!Directory.Exists(dir))
               {
                   Directory.CreateDirectory(dir);
               }
               string[] bgFiles = Directory.GetFiles(dir);
               if (bgFiles != null && bgFiles.Length > 0)
               {
                   int imgIndex = rd.Next(bgFiles.Length);
                   pbxNotity.BackgroundImage = Image.FromFile(bgFiles[imgIndex]);
               }
           }
           #endregion
       }

效果展示



該文章在 2020/4/27 17:29:27 編輯過(guò)
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點(diǎn)晴ERP是一款針對(duì)中小制造業(yè)的專(zhuān)業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國(guó)內(nèi)大量中小企業(yè)的青睞。
點(diǎn)晴PMS碼頭管理系統(tǒng)主要針對(duì)港口碼頭集裝箱與散貨日常運(yùn)作、調(diào)度、堆場(chǎng)、車(chē)隊(duì)、財(cái)務(wù)費(fèi)用、相關(guān)報(bào)表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點(diǎn),圍繞調(diào)度、堆場(chǎng)作業(yè)而開(kāi)發(fā)的。集技術(shù)的先進(jìn)性、管理的有效性于一體,是物流碼頭及其他港口類(lèi)企業(yè)的高效ERP管理信息系統(tǒng)。
點(diǎn)晴WMS倉(cāng)儲(chǔ)管理系統(tǒng)提供了貨物產(chǎn)品管理,銷(xiāo)售管理,采購(gòu)管理,倉(cāng)儲(chǔ)管理,倉(cāng)庫(kù)管理,保質(zhì)期管理,貨位管理,庫(kù)位管理,生產(chǎn)管理,WMS管理系統(tǒng),標(biāo)簽打印,條形碼,二維碼管理,批號(hào)管理軟件。
點(diǎn)晴免費(fèi)OA是一款軟件和通用服務(wù)都免費(fèi),不限功能、不限時(shí)間、不限用戶的免費(fèi)OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved