微信小程序手写签名

微信小程序手写签名组件

在这里插入图片描述
该组件基于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() {try {const { windowWidth, windowHeight, pixelRatio } = wx.getWindowInfo();this.setData({width: windowWidth - 60, // 减去按钮区域height: windowHeight,dpr: Math.max(pixelRatio || 1, 2),})} catch (e) { }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"}
}

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

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

相关文章

九盾叉车U型区域警示灯,高效照明和安全警示

叉车运作的环境比较复杂&#xff0c;在方便人们物流运输的同时也存在着很大的安全隐患&#xff0c;特别是叉车碰撞人的事故发生率很高&#xff0c;那我们该怎么在减少成本的同时又能避免碰撞事故的发生呢&#xff1f; 九盾叉车U型区域警示灯&#xff0c;仅需一盏灯安装在叉车尾…

十一 面向对象技术(考点篇)试题

A &#xff1b;D&#xff0c;D。实际答案&#xff1a;C&#xff1b;D&#xff0c;D 考的很偏了。UML 2.0基础结构的设计目标是定义一个元语言的核心 UML 2.0 【InfrastructureLibrary】,通过对此核心的复用&#xff0c;除了可以定义一个自展的UML元模型&#xff0c;也可以 Infr…

基于IP子网的VLAN典型配置举例(H3C,其他厂商同理)

基于IP子网的VLAN典型配置举例 1. 组网需求 如下图所示&#xff0c;办公区的主机属于不同的网段192.168.5.0/24和192.168.50.0/24&#xff0c;Device C在收到来自办公区主机的报文时&#xff0c;根据报文的源IP地址&#xff0c;使来自不同网段主机的报文分别在指定的VLAN中传…

7、Django Admin删除默认应用程序

admin文件 from django.contrib.auth.models import User, Groupadmin.site.unregister(User) admin.site.unregister(Group) 显示效果&#xff1a; 前 后

基于FreeRTOS的STM32多功能手表

前言 项目背景 项目演示 使用到的硬件 项目原理图 目前版本实现的功能 设计到的freertos知识 实现思路 代码讲解 初始化GPIO引脚、配置时钟 蜂鸣器初始化以及软件定时器创建 系统默认创建的defaultTaskHandle 创建七个Task&#xff0c;代表七个功能 ShowTimeTask …

2024.9自然语言及语言处理设计开发工程师专项培训通知!

为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署要求&#xff0c;深入实施人才强国战略和创新驱动发展战略&#xff0c;加强全国数字化人才队伍建设&#xff0c;持续推进人工智能从业人员…

Epoll 用法

Epoll 监听 EPOLL_CTL_DEL EPOLL_CTL_ADD epoll_event event event.events event.data.fd

双指针(3)_快慢指针_快乐数问题

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 双指针(3)_快慢指针_快乐数问题 收录于专栏【经典算法练习】 本专栏旨在分享学习C的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 1.…

Android Studio gradle下载太慢了!怎么办?(已解决)

Android Studio&#xff01;你到底干了什么&#xff1f;&#xff01; 不能高速下载gradle&#xff0c;我等如何进行app编程&#xff1f;&#xff01; 很简单&#xff0c;我修改gradle地址不就是了。 找到gradle-wrapper.properties文件 修改其中distributionUrl的地址。 将 ht…

ES配合高德地图JS-API实现地理位置查询

目录 实现功能点 技术选型 具体实现 Vue3整合高德地图JS API-2.0 添加商户&#xff1a;前端 添加商户&#xff1a;后端/ES 查询用户当前地理坐标 获取附近&#xff08;指定距离&#xff09;的商户 总结/测试Demo代码地址 测试概述&#xff1a;用户使用高德地图组件获取商户…

SpringBoot2:学SpringBoot前的知识准备-用IDEA创建传统的webapp工程,并整合SpringMVC

1、IDEA创建工程 基于Maven模板创建的SpringMVC工程 工程创建好后&#xff0c;只有webapp目录 这里&#xff0c;我们需要手动创建java目录和resources配置文件目录 创建好后&#xff0c;配置下目录属性 最终结构 至此&#xff0c;工程就创建好了 2、配置Tomcat 参考&am…

论文笔记:2023顶会SIGIR - Strategy-aware Bundle Recommender System

论文笔记&#xff1a;2023顶会SIGIR - Strategy-aware Bundle Recommender System

【Python报错已解决】`Provisional headers are shown Learn more`

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 文章目录 引言&#xff1a;一、问题描述&#xff1a;1.1 报错示例&#xff1a;1.2 报错分析&#xff1a;1.3 解决思路&#xff…

145. 利用 Redis Bitmap实践: 用户签到统计

文章目录 一、Redis Bitmap简介二、Bitmap 的主要应用三、Go使用Redis实现签到统计用户签到查询用户签到状态统计今年累计签到天数统计当月的签到情况 总结 在现代应用程序中&#xff0c;用户签到是一个常见的功能。我们通常使用 MySQL 数据库来存储用户的签到记录。然而&#…

智能家居系统(基于STM32F103C8T6标准库+FreeRTOS+Qt串口开发实现)

视频演示&#xff1a;基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目_哔哩哔哩_bilibili 基于STM32F103C8T6标准库FreeRTOSQt串口开发实现的智能家居项目: https://pan.baidu.com/s/1f41gAfOOnlcQoKoMx3o84A?pwd6j2g 提取码: 6j2g 注&#xff1a;本项目为学习完…

Windows I/O系统

硬件存储体系 寄存器 处理器内部定义的存储体&#xff0c;它们除了存储功能&#xff0c;往往还兼有其他的能力&#xff0c;比如参与运算&#xff0c;地址解析&#xff0c;指示处理器的状态&#xff0c;等等。寄存器是由处理器内部专门的触发器电路实现的&#xff0c;处理器往…

2024年高教杯国赛(B题)数学建模竞赛解题思路|完整代码论文集合

我是Tina表姐&#xff0c;毕业于中国人民大学&#xff0c;对数学建模的热爱让我在这一领域深耕多年。我的建模思路已经帮助了百余位学习者和参赛者在数学建模的道路上取得了显著的进步和成就。现在&#xff0c;我将这份宝贵的经验和知识凝练成一份全面的解题思路与代码论文集合…

基于物联网的低成本便携式传感器节点用于火灾和空气污染的检测与报警

目录 摘要 引言 材料和方法 传感器节点 IoT 微控制器 颗粒物传感器 环境和气体传感器 MQTT代理 Node-Red监控平台 系统结构 数据存储 工作描述 实验结果 讨论 结论 致谢 参考文献 这篇论文的标题是《Low-cost IoT-based Portable Sensor Node for Fire and Air…

数据要素大市场打开新局面——数字经济背景下中国特色的数据产权三权分置

前言 数字经济飞速发展的大背景下&#xff0c;无论是数据要素大市场还是数据资产入表的发展和落地&#xff0c;都需要以数据产权基本制度为保障。对数据产权给与恰当的权利定位&#xff0c;有助于让数据成为创造和捕获价值的新经济资源。数据的价值在于使用&#xff0c;而传统…

链表leetcode-1

目录 1.常用技巧 1.1引入虚拟头结点 1.2对于变量&#xff0c;不要太吝啬&#xff0c;可以多定义&#xff0c;方便处理 1.3快慢双指针 2.例题 2.1两数相加 2.2两两交换链表中的节点 2.3重排链表 2.4合并K个升序链表 2.5K个一组翻转链表 1.常用技巧 1.1引入虚拟头结点 可…