springboot集成钉钉,发送钉钉日报

目录

1.说明

2.示例

3.总结


1.说明

学习地图 - 钉钉开放平台

在钉钉开放文档中可以查看有关日志相关的api,主要用到以下几个api:

        ①获取模板详情

        ②获取用户发送日志的概要信息

        ③获取日志接收人员列表

        ④创建日志

发送日志时需要根据模板规定日志的格式,所以先获取要发送日志的模板信息,然后获取用户在最近一段时间内发送的日志的概要信息,并根据最新一次的日志信息获取日志的接收人员信息,然后调用创建日志的api,设置日志内容,及接收人员。

2.示例

依赖

        <dependency><groupId>com.aliyun</groupId><artifactId>alibaba-dingtalk-service-sdk</artifactId><version>2.0.0</version></dependency>

钉钉工具类

package com.kingagroot.info.common.tools.common;import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.kingagroot.info.common.contants.CommonContants;
import com.kingagroot.info.common.tools.thirdparty.DingDingTool;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.*;/*** @Author linaibo* @Date 2024/1/6 16:18* @Version 1.0*/
@Component
public class DingTool {private static LogTool logTool;@Autowiredpublic void setLogTool(LogTool logTool) {DingTool.logTool = logTool;}// 权限用户名private static String accessKey;// 权限密码private static String secret;// agent_idprivate static Long agentId;// tokenUrlprivate static String tokenUrl;// 发送消息urlprivate static String sendMsgUrl;// 系统urlprivate static String sysUrl;// 模板名称private static String dingTemplateName;// 模板urlprivate static String dingTemplateUrl;// 创建日报urlprivate static String dingCreateUrl;// 日志信息urlprivate static String simpleListUrl;// 接收人信息urlprivate static String receiverUrl;@NacosValue(value = "${dingding.appkey}", autoRefreshed = true)public void setAccessKey(String accessKey) {DingTool.accessKey = accessKey;}@NacosValue(value = "${dingding.appsecret}", autoRefreshed = true)public void setSecret(String secret) {DingTool.secret = secret;}@NacosValue(value = "${dingding.agentId}", autoRefreshed = true)public void setAgentId(Long agentId) {DingTool.agentId = agentId;}@NacosValue(value = "${dingding.gettoken}", autoRefreshed = true)public void setTokenUrl(String tokenUrl) {DingTool.tokenUrl = tokenUrl;}@NacosValue(value = "${dingding.sendMsg}", autoRefreshed = true)public void setSendMsgUrl(String sendMsgUrl) {DingTool.sendMsgUrl = sendMsgUrl;}@NacosValue(value = "${sys.url}", autoRefreshed = true)public void setSysUrl(String sysUrl) {DingTool.sysUrl = sysUrl;}@NacosValue(value = "${dingding.templateName}", autoRefreshed = true)public void setDingTemplateName(String dingTemplateName) {DingTool.dingTemplateName = dingTemplateName;}@NacosValue(value = "${dingding.templateUrl}", autoRefreshed = true)public void setDingTemplateUrl(String dingTemplateUrl) {DingTool.dingTemplateUrl = dingTemplateUrl;}@NacosValue(value = "${dingding.createUrl}", autoRefreshed = true)public void setDingCreateUrl(String dingCreateUrl) {DingTool.dingCreateUrl = dingCreateUrl;}@NacosValue(value = "${dingding.simpleListUrl}", autoRefreshed = true)public void setSimpleListUrl(String simpleListUrl) {DingTool.simpleListUrl = simpleListUrl;}@NacosValue(value = "${dingding.receiverUrl}", autoRefreshed = true)public void setReceiverUrl(String receiverUrl) {DingTool.receiverUrl = receiverUrl;}/*** 获取钉钉token** @return*/public static String getDingToken() {DingTalkClient client = new DefaultDingTalkClient(tokenUrl);OapiGettokenRequest request = new OapiGettokenRequest();request.setAppkey(accessKey);request.setAppsecret(secret);request.setHttpMethod("GET");try {OapiGettokenResponse response = client.execute(request);if (response.isSuccess()) {// 调用成功返回token信息return response.getAccessToken();}// 调用接口异常,输出异常信息,发送钉钉通知processErrMsg("getDingToken", "获取钉钉token失败", JSON.toJSONString(response));} catch (Exception e) {// 调用接口异常,输出异常信息processErrMsg("getDingToken", "获取钉钉token失败", JSON.toJSONString(e));}return null;}public static void processErrMsg(String method, String errorMsg, String responseMsg, String... dingId) {StringBuilder errMsg = new StringBuilder();errMsg.append(errorMsg).append(",响应信息:").append(JSON.toJSONString(responseMsg));if (dingId.length != CommonContants.NUM_0) {errMsg.append(",钉钉id:").append(dingId[0]);}logTool.saveExceptionLog("", "DingTool", method, errMsg.toString());DingDingTool.sendDingMsg(errMsg.toString());}/*** 发送钉钉通知** @param token* @param pwd* @param userCode*/public static boolean sendMsg(String token, String pwd, String userCode) {DingTalkClient client = new DefaultDingTalkClient(sendMsgUrl);OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();request.setAgentId(agentId);request.setUseridList(userCode);request.setToAllUser(false);OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();msg.setMsgtype("text");msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());StringBuilder content = new StringBuilder();content.append("系统地址: ");content.append(sysUrl);content.append("  ");content.append("密码: ");content.append(pwd);msg.getText().setContent(content.toString());request.setMsg(msg);try {OapiMessageCorpconversationAsyncsendV2Response result = client.execute(request, token);if (result.isSuccess()) {return true;}// 调用接口异常,输出异常信息processErrMsg("sendMsg", "发送钉钉消息(密码)失败", JSON.toJSONString(result));} catch (Exception e) {// 调用接口异常,输出异常信息processErrMsg("sendMsg", "发送钉钉消息(密码)失败", JSON.toJSONString(e));}return false;}/*** 发送钉钉通知** @param token* @param message* @param dingId*/public static void sendMessage(String token, String message, String dingId) {DingTalkClient client = new DefaultDingTalkClient(sendMsgUrl);OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();request.setAgentId(agentId);// 设置接收者列表request.setUseridList(dingId);// 是否发送给公司全员request.setToAllUser(false);// 设置发送的消息类型及消息内容OapiMessageCorpconversationAsyncsendV2Request.Msg msg = new OapiMessageCorpconversationAsyncsendV2Request.Msg();msg.setMsgtype(CommonContants.TEXT);msg.setText(new OapiMessageCorpconversationAsyncsendV2Request.Text());msg.getText().setContent(message);request.setMsg(msg);try {OapiMessageCorpconversationAsyncsendV2Response result = client.execute(request, token);if (result.isSuccess()) {return;}// 调用接口异常,输出异常信息processErrMsg("sendMessage", "发送钉钉消息失败", JSON.toJSONString(result));} catch (Exception e) {// 调用接口异常,输出异常信息processErrMsg("sendMessage", "发送钉钉消息失败", JSON.toJSONString(e));}}/*** 查询钉钉模板信息** @param token* @param dingId*/public static OapiReportTemplateGetbynameResponse.ReportTemplateResponseVo getTemplate(String token, String dingId) {DingTalkClient client = new DefaultDingTalkClient(dingTemplateUrl);OapiReportTemplateGetbynameRequest req = new OapiReportTemplateGetbynameRequest();req.setUserid(dingId);req.setTemplateName(dingTemplateName);try {OapiReportTemplateGetbynameResponse rsp = client.execute(req, token);if (rsp.isSuccess()) {// 日志内容的校验if (CollUtil.isEmpty(rsp.getResult().getFields()) ||!Objects.equals(rsp.getResult().getFields().get(0).getType(), CommonContants.LONG_1)) {processErrMsg("getTemplate", "模板内容已经修改", JSON.toJSONString(rsp.getResult()), dingId);sendMessage(token, "模板内容已经修改,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);return null;}return rsp.getResult();}// 调用接口异常,输出异常信息,发送钉钉通知processErrMsg("getTemplate", "获取作物育种信息模板失败", JSON.toJSONString(rsp), dingId);sendMessage(token, "获取作物育种信息模板失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);} catch (Exception e) {// 调用接口异常,输出异常信息,发送钉钉通知processErrMsg("getTemplate", "获取作物育种信息模板失败", JSON.toJSONString(e), dingId);sendMessage(token, "获取作物育种信息模板失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);}return null;}/*** 获取用户在某个时间段的日志信息** @param dingId* @param token* @return*/public static OapiReportSimplelistResponse.ReportOapiVo getSimpleReport(String token, String dingId) {DingTalkClient client = new DefaultDingTalkClient(simpleListUrl);OapiReportSimplelistRequest req = new OapiReportSimplelistRequest();long endTime = System.currentTimeMillis();long startTime = Instant.now().minus(CommonContants.LONG_21, ChronoUnit.DAYS).toEpochMilli();req.setStartTime(startTime);req.setEndTime(endTime);req.setTemplateName(dingTemplateName);req.setUserid(dingId);req.setCursor(CommonContants.LONG_0);req.setSize(CommonContants.LONG_20);try {OapiReportSimplelistResponse rsp = client.execute(req, token);if (rsp.isSuccess()) {List<OapiReportSimplelistResponse.ReportOapiVo> dataList = rsp.getResult().getDataList();if (CollUtil.isEmpty(dataList)) {DingDingTool.sendDingMsg("获取最近的日志信息为空,钉钉id:" + dingId);sendMessage(token, "获取最近的日志信息为空,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);return null;} else {// 获取最新一次的日报信息Optional<OapiReportSimplelistResponse.ReportOapiVo> lastReport = dataList.stream().max(Comparator.comparingLong(OapiReportSimplelistResponse.ReportOapiVo::getCreateTime));return lastReport.get();}}processErrMsg("getSimpleReport", "获取最近的日志信息失败", JSON.toJSONString(rsp), dingId);sendMessage(token, "获取最近的日志信息失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);} catch (Exception e) {processErrMsg("getSimpleReport", "获取最近的日志信息失败", JSON.toJSONString(e), dingId);sendMessage(token, "获取最近的日志信息失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), dingId);}return null;}public static List<String> getReceiver(OapiReportSimplelistResponse.ReportOapiVo report, String token) {DingTalkClient client = new DefaultDingTalkClient(receiverUrl);OapiReportReceiverListRequest req = new OapiReportReceiverListRequest();req.setReportId(report.getReportId());try {OapiReportReceiverListResponse rsp = client.execute(req, token);if (rsp.isSuccess()) {List<String> useridList = rsp.getResult().getUseridList();if (CollUtil.isEmpty(useridList)) {DingDingTool.sendDingMsg("查询的日志接收人信息为空,请求信息:" + JSON.toJSONString(report));sendMessage(token, "查询的日志接收人信息为空,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), report.getCreatorId());return null;}return useridList;}processErrMsg("getReceiver", "查询日志的接收人信息失败", JSON.toJSONString(rsp), report.getCreatorId());sendMessage(token, "查询日志的接收人信息失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), report.getCreatorId());} catch (Exception e) {processErrMsg("getReceiver", "查询日志的接收人信息失败", JSON.toJSONString(e), report.getCreatorId());sendMessage(token, "查询日志的接收人信息失败,系统无法进行日志推送,请自行发送。" + DateUtil.formatDateTime(new Date()), report.getCreatorId());}return null;}/*** 发送钉钉日报** @param createDataParam* @param token*/public static void createReport(OapiReportCreateRequest.OapiCreateReportParam createDataParam, String token) {DingTalkClient client = new DefaultDingTalkClient(dingCreateUrl);OapiReportCreateRequest req = new OapiReportCreateRequest();req.setCreateReportParam(createDataParam);try {OapiReportCreateResponse rsp = client.execute(req, token);if (!rsp.isSuccess()) {// 调用接口异常,输出异常信息processErrMsg("createReport", "发送日报失败", JSON.toJSONString(rsp), JSON.toJSONString(createDataParam));sendMessage(token, "系统发送日志失败,请自行发送。" + DateUtil.formatDateTime(new Date()), createDataParam.getUserid());}} catch (Exception e) {// 调用接口异常,输出异常信息processErrMsg("createReport", "发送日报失败", JSON.toJSONString(e), JSON.toJSONString(createDataParam));sendMessage(token, "系统发送日志失败,请自行发送。" + DateUtil.formatDateTime(new Date()), createDataParam.getUserid());}}
}

发送钉钉日报

    /*** 发送钉钉日报** @param farmWorkMap*/private void processDingTalkReports(Map<String, List<FarmInfoDto>> farmWorkMap) {// 钉钉id为空的用户列表,此类用户没有加入钉钉组织StringBuilder errUserId = new StringBuilder();// 循环农事信息列表,进行如下处理for (Map.Entry<String, List<FarmInfoDto>> farm : farmWorkMap.entrySet()) {// 用户及钉钉idString userId = farm.getKey();String dingId = farm.getValue().get(0).getDingId();// 钉钉id为空时,无法进行发送处理if (StrUtil.isBlank(dingId)) {errUserId.append(userId).append(",");continue;}// 获取钉钉的token信息String dingToken = getDingToken();if (StrUtil.isBlank(dingToken)) {continue;}// 获取模板信息OapiReportTemplateGetbynameResponse.ReportTemplateResponseVo template =DingTool.getTemplate(dingToken, dingId);if (ObjectUtil.isNull(template)) {continue;}// 获取接收人信息OapiReportSimplelistResponse.ReportOapiVo simpleReport = DingTool.getSimpleReport(dingToken, dingId);List<String> receiver = new ArrayList<>();if (ObjectUtil.isNotNull(simpleReport)) {receiver = DingTool.getReceiver(simpleReport, dingToken);}if (CollUtil.isNotEmpty(receiver)) {// 构建发送日报的请求信息OapiReportCreateRequest.OapiCreateReportParam createDataParam = getCreateDataParam(template, farm, receiver);// 发送钉钉日报DingTool.createReport(createDataParam, dingToken);}}// 如果有问题的用户列表不为空,则将有问题的用户列表推送至钉钉群中if (StrUtil.isNotEmpty(errUserId)) {DingDingTool.sendDingMsg("以下用户不存在钉钉id,用户:" + errUserId);}}
    // 获取钉钉tokenpublic String getDingToken() {String dingDingToken = RedisTool.getString(redisEntr.getJedis(), CommonContants.DINGDING_TOKEN);if (StrUtil.isEmpty(dingDingToken)) {// 获取tokendingDingToken = DingTool.getDingToken();// 存储tokenRedisTool.setString(redisEntr.getJedis(), CommonContants.DINGDING_TOKEN, dingDingToken, 5400);}return dingDingToken;}
 /*** 获取创建日报的请求信息** @param template* @param farmMap*/public OapiReportCreateRequest.OapiCreateReportParam getCreateDataParam(OapiReportTemplateGetbynameResponse.ReportTemplateResponseVo template,Map.Entry<String, List<FarmInfoDto>> farmMap,List<String> receivers) {// 获取模板内容信息List<OapiReportTemplateGetbynameResponse.Fields> fields = template.getFields();// 构建创建日报请求结构OapiReportCreateRequest.OapiCreateReportParam createReportParam = new OapiReportCreateRequest.OapiCreateReportParam();List<OapiReportCreateRequest.OapiReportContentVo> list = new ArrayList<>();OapiReportCreateRequest.OapiReportContentVo obj = new OapiReportCreateRequest.OapiReportContentVo();list.add(obj);// 添加日报内容,只添加模板的第一项OapiReportTemplateGetbynameResponse.Fields field = fields.get(0);obj.setSort(field.getSort());obj.setType(field.getType());obj.setContentType(CommonContants.MARKDOWN);StringBuilder farmInfo = new StringBuilder();for (int i = 0; i < farmMap.getValue().size(); i++) {FarmInfoDto farm = farmMap.getValue().get(i);farmInfo.append(i + 1).append(". ").append(farm.getBsName()).append(" ").append(farm.getFarmName()).append(" ");if (farm.getWorkCount().compareTo(BigDecimal.ZERO) > CommonContants.NUM_0) {farmInfo.append(farm.getWorkCount().stripTrailingZeros().toPlainString()).append(farm.getWorkValue()).append(" ");}if (StrUtil.isNotBlank(farm.getParticipants())) {farmInfo.append("参与人:").append(farm.getParticipants());}farmInfo.append("\n");}obj.setContent(farmInfo.toString());obj.setKey(field.getFieldName());createReportParam.setContents(list);// 设置汇报人信息createReportParam.setToUserids(receivers);// 设置模板idcreateReportParam.setTemplateId(template.getId());// 是否发送单聊消息createReportParam.setToChat(false);// 日志来源createReportParam.setDdFrom(CommonContants.TJNS);// 创建日志的用户idcreateReportParam.setUserid(template.getUserid());return createReportParam;}

3.总结

①我使用的是企业内部创建应用的方式,创建应用后可以拿到应用的凭证信息。

②要调用日志相关的接口,需要开通日志接口的权限信息,如下:

③测试时,可以创建一个企业账号,然后创建应用,并开通日志相关接口的权限,拉入相关人员,设置日志模板,并设置人员的上下级关系进行测试。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python算法和数据结构刷题[1]:数组、矩阵、字符串

一画图二伪代码三写代码 LeetCode必刷100题&#xff1a;一份来自面试官的算法地图&#xff08;题解持续更新中&#xff09;-CSDN博客 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 面试经典 150 题 - 学习计…

院校联合以项目驱动联合培养医工计算机AI人才路径探析

一、引言 1.1 研究背景与意义 在科技飞速发展的当下&#xff0c;医疗人工智能作为一个极具潜力的新兴领域&#xff0c;正深刻地改变着传统医疗模式。从疾病的早期诊断、个性化治疗方案的制定&#xff0c;到药物研发的加速&#xff0c;人工智能技术的应用极大地提升了医疗服务…

【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】2.18 对象数组:在NumPy中存储Python对象

2.18 对象数组&#xff1a;在NumPy中存储Python对象 目录 #mermaid-svg-shERrGOBuM2rBzeB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-shERrGOBuM2rBzeB .error-icon{fill:#552222;}#mermaid-svg-shERrGOBuM2rB…

响应式编程与协程

响应式编程与协程的比较 响应式编程的弊端虚拟线程Java线程内核线程的局限性传统线程池的demo虚拟线程的demo 响应式编程的弊端 前面用了几篇文章介绍了响应式编程&#xff0c;它更多的使用少量线程实现线程间解耦和异步的作用&#xff0c;如线程的Reactor模型&#xff0c;主要…

python学opencv|读取图像(五十三)原理探索:使用cv.matchTemplate()函数实现最佳图像匹配

【1】引言 前序学习进程中&#xff0c;已经探索了使用cv.matchTemplate()函数实现最佳图像匹配的技巧&#xff0c;并且成功对两个目标进行了匹配。 相关文章链接为&#xff1a;python学opencv|读取图像&#xff08;五十二&#xff09;使用cv.matchTemplate()函数实现最佳图像…

javaEE-8.JVM(八股文系列)

目录 一.简介 二.JVM中的内存划分 JVM的内存划分图: 堆区:​编辑 栈区:​编辑 程序计数器&#xff1a;​编辑 元数据区&#xff1a;​编辑 经典笔试题&#xff1a; 三,JVM的类加载机制 1.加载: 2.验证: 3.准备: 4.解析: 5.初始化: 双亲委派模型 概念: JVM的类加…

【01】共识机制

BTF共识 拜占庭将军问题 拜占庭将军问题是一个共识问题 起源 Leslie Lamport在论文《The Byzantine Generals Problem》提出拜占庭将军问题。 核心描述 军中可能有叛徒&#xff0c;却要保证进攻一致&#xff0c;由此引申到计算领域&#xff0c;发展成了一种容错理论。随着…

AI大模型开发原理篇-1:语言模型雏形之N-Gram模型

N-Gram模型概念 N-Gram模型是一种基于统计的语言模型&#xff0c;用于预测文本中某个词语的出现概率。它通过分析一个词语序列中前面N-1个词的出现频率来预测下一个词的出现。具体来说&#xff0c;N-Gram模型通过将文本切分为长度为N的词序列来进行建模。 注意&#xff1a;这…

【汽车电子软件架构】AutoSAR从放弃到入门专栏导读

本文是汽车电子软件架构&#xff1a;AutoSAR从放弃到入门专栏的导读篇。文章延续专栏文章的一贯作风&#xff0c;从概念与定义入手&#xff0c;希望读者能对AutoSAR架构有一个整体的认识&#xff0c;然后对专栏涉及的文章进行分类与链接。本文首先从AutoSAR汽车软件架构的概念&…

python-UnitTest框架笔记

UnitTest框架的基本使用方法 UnitTest框架介绍 框架&#xff1a;framework&#xff0c;为了解决一类事情的功能集合 UnitTest框架&#xff1a;是python自带的单元测试框架 自带的&#xff0c;可以直接使用&#xff0c;不需要格外安装 测试人员用来做自动化测试&#xff0c;作…

【数据结构】_链表经典算法OJ:复杂链表的复制

目录 1. 题目链接及描述 2. 解题思路 3. 程序 1. 题目链接及描述 题目链接&#xff1a;138. 随机链表的复制 - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &#xff0c;…

Linux——进程间通信之SystemV共享内存

前言 SystemV通信一般包括三种&#xff1a;共享内存、消息队列和信号量。共享内存区是最快的IPC形式。一旦这样的内存映射到共享它的进程的地址空间&#xff0c;这些进程间数据传递不再涉及到 内核&#xff0c;换句话说是进程不再通过执行进入内核的系统调用来…

Linux网络 | 网络层IP报文解析、认识网段划分与IP地址

前言&#xff1a;本节内容为网络层。 主要讲解IP协议报文字段以及分离有效载荷。 另外&#xff0c; 本节也会带领友友认识一下IP地址的划分。 那么现在废话不多说&#xff0c; 开始我们的学习吧&#xff01;&#xff01; ps&#xff1a;本节正式进入网络层喽&#xff0c; 友友们…

SQLGlot:用SQLGlot解析SQL

几十年来&#xff0c;结构化查询语言&#xff08;SQL&#xff09;一直是与数据库交互的实际语言。在一段时间内&#xff0c;不同的数据库在支持通用SQL语法的同时演变出了不同的SQL风格&#xff0c;也就是方言。这可能是SQL被广泛采用和流行的原因之一。 SQL解析是解构SQL查询…

Windows程序设计10:文件指针及目录的创建与删除

文章目录 前言一、文件指针是什么&#xff1f;二、设置文件指针的位置&#xff1a;随机读写&#xff0c;SetFilePointer函数1.函数说明2.函数实例 三、 目录的创建CreateDirectory四、目录的删除RemoveDirectory总结 前言 Windows程序设计10&#xff1a;文件指针及目录的创建与…

线程互斥同步

前言&#xff1a; 简单回顾一下上文所学&#xff0c;上文我们最重要核心的工作就是介绍了我们线程自己的LWP和tid究竟是个什么&#xff0c;总结一句话&#xff0c;就是tid是用户视角下所认为的概念&#xff0c;因为在Linux系统中&#xff0c;从来没有线程这一说法&#xff0c;…

DRM系列七:Drm之CREATE_DUMB

本系列文章基于linux 5.15 DRM驱动的显存由GEM&#xff08;Graphics execution management&#xff09;管理。 一、创建流程 创建buf时&#xff0c;user层提供需要buf的width,height以及bpp(bite per pixel)&#xff0c;然后调用drmIoctl(fd, DRM_IOCTL_MODE_CREATE_DUMB, &…

我们信仰AI?从神明到人工智能——信任的进化

信任的进化&#xff1a; 信任是我们最宝贵的资产。而现在&#xff0c;它正像黑色星期五促销的廉价平板电视一样&#xff0c;被一点点拆解。在过去&#xff0c;世界很简单&#xff1a;人们相信晚间新闻、那些满是灰尘书籍的教授&#xff0c;或者手持病历、眉头紧锁的医生。而如…

数据分析系列--[11] RapidMiner,K-Means聚类分析(含数据集)

一、数据集 二、导入数据 三、K-Means聚类 数据说明:提供一组数据,含体重、胆固醇、性别。 分析目标:找到这组数据中需要治疗的群体供后续使用。 一、数据集 点击下载数据集 二、导入数据 三、K-Means聚类 Ending, congratulations, youre done.

1-刷力扣问题记录

25.1.19 1.size()和.length()有什么区别 2.result.push_back({nums[i], nums[left], nums[right]});为什么用大括号&#xff1f; 使用大括号 {} 是 C11 引入的 初始化列表 语法&#xff0c;它允许我们在构造或初始化对象时直接传入一组值。大括号的使用在许多情况下都能让代码…