当前位置: 首页 > news >正文

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.总结

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

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

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

相关文章:

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

目录 1.说明 2.示例 3.总结 1.说明 学习地图 - 钉钉开放平台 在钉钉开放文档中可以查看有关日志相关的api&#xff0c;主要用到以下几个api&#xff1a; ①获取模板详情 ②获取用户发送日志的概要信息 ③获取日志接收人员列表 ④创建日志 发送日志时需要根据模板规定日志…...

【机器学习】自定义数据集 使用scikit-learn中svm的包实现svm分类

一、支持向量机(support vector machines. &#xff0c;SVM)概念 1. SVM 绪论 支持向量机&#xff08;SVM&#xff09;的核心思想是找到一个最优的超平面&#xff0c;将不同类别的数据点分开。SVM 的关键特点包括&#xff1a; ① 分类与回归&#xff1a; SVM 可以用于分类&a…...

快速提升网站收录:利用网站历史数据

本文转自&#xff1a;百万收录网 原文链接&#xff1a;https://www.baiwanshoulu.com/38.html 利用网站历史数据可以有效提升网站的收录速度&#xff0c;以下是一些具体的策略和方法&#xff1a; 一、理解网站历史数据的重要性 网站历史数据记录了网站过去的运营情况、用户行…...

【Git】初识Git Git基本操作详解

文章目录 学习目标Ⅰ. 初始 Git&#x1f4a5;注意事项 Ⅱ. Git 安装Linux-centos安装Git Ⅲ. Git基本操作一、创建git本地仓库 -- git init二、配置 Git -- git config三、认识工作区、暂存区、版本库① 工作区② 暂存区③ 版本库④ 三者的关系 四、添加、提交更改、查看提交日…...

Python NumPy(11):NumPy 排序、条件筛选函数

1 NumPy 排序、条件筛选函数 NumPy 提供了多种排序的方法。 这些排序函数实现不同的排序算法&#xff0c;每个排序算法的特征在于执行速度&#xff0c;最坏情况性能&#xff0c;所需的工作空间和算法的稳定性。 下表显示了三种排序算法的比较。 种类速度最坏情况工作空间稳定性…...

AJAX综合案例——图书管理

黑马程序员视频地址&#xff1a; AJAX-Day02-10.案例_图书管理AJAX-Day02-10.案例_图书管理_总结_V1.0是黑马程序员前端AJAX入门到实战全套教程&#xff0c;包含学前端框架必会的&#xff08;ajaxnode.jswebpackgit&#xff09;&#xff0c;一套全覆盖的第25集视频&#xff0c…...

JDK自带工具解析与生产问题定位指南(一)

1. 引言 Java开发工具包&#xff08;JDK&#xff09;内置了强大的诊断工具集&#xff0c;用于监控、分析和调试Java应用程序。这些工具涵盖了从进程管理、内存分析到性能监控的各个方面。本文将介绍一些最常用的Java开发工具&#xff0c;包括jps、jmap、jstat、jcmd、jstack、…...

FPGA 使用 CLOCK_DEDICATED_ROUTE 约束

使用 CLOCK_DEDICATED_ROUTE 约束 CLOCK_DEDICATED_ROUTE 约束通常在从一个时钟区域中的时钟缓存驱动到另一个时钟区域中的 MMCM 或 PLL 时使 用。默认情况下&#xff0c; CLOCK_DEDICATED_ROUTE 约束设置为 TRUE &#xff0c;并且缓存 /MMCM 或 PLL 对必须布局在相同…...

《解锁AI黑科技:数据分类聚类与可视化》

在当今数字化时代&#xff0c;数据如潮水般涌来&#xff0c;如何从海量数据中提取有价值的信息&#xff0c;成为了众多领域面临的关键挑战。人工智能&#xff08;AI&#xff09;技术的崛起&#xff0c;为解决这一难题提供了强大的工具。其中&#xff0c;能够实现数据分类与聚类…...

Java小白入门教程:Object

目录 一、定义 二、作用 三、使用场景 四、语法以及示例 1、创建Object类型的对象 2、使用 toString()方法 3、使用 equals()方法 4、使用 hashCode()方法 5、使用 getClass()方法 6、使用 clone()方法 7、使用 finalize()方法 一、定义 在Java中&#xff0c; object…...

记6(人工神经网络

目录 1、M-P神经元2、感知机3、Delta法则4、前馈型神经网络&#xff08;Feedforward Neural Networks&#xff09;5、鸢尾花数据集——单层前馈型神经网络&#xff1a;6、多层神经网络&#xff1a;增加隐含层7、实现异或运算&#xff08;01、10为1,00、11为0&#xff09;8、线性…...

stm32硬件实现与w25qxx通信

使用的型号为stm32f103c8t6与w25q64。 STM32CubeMX配置与引脚衔接 根据stm32f103c8t6引脚手册&#xff0c;采用B12-B15四个引脚与W25Q64连接&#xff0c;实现SPI通信。 W25Q64SCK&#xff08;CLK&#xff09;PB13MOSI&#xff08;DI&#xff09;PB15MISO(DO)PB14CS&#xff08…...

编程题-最接近的三数之和

题目&#xff1a; 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 解法一&#xff08;排序双指针&#xff09;&#xff1a; 题目要求找…...

索引的底层数据结构、B+树的结构、为什么InnoDB使用B+树而不是B树呢

索引的底层数据结构 MySQL中常用的是Hash索引和B树索引 Hash索引&#xff1a;基于哈希表实现的&#xff0c;查找速度非常快&#xff0c;但是由于哈希表的特性&#xff0c;不支持范围查找和排序&#xff0c;在MySQL中支持的哈希索引是自适应的&#xff0c;不能手动创建 B树的…...

【工欲善其事】利用 DeepSeek 实现复杂 Git 操作:从原项目剥离出子版本树并同步到新的代码库中

文章目录 利用 DeepSeek 实现复杂 Git 操作1 背景介绍2 需求描述3 思路分析4 实现过程4.1 第一次需求确认4.2 第二次需求确认4.3 第三次需求确认4.4 V3 模型&#xff1a;中间结果的处理4.5 方案验证&#xff0c;首战告捷 5 总结复盘 利用 DeepSeek 实现复杂 Git 操作 1 背景介绍…...

网络编程套接字(中)

文章目录 &#x1f34f;简单的TCP网络程序服务端创建套接字服务端绑定服务端监听服务端获取连接服务端处理请求客户端创建套接字客户端连接服务器客户端发起请求服务器测试单执行流服务器的弊端 &#x1f350;多进程版的TCP网络程序捕捉SIGCHLD信号让孙子进程提供服务 &#x1…...

前端学习-事件委托(三十)

目录 前言 课前思考 for循环注册事件 语法 事件委托 1.事件委托的好处是什么? 2.事件委托是委托给了谁&#xff0c;父元素还是子元素 3.如何找到真正触发的元素 示例代码 总结 前言 才子佳人&#xff0c;自是白衣卿相 课前思考 1.如果同时给多个元素注册事件&…...

线程池以及在QT中的接口使用

文章目录 前言线程池架构组成**一、任务队列&#xff08;Task Queue&#xff09;****二、工作线程组&#xff08;Worker Threads&#xff09;****三、管理者线程&#xff08;Manager Thread&#xff09;** 系统协作流程图解 一、QRunnable二、QThreadPool三、线程池的应用场景W…...

c语言操作符(详细讲解)

目录 前言 一、算术操作符 一元操作符&#xff1a; 二元操作符&#xff1a; 二、赋值操作符 代码例子&#xff1a; 三、比较操作符 相等与不相等比较操作符&#xff1a; 大于和小于比较操作符&#xff1a; 大于等于和小于等于比较操作符&#xff1a; 四、逻辑操作符 逻辑与&…...

【自然语言处理(NLP)】深度学习架构:Transformer 原理及代码实现

文章目录 介绍Transformer核心组件架构图编码器&#xff08;Encoder&#xff09;解码器&#xff08;Decoder&#xff09; 优点应用代码实现导包基于位置的前馈网络残差连接后进行层规范化编码器 Block编码器解码器 Block解码器训练预测 个人主页&#xff1a;道友老李 欢迎加入社…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢&#xff0c;博主的学习进度也是步入了Java Mybatis 框架&#xff0c;目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学&#xff0c;希望能对大家有所帮助&#xff0c;也特别欢迎大家指点不足之处&#xff0c;小生很乐意接受正确的建议&…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业

6月9日&#xff0c;国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解&#xff0c;“超级…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态&#xff08;编译时多态&#xff09; 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1&#xff09;.协变 2&#xff09;.析构函数的重写 5.override 和 final关键字 1&#…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机&#xff0c;因为在使用过程中发现 Airsim 对外部监控相机的描述模糊&#xff0c;而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置&#xff0c;最后在源码示例中找到了&#xff0c;所以感…...