kaoqin-services
Version:
考勤系统服务库
1 lines • 12.9 kB
JavaScript
"use strict";const dayjs=require("dayjs"),{TimeUtils}=require("kaoqin-utils");class KaoqinService{constructor(a){this.configManager=a.configManager,this.stateManager=a.stateManager,this.apiService=a.apiService,this.notificationService=a.notificationService,this.holidayService=a.holidayService,this.logger=console,this.userInfo=null,this.loginToken=null,this.userGrbh=null}async initialize(a){try{const b=a||this.configManager.get("USERNAME"),c=await this.getTokenByname(b);if(!c?.data)return!1;const d=c.data.find(a=>"app_02"===a.blqd);if(!d)return this.logger.error("\u627E\u4E0D\u5230app\u7528\u6237"),!1;this.loginToken=d.loginToken,global.loginToken=this.loginToken,this.userGrbh=d.grbh,console.log(`获取到用户 ${b} 的个人编号: ${this.userGrbh}`);const e=await this.getJbxxByToken();return this.userInfo=e,e}catch(a){return this.logger.error("\u521D\u59CB\u5316\u5931\u8D25",a),!1}}async getTokenByname(a){return await this.apiService.request("/PT/business/token/userLoginInfo",{page:1,size:10,username:a,zxbm:this.configManager.get("KAOQIN.organizationNumber")})}async getJbxxByToken(){return await this.apiService.request("/PT/business/token/getUserInfoViaToken",null,{method:"GET",params:{token:this.loginToken},headers:{"Content-Type":"application/json"}})}async queryKaoqinRecords(a){const b=dayjs(a).format("YYYY/MM/DD");if(!this.userGrbh)throw new Error("\u65E0\u6CD5\u83B7\u53D6\u7528\u6237\u4E2A\u4EBA\u7F16\u53F7(grbh)\uFF0C\u8BF7\u5148\u8C03\u7528initialize\u65B9\u6CD5");try{const a=await this.apiService.request("/V2/GLDX/business/common/allManageObjectInstance$m=query.service",{organizationNumber:this.configManager.get("KAOQIN.organizationNumber"),page:1,size:20,queryContent:"{\"dx_29_id\":\"dx_29_id\",\"dx_29_dxlx\":\"dx_29_dxlx\",\"dx_29_dxzt\":\"dx_29_dxzt\",\"dx_29_dkrq\":\"dx_29_dkrq\",\"dx_29_ywlsh\":\"dx_29_ywlsh\",\"dx_29_dksj\":\"dx_29_dksj\",\"dx_29_dkwz\":\"dx_29_dkwz\"}",queryCriteria:`{\"syObjectNumber\":\"29\",\"organizationNumber\":\"${this.configManager.get("KAOQIN.organizationNumber")}\",\"dx_03_dxbh\":\"${this.userGrbh}\"}`,sortCriteria:"{\"dx_29_dksj\":\"asc\",\"dx_29_dkrq\":\"desc\"}",associated:"{\"dx_29_dxlx\":\"dx_29_dxlxmc\",\"dx_29_dxzt\":\"dx_29_dxztmc\"}",noteSql:` and dx_29_dkrq between to_date('${b}', 'yyyy/mm/dd') and to_date('${b}', 'yyyy/mm/dd') and dx_29_dxlx <> '15' `},{headers:{channel:"app_02",zzbs:this.configManager.get("KAOQIN.organizationNumber")}});return a}catch(a){throw this.logger.error("\u67E5\u8BE2\u6253\u5361\u8BB0\u5F55\u5931\u8D25",a),a}}async processKaoqinRecords(a){try{const b=a?dayjs(a).format("YYYY-MM-DD"):TimeUtils.getTodayString(),c=a?TimeUtils.getDateFullString(a):TimeUtils.getTodayFullString();console.log(`处理 ${c} 的打卡记录...`);const d=this.stateManager.get("hasSentMorningSuccess"),e=this.stateManager.get("hasSentEveningSuccess");console.log(`当前通知状态标识: 上班提醒[${d?"\u5DF2\u53D1\u9001":"\u672A\u53D1\u9001"}], 下班提醒[${e?"\u5DF2\u53D1\u9001":"\u672A\u53D1\u9001"}]`);const f=this.stateManager.get("lastDate");f!==b&&(console.log(`状态日期(${f})与目标日期(${b})不一致,重置通知状态`),this.stateManager.resetState(),a&&this.stateManager.set("lastDate",b,!1));const g=await this.queryKaoqinRecords(b);if(!g||!g.results)return console.error("API\u8FD4\u56DE\u6570\u636E\u5F02\u5E38"),void(await this.notificationService.sendErrorNotification("\u6253\u5361\u8BB0\u5F55\u67E5\u8BE2\u5F02\u5E38",`${c}:未查询到打卡记录数据,可能是接口异常`));const h=g.results;console.log(`查询到${h.length}条打卡记录`);let i=h.find(a=>"01"===a.dx_29_dxlx||a.dx_29_dxlxmc?.includes("\u4E0A\u73ED")),j=h.find(a=>"02"===a.dx_29_dxlx||a.dx_29_dxlxmc?.includes("\u4E0B\u73ED")),k="",l=!1;if(!i&&!j)k="\u76EE\u524D\u5C1A\u65E0\u6253\u5361\u8BB0\u5F55\uFF0C\u8BF7\u6CE8\u610F\u53CA\u65F6\u6253\u5361\uFF01",TimeUtils.shouldSendReminder(this.configManager.get("REMINDER"),"morning")?(l=!0,console.log("\u5728\u4E0A\u73ED\u65F6\u95F4\u8303\u56F4\u5185\uFF0C\u53D1\u9001\u672A\u6253\u5361\u63D0\u9192")):console.log("\u4E0D\u5728\u4E0A\u73ED\u63D0\u9192\u65F6\u95F4\u8303\u56F4\u5185\uFF0C\u4E0D\u53D1\u9001\u672A\u6253\u5361\u63D0\u9192");else if(!(i&&!j))i&&j?this.stateManager.get("hasSentEveningSuccess")?console.log("\u4E0B\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5\u5DF2\u53D1\u9001\u8FC7\uFF0C\u4E0D\u91CD\u590D\u53D1\u9001"):(k="\u4E0B\u73ED\u6253\u5361\u6210\u529F\uFF0C\u4ECA\u65E5\u6253\u5361\u5DF2\u5B8C\u6210\uFF0C\u8F9B\u82E6\u4E86\uFF01",l=!0,console.log("\u8BBE\u7F6E\u4E0B\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5\u6807\u8BC6\u4E3A[\u5DF2\u53D1\u9001]"),this.stateManager.set("hasSentEveningSuccess",!0),console.log("\u53D1\u9001\u4E0B\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5")):!i&&j&&(k="\u6253\u5361\u8BB0\u5F55\u5F02\u5E38\uFF1A\u6709\u4E0B\u73ED\u5361\u4F46\u65E0\u4E0A\u73ED\u5361\uFF0C\u8BF7\u68C0\u67E5\uFF01",l=!0,console.log("\u53D1\u73B0\u5F02\u5E38\u6253\u5361\u8BB0\u5F55\uFF0C\u53D1\u9001\u5F02\u5E38\u63D0\u9192"));else if(!!this.stateManager.get("hasSentMorningSuccess"))console.log("\u4E0A\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5\u5DF2\u53D1\u9001\u8FC7\uFF0C\u4E0D\u91CD\u590D\u53D1\u9001"),TimeUtils.shouldSendReminder(this.configManager.get("REMINDER"),"evening")?(k="\u63A5\u8FD1\u4E0B\u73ED\u65F6\u95F4\uFF0C\u8BF7\u8BB0\u5F97\u4E0B\u73ED\u6253\u5361\uFF01",l=!0,console.log("\u53D1\u9001\u4E0B\u73ED\u6253\u5361\u63D0\u9192")):console.log("\u4E0D\u5728\u4E0B\u73ED\u63D0\u9192\u65F6\u95F4\u8303\u56F4\u5185\uFF0C\u4E0D\u53D1\u9001\u4E0B\u73ED\u6253\u5361\u63D0\u9192");else if(TimeUtils.shouldSendReminder(this.configManager.get("REMINDER"),"morning"))k="\u4E0A\u73ED\u6253\u5361\u6210\u529F\uFF0C\u795D\u60A8\u5DE5\u4F5C\u6109\u5FEB\uFF01",l=!0,console.log("\u8BBE\u7F6E\u4E0A\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5\u6807\u8BC6\u4E3A[\u5DF2\u53D1\u9001]"),this.stateManager.set("hasSentMorningSuccess",!0),console.log("\u53D1\u9001\u4E0A\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5");else{console.log("\u4E0D\u5728\u4E0A\u73ED\u63D0\u9192\u65F6\u95F4\u8303\u56F4\u5185\uFF0C\u4E0D\u53D1\u9001\u4E0A\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5");const a=new Date,b=a.getHours(),c=a.getMinutes(),d=this.configManager.get("REMINDER.morningEnd"),e=60*d.hour+d.minute;60*b+c>e&&(console.log("\u5F53\u524D\u65F6\u95F4\u5DF2\u8D85\u8FC7\u4E0A\u73ED\u6253\u5361\u63D0\u9192\u65F6\u95F4\u6BB5\uFF0C\u81EA\u52A8\u8BBE\u7F6E\u4E0A\u73ED\u6253\u5361\u6210\u529F\u901A\u77E5\u6807\u8BC6\u4E3A[\u5DF2\u53D1\u9001]"),this.stateManager.set("hasSentMorningSuccess",!0),TimeUtils.shouldSendReminder(this.configManager.get("REMINDER"),"evening")?(k="\u63A5\u8FD1\u4E0B\u73ED\u65F6\u95F4\uFF0C\u8BF7\u8BB0\u5F97\u4E0B\u73ED\u6253\u5361\uFF01",l=!0,console.log("\u53D1\u9001\u4E0B\u73ED\u6253\u5361\u63D0\u9192")):console.log("\u4E0D\u5728\u4E0B\u73ED\u63D0\u9192\u65F6\u95F4\u8303\u56F4\u5185\uFF0C\u4E0D\u53D1\u9001\u4E0B\u73ED\u6253\u5361\u63D0\u9192"))}const m=this.configManager.get("REMINDER.forceSend");if(l||m){k||(i&&j?k=`${c} 打卡已完成,辛苦了!`:i&&!j?k=`${c} 已上班打卡,未下班打卡。`:i||j?k=`${c} 打卡状态检查。`:k=`${c} 暂无打卡记录。`);const a=i?`${TimeUtils.formatTimestamp(i.dx_29_dksj)} (${i.dx_29_dxztmc||"\u6B63\u5E38"})`:"\u5C1A\u672A\u6253\u5361",b=j?`${TimeUtils.formatTimestamp(j.dx_29_dksj)} (${j.dx_29_dxztmc||"\u6B63\u5E38"})`:"\u5C1A\u672A\u6253\u5361";await this.notificationService.sendKaoqinNotification(c,m&&!l?k+" (\u5F3A\u5236\u53D1\u9001\u6A21\u5F0F)":k,a,b),2<h.length&&(await this.notificationService.sendDetailedRecords(c,h))}else if(this.configManager.get("NTFY.forceSend")){console.log("Ntfy\u5F3A\u5236\u53D1\u9001\u6A21\u5F0F\u5DF2\u542F\u7528\uFF0C\u5C06\u5FFD\u7565\u65F6\u95F4\u9650\u5236\u53D1\u9001\u901A\u77E5");const a=i?`${TimeUtils.formatTimestamp(i.dx_29_dksj)} (${i.dx_29_dxztmc||"\u6B63\u5E38"})`:"\u5C1A\u672A\u6253\u5361",b=j?`${TimeUtils.formatTimestamp(j.dx_29_dksj)} (${j.dx_29_dxztmc||"\u6B63\u5E38"})`:"\u5C1A\u672A\u6253\u5361";k||(i&&j?k=`${c} 打卡已完成,辛苦了!`:i&&!j?k=`${c} 已上班打卡,未下班打卡。`:i||j?k=`${c} 打卡状态检查。`:k=`${c} 暂无打卡记录。`),await this.notificationService.sendKaoqinNotification(c,k+" (\u5F3A\u5236\u53D1\u9001\u6A21\u5F0F)",a,b),0<h.length&&(await this.notificationService.sendDetailedRecords(c,h))}this.stateManager.saveState()}catch(a){this.logger.error("\u5904\u7406\u6253\u5361\u8BB0\u5F55\u5931\u8D25",a),await this.notificationService.sendErrorNotification("\u6253\u5361\u8BB0\u5F55\u67E5\u8BE2\u5F02\u5E38",`查询打卡记录时发生错误:${a.message}`)}}async testNtfyNotification(){try{if(console.log("\u5F00\u59CB\u6D4B\u8BD5ntfy\u901A\u77E5\u529F\u80FD..."),!this.configManager.get("NTFY.enabled")&&!this.configManager.get("NTFY.forceSend"))return console.log("Ntfy\u901A\u77E5\u672A\u542F\u7528\uFF0C\u8BF7\u68C0\u67E5\u914D\u7F6E"),!1;console.log("\u6D4B\u8BD5\u53D1\u9001\u57FA\u672C\u901A\u77E5..."),await this.notificationService.sendNotification("\u6D4B\u8BD5\u901A\u77E5","\u8FD9\u662F\u4E00\u6761\u6D4B\u8BD5\u6D88\u606F\u3002\n\u53D1\u9001\u65F6\u95F4: "+dayjs().format("YYYY-MM-DD HH:mm:ss"),{tags:["test","plain"],priority:"3"}),console.log("\u6D4B\u8BD5\u53D1\u9001\u5DF2\u5B8C\u6210\u6253\u5361\u63D0\u9192\u901A\u77E5..."),await this.notificationService.sendKaoqinNotification(TimeUtils.getTodayFullString(),"\u4ECA\u65E5\u6253\u5361\u5DF2\u5B8C\u6210\uFF0C\u8F9B\u82E6\u4E86\uFF01","09:XX:23 (\u6B63\u5E38)","18:XX:07 (\u6B63\u5E38)"),console.log("\u6D4B\u8BD5\u53D1\u9001\u672A\u6253\u5361\u63D0\u9192\u901A\u77E5..."),await this.notificationService.sendKaoqinNotification(TimeUtils.getTodayFullString(),"\u5C1A\u672A\u4E0A\u73ED\u6253\u5361\uFF0C\u8BF7\u6CE8\u610F\u53CA\u65F6\u6253\u5361\uFF01","\u5C1A\u672A\u6253\u5361","\u5C1A\u672A\u6253\u5361"),console.log("\u6D4B\u8BD5\u53D1\u9001\u8BE6\u7EC6\u6253\u5361\u8BB0\u5F55...");const a=[{dx_29_dxlxmc:"\u4E0A\u73ED\u6253\u5361",dx_29_dksj:Date.now()-28800000,dx_29_dxztmc:"\u6B63\u5E38",dx_29_dkwz:"\u6B66\u6C49\u5E02\u6D2A\u5C71\u533A\u5149\u8C37\u8F6F\u4EF6\u56ED"},{dx_29_dxlxmc:"\u4E0B\u73ED\u6253\u5361",dx_29_dksj:Date.now()-3600000,dx_29_dxztmc:"\u6B63\u5E38",dx_29_dkwz:"\u6B66\u6C49\u5E02\u6D2A\u5C71\u533A\u5149\u8C37\u8F6F\u4EF6\u56ED"}];return await this.notificationService.sendDetailedRecords(TimeUtils.getTodayFullString(),a),console.log("\u6D4B\u8BD5\u53D1\u9001\u9519\u8BEF\u901A\u77E5..."),await this.notificationService.sendErrorNotification("\u8003\u52E4\u7CFB\u7EDF\u5F02\u5E38","\u65E0\u6CD5\u8FDE\u63A5\u5230\u8003\u52E4\u670D\u52A1\u5668\uFF0C\u8BF7\u68C0\u67E5\u7F51\u7EDC\u8FDE\u63A5\u6216\u8054\u7CFB\u7BA1\u7406\u5458\u3002"),console.log("ntfy\u901A\u77E5\u6D4B\u8BD5\u5B8C\u6210"),!0}catch(a){return console.error("ntfy\u901A\u77E5\u6D4B\u8BD5\u5931\u8D25:",a),!1}}resetNotificationStatus(){try{return this.stateManager.set("hasSentMorningSuccess",!1),this.stateManager.set("hasSentEveningSuccess",!1),this.stateManager.saveState(),console.log("\u901A\u77E5\u72B6\u6001\u5DF2\u91CD\u7F6E:",{hasSentMorningSuccess:this.stateManager.get("hasSentMorningSuccess"),hasSentEveningSuccess:this.stateManager.get("hasSentEveningSuccess")}),!0}catch(a){return console.error("\u91CD\u7F6E\u901A\u77E5\u72B6\u6001\u5931\u8D25:",a),!1}}async testSpecificDate(a){try{console.log(`开始测试指定日期 ${a} 的处理流程...`);const b=await this.holidayService.isWorkday(a);if(console.log(`${a} 节假日详细信息:`,b),!b.isWorkday){b.holidayName?console.log(`${a} 是 ${b.holidayName}${b.isWeekend?"(\u5468\u672B)":""}`):console.log(`${a} 是休息日`),console.log("\u6D4B\u8BD5\u751F\u6210\u8282\u65E5\u95EE\u5019...");const c=process.argv.includes("--send-notification");if(c)console.log(`将发送通知...`),await this.holidayService.sendHolidayGreeting(a,this.notificationService),console.log(`消息发送完成,时间: ${dayjs().format("YYYY-MM-DD HH:mm:ss")}`);else{console.log("\u672A\u542F\u7528\u5B9E\u9645\u901A\u77E5\u53D1\u9001\uFF0C\u5982\u9700\u53D1\u9001\u8BF7\u6DFB\u52A0 --send-notification \u53C2\u6570");const c=b.holidayName||"\u5047\u65E5",d=this.holidayService.generateGreeting(a,c);console.log(`生成的问候语为: ${d}`)}}else console.log(`${a} 是工作日${b.isInLieu?"(\u8865\u73ED\u65E5)":""},将执行正常打卡检查流程`),this.userGrbh||(await this.initialize()),process.argv.includes("--query-records")||process.argv.includes("--send-notification")?await this.processKaoqinRecords(a):console.log("\u672A\u542F\u7528\u67E5\u8BE2\u548C\u901A\u77E5\uFF0C\u5982\u9700\u67E5\u8BE2\u8BB0\u5F55\u8BF7\u6DFB\u52A0 --query-records \u53C2\u6570\uFF0C\u5982\u9700\u53D1\u9001\u901A\u77E5\u8BF7\u6DFB\u52A0 --send-notification \u53C2\u6570");return console.log("\u6307\u5B9A\u65E5\u671F\u6D4B\u8BD5\u5B8C\u6210"),!0}catch(a){return console.error("\u6307\u5B9A\u65E5\u671F\u6D4B\u8BD5\u5931\u8D25:",a),!1}}}module.exports=KaoqinService;