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

微信小程序手写签名

微信小程序手写签名组件

在这里插入图片描述
该组件基于signature_pad封装,signature_pad本身是web端的插件,此处将插件代码修改为小程序端可用。
signature_pad.js

/*!* Signature Pad v5.0.3 | https://github.com/szimek/signature_pad* (c) 2024 Szymon Nowak | Released under the MIT license*/
!(function (t, e) {"object" == typeof exports && "undefined" != typeof module? (module.exports = e()): "function" == typeof define && define.amd? define(e): ((t ="undefined" != typeof globalThis? globalThis: t || self).SignaturePad = e());
})(this, function () {"use strict";class t {constructor(t, e, i, n) {if (isNaN(t) || isNaN(e))throw new Error(`Point is invalid: (${t}, ${e})`);(this.x = +t),(this.y = +e),(this.pressure = i || 0),(this.time = n || Date.now());}distanceTo(t) {return Math.sqrt(Math.pow(this.x - t.x, 2) + Math.pow(this.y - t.y, 2));}equals(t) {return (this.x === t.x &&this.y === t.y &&this.pressure === t.pressure &&this.time === t.time);}velocityFrom(t) {return this.time !== t.time? this.distanceTo(t) / (this.time - t.time): 0;}}class e {static fromPoints(t, i) {const n = this.calculateControlPoints(t[0], t[1], t[2]).c2,s = this.calculateControlPoints(t[1], t[2], t[3]).c1;return new e(t[1], n, s, t[2], i.start, i.end);}static calculateControlPoints(e, i, n) {const s = e.x - i.x,o = e.y - i.y,r = i.x - n.x,h = i.y - n.y,a = (e.x + i.x) / 2,c = (e.y + i.y) / 2,d = (i.x + n.x) / 2,l = (i.y + n.y) / 2,u = Math.sqrt(s * s + o * o),v = Math.sqrt(r * r + h * h),_ = u + v == 0 ? 0 : v / (u + v),p = d + (a - d) * _,m = l + (c - l) * _,g = i.x - p,w = i.y - m;return { c1: new t(a + g, c + w), c2: new t(d + g, l + w) };}constructor(t, e, i, n, s, o) {(this.startPoint = t),(this.control2 = e),(this.control1 = i),(this.endPoint = n),(this.startWidth = s),(this.endWidth = o);}length() {let t,e,i = 0;for (let n = 0; n <= 10; n += 1) {const s = n / 10,o = this.point(s,this.startPoint.x,this.control1.x,this.control2.x,this.endPoint.x),r = this.point(s,this.startPoint.y,this.control1.y,this.control2.y,this.endPoint.y);if (n > 0) {const n = o - t,s = r - e;i += Math.sqrt(n * n + s * s);}(t = o), (e = r);}return i;}point(t, e, i, n, s) {return (e * (1 - t) * (1 - t) * (1 - t) +3 * i * (1 - t) * (1 - t) * t +3 * n * (1 - t) * t * t +s * t * t * t);}}class i {constructor() {try {this._et = new EventTarget();} catch (t) {this._et = document;}}dispatchEvent(t) {return this._et.dispatchEvent(t);}}class n extends i {constructor(t, e = {}) {var i, s, o;super(),(this.canvas = t),(this._drawingStroke = !1),(this._isEmpty = !0),(this._lastPoints = []),(this._data = []),(this._lastVelocity = 0),(this._lastWidth = 0),(this._handleMouseDown = (t) => {this._isLeftButtonPressed(t, !0) &&!this._drawingStroke &&this._strokeBegin(this._pointerEventToSignatureEvent(t));}),(this._handleMouseMove = (t) => {this._isLeftButtonPressed(t, !0) && this._drawingStroke? this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t)): this._strokeEnd(this._pointerEventToSignatureEvent(t), !1);}),(this._handleMouseUp = (t) => {this._isLeftButtonPressed(t) ||this._strokeEnd(this._pointerEventToSignatureEvent(t));}),(this._handleTouchStart = (t) => {1 !== t.touches.length ||this._drawingStroke ||(t.cancelable && t.preventDefault(),this._strokeBegin(this._touchEventToSignatureEvent(t)));}),(this._handleTouchMove = (t) => {1 === t.touches.length &&(t.cancelable && t.preventDefault(),this._drawingStroke? this._strokeMoveUpdate(this._touchEventToSignatureEvent(t)): this._strokeEnd(this._touchEventToSignatureEvent(t), !1));}),(this._handleTouchEnd = (t) => {0 === t.touches.length &&(t.cancelable && t.preventDefault(),this._strokeEnd(this._touchEventToSignatureEvent(t)));}),(this._handlePointerDown = (t) => {this._isLeftButtonPressed(t) &&!this._drawingStroke &&(t.preventDefault(),this._strokeBegin(this._pointerEventToSignatureEvent(t)));}),(this._handlePointerMove = (t) => {this._isLeftButtonPressed(t, !0) && this._drawingStroke? (t.preventDefault(),this._strokeMoveUpdate(this._pointerEventToSignatureEvent(t))): this._strokeEnd(this._pointerEventToSignatureEvent(t), !1);}),(this._handlePointerUp = (t) => {this._isLeftButtonPressed(t) ||(t.preventDefault(),this._strokeEnd(this._pointerEventToSignatureEvent(t)));}),(this.velocityFilterWeight = e.velocityFilterWeight || 0.7),(this.minWidth = e.minWidth || 0.5),(this.maxWidth = e.maxWidth || 2.5),(this.throttle = null !== (i = e.throttle) && void 0 !== i ? i : 16),(this.minDistance =null !== (s = e.minDistance) && void 0 !== s ? s : 5),(this.dotSize = e.dotSize || 0),(this.penColor = e.penColor || "black"),(this.backgroundColor = e.backgroundColor || "rgba(0,0,0,0)"),(this.compositeOperation = e.compositeOperation || "source-over"),(this.canvasContextOptions =null !== (o = e.canvasContextOptions) && void 0 !== o ? o : {}),(this._strokeMoveUpdate = this.throttle? (function (t, e = 250) {let i,n,s,o = 0,r = null;const h = () => {(o = Date.now()),(r = null),(i = t.apply(n, s)),r || ((n = null), (s = []));};return function (...a) {const c = Date.now(),d = e - (c - o);return ((n = this),(s = a),d <= 0 || d > e? (r && (clearTimeout(r), (r = null)),(o = c),(i = t.apply(n, s)),r || ((n = null), (s = []))): r || (r = setTimeout(h, d)),i);};})(n.prototype._strokeUpdate, this.throttle): n.prototype._strokeUpdate),(this._ctx = t.getContext("2d", this.canvasContextOptions)),this.clear();}clear() {const { _ctx: t, canvas: e } = this;(t.fillStyle = this.backgroundColor),t.clearRect(0, 0, e.width, e.height),t.fillRect(0, 0, e.width, e.height),(this._data = []),this._reset(this._getPointGroupOptions()),(this._isEmpty = !0);}fromDataURL(t, e = {}) {return new Promise((i, n) => {const s = new Image(),o = e.ratio || window.devicePixelRatio || 1,r = e.width || this.canvas.width / o,h = e.height || this.canvas.height / o,a = e.xOffset || 0,c = e.yOffset || 0;this._reset(this._getPointGroupOptions()),(s.onload = () => {this._ctx.drawImage(s, a, c, r, h), i();}),(s.onerror = (t) => {n(t);}),(s.crossOrigin = "anonymous"),(s.src = t),(this._isEmpty = !1);});}toDataURL(t = "image/png", e) {return ("number" != typeof e && (e = void 0), this.canvas.toDataURL(t, e));}isEmpty() {return this._isEmpty;}fromData(t, { clear: e = !0 } = {}) {e && this.clear(),this._fromData(t, this._drawCurve.bind(this), this._drawDot.bind(this)),(this._data = this._data.concat(t));}toData() {return this._data;}_isLeftButtonPressed(t, e) {return e ? 1 === t.buttons : !(1 & ~t.buttons);}_pointerEventToSignatureEvent(t) {return {event: t,type: t.type,x: t.x,y: t.y,pressure: "pressure" in t ? t.pressure : 0,};}_touchEventToSignatureEvent(t) {const e = t.changedTouches[0];return {event: t,type: t.type,x: e.x,y: e.y,pressure: e.force,};}_getPointGroupOptions(t) {return {penColor: t && "penColor" in t ? t.penColor : this.penColor,dotSize: t && "dotSize" in t ? t.dotSize : this.dotSize,minWidth: t && "minWidth" in t ? t.minWidth : this.minWidth,maxWidth: t && "maxWidth" in t ? t.maxWidth : this.maxWidth,velocityFilterWeight:t && "velocityFilterWeight" in t? t.velocityFilterWeight: this.velocityFilterWeight,compositeOperation:t && "compositeOperation" in t? t.compositeOperation: this.compositeOperation,};}_strokeBegin(event) {this._drawingStroke = !0;const i = this._getPointGroupOptions()const n = Object.assign(Object.assign({}, i), { points: [] })this._data.push(n);this._reset(i);this._strokeUpdate(event);}_strokeUpdate(t) {if (!this._drawingStroke) return;if (0 === this._data.length) return void this._strokeBegin(t);const e = this._createPoint(t.x, t.y, t.pressure),i = this._data[this._data.length - 1],n = i.points,s = n.length > 0 && n[n.length - 1],o = !!s && e.distanceTo(s) <= this.minDistance,r = this._getPointGroupOptions(i);if (!s || !s || !o) {const t = this._addPoint(e, r);s ? t && this._drawCurve(t, r) : this._drawDot(e, r),n.push({ time: e.time, x: e.x, y: e.y, pressure: e.pressure });}}_strokeEnd(t, e = !0) {this._drawingStroke &&(e && this._strokeUpdate(t),(this._drawingStroke = !1));}_reset(t) {(this._lastPoints = []),(this._lastVelocity = 0),(this._lastWidth = (t.minWidth + t.maxWidth) / 2),(this._ctx.fillStyle = t.penColor),(this._ctx.globalCompositeOperation = t.compositeOperation);}_createPoint(e, i, n) {return new t(e , i, n, new Date().getTime());}_addPoint(t, i) {const { _lastPoints: n } = this;if ((n.push(t), n.length > 2)) {3 === n.length && n.unshift(n[0]);const t = this._calculateCurveWidths(n[1], n[2], i),s = e.fromPoints(n, t);return n.shift(), s;}return null;}_calculateCurveWidths(t, e, i) {const n =i.velocityFilterWeight * e.velocityFrom(t) +(1 - i.velocityFilterWeight) * this._lastVelocity,s = this._strokeWidth(n, i),o = { end: s, start: this._lastWidth };return (this._lastVelocity = n), (this._lastWidth = s), o;}_strokeWidth(t, e) {return Math.max(e.maxWidth / (t + 1), e.minWidth);}_drawCurveSegment(t, e, i) {const n = this._ctx;n.moveTo(t, e), n.arc(t, e, i, 0, 2 * Math.PI, !1), (this._isEmpty = !1);}_drawCurve(t, e) {const i = this._ctx,n = t.endWidth - t.startWidth,s = 2 * Math.ceil(t.length());i.beginPath(), (i.fillStyle = e.penColor);for (let i = 0; i < s; i += 1) {const o = i / s,r = o * o,h = r * o,a = 1 - o,c = a * a,d = c * a;let l = d * t.startPoint.x;(l += 3 * c * o * t.control1.x),(l += 3 * a * r * t.control2.x),(l += h * t.endPoint.x);let u = d * t.startPoint.y;(u += 3 * c * o * t.control1.y),(u += 3 * a * r * t.control2.y),(u += h * t.endPoint.y);const v = Math.min(t.startWidth + h * n, e.maxWidth);this._drawCurveSegment(l, u, v);}i.closePath(), i.fill();}_drawDot(t, e) {const i = this._ctx,n = e.dotSize > 0 ? e.dotSize : (e.minWidth + e.maxWidth) / 2;i.beginPath(),this._drawCurveSegment(t.x, t.y, n),i.closePath(),(i.fillStyle = e.penColor),i.fill();}_fromData(e, i, n) {for (const s of e) {const { points: e } = s,o = this._getPointGroupOptions(s);if (e.length > 1)for (let n = 0; n < e.length; n += 1) {const s = e[n],r = new t(s.x, s.y, s.pressure, s.time);0 === n && this._reset(o);const h = this._addPoint(r, o);h && i(h, o);}else this._reset(o), n(e[0], o);}}}return n;
});
//# sourceMappingURL=signature_pad.umd.min.js.map

组件代码

这里封装展示的是横向签名,但其实画布是竖向,最后获取的是将画布旋转-90度的图片。
在这里插入图片描述
signature.wxml

<page-container show="{{show}}" position="right" bind:afterleave="pageLeave"><view hidden="{{!show}}" class="signature-wrap"><view class="actions-wrap"><view class="actions"><button type="default" class="sign-button" bindtap="tapUndo">撤销</button><button type="warn" class="sign-button" bindtap="tapClear">清除</button><button type="primary" class="sign-button" bindtap="tapConfirm">完成</button></view></view><canvastype="2d"id="signature"class="signature"style="width:{{width}}px; height:{{height}}px;"disable-scroll="{{true}}"bindtouchstart="handleTouchStart"bindtouchmove="handleTouchMove"bindtouchend="handleTouchEnd"></canvas><!-- 旋转图片canvas容器,不在页面上展示 --><view class="offscreen"><canvasid="targetSignature"type="2d"style="width:{{height}}px; height:{{width}}px;"/></view></view>
</page-container>

signature.js 这里需要注意,我的引用路径是'@/static/signature_pad',这种写法需要在app.json处配置resolveAlias自定义路径映射

import SignaturePad from '@/static/signature_pad'Component({/*** 组件的属性列表*/properties: {show: false},/*** 组件的初始数据*/data: {signature: null,width: 0,height: 0,dpr: 1},lifetimes: {ready() {const { windowWidth, windowHeight, pixelRatio } = wx.getWindowInfo()this.setData({width: windowWidth - 60, // 减去按钮区域height: windowHeight,dpr: Math.max(pixelRatio || 1, 2),}, () => {this.init()})}},/*** 组件的方法列表*/methods: {init() {this.createSelectorQuery().select('#signature').fields({ node: true, size: true }).exec((res) => {const { width, height, dpr } = this.dataconst canvas = res[0].nodeconst ctx = canvas.getContext('2d')canvas.width = width * dprcanvas.height = height * dprctx.scale(dpr, dpr)const signature = new SignaturePad(canvas, {ratio: dpr,minWidth: 1,maxWidth: 4,backgroundColor: '#fff'});this.setData({signature})})},handleTouchStart(e) {this.data.signature._handleTouchStart(e)},handleTouchMove(e) {this.data.signature._handleTouchMove(e)},handleTouchEnd(e) {this.data.signature._handleTouchEnd(e)},tapClear() {this.data.signature.clear()},tapUndo() {let data = this.data.signature.toData()if (data) {data.pop()this.data.signature.fromData(data)}},async tapConfirm() {let isEmpty = this.data.signature.isEmpty()if (isEmpty) {return wx.showToast({title: '未签名',icon: 'none'})}const base64Url = this.data.signature.toDataURL()const targetSign = await this.getRotateImage(base64Url)this.triggerEvent('confirm', targetSign)},// 获取旋转后的图片getRotateImage(url) {return new Promise((resolve, reject) => {const query = this.createSelectorQuery()query.select('#targetSignature').node(res => {let canvas = res.nodeconst { width, height } = this.dataconst ctx = canvas.getContext('2d')canvas.width = heightcanvas.height = widthctx.clearRect(0, 0, height, width)ctx.translate(0, width)ctx.rotate(-Math.PI / 2)const image = canvas.createImage()image.onload = () => {ctx.drawImage(image, 0, 0, width, height)// 如果只需要base64,只取这部分就可以const rotatedSign = canvas.toDataURL()ctx.clearRect(0, 0, height, width)resolve(rotatedSign)// 如果需要上传文件等相关处理,写到本地临时文件后做你自己的处理// wx.canvasToTempFilePath({//   canvas,//   success(res) {//     resolve(res.tempFilePath)//   }// })}image.src = url}).exec()})}}
})

signature.wxss

.signature-wrap {width: 100vw;height: 100vh;display: flex;z-index: 99;background-color: #fff;border-top: 2rpx solid #eee;
}
.actions-wrap {width: 60px;display: flex;justify-content: center;align-items: flex-end;padding-bottom: 320rpx;border-right: 2rpx solid #eee;
}
.actions {white-space: nowrap;transform: rotate(90deg);display: flex;
}
.actions .sign-button {width: 160rpx;margin-left: 20rpx;
}
.offscreen {position: fixed;left: 9999px;
}

调用组件

index.wxml

<view class="row"><view class="label">签名</view><view class="value" bind:tap="tapSignature"><image wx:if="{{signImg}}" class="sign-img" src="{{signImg}}" mode="heightFix" /><text wx:else class="input">请点击签名</text></view>
</view><!-- 签名组件 -->
<signature wx:if="{{showSign}}" show="{{showSign}}" bindconfirm="confirmSign" bindcancel="cancelSign"></signature>

index.wxss

	.row {display: flex;align-items: center;padding: 16rpx 30rpx;border-bottom: 2rpx solid #f2f2f2;
}
.row .label {flex-shrink: 0;
}
.row .value {flex: 1;display: flex;justify-content: flex-end;
}
.row .value .input {color: #999;
}
.row .value .sign-img {height: 80rpx;
}

index.json

{"usingComponents": {"signature": "/components/signature/signature"}
}

相关文章:

微信小程序手写签名

微信小程序手写签名组件 该组件基于signature_pad封装&#xff0c;signature_pad本身是web端的插件&#xff0c;此处将插件代码修改为小程序端可用。 signature_pad.js /*!* Signature Pad v5.0.3 | https://github.com/szimek/signature_pad* (c) 2024 Szymon Nowak | Releas…...

Javascript 使用中点查找矩形的角(Find Corners of Rectangle using mid points)

考虑一个矩形 ABCD&#xff0c;我们给出了边 AD 和 BC 中点&#xff08;分别为 p 和 q&#xff09;的坐标以及它们的长度 L&#xff08;AD BC L&#xff09;。现在给定参数&#xff0c;我们需要打印 4 个点 A、B、C 和 D 的坐标。 例子&#xff1a; 输入&#xff1a;p (1,…...

【困难】 猿人学web第一届 第18题 jsvmp 洞察先机

文章目录 数据接口分析还原加密参数插桩调试分析日志插桩补充 python 代码 数据接口分析 数据接口 https://match.yuanrenxue.cn/match/18data 请求参数 {page: 页码, t: 时间戳, v: 加密值} 请求第一页不需要携带 t, v 参数 cookie 只需要携带 sessionid 只要 还原加密字段…...

IDEA Maven 源修改为国内阿里云镜像的正确方式

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…...

OpenCV 旋转矩形边界

边界矩形是用最小面积绘制的&#xff0c;所以它也考虑了旋转。使用的函数是**cv.minAreaRect**()。 import cv2 import numpy as npimgcv2.imread(rD:\PythonProject\thunder.jpg) img1cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) print(img.dtype) ret,threshcv2.threshold(img1,1…...

人车防撞系统安全生产方案

根据《市场监管总局关于2021~2023年全国特种设备安全状况的通告》数据显示&#xff1a;2023年&#xff1a;全国共发生特种设备事故和相关事故71起&#xff0c;其中死亡69人。包含叉车在内的场(厂)内专用机动车辆事故29起、死亡28人&#xff0c;占事故总数的40.85%、死亡人数的4…...

开放式耳机哪个牌子好?长文传授6招秘籍,彻底远离坑货!

​大家好&#xff0c;作为一位专注于评测各类数码产品的博主&#xff0c;今天我特别推荐开放式耳机作为我们日常的首选。这种耳机以其独特的设计&#xff0c;避免了传统耳机长时间佩戴可能带来的不适和感染风险。开放式耳机佩戴简便且稳固&#xff0c;尤其适合热爱跑步和运动的…...

vue2和vue3双向绑定的原理

Vue.js 的双向绑定是 Vue 框架的核心特性之一&#xff0c;它允许数据和视图之间保持同步。虽然 Vue 2 和 Vue 3 都实现了双向绑定&#xff0c;但它们在实现细节上有所不同。 Vue 2 双向绑定的原理 在 Vue 2 中&#xff0c;双向绑定主要依赖于 Object.defineProperty 和观察者…...

别为大文件烦恼!mp4文件太大怎么变小?3个管用方法

你是否曾经遇到过mp4视频文件过大的困扰&#xff1f;每当想要分享或存储mp4文件时&#xff0c;巨大的文件就成了阻碍。明明感觉感觉没占用多少空间&#xff0c;但是设备却常常出现空间过满警告。 没多少空间的设备真是让人大为恼火&#xff0c;没人想多花一份钱买设备。那么只…...

cocotb的接收和发送逻辑,还是没有弄明白

发送有两种方式 1、定义这样的发 通过前缀连接DUT里面的信号 发送的时候&#xff0c;通过.去访问就可以 2、如果是AXI总线&#xff0c;可以直接调用cocotb的库文件 AXIS总线可以包含以下的信号 通过这个类&#xff0c;可以产生一个AXIS的一帧数据 类的实现大概如下 然后也…...

XXL-JOB调度中心与执行器

XXL-JOB是一个轻量级的分布式任务调度平台&#xff0c;主要由调度中心和执行器两部分组成。下面详细讲解调度中心与执行器的功能和作用。 调度中心 调度中心是XXL-JOB的核心组件&#xff0c;负责任务的调度管理。其主要功能包括&#xff1a; 任务管理&#xff1a;调度中心提供…...

Notepad++ 8.6.9 (代码编辑) 绿色版

Notepad编辑器是一款非常流行的编辑软件&#xff0c;对于技术白菜来说&#xff0c;有这么个神器真是方便多了&#xff0c;Notepad界面简洁明了&#xff0c;而且可以定制界面&#xff0c;又支持多国语言&#xff0c;是站长们的得力助手。免费、开源、绿色&#xff0c;对中文支持…...

【例003】利用MATLAB绘制有趣平面图形

题目&#xff1a; 用 ezplot 画出由方程 sin ⁡ ( x 2 m y 2 1000 ) cos ⁡ ( x y ) \sin(x^2\frac{my^2}{1000})\cos(xy) sin(x21000my2​)cos(xy) 确定隐函数的图形。 求解&#xff1a; 我们分别取m为100&#xff0c;1000,10000不同的值&#xff0c;绘制不同情况下的图…...

Ignis公链探索生态建设新范式:产业区块链与GameFi双轨驱动

Ignis公链凭借其独特的技术架构&#xff0c;选择了产业区块链与GameFi这两个赛道作为生态建设的双轮驱动&#xff0c;逐步形成了一个多元化的Web3生态系统。 一、产业区块链的革新&#xff1a;Vessel Chain的成功案例 在产业区块链领域&#xff0c;Ignis公链通过推出Vessel Ch…...

河南测绘资质申请中的技术装备需求

技术装备要求概览 购置与测绘业务相适应的技术设备&#xff1a;需要购置与测绘业务相适应的技术设备&#xff0c;如全站仪、水准仪、GNSS接收机等。 需要建立技术装备清单&#xff0c;并确保这些设备处于良好的工作状态。 技术装备的精度要求&#xff1a;GNSS接收机、全站仪…...

如何使用C# 读写西门子PLC

在C# WPF应用程序中,与西门子S7系列PLC进行通信是一个常见的需求,尤其是在工业自动化领域。以下是三种实现WPF上位机与西门子S7系列PLC通信同步的方式,每种方式都提供了代码实例、优缺点和使用场景。 1. 使用S7.Net库 代码示例: // 创建PLC连接 var plc = new S7.Net.Pl…...

反向沙箱-安全上网解决方案

随着信息化的发展&#xff0c;企业日常办公越来越依赖互联网。终端以及普通PC终端在访问互联网过程中&#xff0c;会遇到各种各样不容忽视的风险&#xff0c;例如员工主动故意的数据泄漏&#xff0c;后台应用程序偷偷向外部发信息&#xff0c;木马间谍软件的外联&#xff0c;以…...

尚品汇-延迟插件实现订单超时取消(四十五)

目录&#xff1a; &#xff08;1&#xff09;延迟插件封装 &#xff08;2&#xff09;基于延迟插件测试 如何保证消息幂等性&#xff1f; &#xff08;3&#xff09;改造订单service-order模块-实现订单超时取消 &#xff08;1&#xff09;延迟插件封装 把消息带过去&#…...

欺诈文本分类检测(十一):LLamaFactory多卡微调

1. 引言 前文训练时都做了一定的编码工作&#xff0c;其实有一些框架可以支持我们零代码微调&#xff0c;LLama-Factory就是其中一个。这是一个专门针对大语言模型的微调和训练平台&#xff0c;有如下特性&#xff1a; 支持常见的模型种类&#xff1a;LLaMA、Mixtral-MoE、Qw…...

SprinBoot+Vue健康管管理微信小程序的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue3.6 uniapp代码 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

docker 部署发现spring.profiles.active 问题

报错&#xff1a; org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

【生成模型】视频生成论文调研

工作清单 上游应用方向&#xff1a;控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...

HarmonyOS运动开发:如何用mpchart绘制运动配速图表

##鸿蒙核心技术##运动开发##Sensor Service Kit&#xff08;传感器服务&#xff09;# 前言 在运动类应用中&#xff0c;运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据&#xff0c;如配速、距离、卡路里消耗等&#xff0c;用户可以更清晰…...

C/C++ 中附加包含目录、附加库目录与附加依赖项详解

在 C/C 编程的编译和链接过程中&#xff0c;附加包含目录、附加库目录和附加依赖项是三个至关重要的设置&#xff0c;它们相互配合&#xff0c;确保程序能够正确引用外部资源并顺利构建。虽然在学习过程中&#xff0c;这些概念容易让人混淆&#xff0c;但深入理解它们的作用和联…...