钉钉企业微应用开发C#-HTTP回调接口
官方的STREAM回调推送的方式,试了几次都认证不过,就放弃了还是用HTTP的模式吧。
/// <summary>/// 应用回调/// </summary>/// <param name="model"></param>/// <returns></returns>public static Dictionary<string, string> CallBack(DingCallBackModel model){WriteLogHelper.WriteLogsAsync(JsonHelper.SerializeObject(model), "实例回调日志");var timeStamp = GetTimestamp(DateTime.Now).ToString();// 2. 使用加解密类型DingTalkEncryptor callbackCrypto = new DingTalkEncryptor(AppsettingsConfig.DingDingConfig.Token, AppsettingsConfig.DingDingConfig.AesKey, AppsettingsConfig.DingDingConfig.AppKey);string decryptMsg = callbackCrypto.getDecryptMsg(model.Msg_signature, model.TimeStamp, model.Nonce, model.Encrypt);string msg = "success";// 3. 反序列化回调事件json数据var approveModel = JsonHelper.DeserializeObject<ApprovalInstanceModel>(decryptMsg);WriteLogHelper.WriteLogsAsync(JsonHelper.SerializeObject(approveModel), "实例回调日志-解密");var type = approveModel.EventType;switch (type){case "check_url":WriteLogHelper.WriteLogsAsync("审批回调:" + JsonHelper.SerializeObject(model), "实例回调日志");// 测试回调break;case "bpms_instance_change":// 实例改变break;}var rspMsg = callbackCrypto.getEncryptedMap(msg);return rspMsg;}
check_url就是钉应用后台设置回调URL时传入数据的类型。拿到数据
public string Msg_signature { set; get; } = "";
public string TimeStamp { set; get; }
public string Nonce { set; get; } = "123456";
/// <summary>
/// 加密后的结果
/// </summary>
public string Encrypt { set; get; }
分为几部分,前面几项用来解密Encrypt密文的参数。
通过提供的DingTalkEncryptor 的 getDecryptMsg方法来进行解密
得到解密后的内容序列化成对象。
/*** 钉钉开放平台加解密方法*/public class DingTalkEncryptor{//private static readonly Charset CHARSET = Charset.forName("utf-8");//private static readonly Base64 base64 = new Base64();private byte[] aesKey;private String token;private String corpId;/**ask getPaddingBytes key固定长度**/private static readonly int AES_ENCODE_KEY_LENGTH = 43;/**加密随机字符串字节长度**/private static readonly int RANDOM_LENGTH = 16;/*** 构造函数* @param token 钉钉开放平台上,开发者设置的token* @param encodingAesKey 钉钉开放台上,开发者设置的EncodingAESKey* @param corpId 企业自建应用-事件订阅, 使用appKey* 企业自建应用-注册回调地址, 使用corpId* 第三方企业应用, 使用suiteKey** @throws DingTalkEncryptException 执行失败,请查看该异常的错误码和具体的错误信息*/public DingTalkEncryptor(String token, String encodingAesKey, String corpId){if (null == encodingAesKey || encodingAesKey.Length != AES_ENCODE_KEY_LENGTH){throw new DingTalkEncryptException(DingTalkEncryptException.AES_KEY_ILLEGAL);}this.token = token;this.corpId = corpId;aesKey = Convert.FromBase64String(encodingAesKey + "=");}/*** 将和钉钉开放平台同步的消息体加密,返回加密Map*/public Dictionary<String, String> getEncryptedMap(String plaintext){var time = DateTime.Now.Millisecond;return getEncryptedMap(plaintext, time);}/*** 将和钉钉开放平台同步的消息体加密,返回加密Map* @param plaintext 传递的消息体明文* @param timeStamp 时间戳* @param nonce 随机字符串* @return* @throws DingTalkEncryptException*/public Dictionary<String, String> getEncryptedMap(String plaintext, long timeStamp){if (null == plaintext){throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_PLAINTEXT_ILLEGAL);}var nonce = Utils.getRandomStr(RANDOM_LENGTH);if (null == nonce){throw new DingTalkEncryptException(DingTalkEncryptException.ENCRYPTION_NONCE_ILLEGAL);}String encrypt = this.encrypt(nonce, plaintext);String signature = getSignature(token, timeStamp.ToString(), nonce, encrypt);Dictionary<String, String> resultMap = new Dictionary<String, String>();resultMap["msg_signature"] = signature;resultMap["encrypt"] = encrypt;resultMap["timeStamp"] = timeStamp.ToString();resultMap["nonce"] = nonce;return resultMap;}/*** 密文解密* @param msgSignature 签名串* @param timeStamp 时间戳* @param nonce 随机串* @param encryptMsg 密文* @return 解密后的原文* @throws DingTalkEncryptException*/public String getDecryptMsg(String msgSignature, String timeStamp, String nonce, String encryptMsg){//校验签名String signature = getSignature(token, timeStamp, nonce, encryptMsg);if (!signature.Equals(msgSignature)){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);}// 解密String result = decrypt(encryptMsg);return result;}/** 对明文加密.* @param text 需要加密的明文* @return 加密后base64编码的字符串*/private String encrypt(String random, String plaintext){try{byte[] randomBytes = System.Text.Encoding.UTF8.GetBytes(random);// random.getBytes(CHARSET);byte[] plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plaintext);// plaintext.getBytes(CHARSET);byte[] lengthByte = Utils.int2Bytes(plainTextBytes.Length);byte[] corpidBytes = System.Text.Encoding.UTF8.GetBytes(corpId);// corpId.getBytes(CHARSET);//MemoryStream byteStream = new MemoryStream();var bytestmp = new List<byte>();bytestmp.AddRange(randomBytes);bytestmp.AddRange(lengthByte);bytestmp.AddRange(plainTextBytes);bytestmp.AddRange(corpidBytes);byte[] padBytes = PKCS7Padding.getPaddingBytes(bytestmp.Count);bytestmp.AddRange(padBytes);byte[] unencrypted = bytestmp.ToArray();RijndaelManaged rDel = new RijndaelManaged();rDel.Mode = CipherMode.CBC;rDel.Padding = PaddingMode.Zeros;rDel.Key = aesKey;rDel.IV = aesKey.ToList().Take(16).ToArray();ICryptoTransform cTransform = rDel.CreateEncryptor();byte[] resultArray = cTransform.TransformFinalBlock(unencrypted, 0, unencrypted.Length);return Convert.ToBase64String(resultArray, 0, resultArray.Length);//Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");//IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);//cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);//byte[] encrypted = cipher.doFinal(unencrypted);//String result = base64.encodeToString(encrypted);//return result;}catch (Exception e){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_ENCRYPT_TEXT_ERROR);}}/** 对密文进行解密.* @param text 需要解密的密文* @return 解密得到的明文*/private String decrypt(String text){byte[] originalArr;try{byte[] toEncryptArray = Convert.FromBase64String(text);RijndaelManaged rDel = new RijndaelManaged();rDel.Mode = CipherMode.CBC;rDel.Padding = PaddingMode.Zeros;rDel.Key = aesKey;rDel.IV = aesKey.ToList().Take(16).ToArray();ICryptoTransform cTransform = rDel.CreateDecryptor();originalArr = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);//return System.Text.UTF8Encoding.UTF8.GetString(resultArray);设置解密模式为AES的CBC模式//Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");//SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");//IvParameterSpec iv = new IvParameterSpec(Arrays.copyOfRange(aesKey, 0, 16));//cipher.init(Cipher.DECRYPT_MODE, keySpec, iv);使用BASE64对密文进行解码//byte[] encrypted = Base64.decodeBase64(text);解密//originalArr = cipher.doFinal(encrypted);}catch (Exception e){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_ERROR);}String plainText;String fromCorpid;try{// 去除补位字符byte[] bytes = PKCS7Padding.removePaddingBytes(originalArr);Console.Out.WriteLine("bytes size:" + bytes.Length);// 分离16位随机字符串,网络字节序和corpIdbyte[] networkOrder = bytes.Skip(16).Take(4).ToArray();// Arrays.copyOfRange(bytes, 16, 20);for (int i = 0; i < 4; i++){Console.Out.WriteLine("networkOrder size:" + (int)networkOrder[i]);}Console.Out.WriteLine("bytes plainText:" + networkOrder.Length + " " + JsonSerializer.Serialize(networkOrder));int plainTextLegth = Utils.bytes2int(networkOrder);Console.Out.WriteLine("bytes size:" + plainTextLegth);plainText = System.Text.UTF8Encoding.UTF8.GetString(bytes.Skip(20).Take(plainTextLegth).ToArray()); // new String(Arrays.copyOfRange(bytes, 20, 20 + plainTextLegth), CHARSET);fromCorpid = System.Text.UTF8Encoding.UTF8.GetString(bytes.Skip(20 + plainTextLegth).ToArray()); //new String(Arrays.copyOfRange(bytes, 20 + plainTextLegth, bytes.length), CHARSET);Console.Out.WriteLine("bytes plainText:" + plainText);}catch (Exception e){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_LENGTH_ERROR);}Console.Out.WriteLine(fromCorpid + "=====" + corpId);// corpid不相同的情况if (!fromCorpid.Equals(corpId)){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_DECRYPT_TEXT_CORPID_ERROR);}return plainText;}/*** 数字签名* @param token isv token* @param timestamp 时间戳* @param nonce 随机串* @param encrypt 加密文本* @return* @throws DingTalkEncryptException*/public String getSignature(String token, String timestamp, String nonce, String encrypt){try{Console.Out.WriteLine(encrypt);String[] array = new String[] { token, timestamp, nonce, encrypt };Array.Sort(array, StringComparer.Ordinal);//var tmparray = array.ToList();//tmparray.Sort(new JavaStringComper());//array = tmparray.ToArray();Console.Out.WriteLine("array:" + JsonSerializer.Serialize(array));StringBuilder sb = new StringBuilder();for (int i = 0; i < 4; i++){sb.Append(array[i]);}String str = sb.ToString();Console.Out.WriteLine(str);//MessageDigest md = MessageDigest.getInstance("SHA-1");//md.update(str.getBytes());//byte[] digest = md.digest();System.Security.Cryptography.SHA1 hash = System.Security.Cryptography.SHA1.Create();System.Text.Encoding encoder = System.Text.Encoding.ASCII;byte[] combined = encoder.GetBytes(str);byte 转换//sbyte[] myByte = new sbyte[]//byte[] mySByte = new byte[myByte.Length];//for (int i = 0; i < myByte.Length; i++)//{// if (myByte[i] > 127)// mySByte[i] = (sbyte)(myByte[i] - 256);// else// mySByte[i] = (sbyte)myByte[i];//}byte[] digest = hash.ComputeHash(combined);StringBuilder hexstr = new StringBuilder();String shaHex = "";for (int i = 0; i < digest.Length; i++){shaHex = ((int)digest[i]).ToString("x");// Integer.toHexString(digest[i] & 0xFF);if (shaHex.Length < 2){hexstr.Append(0);}hexstr.Append(shaHex);}return hexstr.ToString();}catch (Exception e){throw new DingTalkEncryptException(DingTalkEncryptException.COMPUTE_SIGNATURE_ERROR);}}}/*** 钉钉开放平台加解密异常类*/public class DingTalkEncryptException : Exception{/**成功**/public static readonly int SUCCESS = 0;/**加密明文文本非法**/public readonly static int ENCRYPTION_PLAINTEXT_ILLEGAL = 900001;/**加密时间戳参数非法**/public readonly static int ENCRYPTION_TIMESTAMP_ILLEGAL = 900002;/**加密随机字符串参数非法**/public readonly static int ENCRYPTION_NONCE_ILLEGAL = 900003;/**不合法的aeskey**/public readonly static int AES_KEY_ILLEGAL = 900004;/**签名不匹配**/public readonly static int SIGNATURE_NOT_MATCH = 900005;/**计算签名错误**/public readonly static int COMPUTE_SIGNATURE_ERROR = 900006;/**计算加密文字错误**/public readonly static int COMPUTE_ENCRYPT_TEXT_ERROR = 900007;/**计算解密文字错误**/public readonly static int COMPUTE_DECRYPT_TEXT_ERROR = 900008;/**计算解密文字长度不匹配**/public readonly static int COMPUTE_DECRYPT_TEXT_LENGTH_ERROR = 900009;/**计算解密文字corpid不匹配**/public readonly static int COMPUTE_DECRYPT_TEXT_CORPID_ERROR = 900010;private static Dictionary<int, String> msgMap = new Dictionary<int, String>();static DingTalkEncryptException(){msgMap[SUCCESS] = "成功";msgMap[ENCRYPTION_PLAINTEXT_ILLEGAL] = "加密明文文本非法";msgMap[ENCRYPTION_TIMESTAMP_ILLEGAL] = "加密时间戳参数非法";msgMap[ENCRYPTION_NONCE_ILLEGAL] = "加密随机字符串参数非法";msgMap[SIGNATURE_NOT_MATCH] = "签名不匹配";msgMap[COMPUTE_SIGNATURE_ERROR] = "签名计算失败";msgMap[AES_KEY_ILLEGAL] = "不合法的aes key";msgMap[COMPUTE_ENCRYPT_TEXT_ERROR] = "计算加密文字错误";msgMap[COMPUTE_DECRYPT_TEXT_ERROR] = "计算解密文字错误";msgMap[COMPUTE_DECRYPT_TEXT_LENGTH_ERROR] = "计算解密文字长度不匹配";msgMap[COMPUTE_DECRYPT_TEXT_CORPID_ERROR] = "计算解密文字corpid不匹配";}private int code;public DingTalkEncryptException(int exceptionCode) : base(msgMap[exceptionCode]){this.code = exceptionCode;}}/** PKCS7算法的加密填充*/public class PKCS7Padding{//private readonly static Charset CHARSET = Charset.forName("utf-8");private readonly static int BLOCK_SIZE = 32;/*** 填充mode字节* @param count* @return*/public static byte[] getPaddingBytes(int count){int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);if (amountToPad == 0){amountToPad = BLOCK_SIZE;}char padChr = chr(amountToPad);String tmp = string.Empty; ;for (int index = 0; index < amountToPad; index++){tmp += padChr;}return System.Text.Encoding.UTF8.GetBytes(tmp);}/*** 移除mode填充字节* @param decrypted* @return*/public static byte[] removePaddingBytes(byte[] decrypted){int pad = (int)decrypted[decrypted.Length - 1];if (pad < 1 || pad > BLOCK_SIZE){pad = 0;}//Array.Copy()var output = new byte[decrypted.Length - pad];Array.Copy(decrypted, output, decrypted.Length - pad);return output;}private static char chr(int a){byte target = (byte)(a & 0xFF);return (char)target;}}/*** 加解密工具类*/public class Utils{/**** @return*/public static String getRandomStr(int count){String baset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";Random random = new Random();StringBuilder sb = new StringBuilder();for (int i = 0; i < count; i++){int number = random.Next(baset.Length);sb.Append(baset[number]);}return sb.ToString();}/** int转byte数组,高位在前*/public static byte[] int2Bytes(int count){byte[] byteArr = new byte[4];byteArr[3] = (byte)(count & 0xFF);byteArr[2] = (byte)(count >> 8 & 0xFF);byteArr[1] = (byte)(count >> 16 & 0xFF);byteArr[0] = (byte)(count >> 24 & 0xFF);return byteArr;}/*** 高位在前bytes数组转int* @param byteArr* @return*/public static int bytes2int(byte[] byteArr){int count = 0;for (int i = 0; i < 4; ++i){count <<= 8;count |= byteArr[i] & 255;}return count;}}public class JavaStringComper : IComparer<string>{public int Compare(string x, string y){return String.Compare(x, y);}}// 测试加解密的正确性public class Program{public static void Main(string[] args){String[] a = new String[] { "1", "W", "t" };var ding = new DingTalkEncryptor("tokenxxxx", "o1w0aum42yaptlz8alnhwikjd3jenzt9cb9wmzptgus", "dingxxxxxx");var msg = ding.getEncryptedMap("success");Console.Out.WriteLine(msg);//msg_signature, $data->timeStamp, $data->nonce, $data->encryptvar text = ding.getDecryptMsg(msg["msg_signature"], msg["timeStamp"], msg["nonce"], msg["encrypt"]);Console.Out.WriteLine(text);// "msg_signature":"c01beb7b06384cf416e04930aed794684aae98c1","encrypt":"","timeStamp":,"nonce":""//{"timeStamp":"1605695694141","msg_signature":"702c953056613f5c7568b79ed134a27bd2dcd8d0",//"encrypt":"","nonce":"WelUQl6bCqcBa2fMc6eI"}text = ding.getDecryptMsg("f36f4ba5337d426c7d4bca0dbcb06b3ddc1388fc", "1605695694141", "WelUQl6bCqcBa2fM", "X1VSe9cTJUMZu60d3kyLYTrBq5578ZRJtteU94wG0Q4Uk6E/wQYeJRIC0/UFW5Wkya1Ihz9oXAdLlyC9TRaqsQ==");Console.Out.WriteLine(text);}}
public class ApprovalInstanceModel
{
//public long Id { set; get; } = 0;
public string EventType { set; get; }
public string ProcessInstanceId { set; get; }
/// <summary>
/// 企业ID
/// </summary>
public string CorpId { set; get; }
public string Title { set; get; }
/// <summary>
/// 审批状态类型
/// </summary>
public string Type { set; get; }
/// <summary>
/// 审批详情URL
/// </summary>
public string Url { set; get; }
/// <summary>
/// 审批结果 agree refuse 或为空
/// </summary>
public string Result { set; get; }
/// <summary>
/// 员工ID
/// </summary>
public string StaffId { set; get; }
/// <summary>
/// 审批模板code
/// </summary>
public string ProcessCode { set; get; }
public long FinishTime { set; get; } = 0;
public long CreateTime { set; get; } = 0;
public DateTime CreateTimeNormal { set; get; }
public DateTime FinishTimeNormal { set; get; }
}
bpms_instance_change 类型是审批发起与结束时会触发的用来更新我们的微应用单据数据的状态,以及更新时有审批进度的URL,可以关联起来。
好了以上就是审批回调URL的接口内容了。
相关文章:

钉钉企业微应用开发C#-HTTP回调接口
官方的STREAM回调推送的方式,试了几次都认证不过,就放弃了还是用HTTP的模式吧。 /// <summary>/// 应用回调/// </summary>/// <param name"model"></param>/// <returns></returns>public static Dictio…...

Rust编程基础之条件表达式和循环
1.if表达式 if 表达式允许根据条件执行不同的代码分支, 以下代码是一个典型的使用if表达式的例子: fn main() {let number 3; if number < 5 {println!("condition was true");} else {println!("condition was false");} } 所有的 if 表达式都以…...

MATLAB算法实战应用案例精讲-【人工智能】ROS机器人(补充篇)
目录 前言 ROS 机器人导航调参 1 速度和加速度 2 全局路径规划 3 局部路径规划...

基于8086汽车智能小车控制系统
**单片机设计介绍,基于8086汽车智能小车控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于 8086 的汽车智能小车控制系统是一种将微处理器技术应用于汽车控制的系统。下面是其主要的设计介绍: 硬…...

全光谱大面积氙光灯太阳光模拟器老化测试
氙灯光源太阳光模拟器广泛应用于光解水产氢、光化学催化、二氧化碳制甲醇、光化学合成、光降解污染物、 水污染处理、生物光照,光学检测、太阳能电池研究、荧光材料测试(透射、反射、吸收) 太阳能电池特性测试,光热转化,光电材料特性测试,生物…...

linux添加一条到中间路由器的路由
有时候需要配置一些明细路由,不能直接通过网关进行路由转发 配置示例 ip route add 10.0.12.0/24 via 10.0.41.1 dev bond0 这个命令是用于在Linux操作系统上配置IP路由的命令。具体来说,这个命令的含义是: ip route add: 这部分表示要添加…...

不同MySQL服务的表以及库的数据迁移(/备份)
目标: 将本地主机上usernameroot,passwordroot,port3307的MySQL服务中migration_one数据库的table_11数据表导出到本地的D:\start_java\XinQiUtilsOrDemo\testMigrationMySQL\table_11.bak注意:目前D:\start_java\XinQiUtilsOrDemo\testMigrationMySQL该…...

聊聊芯片超净间的颗粒(particle)
在芯片制造领域,颗粒的存在可能对生产过程产生巨大影响。其中,每个微小的颗粒,无论是来自人员、设备,还是自然环境,都有可能在制程中引发故障,从而对产品性能产生负面影响。这就是为什么在芯片厂中…...

服务器(windows Server 2019为例)中的日志中文乱码的解决办法
1. 首先,打开控制面板,找到区域(Region),把Format设置为国语简体中文,点击高级(Administrative)后设置Current system locale为国语简体中文,按照图中步骤:...

Linux 学习(CentOS 7)
CentOS 7 学习 Linux系统内核作者: Linux内核版本 内核(kernel)是系统的心脏,是运行程序和管理像磁盘和打印机等硬件设备的核心程序,它提供了一个在裸设备与应用程序间的抽象层。 Linux内核版本又分为稳定版和开发版,两种版本是相互关联&am…...

架构决策记录 ADR
在项目和产品开发过程中,软件工程团队需要做出架构决策以实现其目标。这些决策可以是技术性的,也可以与流程相关。 技术决策:例如决定使用JBOSS Data Grid作为缓存解决方案还是选择Amazon Elasticache,或者决定使用AWS Network L…...

SSM之spring注解式缓存redis->redis整合,redis的注解式开发及应用场景,redis的击穿穿透雪崩
redis整合redis的注解式开发及应用场景redis的击穿穿透雪崩 1.redis整合 mysql整合 pom配置; String-fmybatis.xml --> mybatis.cfg.xml: 包扫描; 注册了一个jdbc.properties(url/password/username/...); 配置数据源(数据库连…...

数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)
数据库性能优化是提升数据库系统整体性能和响应速度的一系列技术和策略。它可以通过多种方式来实现,包括优化查询语句、索引设计、硬件升级、负载均衡等手段。 合适的数据模型设计 正确的数据模型设计是性能优化的基石。合理的表结构和关系设计可以减少冗余数据&…...

谁说 Linux 不能玩游戏?
在上个世纪最早推出视频游戏的例子是托马斯戈德史密斯(Thomas T. Goldsmith Jr.)于1947年开发的“「Cathode Ray Tube Amusement Device」”,它已经显着发展,并且已成为人类生活中必不可少的一部分。 通过美国游戏行业的统计数据&…...

发电机负载测试方案
发电机负载测试是为了评估发电机在不同负载条件下的性能和稳定性。下面是一个可能的发电机负载测试方案: 测试前准备: - 确定测试的负载范围和条件,包括负载大小、负载类型(如电阻性、感性或容性负载)、负载持续时间等…...

Flask三种文件下载方法
Flask 是一个流行的 Python Web 框架,它提供了多种方法来实现文件下载。在本文中,我们将介绍三种不同的方法,以便你能够选择最适合你应用程序的方法。 方法一:使用 send_file 函数 send_file 函数是 Flask 中最常用的文件下载方法…...

OpenCV C++ 图像处理实战 ——《基于NCC多角度多目标匹配》
OpenCV C++ 图像处理实战 ——《基于NCC多角度多目标匹配》 一、结果演示二、NCC模板匹配2.1、OpenCV matchTemplate2.2、多角度2.3、多目标2.4、NMS非极大值抑制三、代码实现3.1 制作模板3.1 单目标匹配3.1.1 模板图像旋转3.1.2 旋转目标坐标3.2 多目标匹配3.2.1 制作模板3.2.…...

【书籍篇】Spring实战第4版 第2部分 Web中的Spring
Spring实战第4版 第2部分 Web中的Spring 五. 构建Spring Web应用程序5.1 SpirngMVC请求流程5.2 搭建Spring MVC5.2.1 配置DispatcherServlet5.2.2 配置WebConfig5.2.3 配置RootConfig 5.3 编写基本的控制器5.4 Spittr首页5.6 复杂的控制器5.6.1 定义类级别的请求处理5.6.2 传递…...

IC - 基础知识 - SOC与MCU
说明 工作中有涉及到SOC和MCU,非嵌入式专业,对两个概念理解不是很清晰。 共同点 MCU和SOC是两种常见的集成电路 (IC) 设计形式,它们的区别在于它们的设计目的和应用场景。工作中将MCU和SOC都称为IC也是没问题的,但是专业人员会…...

【elasticsearch+kibana基于windows docker安装】
创建网络:es和kibana容器互联 docker network create es-net加载镜像 docker pull elasticsearch:7.12.1运行 docker run -d --name es -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -e ES_JAVA_OPTS"-Xms512m -Xmx512m" -v $…...

VMware网络设置 桥接模式 NAT VMNET0 1 8
1.桥接模式 虚拟机与主机并列 可拥有独立IP 主机与虚拟机之间,以及各虚拟机之间都可以互访。对应虚拟机就被当成主机所在以太网上的一个独立物理机来看待,各虚拟机通过默认的 VMnet0 网卡与主机以太网连接,虚拟机间的虚拟网络为 VMnet0。这…...

【MongoDB】MongoExport如何过滤数据导出
问题 使用MongoDB处理导出数据时,想增加数据过滤操作。 例如:导出所有isGirl为true的所有数据。 分析 在mongoexport说明文档中找到了query字段和queryFile字段,用来进行数据查询匹配导出。 query字段 后面直接跟 json格式数据。 queryF…...

吴恩达《机器学习》6-1->6-3:分类问题、假设陈述、决策界限
一、什么是分类问题? 在分类问题中,我们试图预测的变量𝑦是离散的值,通常表示某种类别或标签。这些类别可以是二元的,也可以是多元的。分类问题的示例包括: 判断一封电子邮件是否是垃圾邮件(二…...

C语言 用字符串比较函数cmp来做一个门禁:账号密码是否匹配 (干货满满)
#include<stdio.h> #include<string.h> void fun04() {for (int i 0; i < 3; i){char *str01 "hello";char uname[100] ;printf("请输入账号");scanf("%s",uname);char *str02 "123456";char pword[100];printf(&qu…...

Uniapp实现多语言切换
前言 之前做项目过程中,也做过一次多语言切换,大致思想都是一样的,想了解的可以看下之前的文章C#WinForm实现多语言切换 使用i18n插件 安装插件 npm install vue-i18n --saveMain.js配置 // 引入 多语言包 import VueI18n from vue-i18n…...

企业数字化转型与供应链效率-基准回归复刻(2007-2022年)
参照张树山(2023)的做法,本团队对来自统计与决策《企业数字化转型与供应链效率》一文中的基准回归部分进行复刻。文章实证检验企业数字化转型对供应链效率的影响。用年报词频衡量上市公司数字化转型程度,以库存周转天数来衡量供应…...

支持向量机 (SVM):初学者指南
照片由 Unsplash上的 vackground.com提供 一、说明 SVM(支持向量机)简单而优雅用于分类和回归的监督机器学习方法。该算法试图找到一个超平面,将数据分为不同的类,并具有尽可能最大的边距。本篇我们将介绍如果最大边距不存在的时候…...

UnityShader(五)
这次要用表面着色器实现一个水的特效。先翻到最下边看代码,看不懂再看下面的解释。 首先第一步要实现水的深浅判断,实现深水区和浅水区的区分。 这里需要用到深度图的概念。不去说太多概念,只去说怎么实现的,首先我们的水面是在…...

Java中的类和对象
文章目录 一、类和对象的基本概念二、类和对象的定义和使用1.创建类的语法2.创建类的对象3.范例(创建一个类的对象) 三、this引用1.什么是this引用2.this引用的特性 四、构造方法五、封装1.封装的概念2.访问限定符3.封装扩展包3.1包的概念3.2常见的包 六、static成员1.static修…...

多测师肖sir_高级金牌讲师_jenkins搭建
jenkins操作手册 一、jenkins介绍 1、持续集成(CI) Continuous integration 持续集成 团队开发成员每天都有集成他们的工作,通过每个成员每天至少集成一次,也就意味着一天有可 能多次集成。在工作中我们引入持续集成,通…...