html打印合同模板

概述(吐槽):记录一个html打印合同模板的功能,技术栈有点杂,千禧年出产老系统的数据库是sqlserver2008,原系统框架是c#,无法二开,因为原系统的合同生成功能出现bug,没有供应商可以解决,因此只能重新开发合同生成的功能。现采用fastadmin后台连接sqlserver数据库(这里又有文章……)提供数据api接口,前端用的是uniapp框架做的h5项目,前端技术栈又很杂,主要用到了vue3+ts+js+uniui+z-paging,是的你没看错,ts和js同时用,就是这么杂……

下面重点讲述html定制打印功能,通过系统自带的打印PDF功能生成合同文件。

一、前端项目目录结构

项目结构如图,一个是list合同列表,detail合同详情表,以及最最核心的print.js

二、效果页面展示

图1是列表页,列表页用了z-paging组件,自带分页查询,强烈推荐~

图2是详情页,豆包写的,也还行~强烈推荐+1

打印预览效果如上图所示

三、代码

print.js

import {generateStandardContract} from './template3_7_no_ad.js'/*** 使用浏览器原生打印功能生成PDF* @param {Object} contractData 合同数据* @param {string} templateType 模板类型* @param {string} fileName 生成的PDF文件名*/
export const printToPdf = (contractData, templateType = 'default', fileName = '合同详情') => {console.log(contractData);// 保存当前滚动位置const scrollTop = window.scrollY;// 创建打印前的回调函数const beforePrint = () => {console.log('准备打印...');};// 创建打印后的回调函数const afterPrint = () => {window.scrollTo(0, scrollTop);console.log('打印完成');};// 检查浏览器是否支持beforeprint/afterprint事件if (window.matchMedia) {const mediaQueryList = window.matchMedia('print');mediaQueryList.addEventListener('change', (mql) => {if (mql.matches) {beforePrint();} else {afterPrint();}});} else {window.onbeforeprint = beforePrint;window.onafterprint = afterPrint;}// 生成合同HTMLconst contractHtml = generateStandardContract(contractData);// 创建临时打印窗口const printWindow = window.open('', '_blank');if (!printWindow) {console.error('无法打开新窗口,请检查浏览器设置(可能被阻止)');return;}// 获取当前页面的样式const styleElements = document.querySelectorAll('style, link[rel="stylesheet"]');let styleHtml = '';styleElements.forEach((element) => {if (element.tagName === 'STYLE') {styleHtml += element.outerHTML;} else if (element.tagName === 'LINK') {styleHtml += `<link rel="stylesheet" href="${element.href}">`;}});// 添加打印专用样式 - A4布局,移除页眉页脚const printStyle = `<style>@media print {/* 设置A4尺寸 */@page {size: A4;margin: 1.5cm; /* 调整页边距 */}body {margin: 0;font-family: "SimSun", "宋体";width: 210mm; /* A4宽度 */min-height: 297mm; /* A4高度 */}/* 隐藏所有不需要打印的元素 */.no-print, .navbar, .action-buttons, .loading-mask {display: none !important;}/* 确保表格不断页 */table, .detail-item {page-break-inside: avoid;}/* 表格样式 */table {border-collapse: collapse;width: 100%;}th, td {border: 1px solid #ddd;padding: 8px;}th {background-color: #f2f2f2;}/* 移除浏览器默认添加的页眉页脚 */@page {margin-top: 0;margin-bottom: 0;@top-left { content: none; }@top-center { content: none; }@top-right { content: none; }@bottom-left { content: none; }@bottom-center { content: none; }@bottom-right { content: none; }}}</style>`;// 生成页眉HTML(含图片)const headerHtml = `<div class="contract-header" style="text-align:center;height:75px;line-height:75px;"><img src="../../../static/header.png" alt="页眉图片" class="header-img" style="max-width:100%;max-height:65px;vertical-align:middle;"></div>`;// 生成页脚HTML(不含固定定位)const footerHtml = `<div class="contract-footer" style="text-align:center;height:50px;line-height:50px;"><img src="../../../static/footer.png" alt="页脚图片" class="footer-img" style="max-width:100%;max-height:40px;vertical-align:middle;"></div>`;// 构建打印页面内容printWindow.document.write(`<html><head><title>${fileName}</title>${styleHtml}${printStyle}</head><body>${headerHtml}${contractHtml}${footerHtml}<script>// 等待页面加载完成后打印window.onload = function() {window.print();// 打印后关闭窗口(可选)// setTimeout(function() { window.close(); }, 100);};</script></body></html>`);printWindow.document.close();
};

打印模板的js

 

/*** 生成标准合同模板(条款显示修复版)* @param {Object} contractData 合同数据* @param {boolean} [showStamp=true] 是否显示电子章,默认为true* @returns {string} 生成的HTML内容*/
const generateStandardContract = (contractData, showStamp = true) => {// 格式化日期const formatDate = (dateStr) => {if (!dateStr) return '';return new Date(dateStr).toLocaleDateString();};// 格式化金额const formatMoney = (amount) => {if (!amount) return '0.00';return parseFloat(amount).toFixed(2);};// 提取主要数据const mainData = contractData.main || {};const detailItems = contractData.datail || [];// 过滤展位和广告项目const boothDetails = detailItems.filter(item => item.OddTypName === '展位');const adDetails = detailItems.filter(item => item.OddTypName !== '展位');// 计算合计金额const totalAmount = detailItems.reduce((sum, item) => {return sum + parseFloat(item.OddTotalPrice || 0);}, 0);// 生成展位表格let boothTableHtml = '';if (boothDetails.length > 0) {boothTableHtml = `<h3 style="font-size:16px;margin:20px 0;padding-bottom:10px;border-bottom:1px solid #ddd;">展位信息</h3><table class="contract-table" style="width:100%;border-collapse:collapse;margin:15px 0;"><thead><tr><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">展馆</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">展位</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">面积</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">展位费(元)</th></tr></thead><tbody>${boothDetails.map(item => {// 从OddName中提取展馆和展位信息const boothInfo = item.OddName || '';const match = boothInfo.match(/展位:([\d-]+)-([\dA-Z]+)/);const srmName = match ? match[1] : '';const bthCode = match ? match[2] : '';// 从名称中提取面积信息const areaMatch = boothInfo.match(/\((\d+\.\d+|\d+)平方米\)/);const area = areaMatch ? areaMatch[1] : '';return `<tr><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${srmName}</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${bthCode}</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${area}平方米</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${formatMoney(item.OddTotalPrice)}</td></tr>`;}).join('')}</tbody></table>`;}// 生成广告表格let adTableHtml = '';if (adDetails.length > 0) {adTableHtml = `<h3 style="font-size:16px;margin:20px 0;padding-bottom:10px;border-bottom:1px solid #ddd;">广告信息</h3><table class="contract-table" style="width:100%;border-collapse:collapse;margin:15px 0;"><thead><tr><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">广告名称</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">规格</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">单价(元)</th><th style="border:1px solid #000;padding:8px 12px;text-align:center;background-color:#f0f0f0;font-weight:bold;">金额(元)</th></tr></thead><tbody>${adDetails.map(item => {// 从名称中提取规格信息const specMatch = item.OddName.match(/\((.*?)\)/);const scale = specMatch ? specMatch[1] : '';return `<tr><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${item.OddName}</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${scale}</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${formatMoney(item.OddPrice)}</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${formatMoney(item.OddTotalPrice)}</td></tr>`;}).join('')}<tr style="font-weight:bold;"><td colspan="3" style="border:1px solid #000;padding:8px 12px;text-align:right;">合计金额:</td><td style="border:1px solid #000;padding:8px 12px;text-align:center;">${formatMoney(totalAmount)}</td></tr></tbody></table>`;}// 生成甲方电子章 - 通过参数控制是否显示const firstPageStamp = showStamp ? `<div class="stamp-container first-page-stamp" style="position:absolute;right:30%;top:30%;width:250px;height:250px;z-index:-10;opacity:0.5%;"><img src="../../../static/stamp.png" alt="电子章" class="stamp-img" style="max-width:100%;max-height:100%;opacity:0.8;"></div>` : '';const signaturePageStamp = showStamp ? `<div class="stamp-container signature-page-stamp" style="position:absolute;right:0%;top:-50px;width:250px;height:250px;z-index:-10;"><img src="../../../static/stamp.png" alt="电子章" class="stamp-img" style="max-width:100%;max-height:100%;opacity:0.9;"></div>` : '';// 生成完整合同HTMLreturn `<div class="contract-container" style="position:relative;min-height:297mm;width:210mm;margin:0 auto;font-family:'SimSun','宋体';font-size:14px;line-height:1.6;margin-bottom:10%;"><!-- 内容容器,用于打印时调整内容位置 --><div class="content-container" style="margin-bottom:10%;"><h1 class="contract-title" style="text-align:center;font-size:22px;margin:30px 0;color:#333;">参展协议书</h1><p class="contract-party" style="margin:10px 0;">甲方:广东现代会展管理有限公司</p><p class="contract-party" style="margin:10px 0;">乙方:${mainData.OdrComName || ''}</p><p class="contract-intro" style="margin:20px 0;">乙方决定参加甲方2025年8月18日至21日举办的"第54届国际名家具(东莞)展览会暨2025东莞国际设计周",经甲乙双方友好协商,确认如下:</p>${boothTableHtml}${adTableHtml}<p class="contract-amount" style="margin:20px 0;font-weight:bold;text-align:right;">合同总金额:${formatMoney(totalAmount)}元</p><p class="contract-handbook" style="margin:20px 0;">《参展商手册》(附件一)中已详细列明各有关事项,乙方必须按《参展商手册》的有关规定进行装修、布展和展览等:</p>${generateContractClauses()}<div class="contract-remark" style="margin:30px 0;padding:15px;border:1px dashed #999;background-color:#f9f9f9;">${mainData.OdrRemark || ''}</div><div class="contract-signatures" style="margin-top:80px;padding-top:20px;border-top:1px dashed #999;display:flex;flex-wrap:wrap;gap:40px;position:relative;"><div class="contract-signature" style="flex:1;position:relative;min-width:200px;"><p class="signature-title" style="font-weight:bold;margin-bottom:10px;">甲方:广东现代会展管理有限公司</p>${signaturePageStamp}<p class="signature-blank" style="margin:20px 0;min-height:40px;border-bottom:1px solid #ccc;">(签署及盖章)</p><p class="signature-info" style="margin-bottom:5px;">联系地址:东莞市厚街家具大道</p><p class="signature-info" style="margin-bottom:5px;">联系人:</p><p class="signature-info" style="margin-bottom:5px;">电话:</p><p class="signature-info" style="margin-bottom:5px;">电子邮箱:</p><p class="signature-date" style="margin-top:20px;">日期:${formatDate(mainData.OdrCreateTime)}</p></div><div class="contract-signature" style="flex:1;position:relative;min-width:200px;"><p class="signature-title" style="font-weight:bold;margin-bottom:10px;">乙方:</p><p class="signature-blank" style="margin:20px 0;min-height:40px;border-bottom:1px solid #ccc;">(签署及盖章)</p><p class="signature-info" style="margin-bottom:5px;">联系地址:</p><p class="signature-info" style="margin-bottom:5px;">联系人:${mainData.OdrHandler || ''}</p><p class="signature-info" style="margin-bottom:5px;">电话:</p><p class="signature-info" style="margin-bottom:5px;">电子邮箱:</p><p class="signature-date" style="margin-top:20px;">日期:20__年_____月_____日</p></div></div></div>${firstPageStamp}</div>`;
};/*** 生成合同条款* @returns {string} 生成的HTML内容*/
const generateContractClauses = () => {const clauses = [{number: '1、',text: '协议签署后,在甲方不违约的情况下,如乙方要求取消展位,已交的展位费不予退还,乙方因此解除协议给甲方造成损失的,甲方有权要求乙方赔偿并保留追究其法律责任的权利。'},{number: '2、',text: '乙方在确认展位后,必须按甲方发出的《缴款通知书》所规定的时间如期付清有关款项,否则,展位不予保留,已缴款项不予退还。'},{number: '3、',text: '甲方保留在特殊条件下,经与乙方协商最终调整展位的权利;甲方如不能安排展位给乙方,甲方将退回乙方已交的展位费。'},{number: '4、',text: '经甲、乙双方确认的展位,乙方必须独立使用。未经甲方书面同意,乙方不得私下转让或部分转让展位。若有上述情况,甲方有权解除本协议并收回展位,所交费用不予退还,且甲方不承担展位受让方及乙方的一切经济损失(备注:甲方收取展台施工平面图、电路图、效果图或产品图片等的行为并不视为甲方默认或同意乙方的转让行为)。若以乙方之名义为其子/母公司、总/分公司、集团公司、关联公司等签署本协议书的,应在签署本协议前向甲方书面声明,否则,视为转让或部分转让展位。'},{number: '5、',text: '乙方保证展出展品拥有自主知识产权,若有合理理由怀疑乙方展品涉嫌侵权,甲方有权以停电、暂封展位,等等方式,要求乙方完全撤出涉嫌侵权产品直至撤出展位;甲方并保留追究乙方违约责任(以甲方的实际损失或2倍合同总金额之间,以价额高者为准)及损害甲方商业信誉的权利(商业信誉损失难以确定的,甲方有权根据该事件违法情节恶劣程度、对甲方商业信誉造成负面影响的范围及损害的程度等因素,在人民币 20 万元至 50 万元的幅度来主张),甲方为此而向第三方承担侵权等法律责任的,有权向乙方追偿全部损失以及支付的一切合理费用(包括但不限于律师费、差旅费、公证费、担保费、保全费、诉讼费、评估鉴定拍卖费、执行费等)。'},{number: '6、',text: '乙方保证展出展品符合国家质量部门相关的质量要求,否则,如有生产商、销售商、消费者等提出存在不符合质量要求并提供初步的证据材料的,甲方有权以停电、暂封展位,等等的方式,要求乙方完全撤出涉事产品直至撤出展位,甲方并保留追究乙方违约责任及损害甲方商业信誉的权利(违约责任及商业信誉损失的计算参照第5条)。'},{number: '7、',text: '为维护展会现场秩序,保障所有参展商的共同利益,严禁乙方在展会现场派人员列队巡游、派发资料或礼品、使用高音设备大声喧哗、举办各种形式的表演活动,否则甲方有权以停电、暂封展位,等等方式制止,情节严重的、或不听劝阻的,甲方有权解除本协议,并对乙方限时撤场,或由甲方自行撤场,甲方无需承担任何的违约责任。'},{number: '8、',text: '乙方需按《参展商手册》的相关规定设计、装修展位,于规定时间前提供展台施工平面图、电路图、效果图给甲方审核,严禁搭建二层,并按《参展商手册》规定缴纳相关费用。未经甲方审核通过的,乙方应在甲方指定的时间内进行整改并重新呈送甲方审核,否则甲方有权解除本协议,已缴款项不予退还。'},{number: '9、',text: '乙方最迟应在展览会开展前48小时,到展览会现场办公室报到,办理有关手续,缴纳清洁押金。否则,甲方有权将其展位另行处理,已支付的展位费用不予退还。'},{number: '10、',text: '遇不可抗力因素(包括但不限于自然灾害、战争、暴动、政府行为、疫情等),展览会需延期举办时,乙方确认之展位保持有效,具体举办时间甲方将另行通知。甲方变更展会举办日期后,以书面、微信、短信、等任何一种形式通知乙方,并同时在公众号及官网对外公告相关信息。'},{number: '11、',text: '乙方务必按照提供给组委会的产品图片摆展,一旦发现展品不符合要求作封展位处理,乙方并需向甲方支付总展位费的两倍金额作为违约金。'},{number: '12、',text: '乙方在布展、参展、撤展过程中发生的一切人身、财产损害以及因劳资纠纷、合同纠纷而产生的一切法律责任,均自行承担全部赔偿,甲方为此而向第三方承担法律责任的,有权向乙方追偿全部损失以及支付的一切合理费用(包括但不限于律师费、差旅费、公证费、担保费、保全费、诉讼费、评估鉴定拍卖费、执行费等)。'},{number: '13、',text: '在甲方有合理理由怀疑撤展方并非乙方的情况下,为保障乙方的财产安全,甲方有权要求乙方提供撤展申请及相关证明文件方可撤场,否则甲方有权拒绝任何相关方的撤展。'},{number: '14、',text: '乙方存在其他违约行为,可参照上述违约条款承担违约责任。'},{number: '15、',text: '本协议履行过程中产生争议的,应双方协商解决,协商不成的,提交甲方所在地人民法院解决。'},{number: '16、',text: '甲、乙双方因履行本协议而相互发出或者提供的所有通知、文件等文书材料,均以本协议所列明的联系地址、电话、电子邮箱通知和送达。一方迁址或者变更电话、电子邮箱的,应当书面通知对方,否则当一方发出的通知和送达被拒收、退回时,仍可视为有效送达。以当面交付文件方式送达的,交付之时视为送达;以电子邮件方式送达的,发出电子邮件时视为送达;以邮寄方式送达的,邮件交邮当日视为送达。'},{number: '17、',text: '附件或合同履行过程中双方签署的补充协议,与本协议具有同等法律效力,内容与本协议不一致的,除有特别约定,以最新形成之文件内容为准。'},{number: '18、',text: '本协议自双方签署之日起发生法律效力,本协议一式两份,双方各执一份。'}];return clauses.map((clause, index) => `<div class="contract-clause" style="margin:10px 0;padding-left:30px;text-indent:-30px;"><span class="clause-text" style="text-indent:0;">${clause.number}${clause.text}</span></div>`).join('');
};// 导出合同生成函数
export { generateStandardContract };

主要实现的功能点:

1、合同模板有七八个,先实现1个,就会有第二、三个,套就完了;

2、排版,这里是耗时最长的,豆包完成了80%,剩下来的只能自己手动调整;

3、关于分页打印的问题,这里我也没有解决,原来是想打印的每一页都能显示页眉页脚,类似word文档的页眉页脚,但是由于内容是动态生成,无法预知具体打印页数,分页控制不好做,求解决办法~

4、使用 CSS 的@page规则;

5、电子签章动态控制是否显示,传个参数控制就好了;

其它页面的代码没啥亮点就不展示了,基本都是豆包+套娃。

四、总结

作为老系统的补充,只能做到这样了~只要思路不滑坡,事情总有解决的办法!

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

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

相关文章

DeepCritic: SFT+RL两阶段训练突破LLM自我监督!显著提升大模型的自我批判能力!!

摘要&#xff1a;随着大型语言模型&#xff08;LLMs&#xff09;的迅速发展&#xff0c;对其输出进行准确反馈和可扩展监督成为一个迫切且关键的问题。利用LLMs作为批评模型以实现自动化监督是一个有前景的解决方案。在本研究中&#xff0c;我们专注于研究并提升LLMs在数学批评…

【深度学习】深度学习中的张量:从多维数组到智能计算单元

✅ 一、n维数组&#xff08;张量&#xff0c;Tensor&#xff09; 1. 定义 张量&#xff08;Tensor&#xff09;是一个通用的n维数组数据结构。 它的维度&#xff08;维数&#xff09;决定了它的形状&#xff0c;例如&#xff1a; 维度名称举例说明0维标量&#xff08;scalar…

以太网MDI信号PCB EMC设计要点

1. PHY侧和RJ45连接器侧通用MDI布局建议 1. MDI差分对保持对称走线&#xff0c;走线上的焊盘封装应一致&#xff0c;焊盘放置位置也应对称。可以减少EMI测试中的模式转换。   2. MDI走线应保持阻抗匹配&#xff0c;从而减少信号线上的反射。   3. MDI走线下需有连续完整的接…

深入浅出WebGL:在浏览器中解锁3D世界的魔法钥匙

WebGL&#xff1a;在浏览器中解锁3D世界的魔法钥匙 引言&#xff1a;网页的边界正在消失 在数字化浪潮的推动下&#xff0c;网页早已不再是静态信息的展示窗口。如今&#xff0c;我们可以在浏览器中体验逼真的3D游戏、交互式数据可视化、虚拟实验室&#xff0c;甚至沉浸式的V…

pysnmp模块中 GET、SET、WALK操作详细分步解析

1. SNMP GET 操作详解 1.1 核心代码结构 from pysnmp.hlapi import *# 定义参数 community public # SNMPv2c 社区名 target_ip 192.168.1.1 # 目标设备 IP oid 1.3.6.1.2.1.1.1.0 # 要查询的 OID# 发起 GET 请求 error_indication, error_status, error_index, …

接收rabbitmq消息

以下是一个使用纯Java&#xff08;非Spring Boot&#xff09;接收RabbitMQ消息的完整实现&#xff0c;包含Maven依赖和持续监听消息的循环&#xff1a; 1. 首先添加Maven依赖 (pom.xml) <dependencies><!-- RabbitMQ Java Client --><dependency><group…

SQL进阶之旅 Day 23:事务隔离级别与性能优化

【SQL进阶之旅 Day 23】事务隔离级别与性能优化 文章简述 在数据库系统中&#xff0c;事务是确保数据一致性和完整性的核心机制。随着业务复杂度的提升&#xff0c;如何合理设置事务隔离级别以平衡并发性能与数据一致性成为开发人员必须掌握的关键技能。本文深入解析事务隔离级…

六.原型模式

一.原型模式的定义 原型模式是一种创建型设计模式&#xff0c;通过复制现有对象&#xff08;原型&#xff09;生成新对象&#xff0c;避免重复初始化成本。需了解以下关键概念&#xff1a; ‌浅拷贝‌&#xff1a;复制基本类型字段&#xff0c;引用类型字段共享内存地址&#…

【笔记】LoRA 理论与实现|大模型轻量级微调

论文链接&#xff1a;LoRA: Low-Rank Adaptation of Large Language Models 官方实现&#xff1a;microsoft/LoRA 非官方实现&#xff1a;huggingface/peft、huggingface/diffusers 这篇文章要介绍的是一种大模型/扩散模型的微调方法&#xff0c;叫做低秩适应&#xff08;也就是…

Cilium动手实验室: 精通之旅---15.Isovalent Enterprise for Cilium: Network Policies

Cilium动手实验室: 精通之旅---15.Isovalent Enterprise for Cilium: Network Policies 1. 环境信息2. 测试环境部署3. 默认规则3.1 测试默认规则3.2 小测验 4. 网络策略可视化4.1 通过可视化创建策略4.2 小测试 5. 测试策略5.1 应用策略5.2 流量观测5.3 Hubble观测5.4 小测试 …

opencv RGB图像转灰度图

这段代码的作用是将一个 3通道的 RGB 图像&#xff08;CV_8UC3&#xff09;转换为灰度图像&#xff08;CV_8UC1&#xff09;&#xff0c;并使用 OpenCV 的 parallel_for_ 对图像处理进行并行加速。 &#x1f50d; 一、函数功能总结 if (CV_8UC3 img.type()) {// 创建灰度图 d…

React Hooks 的原理、常用函数及用途详解

1. ​​Hooks 是什么&#xff1f;​​ Hooks 是 React 16.8 引入的函数式组件特性&#xff0c;允许在不编写 class 的情况下使用 state 和其他 React 特性&#xff08;如生命周期、副作用等&#xff09;。​​本质是一类特殊函数​​&#xff0c;它们挂载到 React 的调度系统中…

学习路之PHP--webman协程学习

学习路之PHP--webman协程学习 一、准备二、配置三、启动四、使用 协程是一种比线程更轻量级的用户级并发机制&#xff0c;能够在进程中实现多任务调度。它通过手动控制挂起和恢复来实现协程间的切换&#xff0c;避免了进程上下文切换的开销 一、准备 PHP > 8.1 Workerman &g…

linux libusb使用libusb_claim_interface失败(-6,Resource busy)解决方案

linux libusb使用libusb_claim_interface失败&#xff08;-6&#xff0c;Resource busy&#xff09;解决方案 ✅ 问题原因&#x1f6e0;️ 解决方案&#x1f538; 方法一&#xff1a;分离内核驱动 libusb_detach_kernel_driver()&#x1f538; 方法二&#xff1a;使用 usb-devi…

使用mpu6500/6050, PID,互补滤波实现一个简单的飞行自稳控制系统

首先&#xff0c;参考ai给出的客机飞机的比较平稳的最大仰府&#xff0c;偏转&#xff0c;和防滚角度&#xff0c;如下&#xff1a; 客机的最大平稳仰俯&#xff08;Pitch&#xff09;、偏转&#xff08;Yaw&#xff09;和防滚&#xff08;Roll&#xff09;角度&#xff0c;通…

深度解析AD7685ARMZRL7:16位精密ADC在低功耗系统中的设计价值

产品概述 AD7685ARMZRL7是16位逐次逼近型&#xff08;SAR&#xff09;ADC&#xff0c;采用MSOP-10紧凑封装。其核心架构基于电荷再分配技术&#xff0c;支持2.3V至5.5V单电源供电&#xff0c;集成低噪声采样保持电路与内部转换时钟。器件采用伪差分输入结构&#xff08;IN/-&a…

EXCEL 实现“点击跳转到指定 Sheet”的方法

&#x1f4cc; WPS 表格技巧&#xff1a;如何实现点击单元格跳转到指定 Sheet 在使用 WPS 表格&#xff08;或 Excel&#xff09;时&#xff0c;我们经常会希望通过点击一个单元格&#xff0c;直接跳转到工作簿中的另一个工作表&#xff08;Sheet&#xff09;。这在制作目录页…

Python格式化:让数据输出更优雅

Python格式化&#xff1a;让数据输出更优雅 Python的格式化功能能让数据输出瞬间变得优雅又规范。不管是对齐文本、控制数字精度&#xff0c;还是动态填充内容&#xff0c;它都能轻松搞定。 一、基础格式化&#xff1a;从简单拼接开始 1. 百分号&#xff08;%&#xff09;格式…

2025年渗透测试面试题总结-小鹏[实习]安全工程师(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 小鹏[实习]安全工程师 1. 自我介绍 2. 有没有挖过src&#xff1f; 3. 平时web渗透怎么学的&#xff0c;有…

VSCode科技风主题设计详细指南

1. 科技风设计的核心特点 科技风设计是一种强调未来感、现代感和高科技感的设计风格,在VSCode主题设计中,可以通过以下几个核心特点来体现: 1.1 色彩特点 冷色调为主:蓝色、紫色、青色等冷色调是科技风设计的主要色彩高对比度:深色背景配合明亮的霓虹色,形成强烈的视觉…