征纳互动人数和在线监控v2
征纳互动人数和在线监控 v2
项目简介
征纳互动人数和在线监控 是一个油猴用户脚本(UserScript),用于实时监控 征纳互动平台 的等待人数和在线状态。当有纳税人等待时自动语音播报提醒,支持自定义常用语快速回复,帮助坐席人员及时响应。
核心特性
- 实时人数监控:每 3 秒自动检测等待人数,有人等待时语音播报提醒
- 掉线检测:自动检测平台掉线弹窗,及时语音告警
- 语音播报:基于 Web Speech API,支持一键开关,带语音队列管理避免播报冲突
- 常用语管理:从远程 YAML 配置文件加载常用语,数据源地址可在设置面板自定义,支持关键字搜索过滤,一键复制并填入 TinyMCE 编辑器;内置 2 小时本地缓存,相同数据源在有效期内打开抽屉不再重复请求
- 工作时间限定:仅在工作时间段(默认上午 9:00-12:00,下午 13:30-18:00,可在设置面板调整)内执行监控,非工作时间自动暂停
- 设备互联到电脑(图片→剪贴板):手机扫码或打开本机专属链接,选图(前端自动压缩)后图片经中继服务器转发到本机,点「复制到剪贴板」即可在征纳互动 Ctrl+V 粘贴;每台电脑有稳定独立的设备 ID,A、B 各自链接互不影响
- 操作日志:面板内嵌日志查看器,按类型(信息/警告/成功/错误)着色显示
- 提示音反馈:复制常用语时播放提示音,提供操作确认
项目结构
znhd-service/
├── public/
│ ├── commonPhrases.yaml # 常用语配置文件(YAML 格式,当前使用)
│ ├── 常用语.json # 常用语配置文件(JSON 格式,已废弃)
│ └── dida.mp3 # 操作提示音文件
├── ReadMe.md # 项目说明文档
├── relay-server/ # 设备互联配套中继服务(Node,需自行部署到公网)
│ ├── server.js # 中继服务器:手机上传页 + 长轮询取图(纯 Node 内置 http,零依赖)
│ └── package.json # 零依赖,运行:node server.js
└── znhd.user.js # 油猴脚本主文件
快速开始
1. 安装油猴扩展
在浏览器中安装 Tampermonkey 或 ScriptCat(脚本猫) 扩展。
2. 安装脚本
方式一:在线安装(推荐)
访问脚本主页 https://scriptcat.org/zh-CN/script-show-page/3650,点击"安装此脚本"按钮。
方式二:手动安装
- 打开
znhd.user.js文件,复制全部内容 - 点击油猴扩展图标 → 创建新脚本
- 粘贴内容并保存(Ctrl+S)
3. 开始使用
- 访问征纳互动平台:https://znhd.hunan.chinatax.gov.cn:8443/
- 脚本自动启动,右下角出现"征纳互动监控"浮动面板
- 面板显示当前版本号、语音播报开关、设置和常用语入口
功能详解
监控面板
脚本在页面右下角创建一个可拖拽的浮动面板,包含:
| 元素 | 说明 |
|---|---|
| 版本号 | 显示当前脚本版本(如 v26.7.18) |
| 🔊 语音 / 🔇 静音 | 一键切换语音播报状态,按钮颜色随状态变化(绿色=开启,红色=静音) |
| 设置 | 打开设置抽屉,可配置工作时间、常用语数据源地址,查看日志和脚本链接 |
| 常用语 | 打开常用语抽屉,加载并搜索常用语 |
人数监控与掉线检测
- 等待人数检测:通过 DOM 选择器
.count:nth-child(2)获取当前等待人数- 人数为 0:记录成功日志
- 人数 > 0:触发语音播报"征纳互动有人来了"
- 掉线检测:检测
.t-dialog__body__icon弹窗元素- 发现"掉线"文本时:记录错误日志并语音播报"征纳互动已掉线"
- 工作时间限定:非工作时间自动跳过检测,节省资源
语音播报
- 基于浏览器
SpeechSynthesisAPI,语言为zh-CN,语速1.0 - 内置语音队列:多条播报按顺序排队播放,避免同时播放导致冲突
- 静音状态下自动跳过播报,不清空队列
- 开启语音时自动初始化语音合成,解决浏览器
not-allowed限制
常用语功能
- 点击"常用语"按钮打开抽屉,自动从设置面板中配置的常用语数据源加载(默认
public/commonPhrases.yaml,可在「设置 → 常用语数据源」处修改地址) - 支持关键字搜索:可按按键名称或内容过滤常用语
- 点击常用语按钮后:
- 自动复制文本到剪贴板(优先使用
GM_setClipboard,降级到navigator.clipboard) - 播放提示音(
dida.mp3) - 将文本追加到页面 TinyMCE 编辑器中(自动处理换行和空输入框场景)
- 自动复制文本到剪贴板(优先使用
- 支持"重新加载"按钮手动刷新常用语数据(强制跳过缓存)
- 本地缓存:加载成功后缓存数据、数据源 URL 与时间戳;2 小时内再次打开抽屉(且数据源 URL 未变)直接复用缓存、不发网络请求,面板日志会提示「使用本地缓存」;修改数据源地址或点击"重新加载"会重新拉取
- 常用语数据源地址可在「设置 → 常用语数据源」中自定义:粘贴你自己的 YAML 地址即可让团队使用各自的常用语;修改后需点"重新加载常用语"生效,留空则恢复默认地址
日志系统
- 设置抽屉内嵌日志查看器,最多保留 20 条记录
- 日志按类型着色:
- 🔵 信息(info)
- 🟠 警告(warning)
- 🟢 成功(success)
- 🔴 错误(error)
- 自动过滤连续重复日志,避免刷屏
设备互联到电脑(图片→剪贴板)
适用场景:坐席在手机上有纳税人发来的图片(如身份证、资料截图),想快速发到电脑剪贴板,直接在征纳互动聊天框 Ctrl+V 粘贴。
工作流程:
- 每台电脑首次运行脚本时用
crypto.randomUUID()生成并持久化一个稳定设备 ID(存在GM_setValue,刷新/重开不变); - 面板「设备互联」抽屉展示本机专属上传链接
https://<中继服务器>/u/<设备ID>及对应二维码(二维码由脚本端 qrcodejs 本地生成,无需服务器参与); - 手机浏览器打开该链接(或直接扫二维码)→ 选图/拍照(支持多选,张数不限,九宫格预览、可单张删除)→ 手机端用 canvas 逐张自动压缩(最大边 1600px、JPEG 质量 0.75;SVG 例外:跳过压缩原样直传,保留矢量与
image/svg+xml类型)→ 逐张按序上传到中继服务器(服务端按设备维护 FIFO 队列,内存保护上限 100 条); - 电脑端脚本在「中继服务器」填好后默认自动用
GM_xmlhttpRequest长轮询/recv/<设备ID>取回图片(无需点击按钮;长轮询而非 WebSocket 是为了绕过征纳互动页面的 CSP 对 connect-src 的限制); - 收到图片后即在网页正中弹出九宫格画廊弹窗(3 列缩略图,收到的图片自动累积、最多保留 27 张,直接挂到
<html>,不受面板 transform 影响):单击缩略图用 Viewer.js 放大查看(缩放/旋转/多图左右切换),每张图下方「复制」按钮把图片写入系统剪贴板(此步必须由一次点击触发,满足浏览器安全策略)→ 去征纳互动 Ctrl+V 即可;「下载」按钮把原图存为文件(自动按原名/MIME 补扩展名);每张右上角 × 可单独移除,底部「清空全部」,弹窗右上角关闭(图片保留,收到新图会再次弹出)。
按用户隔离:设备 ID 是每台电脑随机生成、几乎不可猜测的 UUID,因此 A 的电脑、B 的电脑各自持有不同链接与二维码,图片只进对应那台电脑,互不串。
前置条件:须自行部署配套 relay-server(见上方项目结构)。在「设置 → 中继服务器」填写该服务的公网地址(如 https://你的服务器:端口,末尾不带 /)后,抽屉内的链接与二维码才会生成。
配置说明
脚本内部配置
znhd.user.js 中的 CONFIG 对象(只读的运行参数):
const CONFIG = {
CHECK_INTERVAL: 3000, // 监控检查间隔(毫秒)
MAX_LOG_ENTRIES: 20, // 面板最大日志条目数
didaUrl: '.../dida.mp3', // 提示音文件地址
SPEECH_TIMEOUT: 15000 // 单条语音播报超时保护(毫秒),防止队列卡死
};
可用户配置项(工作时间、常用语数据源、语音开关)存放在 DEFAULTS 中,运行时存于 localStorage(键 scriptCat_Allvalue),可在设置面板直接修改,无需改代码:
const DEFAULTS = {
voiceEnabled: true, // 语音播报开关
workingHours: { // 监控时间段(单位:十进制小时,13.5 = 13:30)
morningStart: 9, morningEnd: 12,
afternoonStart: 13.5, afternoonEnd: 18
},
commonPhrasesUrl: 'https://cdn.jsdelivr.net/gh/Run-os/znhd-service@refs/heads/main/public/commonPhrases.yaml',
relayServer: '' // 设备互联中继服务器公网地址(如 https://你的服务器:端口),留空则功能不可用
};
常用语配置
常用语配置文件为 public/commonPhrases.yaml,采用 YAML 格式。每个键为按钮显示名称,值为点击后填入编辑器的文本内容。
配置示例:
未办理税务登记: |
【未办理税务登记】
●打开 https://etax.hunan.chinatax.gov.cn:8443/xxbg/view/ztxxbg/qssbswzxblwkyqs ,自行打印清税证明
●如果上述方法无法正常打印,这边可以给您出具一个未涉税事项证明,需要您通过法人身份登录征纳互动,并将营业执照和法人身份证发送过来
已办理税务登记: |
【已办理税务登记】
●请先和您的税管员取得联系,税管员同意之后,进入电子税务局电脑端,搜索清税申报(税务注销办理)即可,详细操作流程:https://mp.weixin.qq.com/s/JqIEoAqo-BqWqSCrQYGuMQ
技术栈
| 技术 | 用途 |
|---|---|
| JavaScript (ES6+) | 脚本主语言 |
| 脚本猫UI库 | 浮动面板、抽屉、按钮等 UI 组件 |
| js-yaml | 解析 YAML 格式的常用语配置文件 |
| FingerprintJS | 浏览器指纹识别 |
| Web Speech API | 语音合成播报 |
| GM API | GM_xmlhttpRequest、GM_setClipboard、GM_notification、GM_getValue/GM_setValue 等油猴扩展 API |
| relay-server | 设备互联配套中继服务:纯 Node 内置 http(零依赖),手机上传页内联、电脑端长轮询取图;需部署到公网 |
浏览器兼容性
- Chrome / Edge 88+
- Firefox 85+
- Safari 14+
需要安装 Tampermonkey 或 ScriptCat 扩展以提供 GM API 支持。
常见问题
语音播报不工作
- 检查浏览器是否支持 Web Speech API(在控制台输入
'speechSynthesis' in window应返回true) - 确认面板上语音按钮显示为"🔊 语音"(绿色),而非"🔇 静音"(红色)
- 浏览器可能需要用户首次交互后才能播放语音,尝试点击页面任意位置后再试
常用语加载失败
- 检查网络是否能访问
github.com(常用语配置文件托管在 github) - 打开浏览器开发者工具(F12)→ Console 查看具体错误信息
- 尝试点击常用语抽屉中的"重新加载常用语"按钮
监控不工作
- 确认当前时间是否在工作时间内(上午 9:00-12:00,下午 13:30-18:00)
- 确认征纳互动平台页面已完全加载
- 打开设置抽屉查看日志面板,了解详细状态
设备互联功能用不了
- 确认已在「设置 → 中继服务器」填写公网可访问的服务器地址(如
https://你的服务器:端口,末尾不带/) - 中继服务器需自行部署:进入
relay-server/目录执行node server.js(纯 Node 内置模块、零依赖,默认端口 3000,可用PORT环境变量修改) - 该服务器必须能从手机浏览器公网访问;仅本机
localhost时手机无法连上 - 打开「设备互联」抽屉后,用手机扫二维码或打开链接上传;中继地址填好后脚本自动开始接收(无需点按钮),收到后弹窗点「复制到剪贴板」
- 中继服务更新后必须重启才会生效(它常驻后台进程,不会自动热更)。若改过
relay-server/server.js,请先停掉旧进程再node server.js(PM2/systemd/docker对应restart)。 - 同一设备 ID 在多个标签页/浏览器同时开着会各自接收:中继现已「广播」——每张图会同时推给所有在等待的接收端(你正在看的那个标签页一定会弹窗)。若只想在一个页面弹窗,关掉其余跑了脚本的标签页即可(例如调试用的 example.com)。
常用语点击后未填入编辑器
- 确认页面中存在 TinyMCE 编辑器(输入区域)
- 检查浏览器控制台是否有 iframe 跨域相关错误
- 脚本会自动降级处理:优先使用 TinyMCE API,失败后直接操作 DOM
更新日志
znhd.user.js v26.7.29-v11
- 支持 ESC 键关闭图片预览/文本弹窗:图片放大预览(Viewer.js)弹出后,Viewer.js 自带的键盘监听在本脚本「把
.viewer-container移入overlay」的特殊处理 + 真实税务页面 body 常被加 transform 的环境下常常失效,导致 ESC 关不掉预览。新增一个独立的全局keydown监听兜底:① 预览(Viewer)可见时按 ESC 先退出预览回到画廊九宫格;② 画廊态按 ESC 直接关闭整个图片弹窗;③ 文本弹窗按 ESC 直接关闭。监听仅安装一次(自保护),按当前弹窗状态分支处理,与 Viewer.js 自带 ESC 互不冲突(幂等)。@version→26.7.29-v11。
znhd.user.js v26.7.29-v10
- 修复收到图片弹窗「点缩略图放大后预览跑到弹窗后面 / 右上角关闭按钮消失」:
- 预览跑到弹窗后面:画廊
overlay(z-index:2147483647)与 Viewer 全屏预览容器(同样2147483647)互相压制——Viewer 默认挂在body下、画廊挂在documentElement下,谁压谁取决于页面的层叠上下文(真实税务页面 body 常被加 transform/filter 形成独立层叠上下文,把挂 body 的 Viewer 困住,永远被画廊压后面)。修复:用MutationObserver监听.viewer-container出现即移入画廊overlay内部,使其处于本弹窗的层叠上下文之上(vc.style.zIndex='2',高于白盒的1),预览必定盖在白盒之上、且不受外部页面层叠上下文干扰;全屏预览时由 Viewer 自带 × 关闭回到画廊(标准模态交互)。(注:Viewer.js 该构建无on/addListener事件 API,故不依赖事件,改用 DOM 观察。) - 关闭按钮"消失/点不到":① 全屏 Viewer 容器与画廊等 z-index 时会盖住画廊右上角的 ×——随预览移入 overlay 一并解决;并加安全网:监听 Viewer 显隐(
viewer-in类增删),隐藏后置pointer-events:none,确保残留容器不遮挡画廊关闭按钮/缩略图。② 预存布局 bug:box 是display:flex容器,标题作为 flex item 在层叠里等同z-index:0层,而关闭按钮是position:absolute(同属 z-index:auto 层),同层按 DOM 顺序——标题在关闭按钮之后 append,会画到关闭按钮之上并吃掉点击(视觉无重叠,但标题隐形盒子铺满整行)。给图片画廊与文本弹窗的关闭按钮都加z-index:2!important抬到正 z-index 层修复。浏览器实测:预览在顶层、关闭后关闭按钮可点中均通过。@version→26.7.29-v10。
- 预览跑到弹窗后面:画廊
znhd.user.js v26.7.29-v9
- 修复收到图片弹窗内缩略图/按钮被灰蒙蒙遮罩覆盖的问题:通过浏览器实测复现确认,弹窗自身 CSS 干净(白底、图片/按钮
opacity:1、filter:none、无伪元素遮罩)。灰蒙蒙来自宿主页面的某个 z-index 高于2147483640的半透明灰层(可能是翻译/深色模式/阅读模式类扩展,或税务站自身的高层级遮罩)盖到了弹窗内容上方。修复:将弹窗overlay的z-index提升到 CSS 最大值2147483647;给白盒box增加isolation:isolate、filter:none、backdrop-filter:none、z-index:1;并对grid/thumbWrap/img/ 所有按钮显式声明filter:none、backdrop-filter:none、opacity:1,最大限度隔绝外部滤镜与高级别遮罩的渗透。@version→26.7.29-v9。
znhd.user.js v26.7.29-v8
- 消除图片/文本预览弹窗的
FocusLock: focus-fighting detected告警:预览弹窗(renderImageGallery/showTextPopup,裸 DOM 挂documentElement)内的<button>(复制/下载/清空)是焦点可夺取元素。当脚本面板的 arco 抽屉(设置/常用语/手机传图)或税务页面自身的 arco 弹窗同时开着时,arco 的 focus-lock 焦点锁发现焦点跑到弹窗按钮上又拉不回,反复打架刷此告警。修复:弹窗挂载后对其内所有button设tabIndex=-1且mousedown时preventDefault()(阻止抢占焦点,鼠标点击onClick仍正常)。@version→26.7.29-v8。
znhd.user.js v26.7.29-v7
- 二次修复 CDN 开关(裸
input仍触发 React #137):上一版改用裸createElement('input')报错React error #137; got input——证实 CAT_UI 的 React 渲染器白名单连input也不支持(与img同类)。再次改为白名单内的div模拟勾选框:受控样式(useCdn为真时蓝底白勾、假时灰框),点击onClick调onChangeUseCdn(!useCdn)取反。@version→26.7.29-v7。
znhd.user.js v26.7.29-v6
- 修复设置抽屉崩溃(
CAT_UI.Switch is not a function):实测CAT_UI.Switch运行时为undefined(库清单误列,与TimePicker/Image同类陷阱),导致打开「设置」即报错。改用原生<input type="checkbox">(受控,配合onChange写回useCdn),视觉与交互不变。默认开启 CDN 的逻辑不受影响(loadAllvalue以{...DEFAULTS, ...parsed}合并,useCdn缺省由DEFAULTS.useCdn:true兜底)。@version→26.7.29-v6。
znhd.user.js v26.7.29-v5
- 新增「使用 CDN 加速」配置 +
resolveGithubUrl()转换函数:设置抽屉新增开关「使用 CDN 加速(jsDelivr)加载资源」(默认开启,存于Allvalue.useCdn)。新增模块级函数resolveGithubUrl(githubUrl):输入一个 GitHub 文件链接,开启 CDN 时输出https://cdn.jsdelivr.net/gh/用户名/仓库名@分支/文件路径,关闭时输出原始raw.githubusercontent.com链接;非 GitHub 链接(如 npm CDN)原样返回。分支含斜杠(如refs/heads/main)用单次捕获正则正确转换。已接入:①commonPhrasesUrl默认值改为 GitHub 网页链接、取用时经该函数解析(常用语抽屉「数据源」也显示解析后实际地址);②CONFIG.didaUrl改为 GitHub 链接、playDidaSound取用时解析。Viewer.js 的 npm CDN 链接不属 GitHub 资源,维持原样。@version→26.7.29-v5。
znhd.user.js v26.7.29-v4
- 「本机上传链接」区二维码与链接左右对调:用户要求二维码放在左侧。修正了上一版(v3)嵌套错误导致二维码与链接实际未左右并列的问题——现 flex 容器两个子节点严格左「二维码(
140×140px,带边框圆角)」、右「链接文本 + 复制链接按钮」;二维码未生成时左侧显示占位提示,抽屉窄时自动换行。@version→26.7.29-v4。
znhd.user.js v26.7.29-v3
- **「本机上传链接」区改为左历史*:原「链接 + 复制按钮」与二维码纯上下堆叠,现改为 flex 左右历史左侧显示链接文本与「历史」按钮,右侧显示二维码(
140×140px,带 1px 浅灰历史角);二维码尚未生成时右侧显示占位提示。抽屉较窄或移动端自动换行(flexWrap: 'wrap')。@version→26.7.29-v3。
znhd.user.js v26.7.29-v2
- 面板按钮重排 + 新增「查看待存文件」入口:面板按钮区改为两行——第一行「设置、常用语」,第二行「查看待存文件、设备互联」(「查看待存文件」在「设置」正下方、「设备互联」在「常用语」正下方)。点击「查看待存文件」随时打开已收到图片的画廊(复用
receivedImages+renderImageGallery,与收到新图时弹出的画廊一致,含复制/下载/清空;列表未清空前可反复查看,空列表时提示「暂无待存文件」)。@version→26.7.29-v2。
relay-server v26.7.29-v4
- 手机端收图弹窗视觉与脚本端完全一致:把
#recvPopup从「深色全屏遮罩+纯图片网格」改为脚本端同款白底圆角卡片——标题「收到的图片(N)· 单击放大」+ 红色 × 关闭 + 3 列缩略图(每张带「复制 / 下载」按钮 + 单张移除 ×)+ 底部「清空全部」;点击缩略图仍由 Viewer.js 接管放大/旋转/多图切换(遮罩压黑!important,zIndex:99999盖住卡片)。复制/下载走dataURL→Blob(ClipboardItem复制图片、<a download>保存),CDN 不可达时退回openRecvImage单图查看。relaypackage.jsonversion→26.7.29-v4。
znhd.user.js v26.7.29-v1
- 「发送到手机」选图改为先预览后发送(与手机端一致):原选完图片立即上传,现改为选图仅加入「待发送」预览列表(抽屉内 3 列缩略图网格,单张 × 移除、可继续添加),点「发送 N 张到手机」才真正逐张顺序上传;避免误选即发的冲动操作。发送逻辑与之前一致(逐张顺序、失败即停、进度日志)。
@version→26.7.29-v1。
relay-server v26.7.29-v3
- 手机端收图改用真·Viewer.js(与脚本端一致):
<head>通过https://cdn.jsdelivr.net/npm/viewerjs/dist/viewer.min.js+ 对应 CSS 引入 Viewer.js;画廊渲染后用new Viewer(recvGrid, {...})绑定,点击缩略图即弹出 Viewer.js 查看(缩放/旋转/翻转/多图左右切换),zIndex:99999确保弹窗盖在画廊遮罩之上;CDN 不可达时recvViewer=null,缩略图点击退回openRecvImage自定义单图查看兜底。relaypackage.jsonversion→26.7.29-v3。
relay-server v26.7.29-v1
- 手机端收图改为弹窗查看(真用 Viewer.js,与脚本端一致):原「电脑发送到手机」的图片收进页面底部内联九宫格,现改为收到即自动弹出画廊弹窗(固定全屏遮罩 + 3 列缩略图),点击缩略图用 Viewer.js(
https://cdn.jsdelivr.net/npm/viewerjs/dist/viewer.min.js)弹出放大/旋转/多图左右切换,与脚本端完全一致;CDN 不可达时退回openRecvImage自定义单图查看。点弹窗空白/× 关闭;关闭后底部保留「🖼 收到的图片(N)」按钮可重新打开。文本仍走独立弹层。 - 纯中继手机页改动;relay
package.jsonversion→26.7.29-v1;渲染后手机页脚本new Function语法校验通过。⚠️ 须重启node server.js(容器内docker restart znhd即生效,手机页由中继同源托管)。
v26.7.28-v3
- 画廊新增「下载」按钮:每张缩略图下方按钮区改为「复制 + 下载」两键并排,下载把原图 blob 存为文件(优先原始文件名,无扩展名时按 MIME 自动补
.jpg/.png/.svg等)。 - 「发送到手机」支持多选图片:文件选择器加
multiple,逐张顺序发送(一张成功再发下一张,日志显示进度n/总数,失败即停并提示已发张数)。需配合 relay v26.7.28-v5 的手机收件队列,否则连发会互相覆盖。
relay-server v26.7.28-v6
- 手机端"来自电脑"的图片改为九宫格画廊(与脚本端 Viewer.js 画廊对齐):原实现每收到一张图就弹一个独立全屏弹窗,多选连发时多个弹窗叠在一起、看不到九宫格。现改为把电脑发来的图片统一收进
#recvGrid九宫格(3 列缩略图、多张累积、带序号角标),点击缩略图才放大查看(全屏遮罩 +「长按保存」);文本仍弹独立弹层。已验证:渲染页内联脚本new Function()语法 OK、/\.svg$/i反斜杠未被模板字符串吞掉、recvGrid/renderRecvGrid/openRecvImage均就位。⚠️ 需重新部署,curl /health看到26.7.28-v6即生效。
relay-server v26.7.28-v5
- 修复 SVG 图片兼容问题:手机上传页原对所有图片走 canvas 压缩,SVG 常光栅化失败(无固有尺寸时画布为 0 / 部分 WebView 直接 onerror),导致无法预览也无法发送。现 SVG(按 MIME 或
.svg扩展名识别)跳过压缩原样直传,并强制修正 blob 类型为image/svg+xml——手机预览、电脑端画廊显示、放大查看均正常(注意:SVG「复制到剪贴板」受浏览器限制可能失败,可用「下载」按钮代替)。 - 删除手机端 9 张选图上限:
MAX_PICK移除,选图张数不限;服务端每设备暂存队列上限从 9 提高到 100(纯内存保护,正常收发不会触顶)。 - 电脑 → 手机收件通道队列化:
phonePending从单槽改为 FIFO 队列(同pending,上限 100、超出丢最旧记[丢弃]日志),支持电脑端多选图片连发不丢图。已端到端验证:连发 3 条按序取回、第 4 次返回empty;SVG mime 全链路透传无损。⚠️ 需重新部署,curl /health看到26.7.28-v5即生效。
v26.7.28-v2
- 修复:Viewer.js 放大图片时背景半透明——Viewer 默认遮罩为
rgba(0,0,0,0.5),放大时会透出后面的画廊弹窗("收到的图片 · 单击放大")。现注入覆盖样式把.viewer-backdrop/.viewer-container改为纯黑不透明,放大查看时完全遮住背景。
v26.7.28-v1
- 接收端图片改为九宫格画廊 + Viewer.js 放大:原来"每收一张弹一个单图弹窗、新图顶掉旧图",现在收到的图片累积进画廊弹窗,以 3 列九宫格缩略图展示(最多保留 27 张,超出丢最旧并释放内存)。
- 单击缩略图即用 Viewer.js 放大查看:支持滚轮缩放、旋转、翻转、1:1、多图左右切换(
@requirejsdelivr 的viewer.min.js,CSS 经@resource+GM_getResourceText注入,失败自动回退 CDN<link>;Viewer 未加载时缩略图和复制功能不受影响)。 - 每张缩略图下方独立「复制」按钮(保留点击手势写剪贴板),右上角 × 单独移除;底部「清空全部」;关闭弹窗不清空列表,收到新图会带着历史图片再次弹出。
- 新增授权:
GM_getResourceText。配合 relay v26.7.28-v4 的手机端 9 张多选上传食用最佳。
- 单击缩略图即用 Viewer.js 放大查看:支持滚轮缩放、旋转、翻转、1:1、多图左右切换(
relay-server v26.7.28-v4
- 手机上传页支持多选图片(最多 9 张):
<input>加multiple,选图后九宫格缩略图预览(可单张 × 删除、可分多次追加,合计上限 9 张);发送时逐张压缩上传并显示进度(发送中…(n/总数)),某张失败即停、剩余保留可点按钮重试。 - 中继服务端暂存改为 FIFO 队列:原
pending为每设备单槽,连发多张且电脑端未及时取走时会互相覆盖丢图。现改为每设备队列(上限 9 条,超出丢弃最旧并记[丢弃]日志),/recv长轮询每次投递队头一条,电脑端收到即自动再轮询取下一条——电脑端油猴脚本无需任何改动。 - 已本地端到端验证:连发 3 条按序取回、第 4 次取返回
empty、连发 10 条时最旧一条被正确丢弃;渲染后内联脚本new Function()语法校验通过。⚠️ 需重新部署中继服务,curl /health看到26.7.28-v4即生效。
v26.7.27-v1
- 版本号日期修正(跨天重置):上一轮「双向互传」功能实于 2026-07-27 完成,但
@version误写为26.7.26-v25(沿用了前一天日期)。按版本号约定——跨天须将日期部分改为当天、序号重置为 v1——现更正为26.7.27-v1。功能内容与v26.7.26-v25完全一致(电脑端↔手机端双向互传),无其它代码改动。⚠️ 仍须两端同步更新并重启node server.js。
v26.7.26-v25
- 新增「电脑端 → 手机端」发送(双向互传):脚本端现在也能把文本/图片发回手机。
- 中继服务器
server.js:新增反向通道内存表phoneOnline/phonePending/phoneWaiting与PHONE_TTL=20s;新增 4 条路由——POST /phone/heartbeat/<id>(手机报活)、GET /phone/status/<id>(返回{online},电脑端据此判断是否可发)、POST /phone/send/<id>(电脑发图/文,镜像/u)、GET /phone/recv/<id>(手机长轮询收件,镜像/recv)。
- 手机上传页(内联):打开即每 8s 心跳报活;长轮询
/phone/recv,收到图片自动弹出与脚本端一致的白底卡片画廊弹窗(标题「收到的图片(N)· 单击放大」+ 红色 × + 3 列缩略图,每张带「复制 / 下载」按钮 + 单张移除 ×,底部「清空全部」),点击缩略图用 Viewer.js 放大查看(缩放/旋转/多图切换,与脚本端一致)、CDN 不可达时退回自定义单图查看+「长按保存」;收到文本展示+「复制文本」;关闭弹窗后底部保留「收到的图片(N)」按钮可重新打开;顶部加在线状态指示。 - 电脑端
znhd.user.js:PhoneImageDrawer扩为「手机互传」抽屉——轮询/phone/status显示 🟢已连接/⚪无在线设备;文本输入框+发送按钮、图片选完先在下方的 3 列缩略图网格预览、点「发送 N 张到手机」才真正上传(与手机端上传页行为一致,单张 × 可移除、可继续添加);离线时发送按钮置灰并提示「当前无在线设备,无法发送」;发送成功/失败写面板日志。新增sendToPhone辅助(GM_xmlhttpRequest POST/phone/send)。 - 纯前端+中继改动;
@version→26.7.26-v25;两文件node -c通过。⚠️ 须两端同步更新并重启node server.js;手机页由中继同源托管,重启后即含心跳+收件箱。
v26.7.26-v24
- 文本弹窗固定最小尺寸:原先
box/textEl只设max-*无下限,文本很短时弹窗会缩得很小、观感差。现给box加min-width:360px;min-height:200px,给文本区textEl加min-width:320px;min-height:120px;文字多时仍按max-*正常放大不截断。 - 纯 UI 调整;
@version→26.7.26-v24;语法node -c通过。
v26.7.26-v23
- 移除弹窗右下角的版本号标记:图片预览窗与文本预览窗原本在右下角显示
znhd vX.Y.Z,因版本号已在脚本面板中统一展示,属多余信息,已删除(两处弹窗的ver元素及其appendChild一并移除)。 - 纯 UI 清理,无功能变化;
@version→26.7.26-v23;语法node -c通过。
v26.7.26-v22
- 新增「手机发送文本到电脑」功能(与发图并行):手机上传页新增文本输入框 + 「发送文本到电脑」按钮;中继服务器
/u/<id>的 POST 现同时支持{text}(文本)与{data,mime,name}(图片),并以type字段区分。 - 中继服务端:
pending条目统一带type(image/text);deliverToAll改为回传整条(含 type),由电脑端按类型分流,广播机制对文本同样生效(多标签同时接收互不丢)。 - 电脑端
znhd.user.js:startPhoneReceive的/recv轮询按data.type分流——image走onImage(弹图片预览窗),text走新增的onText(弹文本预览窗)。onText在弹窗前写一条成功日志(含前 40 字),并调用新增showTextPopup:网页正中弹窗展示文本 + 「复制到剪贴板」按钮(复用safeCopyText,含日志与提示音)+ 关闭按钮,点遮罩空白也可关闭。 - 版本标记右下角 →
v22,@version→26.7.26-v22;语法node -c两文件均通过。 - ⚠️ 两端需同步更新并重启中继服务器(
node server.js)才生效;手机页由中继同源托管,重启后即含文本框。
v26.7.26-v21
- 手机收到图片时写入面板日志:
onImage回调原先只弹出预览窗、不记日志,导致"脚本确实收到了图"在设置面板日志里看不到证据。 - 改动
znhd.user.js:onImage在showImagePopup之前新增addLog('[设备互联] 收到图片:' + 文件名 + '(' + MIME + ')', 'success'),日志进入设置面板「日志」区,onImage信息中明确文件名与类型。 - 版本标记右下角 →
v21,@version→26.7.26-v21;语法node -c通过。
v26.7.26-v7
- 加快大图复制:原
blobToPng对整张原图(手机常 4000px+)做全分辨率解码 + canvas + PNG 无损编码,大图点击「复制」后卡顿明显。 - 改为
prepareClipboardImage:写入前先降采样到最大边 1600px 再编码 PNG,像素数降至约 1/6,解码/内存/PNG 编码同步变快;已在限制内的小图不降采样。仅当「原图直写」失败(内核仅支持 image/png)时才走此预处理。 - 仍零客户端依赖;若追求极致速度,可在中继服务器用
sharp(libvips) 在上传时预处理,使电脑端收到即小图、无需任何客户端编码(需给 relay-server 加原生依赖,按需启用)。
v26.7.26-v6
- 修复「复制成功但剪贴板无图」假成功:根因是旧实现把
GM_setClipboard(blob, type)作为图片复制首选项——而 ScriptCat 的GM_setClipboard(data:string)仅支持文本,传 Blob 时不报错也不真正写图,导致resolve(true)误报成功。 - 改为:图片复制唯一可靠路径 = 页面主世界
unsafeWindow.navigator.clipboard.write(先拿原始 blob 直接写以保留点击手势,失败再统一转 PNG 重试);隔离世界同名 API 作兜底;彻底移除不可靠的GM_setClipboard图片分支。 - 弹窗「复制到剪贴板」按钮文案随真实结果变化(成功→绿色"已复制,去 Ctrl+V";失败→"复制失败,请长按图片保存")。
v26.7.26-v15
- 真正修复弹窗「透出文字」(浏览器实测坐实):在连着的真实 Chrome 里测量运行中的弹窗,发现遮罩
overlayComputedOpacity = 0.8(实测runningPopupVersionMarker = "znhd v26.7.26-v14"),即弹窗遮罩自身带opacity:0.8——黑底只盖 80%,故透出后面文字。关键 CSS 机制:opacity<1会把元素与其全部子元素(白框/图片/按钮)整体压成同透明度一起半透明,所以一透全透。 - 同时实测:遮罩
overlayRect = {0,0,1774,950}已铺满视口、bodyTransform=none、挂到<html>也正常——证明「body的 transform 改写 fixed 包含块」并非本例真因(旧推断被实测推翻)。 - 修复:给弹窗
overlay/box/ver/close/copyBtn全部内联加opacity:1!important(内联!important优先级最高,能压过任何旧副本或全局 CSS)。现场验证:在运行中的旧弹窗上注入opacity:1!important,计算透明度即时由0.8 → 1,证明修复有效。 - 教训:此前多版推断(半透明遮罩背景、
bodytransform、CAT_UI 污染、旧脚本未重载)均被实测数据逐一排除;最终靠"测量运行中弹窗的计算样式"而非"读代码猜"才定位。版本标记右下角同步改为v15。
v26.7.26-v16
- 遮罩改回半透明、但弹窗与图片保持不透明(标准模态效果):用户要求背景半透明(能隐约看到页面),但白色弹窗框与图片本身不透明。
- 关键 CSS 机制(v15 已确认):
opacity<1会令元素与其全部子元素一起半透明,故不能用overlay{opacity:0.55}实现。正确做法:overlay保持opacity:1!important,只让背景色用半透明rgba(0,0,0,0.55)!important——这样只有"背景那层黑"是透的,而box(白底#fff)/img(JPEG 不透明) 各有自己的不透明背景,互不影响,弹窗与图片完全不透明。 - 改动
znhd.user.js:overlay背景由 v15 的纯黑#000!important改回background:rgba(0,0,0,0.55)!important;overlay/box/ver/close/copyBtn的opacity:1!important全部保留。版本标记右下角 →v16,@version→26.7.26-v16;语法node -c通过。
v26.7.26-v20
- 修复"连上服务器"日志误报「连接服务器超时」:v19 用
/health即时探测触发onConnected,但用户运行的是旧版中继(无/health路由),该探测请求一直挂起、5 秒后超时报「连接服务器超时」;而真正的/recv接收始终正常,所以图片照收、markConnected仍通过/recv的onload触发了「已自动开始接收」——两条日志同秒出现即此矛盾。- 彻底删除
checkConnectivity()与/health探测(本身脆弱,依赖服务器有该端点)。 - 改用「首次
/recv长轮询用极短maxwait=1000」快速确认已连上:服务器很快返回空响应即markConnected→onConnected触发「已自动开始接收」日志(约 1 秒内),后续轮询恢复maxwait=25000实时等待图片。 - 真正的「连接服务器失败」仅在
/recv首次onerror(网络真不可达)时一次性提示,不再有矛盾的超时误报。
- 彻底删除
- 版本标记右下角 →
v20,@version→26.7.26-v20;语法node -c通过。
v26.7.26-v19
- 「已自动开始接收」日志时机再定为"连上服务器即立即显示"(推翻 v18):用户澄清——日志应在脚本连上服务器时立即出现,而非手机发送/收到图片之后。v18 的
onImage写法被撤销。startPhoneReceive新增/health即时连通性探测(checkConnectivity(),在poll()前调用):GM_xhrGET /health,一旦服务器响应就markConnected()触发onConnected→ 日志立即显示。此方案在 v20 被推翻(见下)。- 长轮询
onload内的markConnected()保留作兜底(connected标记去重,不会重复打日志)。 - 自动接收
useEffect把该addLog重新移回onConnected回调(与 v17 一致),地址末尾/一并归一replace(/\/+$/,'')。
- 中继服务器地址填写时自动去尾斜杠(请求 #3):设置输入框
onChange在校验前加url = url.trim().replace(/\/+$/, '')——用户粘贴http://x:5689/这类带/的地址会被即时处理为http://x:5689再保存/显示。startPhoneReceive与设备互联抽屉拼链接处本就归一,显示链接始终干净。 - 版本标记右下角 →
v19,@version→26.7.26-v19;语法node -c通过。
v26.7.26-v18
- 「已自动开始接收」日志时机再修正:v17 改为"连上服务器(首次轮询
onload)才显示",但长轮询即便未收到图片也会在maxwait后返回空响应,导致该日志仍会在脚本一启动轮询(约 25s 内)就打出,并非手机发送后。- 现改为:日志移到
onImage首次真正收到手机图片 时才addLog,即手机端点击发送之后才显示「[设备互联] 已自动开始接收(…)」。用firstImageLogged标记去重,避免后续每张图都刷该日志。 - 自动接收
useEffect删除onConnected用法(该回调改为不再用于此日志)。
- 现改为:日志移到
- 版本标记右下角 →
v18,@version→26.7.26-v18;语法node -c通过。
v26.7.26-v17
- 设置面板排版调整:删除「常用语数据源」「中继服务器(设备互联)」两个分隔标题(Divider);「常用语数据地址」与「中继服务器地址」两项内容直接并入「其他设置」分组之下(去掉各自标题、保留说明文字与输入框)。
- 「已自动开始接收」日志改为"连上服务器后才显示":原逻辑在
relayServer一填好就立刻addLog('[设备互联] 已自动开始接收…'),此时其实还没连通服务器,属误报。startPhoneReceive新增onConnected回调:长轮询首次onload(真正收到服务器响应)时markConnected()触发一次 → 仅此时才打「已自动开始接收」日志(含服务器地址)。- 顺带:连不上时(
onerror)打一次性「[设备互联] 连接服务器失败,请检查中继地址/网络(…)」错误日志(loggedConnFail去重,避免 2s 轮询刷爆),不再静默让用户误以为已连。 - 自动接收
useEffect把该addLog从「启动前」移入onConnected回调内。版本标记右下角 →v17,@version→26.7.26-v17;语法node -c通过。
v26.7.26-v14
- 弹窗加固(防御性,但非本 bug 真因,实测推翻):遮罩改挂到
document.documentElement(<html>而非<body>),以规避个别 SPA 在body施加transform/filter/will-change/contain改写position:fixed包含块、导致遮罩偏移的可能;并加!important+ 铺满100vw/vh双保险、右下角显版本标记、加自动诊断日志。 - ⚠️ 事后实测(v15)表明:本例真实页面
bodyTransform=none且遮罩已铺满视口,故 transform 偏移理论不成立;真因是遮罩自身opacity:0.8(见 v15)。v14 的documentElement挂载与!important仍保留作为防御层。
v26.7.26-v13
- 弹窗透字自动诊断:用户确认 ScriptCat 实际运行的是 v12(排除"旧版半透明遮罩"假设)。v12 遮罩
#000+!important+铺满100vw/vh且 CAT_UI 样式隔离,逻辑上不应透字,故"仍透字"只可能来自外部:①更高/同级半透明元素遮挡;②祖先transform把position:fixed限制住、遮罩未真正铺满视口。 - 新增弹窗出现即自动诊断:在 Console 打印
[znhd弹窗诊断]一行,含视口/遮罩尺寸、computed 背景色、document.elementsFromPoint中心点元素栈(顶→底),并据此 warn:遮罩非最顶层(有遮挡) / 背景非纯黑(被外部样式覆盖) / 遮罩未铺满视口(疑祖先 transform 限制)。用户重装后看一行日志即可定位。
v26.7.26-v12
- 排查"弹窗仍半透明":经核查 CAT_UI 库源码,其样式全部带
.ar.co-前缀且面板在 Shadow DOM 内,页面级无任何无前缀全局规则(adoptedStyleSheets0 次、document.head仅用于加载脚本),故面板半透明不会影响挂在document.body的弹窗。 - 弹窗仍透字的最大可能 = ScriptCat 实际跑的仍是旧版遮罩
rgba(0,0,0,0.55)(与面板半透明是两回事)。 - 加固:① 弹窗全部样式加
!important、遮罩铺满100vw/vh,隔绝任何外部 CSS 覆盖;② 弹窗右下角显示版本号znhd v26.7.26-v12,一眼确认加载版本,终结"改了却没生效"的扯皮。
v26.7.26-v11
- 加固弹窗遮罩必定铺满全屏:遮罩定位由
inset:0简写改为显式top/left/right/bottom:0,规避个别内核不识别inset导致遮罩未铺满、从而露出底层页面文字的可能;背景保持#000实心不透明。
v26.7.26-v10
- 图片弹窗遮罩改为完全不透明:原遮罩背景为
rgba(0,0,0,0.55)(半透明,会透出底层页面),现改为纯黑#000不透明,弹窗显示时不再透出后面页面内容。
v26.7.26-v8
- 修复「复制到剪贴板」点击后长时间等待:根因是 PNG 重编码(
createImageBitmap+canvas.toBlob)发生在点击时,卡在点击与「已复制」之间。改为图片到达弹窗显示时即在后台预转换好 PNG,点击直接写入、零转换、即时响应。同时移除「先尝试原图 jpeg」的浪费分支(ScriptCat 内核仅可靠支持image/png,该尝试必失败再转 PNG)。prepareClipboardImage对已是 PNG 的图直接复用、不再重编码。
v26.7.26-v7
- 大图复制提速(客户端降采样):
blobToPng改为prepareClipboardImage,在退回 PNG 时先按最大边 1600px 降采样再编码,解码内存/Canvas 分配/PNG 编码同步变快;小图不降采样。仅在「原图直写」失败(内核仅支持image/png)时触发。
v26.7.26-v6
- 修复图片复制「假成功」:旧代码把
GM_setClipboard(blob, type)放最优先,而 ScriptCat 该 API 仅支持文本,传 Blob 会静默无效且resolve(true)报成功、剪贴板却为空。改为唯一可靠路径 = 页面主世界unsafeWindow.navigator.clipboard.write(先试原始 blob 直写以保留点击手势,失败再转 PNG 重试),彻底移除假成功的GM_setClipboard图片分支。
v26.7.26-v5
- 图片复制再加固(依据异步 Clipboard API 文档):文档指出 Chromium 内核
navigator.clipboard.write对图片只可靠支持image/png,而中继转发的是手机原图(多为image/jpeg)。新增blobToPng()(用createImageBitmap+Canvas 转 PNG,best‑effort)在写入前统一转 PNG,规避该限制。各级兜底(GM_setClipboard / unsafeWindow 页面主世界 / 隔离世界)均改为写 PNG。
v26.7.26-v4
- 修复手机图片复制到剪贴板失败:原
copyImageToClipboard只走navigator.clipboard.write,而 ScriptCat 隔离世界里ClipboardItem全局常不存在 → 直接判定失败。改为三级兜底:①GM_setClipboard(blob,type)(扩展特权)②页面主世界unsafeWindow.navigator.clipboard.write+unsafeWindow.ClipboardItem(HTTPS 页面下必定可用,保留点击手势)③原隔离世界写法。 - 图片弹窗关闭按钮美化:右上角「×」改为红底白字圆形按钮(
#e4393c,hover 加深为#c9302c)。
v26.7.26-v3
- 「设备互联」改为默认自动接收:「设置 → 中继服务器」填好公网地址(默认
http://45.207.199.216:5689)后脚本即自动长轮询取图,移除「开始/停止接收」按钮,无需手动点击 - 收到图片时在网页正中弹出预览弹窗(直接挂到
document.body,不受 CAT_UI 面板 transform 影响):含底部「复制到剪贴板」按钮与右上角关闭按钮 @version按YY.M.D-vN规范递增为26.7.26-v3
v26.7.26-v2
- 「设备互联」二维码改为脚本端本地生成:引入客户端库 qrcodejs(
@require),抽屉内用new QRCode渲染后读取canvas.toDataURL()显示,二维码本地秒出、不再依赖服务器 - 中继服务器
relay-server移除/qr端点与qrcode依赖,现为纯 Node 内置 http、零依赖,仅保留手机上传页、/recv长轮询取图、/health @version按YY.M.D-vN规范递增为26.7.26-v2
v26.7.26-v1
- 新增「设备互联到电脑」功能:手机图片经中继服务器转发到本机剪贴板(在征纳互动聊天框 Ctrl+V 粘贴)
- 每台电脑生成稳定设备 ID(
GM_setValue持久化),拼出独立上传链接/u/<ID>与二维码,实现 A/B 按用户隔离 - 中继服务器
relay-server/server.js(纯 Node 内置模块 + qrcode):托管手机上传页(前端 canvas 压缩)、/recv/<ID>长轮询取图、/qr服务端生成二维码 - 电脑端用
GM_xmlhttpRequest长轮询取图(绕过税务页面 CSP 对 connect-src 的限制),收到后「复制到剪贴板」按钮触发navigator.clipboard.write写图片 - 设置面板新增「中继服务器」地址配置项;
@version按YY.M.D-vN规范递增为26.7.26-v1
v26.7.19-v2
- 语音队列增加长度上限(
CONFIG.MAX_SPEECH_QUEUE=10):连续产生大量播报时,超出部分丢弃最早(最旧)的消息,避免内存堆积 - 新增过期清理:队列消息超过
CONFIG.SPEECH_QUEUE_TTL=30s视为过期,speak()入队与processSpeechQueue()播放前均会剔除,避免播报过时内容 - 新增
clearSpeechQueue():语音开关从开启切换为关闭时立即清空队列(并speechSynthesis.cancel()中止当前播报),防止旧消息堆积、再次开启时集中涌出 - 队列元素结构调整:由直接存
SpeechSynthesisUtterance改为{ utterance, enqueuedAt },enqueuedAt用于过期判断;语法校验通过
v26.7.19-v1
- 为脚本内全部 32 个具名公开函数补全 JSDoc 注释:统一包含
@description用途说明、@param(含名称/类型/说明,可选参数用[name]语法)、@returns(类型与说明) - 覆盖范围:日志/存储管理、工具函数(时间/HTML 转义)、四个 UI 组件(LogPanel/SettingsDrawer/CommonPhrasesDrawer/DM)、面板位置跟踪模块、监控检测(checkCount/isWorkingHours 等)、语音播报(speak/processSpeechQueue)、复制与提示音(safeCopyText/playDidaSound)等
- 纯注释补充,不改变运行时行为;语法校验通过
v26.7.18-v4
- 常用语新增本地缓存策略:加载成功后缓存数据、数据源 URL 与时间戳
- 打开常用语抽屉时,若 2 小时内已加载且数据源 URL 未变,直接复用本地缓存、跳过网络请求(面板日志提示「使用本地缓存」)
- 「重新加载常用语」按钮改为强制刷新(忽略缓存);修改数据源地址也会触发重新拉取
v26.7.18-v3
- 常用语数据源地址现可在设置面板自定义(「设置 → 常用语数据源」),默认仍为 github 上的 commonPhrases.yaml
- 数据源支持留空回退默认地址,并校验必须以 http(s):// 开头
- 同期累积改进(v1→v3):面板位置拖拽持久化与边界约束、工作时间段可在设置面板配置、工作时间控件改为时间选择器、面板标题改用站点 favicon、确立
YY.M.D-vN版本号规范
v26.2.26
- 新增操作提示音功能(
dida.mp3),复制常用语时播放 - 新增安全复制机制:优先
GM_setClipboard,降级navigator.clipboard - 常用语新增关键字搜索过滤功能
- 优化 TinyMCE 文本追加逻辑:自动检测输入框是否为空,智能处理换行
- 语音播报新增队列管理,避免多条播报冲突
- 日志系统新增重复内容过滤
v26.2.23
- 删除 P2P 传输功能
- 删除图片复制功能
- 常用语数据源从 JSON 格式改为 YAML 格式
免责声明
本项目所有代码及脚本仅供学习、研究与个人非商业使用。
使用者需自行遵守所在网络环境及相关法律法规,严禁用于非法用途、商业用途或侵犯他人权益的场景。
使用本脚本所产生的一切风险、后果及法律责任均由使用者自行承担,项目作者不承担任何直接或间接责任。
如侵犯到您的权益,请联系项目维护者进行处理。
许可证
MIT License
联系方式
- 作者:runos
- 项目地址:https://github.com/runos/znhd-service
- 脚本主页:https://scriptcat.org/zh-CN/script-show-page/3650
- 使用教程:https://flowus.cn/runos/share/e48623a2-f273-4327-8597-639e08902be8?code=1YD5Z5
贡献
欢迎提交 Issue 和 Pull Request!