WPS本地镜像化在线文档操作以及样例
一个客户项目有引进在线文档操作需求,让我这边做一个demo调研下,给我的对接文档里有相关方法的说明,照着对接即可。但在真正对接过程中还是踩过不少坑,这儿对之前的对接工作做个记录。
按照习惯先来一个效果:
Demo下载链接:https://download.csdn.net/download/qxyywy/88117444
接入指引
1. 申请授权证书并进行授权。
2. 登录系统后台页面
3. 创建、获取应用信息 access_key (简称ak)、 secret_key (简称 sk )。开发者在接口调用时,使用ak 、 sk 生成WPS-4签名进行鉴权。
4. 在线编辑、在线预览、格式转换接入按照对应开放能力文档接入。在线编辑、在线预览对接过程中需要设置回调地址。其中,在线编辑可通过配置开启历史版本功能。
5. 使用过程中需通过证书查询接口关注授权证书状态,若证书即将过期或者不可用,需进行更新证书操作。
6. 在线编辑或在线预览服务端对接完毕,对接方可使用JSSDK,调用API实现相关需求。
WPS-4签名算法
在对接时,耗费了一定时间在WPS-4签名处,对接文档中有WPS-4的说明和样例,自己在对接转换成NetCore的时候踩了一些坑,签名算法中最主要是:Wps-Docs-Authorization的计算方法
签名格式:WPS-4 {accessKey}:{signature} 注意WPS-4后面有空格。
signature:hmac-sha256(secret_key, Ver + HttpMethod + URI + Content-Type + WpsDocs-Date + sha256(HttpBody))
signature的样例如下:WPS-4POST/callback/path/demoapplication/jsonWed, 20 Apr 2022 01:33:07GMTfc005f51a6e75586d2d5d078b657dxxxdf9c1dfa6a7c0c0ba38c715daeb6ede9
这是文档中对签名算法的解释,对照着格式完成相关算法,具体算法如下:
signature的组装:
/// <summary>/// 获取签名/// </summary>/// <param name="method">请求方法,如:GET,POST</param>/// <param name="uri">请求url,带querystring</param>/// <param name="body">请求body</param>/// <param name="date">日期</param>/// <param name="contentType">默认:application/json</param>/// <param name="secretKey">应用SK</param>/// <returns></returns>public static string WPS4Signature(string secretKey,string method,string uri, byte[] body=null,DateTime? date=null,string contentType= "application/json"){//获取uri路径string path = uri;//日期格式化if (date == null)date = DateTime.Now;string dateStr = String.Format("{0:r}", date);//open不参与签名,做替换处理if (path.StartsWith("/open")){path = path.Replace("/open", "");}string sha256body;//body为空则为空,否则返回sha256(body)if (body != null && body.Length > 0){sha256body = Sha256(body);}else{sha256body = "";}String signature = null;signature = HmacSHA256Encrypt($"WPS-4{method.ToUpper()}{path}{contentType}{dateStr}{sha256body}", secretKey);return signature;}
HmacSHA256加密算法:
/// <summary>/// HmacSHA256加密/// </summary>/// <param name="secret"></param>/// <param name="signKey"></param>/// <returns></returns>public static string HmacSHA256Encrypt(string secret, string signKey){string signRet = string.Empty;using (HMACSHA256 mac = new HMACSHA256(Encoding.UTF8.GetBytes(signKey))){byte[] hash = mac.ComputeHash(Encoding.UTF8.GetBytes(secret));//signRet = Convert.ToBase64String(hash);signRet = ToHexStrFromByte(hash); }return signRet;}
Sha256转换:
/// <summary>/// Sha256转换/// </summary>/// <param name="input">The input.</param>/// <returns>A hash.</returns>public static string Sha256(this byte[] input){if (input == null){return null;}using (var sha = SHA256.Create()){var hash = sha.ComputeHash(input);return ToHexStrFromByte(hash);}}
字节数组转16进制字符串:
/// <summary>/// 字节数组转16进制字符串:空格分隔/// </summary>/// <param name="byteDatas"></param>/// <returns></returns>public static string ToHexStrFromByte(this byte[] byteDatas){StringBuilder builder = new StringBuilder();for (int i = 0; i < byteDatas.Length; i++){builder.Append(string.Format("{0:X2}", byteDatas[i]));}return builder.ToString().Trim().ToLower();}
获取在线预览链接
/// <summary>/// 获取在线预览链接/// </summary>/// <param name="request"></param>/// <returns></returns>[Route("api/wps/previewgenarate")][HttpPost]public Task<GenarateResult> GenarateWPSPreviewUrl(GenarateRequest request){return Task.Run(() =>{string wpsHost = "http://10.4.**.**";string uri = $"/api/preview/v1/files/{defaultFileId}/link?type=w&preview_mode=high_definition";string fullUrl = $"{wpsHost}/open{uri}";Dictionary<string, string> headers = new Dictionary<string, string>();DateTime now = DateTime.Now;headers.Add("Content-Type", "application/json");headers.Add("Wps-Docs-Date", String.Format("{0:r}", now));var signature = WPSLocalSIgnatureHelper.WPS4Signature("SKrpaxjdwoetijjv", "get", uri, null, now);string docsAuthorization = WPSLocalSIgnatureHelper.WPS4SignAuthorization("UOMYPEVAHWQLTKJF", signature);headers.Add("Wps-Docs-Authorization", docsAuthorization);HttpHelper httpHelper = new HttpHelper();var resultTemp = httpHelper.Get(fullUrl, headers);var result = JsonConvert.DeserializeObject<ResponseBaseModel<OnlineEditResultModel>>(resultTemp);string url = "";if (result != null && result.data != null){url = result.data.link;}return new GenarateResult { Url = url };});}
这儿比较坑的地方来了,方法参数都组装好了,通过HttpWebRequest后端发起请求获取WPS中台返回的在线预览地址时,始终提示401报错获取不到数据。迫不得已自己通过APIPost组装了相关请求和参数居然又能获取到相关数据。对照了下请求头,又差异后调整了程序的请求头,保证和apiPost里的完全一致,依然返回401,通过查阅相关资料找到一个处理办法,在发起的请求后手动捕获WebException,然后在WebException里解析数据流获取信息。
HttpWebRequest Get方式访问
/// <summary>/// Get方式访问/// </summary>/// <param name="url"></param>/// <param name="encode"></param>/// <param name="referer"></param>/// <param name="headers"></param>/// <returns></returns>public string Get(string url, string encode, string referer, Dictionary<string, string> headers=null){int num = _tryTimes;HttpWebRequest request = null;HttpWebResponse response = null;StreamReader reader = null;while (num-- >= 0){try{DelaySomeTime();ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);//验证服务器证书回调自动验证request = (HttpWebRequest)WebRequest.Create(url);request.Headers.Add("accept", "*/*");request.Headers.Add("accept-encoding", "gzip, deflate, br");request.Headers.Add("accept-language", "zh-CN");request.Headers.Add("connection", "keep-alive");if (headers != null) {foreach (var item in headers){request.Headers.Add(item.Key, item.Value);}}//request.UserAgent = reqUserAgent;request.CookieContainer = _cookie;request.Referer = referer;request.Method = "GET";request.Timeout = _timeOut;if (_proxy != null && _proxy.Credentials != null){request.UseDefaultCredentials = true;}request.Proxy = _proxy;response = (HttpWebResponse)request.GetResponse();reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encode));return reader.ReadToEnd();}catch (WebException ex){response = (HttpWebResponse)ex.Response; //解析401等错误返回的有效信息var resultTemp = "";Stream stream = response.GetResponseStream();using (StreamReader readers = new StreamReader(stream, Encoding.UTF8)){resultTemp = readers.ReadToEnd();}return resultTemp;}catch (Exception ex){_logger.Error(url + "\r\n" + ex.ToString());continue;}finally{if (request != null){request.Abort();}if (response != null){response.Close();}if (reader != null){reader.Close();}}}return string.Empty;}
DemoHtml
到上面时后端的处理就基本完成,前端这边因为时临时demo就用了一个html来处理,真实项目中需要用VUE等处理也都类似。
以下为 html的代码:
<!DOCTYPE html>
<html><head><meta charset="UTF-8" /><!-- 建议禁用外框浏览器自带的缩放 --><metaname="viewport"content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0,user-scalable=no"/><meta http-equiv="X-UA-Compatible" content="ie=edge" /><title>WPS Web Office(iframe)接入指南</title><style>* {box-sizing: border-box;}html,body {display: flex;flex-direction: column;padding: 0;margin: 0;height: 100%;/* 防止双击缩放 */touch-action: manipulation;}iframe {flex: 1;}</style><!-- cdn引入JQ --><script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.4.1.min.js"></script><script src="./jwps.js"></script><script type="text/javascript">var appHost = "http://10.4.146.19:8890";// 支持 HTTPS// 注意:如果通过postMessage来设置token,请在url参数加上_w_tokentype=1function showWPS(url) {// 初始化var wps = WPS.config({mount: document.querySelector("#wpsPanl"),// 文字wpsUrl: url,headers: {shareBtn: {tooltip: "分享",subscribe: function() {console.log("click callback");}},otherMenuBtn: {tooltip: "其他按钮",items: [{// 自定义, type 固定填 'custom'type: "custom",icon:"http://ep.wps.cn/index/images/logo_white2.png",text: "API 导出 PDF",subscribe: function(wps) {if (wps.WpsApplication) {wps.WpsApplication().ActiveDocument.ExportAsFixedFormatAsync().then(function(result) {console.table(result);});}}},{// 自定义, type 固定填 'custom'type: "custom",icon:"http://ep.wps.cn/index/images/logo_white2.png",text: "API 使用",subscribe: function(wps) {let result;if (wps.WpsApplication) {wps.WpsApplication().ActiveDocument.ExportAsFixedFormatAsync().then(function(result) {console.table(result);});}}}]}}});return wps;}window.onload = function() {$.ajax({url: appHost+"/api/wps/previewgenarate",contentType: "application/json",dataType: "json",data: JSON.stringify({fileId: 'a123',fileName: "test.docx",fileType: 1,userId: 1505340867}),type: "post",success: function(res) {var wpsUrl = res.url;console.log(wpsUrl);var wps = showWPS(wpsUrl);}});var fileInput = document.getElementById("bookimg1");//选择文件fileInput.addEventListener('change', function () {//如果未传入文件则中断if (fileInput.files[0] == undefined) {return;}var file = fileInput.files[0];//FileReader可直接将上传文件转化为二进制流var reader = new FileReader();reader.readAsDataURL(file);//转化二进制流,异步方法reader.onload = function (result) {//完成后this.result为二进制流var base64Str = this.result;$('#uploadImg').attr('src', base64Str);$('#imgPreview').show();} })};function replaceWps() {$('.tdname1').html($('#name1').val());$('.tddept1').html($('#dept1').val());$('.tdage1').html($('#age1').val());$('.tdname2').html($('#name2').val());$('.tddept2').html($('#dept2').val());$('.tdage2').html($('#age2').val());var fileBytes = "";var fileName = "";if ($('#bookimg1')[0].files[0] != undefined) {var imgFile = $('#bookimg1')[0].files[0];fileName = imgFile.name;//FileReader可直接将上传文件转化为二进制流var reader = new FileReader();reader.readAsDataURL(imgFile);//转化二进制流,异步方法reader.onload = function (result) {//完成后this.result为二进制流var base64Str = this.result;var startNum = base64Str.indexOf("base64,");startNum = startNum * 1 + 7;//去除前部格式信息(如果有需求)var baseStr = base64Str.slice(startNum);fileBytes = baseStr;$.ajax({url: appHost + "/api/wps/wrapheader",contentType: "application/json",dataType: "json",data: JSON.stringify({sample_list: [{bookmark: 'bookmark1',type: 'TEXT',text: $('#bookmark1').val()},{bookmark: 'bookmark2',type: 'TEXT',text: $('#bookmark2').val()},{bookmark: 'bookmark3',type: 'TEXT',text: $('#bookmark3').val()},{bookmark: 'bookimg1',type: 'IMAGE',/*sample_url:$('#bookimg1').val(),*/sample_filename: fileName,text: fileBytes,},{bookmark: 'bookform1',type: 'TEXT',text: $('#testForm').prop("outerHTML")}],}),type: "post",success: function (res) {var wpsUrl = res.url;;var wps = showWPS(wpsUrl);}});}} else {$.ajax({url: "http://10.4.146.19:8890/api/wps/wrapheader",contentType: "application/json",dataType: "json",data: JSON.stringify({sample_list: [{bookmark: 'bookmark1',type: 'TEXT',text: $('#bookmark1').val()},{bookmark: 'bookmark2',type: 'TEXT',text: $('#bookmark2').val()},{bookmark: 'bookmark3',type: 'TEXT',text: $('#bookmark3').val()},{bookmark: 'bookform1',type: 'TEXT',text: $('#testForm').prop("outerHTML")}],}),type: "post",success: function (res) {var wpsUrl = res.url;;var wps = showWPS(wpsUrl);}});}}</script></head><body><div style="width:100%;height:700px;"><div id="wpsPanl" style="width:65%;float:left;height:100%;"></div><div id="form" style="width:34%;float:left;height:100%;padding-top:50px;padding-left: 20px;"><div><div class="title">课题名称:</div><input class="input" type="text" id="bookmark1" placeholder="请填写课题名称"></div><dl style="clear:both;"></dl><div><div class="title">课题申报单位:</div><input class="input" type="text" id="bookmark2" placeholder="请填写课题申报单位"></div><dl style="clear:both;"></dl><div><div class="title">课题负责人:</div><input class="input" type="text" id="bookmark3" placeholder="请填写课题负责人"></div><dl style="clear:both;"></dl><div style="height:140px"><div class="title">课题成员:</div><table><thead><tr><td>姓名</td><td>所属部门</td><td>年龄</td></tr></thead><tr><td><input class="forminput" type="text" id="name1" placeholder="请填写姓名"></td><td><input class="forminput" type="text" id="dept1" placeholder="请填写所属部门"></td><td><input class="forminput" type="text" id="age1" placeholder="请填写年龄"></td></tr><tr><td><input class="forminput" type="text" id="name2" placeholder="请填写姓名"></td><td><input class="forminput" type="text" id="dept2" placeholder="请填写所属部门"></td><td><input class="forminput" type="text" id="age2" placeholder="请填写年龄"></td></tr></table><div style="width:100%;display:none;"><table border="1" cellspacing="0" style="width:90%;" id="testForm"><thead><tr><td>姓名</td><td>所属部门</td><td>年龄</td></tr></thead><tr><td class="tdname1"></td><td class="tddept1"></td><td class="tdage1"></td></tr><tr><td class="tdname2"></td><td class="tddept2"></td><td class="tdage2"></td></tr></table></div></div><dl style="clear:both;"></dl><div style="height:20px;margin:0;"><div class="title"></div><span style="color:red">表格替换在第6页</span></div><dl style="clear:both;"></dl><div><div class="title">图片上传:</div><input style="padding:8px 0;" type="file" id="bookimg1"></div><div style="display:none;" id="imgPreview"><img src="" id="uploadImg" width="100" /></div><dl style="clear:both;"></dl><div style="height:20px;margin:0;"><div class="title"></div><span style="color:red">图片替换在第7页</span></div><dl style="clear:both;"></dl><div style="text-align:center;"><input style="margin: 0 150px;height: 40px;background: rgba(2,128,204,1);border-radius: 2px;display: block;width: 80px;border: none;cursor: pointer;font-size: 14px;font-weight: 600;color: rgba(255,255,255,1);" type="button" value="替换" onclick="replaceWps()" id="submit"></div></div><div></body><style>#wpsPanl iframe{width:99%;height:850px;}#form div{margin: 10px 0;height: 40px;color: rgba(51,51,51,1);float: left;}#form div .input{height: 35px;margin: 2px 0;width: 358px;border: solid 1px rgba(193,193,193,.35);}#form div .forminput {height: 35px;margin: 2px 0;width: 94px;border: solid 1px rgba(193,193,193,.35);}#form div .title{width:120px;text-align: right;}td {border: 1px solid rgba(193,193,193,.35);padding: 8px 12px;}tr {background-color: inherit;font-size: 14px;border-top: 1px solid var(--vp-c-divider);transition: background-color .5s;}table {/*width: 100%;*/display: table;border-collapse: collapse;/*margin: 20px 0;*/overflow-x: auto;}table thead {font-weight: bold;}</style>
</html>
个人总结:需要在线编辑等相关操作,其实也可以用免费的组件组合,比如可以用onlyoffice+Aspose.Words去操作,仅个人见解。
相关文章:

WPS本地镜像化在线文档操作以及样例
一个客户项目有引进在线文档操作需求,让我这边做一个demo调研下,给我的对接文档里有相关方法的说明,照着对接即可。但在真正对接过程中还是踩过不少坑,这儿对之前的对接工作做个记录。 按照习惯先来一个效果: Demo下载…...

STM32 Flash学习(一)
STM32 FLASH简介 不同型号的STM32,其Flash容量也不同。 MiniSTM32开发板选择的STM32F103RCT6的FLASH容量为256K字节,属于大容量产品。 STM32的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等3部分组成。 主存储器,该部分…...
Spring中IOC容器常用的接口和具体的实现类
在Spring框架没有出现之前,在Java语言中,程序员们创建对象一般都是通过关键字new来完成,那时流行一句话“万物即可new,包括女朋友”。但是这种创建对象的方式维护成本很高,而且对于类之间的相互关联关系很不友好。鉴于…...

【MySQL】索引特性
🌠 作者:阿亮joy. 🎆专栏:《零基础入门MySQL》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录 👉没…...

【深度学习笔记】动量梯度下降法
本专栏是网易云课堂人工智能课程《神经网络与深度学习》的学习笔记,视频由网易云课堂与 deeplearning.ai 联合出品,主讲人是吴恩达 Andrew Ng 教授。感兴趣的网友可以观看网易云课堂的视频进行深入学习,视频的链接如下: 神经网络和…...

《TCP IP网络编程》第十二章
第 12 章 I/O 复用 12.1 基于 I/O 复用的服务器端 多进程服务端的缺点和解决方法: 为了构建并发服务器,只要有客户端连接请求就会创建新进程。这的确是实际操作中采用的一种方案,但并非十全十美,因为创建进程要付出很大的代价。…...

基于CNN卷积神经网络的调制信号识别算法matlab仿真
目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 1. 卷积神经网络(CNN) 2. 调制信号识别 3.实现过程 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 MATLAB2022A 3.部分核心程序 % 构建调制类型…...
正则,JS:this,同步异步,原型链笔记整理
一 正则表达式 正则表达式(regular expression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本 正则表达式可以用于以下常见操作: 匹配&…...
【NOIP】小鱼的数字游戏题解
author:&Carlton tag:递归,栈 topic:【NOIP】小鱼的数字游戏题解 language:C website:洛谷 date:2023年7月29日 目录 我的题解思路 优化 别人的优秀思路: 我的题解思路 题…...

算法的时间复杂度、空间复杂度如何比较?
目录 一、时间复杂度BigO 大O的渐进表示法: 例题一: 例题2: 例题3:冒泡排序的时间复杂度 例题4:二分查找的时间复杂度 书写对数的讲究: 例题5: 实例6: 利用时间复杂度解决编…...
We are the Lights 2023牛客暑期多校训练营4-L
登录—专业IT笔试面试备考平台_牛客网 题目大意:有n*m盏灯,q次操作,每次可以将一整行或一整列的等打开或关闭 1<n,m<1e6;1<q<1e6 思路:对于同一行或者同一列来说,只要最后一次操作时开或者关࿰…...
ant-design-vue中table组件使用customRender渲染v-html
ant-design-vue遇到table中列表数据需要高亮渲染 1、customRender可以使用,但是使用v-html发现不生效还报错 const columns [title: name,dataIndex: name,customRender: (val, row) > {return <span v-html{val}></span>} ]2、customeRender函数…...
若依框架实现后端防止用户重复点击
若依框架实现后端防止用户重复点击 基于自定义注解、切面、Redis实现 1. 添加自定义注解: 代码放置位置:com/ruoyi/common/annotation/RepeatClick.java time: 时间默认0; unit:单位默认 秒; key: 默认空字符串 package com.ruoyi.fra…...
PCA对手写数字数据集的降维
手写数字的数据集结构为(42000, 784),用KNN跑一次半小时,得到准确率在96.6%上下,用随机森林跑一次12秒,准确率在93.8%,虽然KNN效果好,但由于数据量太大,KNN计算太缓慢,所以我们不得不选用随机森林。我们使用了各种技术对手写数据集进行特征选择,最后使用嵌入 法Select…...

Python入门【变量的作用域(全局变量和局部变量)、参数的传递、浅拷贝和深拷贝、参数的几种类型 】(十一)
👏作者简介:大家好,我是爱敲代码的小王,CSDN博客博主,Python小白 📕系列专栏:python入门到实战、Python爬虫开发、Python办公自动化、Python数据分析、Python前后端开发 📧如果文章知识点有错误…...

下级平台级联安防视频汇聚融合EasyCVR平台,层级显示不正确是什么原因?
视频汇聚平台安防监控EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等…...
vue : 无法加载文件 C:\Users\jianfei\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本。...
背景 在新电脑上配置vue环境 PS E:\CODE_PROJ\myvue\vue23\P61_使用脚手架\vue_test> npm install -g vue/cli npm WARN deprecated source-map-url0.4.1: See https://github.com/lydell/source-map-url#deprecated npm WARN deprecated urix0.1.0: Please see https://git…...
godot引擎c++源码深度解析系列二
记录每次研究源码的突破,今天已经将打字练习的功能完成了一个基本模型,先来看下运行效果。 godot源码增加打字练习的demo 这个里面需要研究以下c的控件页面的开发和熟悉,毕竟好久没有使用c了,先来看以下代码吧。 //第一排 显示文本…...
专才or 通才
前言 不知道大家有没有这样的感觉,现在的工作专业化程度越来越高,而且是细分方向越来越小。IT领域分到你是计算里面的数据库或者了流式计算引擎,或者是协议存储还是KV存储引擎。 专业化的优势 专业化的程度带来了一个好处就是你在这个领域…...

【小白必看】Python爬虫实战之批量下载女神图片并保存到本地
文章目录 前言运行结果部分图片1. 引入所需库2. 发送请求获取网页内容3. 解析网页内容并提取图片地址和名称4. 下载并保存图片完整代码关键代码讲解 结束语 前言 爬取网络上的图片是一种常见的需求,它可以帮助我们批量下载大量图片并进行后续处理。本文将介绍如何使…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

Springboot社区养老保险系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
Python Einops库:深度学习中的张量操作革命
Einops(爱因斯坦操作库)就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库,用类似自然语言的表达式替代了晦涩的API调用,彻底改变了深度学习工程…...

逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
libfmt: 现代C++的格式化工具库介绍与酷炫功能
libfmt: 现代C的格式化工具库介绍与酷炫功能 libfmt 是一个开源的C格式化库,提供了高效、安全的文本格式化功能,是C20中引入的std::format的基础实现。它比传统的printf和iostream更安全、更灵活、性能更好。 基本介绍 主要特点 类型安全:…...
redis和redission的区别
Redis 和 Redisson 是两个密切相关但又本质不同的技术,它们扮演着完全不同的角色: Redis: 内存数据库/数据结构存储 本质: 它是一个开源的、高性能的、基于内存的 键值存储数据库。它也可以将数据持久化到磁盘。 核心功能: 提供丰…...