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

钉钉企业微应用开发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回调推送的方式&#xff0c;试了几次都认证不过&#xff0c;就放弃了还是用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汽车智能小车控制系统

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

全光谱大面积氙光灯太阳光模拟器老化测试

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

linux添加一条到中间路由器的路由

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

不同MySQL服务的表以及库的数据迁移(/备份)

目标&#xff1a; 将本地主机上usernameroot,passwordroot,port3307的MySQL服务中migration_one数据库的table_11数据表导出到本地的D:\start_java\XinQiUtilsOrDemo\testMigrationMySQL\table_11.bak注意&#xff1a;目前D:\start_java\XinQiUtilsOrDemo\testMigrationMySQL该…...

聊聊芯片超净间的颗粒(particle)

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

服务器(windows Server 2019为例)中的日志中文乱码的解决办法

1. 首先&#xff0c;打开控制面板&#xff0c;找到区域&#xff08;Region&#xff09;&#xff0c;把Format设置为国语简体中文&#xff0c;点击高级(Administrative)后设置Current system locale为国语简体中文&#xff0c;按照图中步骤&#xff1a;...

Linux 学习(CentOS 7)

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

架构决策记录 ADR

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

SSM之spring注解式缓存redis->redis整合,redis的注解式开发及应用场景,redis的击穿穿透雪崩

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

数据库性能优化(查询优化、索引优化、负载均衡、硬件升级等方面)

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

谁说 Linux 不能玩游戏?

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

发电机负载测试方案

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

Flask三种文件下载方法

Flask 是一个流行的 Python Web 框架&#xff0c;它提供了多种方法来实现文件下载。在本文中&#xff0c;我们将介绍三种不同的方法&#xff0c;以便你能够选择最适合你应用程序的方法。 方法一&#xff1a;使用 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&#xff0c;非嵌入式专业&#xff0c;对两个概念理解不是很清晰。 共同点 MCU和SOC是两种常见的集成电路 (IC) 设计形式&#xff0c;它们的区别在于它们的设计目的和应用场景。工作中将MCU和SOC都称为IC也是没问题的&#xff0c;但是专业人员会…...

【elasticsearch+kibana基于windows docker安装】

创建网络&#xff1a;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 $…...

Spark 之 入门讲解详细版(1)

1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室&#xff08;Algorithms, Machines, and People Lab&#xff09;开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目&#xff0c;8个月后成为Apache顶级项目&#xff0c;速度之快足见过人之处&…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

条件运算符

C中的三目运算符&#xff08;也称条件运算符&#xff0c;英文&#xff1a;ternary operator&#xff09;是一种简洁的条件选择语句&#xff0c;语法如下&#xff1a; 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true&#xff0c;则整个表达式的结果为“表达式1”…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

数据库分批入库

今天在工作中&#xff0c;遇到一个问题&#xff0c;就是分批查询的时候&#xff0c;由于批次过大导致出现了一些问题&#xff0c;一下是问题描述和解决方案&#xff1a; 示例&#xff1a; // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...