RONGYAN IMAGE,Typecho博客日记,NAS技术,网站SEO优化
type: channel
link: https://rongyan.cc/
description: RONGYAN IMAGE,Typecho博客日记,NAS技术,网站SEO优化
items: 剪映字幕识别要花钱？我开发了FCPX字幕自动AI识别工具AiFcpxSrt
items: 从零到一：Linux 服务器安全加固 + 日报监控完整部署指南
items: WINRAR-30年的行为艺术，我们都欠它一个付款记录
items: 轻量级的 Typecho 垃圾评论拦截插件SpamBlocker
items: 服务器被植入流量劫持后门(跳转世界杯赌球网站)的排查与解决方案
items: 修改VisitorLoggerPro插件适配Joe主题前端访客统计独立页
items: Typecho 1.3+Php8.0可以使用的图片水印插件
items: 换了新服务器&彻底解决Typecho博客头像源显示问题
items: 开发了一套IT资产管理系统
items: 小米K70 PRO手机检测电池健康度及衰减情况

剪映字幕识别要花钱？我开发了FCPX字幕自动AI识别工具AiFcpxSrt
type: item
date: 2026-07-11T12:32:00+08:00
description: 为什么做这个工具？剪辑师都懂：给视频加字幕是一件耗时且枯燥的事。用 SRT 导入 FCPX？文字样式没法调，想改字体、大小、位置、颜色？抱歉，不行。一条条手动打字幕？几十条字幕输完，半天过去了。外包给语音转文字服务？音频文件要上传，隐私不保障，还要花钱。AiFcpxSrt 就是为解决这些问题做的。它能做什么把音频文件拖进去，点一下，字幕就出来了。不是简单的 SRT 文件，是原生 FCPX 字幕——导入后直接出现在时间线上，字体、大小、颜色、位置、效果，全部可以在 FCPX 里自由调整，和手动加的字幕一模一样。支持双语模式（中文 + 英文双行字幕），英文原生 FCPX 样式。核心流程音频 → Whisper 语音识别 → 文案对齐校正 → LLM 翻译 → 原生 FCPXML 字幕全程本地运行，不需要上传任何文件。Apple Silicon M 芯片 GPU 加速。开发历程（按时间）第一阶段：核心功能Whisper 语音识别 + Qwen LLM 纠错 pipeline原生 FCPXML 字幕导出（多行 title 元素）双语模式（CN lane 1 / EN lane 2）一键导入 FCPX第二阶段：交互优化双语预览/编辑（CN 可编辑，EN 灰色不可编辑状态）右击「重新翻译」单条字幕保存/打开会话进度（.aifcpxsession JSON 文件）HSplitView 布局，黑线分隔工具栏和内容区深色模式第三阶段：授权系统LicenseManager 单例状态机OnlineVerifier 服务端通信 + HMAC 验签设备指纹生成（DeviceFingerprint）LicenseView 输入界面激活成功弹窗确认第四阶段：稳定性修复指纹计算去掉 MAC 地址（解决网络接口顺序导致的指纹不稳定）指纹结果缓存到默认设置（解决算法变更导致的设备身份变化）启动状态同步判定（不再依赖异步 cache 校验，消除界面闪烁）后台校验不降级状态（只显示错误，不踢回授权页）第五阶段：产品化SVG/PNG 图标制作，替换为 Final Cut Pro 风格图标正式将软件名称定为「AiFcpxSrt」关于界面（开发链接、邮箱、版本信息、发行说明）构建脚本自动打包（build.sh）ffmpeg 捆绑第六阶段：真实进度 + LLM 翻译ASR 进度从假脉冲（线性 2%/2s）改为截获 mlx_whisper 内部 tqdm 的真实进度中+英双语的英文通道从双次 ASR 改为 LLM 翻译（Qwen 2.5）引入音频语言选择器（中文 / English），分离 ASR 语种和目标字幕语种"自动校正"按钮扩展为两步：校正（有文案时）→ 翻译（需翻译时）翻译在校正之后执行，保证英文翻译质量技术栈语言: Swift 6.2 (SwiftUI + Combine) + Python 3AI 模型: Whisper medium (MLX 4bit) + Qwen 2.5 1.5B (4bit)语音识别: mlx-whisper（Apple GPU 加速）LLM 翻译: Mlx-lm + Qwen 2.5（离线本地推理）加密: CryptoKit (AES-GCM, HMAC-SHA256)构建: Swift Package Manager + PyInstaller最低系统: 理论上MAC M1以上系统都能运行，不限版本架构: Apple Silicon (arm64)补充说明：站长的开发环境为MacBook Pro M4 16+512 2024 Sequoia 15.7.5 在此系统上测试了全流程通过，所以环境仅供参考。由于没有更多系统版本的机器、系统可供测试，拿到软件的，请自行测试。 Intel 版的Mac 机器就不要试了，跑不起来的，架构不一样。Final Cut Pro: 我测试了两个版本 11.2和 12.3，均导入通过。硬件要求Apple Silicon Mac（M1 / M2 / M3 / M4 /M5）macOS 11+(编译环境系统为15.7.5)建议 16GB 内存当前状态（2026-07-11）核心功能稳定，授权系统运行正常双语模式：中文 ASR + LLM 翻译为英文，英文音频同理反向构建系统完成：一次脚本生成两种 app（Dev / Release）待做：服务端解除设备绑定 API、在线校验周期性定时器持续优化：更详细的错误信息透传、用户体验打磨一点感受做这个工具的初衷其实很简单——我懒得一条条打字幕。又不想给剪映充钱，我就是想白嫖。但做着做着发现，很多剪辑师都在忍受同样的事情。FCPX 文件格式晦涩难懂，SRT 与 FCPX 之间存在巨大的功能鸿沟。本地的 AI 模型越来越强，跑在 M 芯片上又快又省电，为什么不利用起来？这么…

从零到一：Linux 服务器安全加固 + 日报监控完整部署指南
type: item
date: 2026-06-26T14:54:00+08:00
description: 一、前言我的服务器半个月前中过木马，具体见这篇文章： 服务器被植入流量劫持后门(跳转世界杯赌球网站)的排查与解决方案 后门连着海外的C2服务器，Docker里还藏着挖矿程序。清理干净之后我意识到一件事：没有防护的服务器，在互联网上就像没锁门的房子，是条狗都能进来撒泡尿。于是我试着弄了这么一个日报程序，这套每日汇报方案是经过我自己实操用了多台服务器布署后的实践总结，囊括了Ubuntu、CentOS、Debain等市面上主流Linux服务器系统，从系统加固、SSH安全、fail2ban防暴力破解，到每天自动发邮件汇报安全状况。从程序写出来到今天为止，三天了，经过不断优化、更迭，差不多能达到我理想中的状态了，所以我把它分享出来，希望能帮到同样在维护服务器的你。2026-07-22 更新说明macOS 客户端多服务器数据隔离 — 按 serverID 分目录缓存，切换服务器后不显示旧服务器数据打开配置目录 — 界面增加按钮，一键打开 ~/.config/server-report/ 目录服务器 IP 默认隐藏 — 列表 IP 以 *** 显示，👁 按钮可切换显示/隐藏Windows 客户端多服务器数据隔离 — 按 serverID 分目录缓存，切换服务器后不显示旧服务器数据服务器 IP 默认隐藏 — 列表 IP 以 *** 显示，👁 按钮可切换显示/隐藏2026-07-08 更新说明服务端新增 /api/v1/dates 接口 — 返回服务器所有存档日期列表，客户端据此按需同步缺失数据SSH 审计支持日期过滤 — `归档时按指定日期查询，不再显示实时数据fail2ban "本日封禁" — 实时报告和归档统一按日期过滤 IP 列表，只显示当日新增封禁数，不显示历史累计值封禁时间零"未知" — 同时提取 IP 和时间，消除封禁时间显示未知的问题实时报告日期策略 — 默认显示当日数据API 响应精简 — server 字段返回空字符串（服务器名称已由客户端侧边栏显示）macOS windows 客户端数据同步 — 同步对应服务器新增接口，对比本地日期，缺失的自动下载；开屏、刷新、切换服务器均触发同步标题居中 —实现日历按钮右侧覆盖，标题绝对居中日期格式 — 仅显示当前数据显示的日期时间戳标签 — 加 查询时间： 前缀界面精简 — 标题去掉服务器名称行和图标；左侧已有服务器信息，没必要多次显示运行时间本地化 — 直接中文显示如“15天1小时19分钟”，更直观网络超时 — 配置 30s 请求超时、60s 资源超时，不无限卡 loading防重入 — 客户端同步数据优化，自动跳过已有数据，避免数据错乱或闪烁列宽优化 —优化显示，解决封禁时间显示不全的问题邮件发送优化`改用新版数据采集 — 邮件发送不再使用旧版文本采集函数，容易导致卡死），改为调用新函数获取结构化数据，再格式化为邮件正文新增 构建邮件文本 — 从 JSON 报告生成邮件文本，按模块独立格式化函数，类型安全依赖变更客户端新增依赖：服务端 /api/v1/dates 接口（2026-07-08 后更新的服务端版本）中国 IP 市县细化依赖：ip-api.com（geoLookupDetail 接口），需服务器能访问外网2026-06-30 更新说明服务端增加api key功能，供客户端调用增加 Windows、macOS 客户端(付费)服务端改为定时采集 + 文件缓存策略，客户端查询毫秒级响应数据保留 180 天，每天自动清理超期数据服务端源代码、预编译二进制同步更新二、系统初始化2.1 更新系统刚买的服务器系统包可能比较旧，先更新到最新版本，避免因为旧版本的已知漏洞被入侵。# ------------------- Ubuntu / Debian 系统 ------------------- # apt 是 Ubuntu/Debian 的包管理器 # update = 更新软件源列表（检查有哪些新版本可用） # upgrade -y = 升级所有已安装的软件包（-y 表示自动确认，不弹询问） apt update && apt upgrade -y # ------------------- CentOS 系统 ------------------- # yum 是 CentOS 的包管理器，update 同时更新源和升级包 yum update -y2.2 安装基础工具安装一些后续操作会用到的常用命令行工具。工具作用curl用来下载文件、调用 API、测试网络请求wget下载文件（和 curl 类似，但更专注于文件下载）git用来克隆代码仓库（如果需要从 GitHub 下载源码时用到）vim一个命令行文本编辑器（编辑配置文件用）# ------------------- Ubunt…

WINRAR-30年的行为艺术，我们都欠它一个付款记录
type: item
date: 2026-06-21T09:24:00+08:00
description: WinRAR 收到一笔付款就全网狂欢，这出戏演了 30 年还没停2026 年 6 月 18 日，WinRAR 的官方 X 账号突然发了一条帖子，语气兴奋得像中了彩票："We got paid... AGAIN! We'll try not to let all this cash go to our heads! 🤑🤑🤑👑💎"（"我们又收到钱了！我们会努力不让这些现金冲昏头脑！"）短短几天，这条帖子就收获了 15 万点赞、347 万次浏览 和 904 条评论。但真正让这条帖子爆火的，不是帖子本身，而是背后那件事的荒诞感——一个软件收到了一笔付款，官方像中了彩票一样公开庆祝。如果你用过电脑，你大概知道为什么。全世界最著名的"40 天试用"WinRAR 的许可证页面上白纸黑字写着："The software is distributed as try before you buy. This means that anyone may use the software during a test period of a maximum of 40 days at no charge."（"本软件以先试后买的方式分发。任何人可在最长 40 天的试用期内免费使用。"）听起来很正常，但所有用过 WinRAR 的人都知道一个公开的秘密：40 天到期之后，软件照常运行，一个功能都不锁。它只做一件事——弹出一个窗口，礼貌地提醒你："嘿，试用期过了，要不要买个许可证？"你点"关闭"，继续用。明天打开，再弹。你再关，再用。就这样，一弹就是十年、二十年、三十年。WinRAR 1995 年诞生，到 2026 年已经 31 岁了。这个弹窗陪着无数人从学生时代走到了职场，成为数字世界里最持久的"温柔催款"。维基百科对这种模式有精确的描述：非企业用户的功能始终可用（"the non-enterprise functionalities remain available"）。翻译过来就是——官方明知道你不会付钱，但选择不卡你。所以当真的有人掏钱买了许可证，WinRAR 官方的反应就像见到了独角兽。两周之内，"又"收到钱了这次帖子里的"AGAIN"大有来头。就在两周前，6 月 4 日，一个用户发帖 @ 了 WinRAR 官方，配文："I PAID MY DEBT"（我还债了）。官方立刻发帖庆祝："Yay! We finally got paid! 🤑🤑🤑😎😍🥳🤣"（"耶！我们终于收到钱了！"）那条帖子也拿了 7.1 万赞。然后仅仅 14 天后，又一个用户 @ParenteRamon 晒出了自己的 WinRAR 付款截图，官方再次"狂喜"——这次直接冲到 14.5 万赞，翻了一倍。两周内两次"收到钱了"，对于 WinRAR 来说可能已经算是史无前例的"营收爆发期"了。一个玩了三年以上的固定节目翻一下 WinRAR 官方的历史帖子，你会发现这个"庆祝有人付费"的套路至少从 2023 年就开始了。2023 年 6 月 6 日，官方发帖："To all of you who have paid for a license... Cheers to you! #IBoughtWinRAR"（"致所有为许可证付费的用户……为你们干杯！"）从 2023 年的"为你们干杯"，到 2026 年的"我们又收到钱了！"——官方的语气越来越放飞，emoji 越来越密集，自嘲越来越纯熟。三年下来，这个"梗"已经进化成了一套成熟的品牌运营策略。而且它真的在驱动销售。评论区：大型集体忏悔现场主帖下面的评论区，简直就是互联网内疚大会。有人终于来"赎罪"了："Hey! I bought it too! (after like 25 years... but I bought it!!)"（"嘿！我也买了！用了大概 25 年之后……但我买了！！"）官方回复："Better late than never!"（迟到总比不到好！）有人做出了人生规划："Ever since I was a child, I've dreamt that the first thing I'll do when I get rich is buy a WinRAR license."（"从小我就梦想，等我发财了，第一件事就是买一份 WinRAR 许可证。"）有人试图打听商业机密："How is this business strategy called?"官方只回了一个词："Genius"（天才）。还有人直接开始忏悔，求付款链接："WinRAR, I'm sorry. My 40-day trial turns 22 this year... DM me the payment link and I'll pay up…

轻量级的 Typecho 垃圾评论拦截插件SpamBlocker
type: item
date: 2026-06-16T08:01:00+08:00
description: 这是一个轻量级的 Typecho 插件，通过邮箱、域名、关键词黑名单自动拦截垃圾评论。开发此插件的由来 写这个插件是有原因的，连续两天，一直有个鸟人来我博客发留言（最新两篇文章）,他的主要目的其实是发他的算命网站链接。我后台删了他的留言他第二天又来发了。首先不能用禁IP的方式，因为我发现他IP是广西联通（一般都是家庭宽带，这个IP只是他临时的，封了也没用，而且还可能会造成整个广西联通的网都来不了）。一般他会发两条留言，一篇文章一条，留的QQ邮箱都是一样5652xx5524@qq.com，但是在两篇文章中的留言名字改了，配套的网址也不一样，一个叫做免费算命，留的网址是https://www.resoxxxg.cn/，一个叫做姓名测试打分，留的网址是https://www.tiatixxxxxiao.com/。于是针对这个垃圾玩艺，这套插件应运而生。功能环境要求 — 在 Typecho 1.3 上测试通过，其他版本请自行测试邮箱拦截 — 支持部分匹配，如 qq.com 可拦截所有 QQ 邮箱域名拦截 — 拦截评论者填写的网站域名关键词拦截 — 拦截昵称或正文中的关键词两种拦截方式：直接拦截 — 匹配规则时拒绝评论，前台提示错误标记为垃圾 — 匹配规则时标记为 spam 状态，前台不报错也不显示，后台可审查安装将 SpamBlocker 文件夹上传至 /usr/plugins/登录 Typecho 后台，进入 控制台 → 插件找到 SpamBlocker，点击 启用点击 设置，填写拦截规则使用方法在插件设置页面填入需要拦截的内容，每行一条：# 拦截邮箱（部分匹配） spammer@example.com qq.com # 拦截域名（部分匹配） spam-site.cn # 拦截关键词 免费算命选择拦截方式后保存即可生效。数据存储配置存储在 typecho_options 表中，name = 'plugin:SpamBlocker'，值为序列化数组。无需手动建表或改表结构。拦截原理通过 Typecho_Plugin::factory('Widget_Feedback')->comment 钩子，在评论提交前对邮箱、网址、昵称、正文进行匹配检查。开源协议MIT已在github上开源， Github开源地址 {lamp/}

服务器被植入流量劫持后门(跳转世界杯赌球网站)的排查与解决方案
type: item
date: 2026-06-13T08:39:00+08:00
description: 前言 今天早上遇到一个非常头疼的问题：我的一台云服务器上部署的网站，访问时会有很大概率跳转到赌球网站（刚好世界杯期间，什么牛鬼蛇神都出来了）。更诡异的是，哪怕我放一个纯空白 HTML 页面上去，依然会被劫持。折腾了半天，最终定位到是一套精心伪装的博彩木马。本文记录完整的排查、分析和清理过程。一、症状描述先说环境：三台云服务器，同一家服务商出问题的这台：Ubuntu 系统另外两台正常的：CentOS 系统所有网站运行在 Nginx 上，通过 宝塔面板 管理症状：访问网站（无论哪个域名），浏览器有很高概率跳转到 https://dd0a000h4orvt.cloudfxxxt.net/?cid=8214805 （域名已做了无害处理）这个赌球网站即使是刚上传的空白 test.html（内容就一句 hello），依然会跳转；开启 Cloudflare 小黄云（代理模式）无效，关闭小黄云（DNS only）也无效；从服务器上 curl 访问页面，返回正常，没有任何跳转；另外两台 CentOS 服务器完全正常跳转链（之前没有捕捉到前面那个xyz跳转链接所以走了一些弯路）：先是跳转faradfdsa.anfxxc.xyz，接着很快跳转至dd0a000h4orvt.cloudfxxxt.net/?cid=8214805二、初步分析2.1 排除 ISP/DNS 层面因为只有这一台服务器有问题，而三台机器用的是同一家云服务商，所以排除了"运营商线路劫持"的可能。如果是 ISP 层面的劫持，三台服务器应该都会中招。2.2 为什么 Cloudflare 无效Cloudflare 的代理模式会将用户流量先经过 Cloudflare 节点再转发到源服务器。如果劫持发生在源服务器发出响应之后（比如浏览器执行时），那么 Cloudflare 也救不了。2.3 核心疑点：curl 正常但浏览器跳转这说明劫持不是发生在 Nginx 配置层面（因为 curl 返回的是原始响应），而是在更上层——要么是浏览器端被注入 JavaScript，要么是网络传输层被篡改。三、第一轮排查：发现 defunct / iptable6 rootkit3.1 先看 Nginx 配置nginx -T 2>/dev/null | grep -i "redirect\|rewrite\|return 302\|sub_filter"输出中除了正常的 rewrite 规则外，没有发现明显的恶意配置。3.2 检查进程——发现重大线索lsof -i :443输出赫然出现了三个可疑进程：defunct 812 root 3u TCP spk.laws.ms:33018->ec2.us-east-2.amazonaws.com:https (ESTABLISHED) iptable6 817 root 4u TCP spk.laws.ms:54498->ec2-13-57-38-185.us-west-1.compute.amazonaws.com:https (ESTABLISHED) iptable6 28789 root 4u TCP spk.laws.ms:54498->ec2-13-57-38-185.us-west-1.compute.amazonaws.com:https (ESTABLISHED)defunct——这个名字看起来像是进程状态（<defunct> 表示僵尸进程），实则是恶意程序iptable6——伪装成系统工具（正确名称是 ip6tables），拼写故意只差一点点这两个进程都在向外部的 AWS EC2 服务器建立 HTTPS 连接。3.3 定位二进制文件file /usr/bin/defunct /usr/bin/iptable6 ls -la /usr/bin/defunct /usr/bin/iptable6/usr/bin/defunct: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), static-pie linked, stripped /usr/bin/iptable6: ELF 32-bit LSB executable, Intel 80386, version 1 (GNU/Linux), statically linked, no section header两个文件都是静态链接、strip 去符号，显然是恶意软件标准做法。defunct 的文件日期被伪造为 2003-09-08，而 iptable6 的日期是 2026-04-28，说明是近期才植入的。lsof -i -P -n | grep -E "defunct|iptable6"defunct 812 root TCP 12…

修改VisitorLoggerPro插件适配Joe主题前端访客统计独立页
type: item
date: 2026-06-12T09:32:00+08:00
description: 一、VisitorLoggerPro介绍本站用的访客统计插件名称叫VisitorLoggerPro： 作者开源地址 并且作者还专门做了一个前端访客统计独立页，但是只适配handsome主题，我试了在JOE主题下是无法正常使用的。于是我对其进行了一些修改，以使其能够在Joe主题下可以正常使用，可以在我的网站导航菜单点击访客统计查看。二、VisitorLoggerPro 适配 Joe主题修改主要的一些修改：1、改变前端样式结构，使其适应joe主题；2、改变读取数据库方式，使其在Joe主题下能够正常读取数据并显示；3、原插件默认显示最近7天数据，改为默认显示当天数据；三、在Joe主题下的使用方法正常安装插件后，将插件目录下的visitor-stats.php拷贝到主题joe目录，在后台创建独立页，选择访客统计模板即可。四、下载地址百度网盘，回复可见：{hide}https://pan.baidu.com/s/16YPMUE6YitYgoucFLN8eOQ?pwd=6tvc{/hide}

Typecho 1.3+Php8.0可以使用的图片水印插件
type: item
date: 2026-05-31T21:36:00+08:00
description: 经常来看我博客的访客都会知道，我的博客文章中的图片都会有一个域名文字的水印。所以也经常在后台有人私信问我这个水印是怎么弄的。其实这是一个插件，原作者插件github开源地址（感谢！）： 图片水印插件 然后根据你自己的需求，弄两张水印图（一大一小，覆盖大的图片和小的图片，Png格式）如下图，看上去似乎一样，实际上分辨率是不同的，就是同一张图我在PS中导出为两种分辨率的而已。我这里一开始就是随便测试的两张图，没想到效果出奇的符合我的味口，所以就一直沿用至今：后台的插件设置也非常简单直接：这样子你在编写文章的时候，上传的图片会自动进行水印处理。但是作者的这个插件好久没有更新了，我测试了在我的php8.2下有一些问题。我的博客之前用的老服务器是php7.4，这个插件使用一切正常。昨天我的博客进行了搬家，现在新的服务器是php8.2，这个插件就不正常了，症状是上传图片会显示上传失败，但实际上图片已经上传成功了，水印也附着了，就是需要刷新网页才能显示出来。后来查了日志才知道是这个水印插件的问题，waterMark插件在返回JSON前输出了PHP8.2弃用警告，导致整个响应不是合法的JSON，JavaScript解析失败。说人话就是imgfunc.php参数顺序不符合PHP8.2，必选参数在可选参数之后，输出Deprecated 警告污染了JSON响应。上传其实是成功的（文件已保存），但浏览器解析JSON时报错，所以显示"上传失败"。修复方法：修正 waterMark 插件的函数参数顺序。改动的地方有两处：imgfunc.php:6 — 把 $w_pct, $w_quality 移到可选参数前面 Plugin.php:79 — 同步调整调用顺序为了以后更新方便，我直接把作者的github项目fork之后更新了：本次更新日志（2026-05-31）：兼容 PHP 8.0+修复 ImgWaterMark() 函数参数顺序：将必选参数 $w_pct、$w_quality 移至可选参数之前解决 PHP 8.0+ 报 Deprecated: Optional parameter declared before required parameter 警告的问题修复因该警告导致 Typecho 上传图片后 JSON 响应被污染、前端提示"上传失败"的 bug下载地址（回复可见）：{hide}[...]

换了新服务器&彻底解决Typecho博客头像源显示问题
type: item
date: 2026-05-31T16:31:00+08:00
description: 序言：服务器搬家了~今天是个里程碑的日子，因为网站正式搬迁到新家落户了！虽然都是香港的服务器，但是这个是CN2，懂的都懂。为何又是香港而不是内地的服务器，懂的也都懂。和nobbcc的站长认识，他给了我JOE主题的魔改包，可惜原来的服务器上面有太多的兼容性问题，一直没能够用上。旧务器是Nginx 1.28+PHP7.4+MySQL 5.7,新服务器是Nginx 1.3+PHP8.2+MySQL8.0，刚好乘这个机会直接把主题用新版的了。有兴趣的可以去nobcc站长的博客去下载：JOE魔改主题下载地址（基于JOE 7.7.1魔改优化而来）Typecho 的头像源问题一番测试下来，感觉良好，就是有一个打从Typecho娘胎里带来的怪病（中国大陆地区水土不服），访客头像破图问题依然存在。相信用Typecho做博客的站长都知道，网上一堆的说法就是换Cravatar的解析地址。虽然我换了国内的cravatar.cn地址，可是我测试换过了依然有的访客的头像是破的，或者是灰色的（无头像，加载不了QQ邮箱头像+没有注册Cravatar头像的邮箱地址大有人在）。于是我试着解决这个问题。我用好几个邮件地址作了测试，诸如123@qq.com(这个能正常加载头像)、abc@qq.com(QQ别名邮箱地址，很难加载头像，显示破图)、abc@163\sina\gmail\msn等等，有一半的机率是灰图以及破图，很不好看。通过分析代码分析可能的原因：1、头像走的是library/avatar.php代理（服务器去下载头像再返回），服务器连不上外部源就会破图。2、QQ邮箱头像接口只能通过纯数字QQ号查询头像。诸如abc@qq.com这样的邮箱前缀不是数字，所以走不到QQ头像通道，降级到Cravatar查头像，而该邮箱没有注册 Cravatar/Gravatar，就返回了默认灰图（其它非qq.com邮箱同理）。所以我现在解决的方式是这样：1、头像函数从本地代理avatar.php改为直链cravatar.cn（QQ邮箱自动优先用QQ头像）；2、非QQ邮箱同步头像源改为从cravatar.cn获取；3、在JOE主题目录下新建avatar头像目录并存放了100多张随机头像，若以上都失败（非QQ邮箱，也没在Cravatar注册头像），根据邮箱的MD5哈希值取模，从本地头像目录里选一张固定分配给该邮箱——同一个邮箱始终显示同一张图。解决方法一、先直接切回直链方式，改为直接输出 CDN 地址：1、编辑 function.php 位于/usr/themes/joe/core//* 头像函数从本地代理 avatar.php 改为直链 cravatar.cn（QQ 邮箱自动用 QQ 头像），从第311行开始 */ echo $timeTotal < 1 ? $timeTotal * 1000 . 'ms' : $timeTotal . 's'; } function _getAvatarByMail($mail) { $themeUrl = Helper::options()->themeUrl; $encodedMail = base64_encode($mail); $proxyUrl = $themeUrl . '/library/avatar.php?data=' . $encodedMail; echo $proxyUrl; } /*function _getAvatarByMail($mail) { $gravatarsUrl = Helper::options()->JCustomAvatarSource ? Helper::options()->JCustomAvatarSource : 'https://cn.cravatar.com/avatar/'; $gravatarsUrl = Helper::options()->JCustomAvatarSource ? Helper::options()->JCustomAvatarSource : 'https://cravatar.cn/avatar/'; $mailLower = strtolower($mail); $md5MailLower = md5($mailLower); $qqMail = str_replace('@qq.com', '', $mailLower); if (strstr($mailLower, "qq.com") && is_numeric($qqMail) && strlen($qqMail) < 11 && strlen($qqMail) > 4) { echo 'https://thirdqq.qlogo.cn/g?b=qq&nk=' . $qqMail . '&s=1…

开发了一套IT资产管理系统
type: item
date: 2026-05-20T11:58:00+08:00
description: 一、系统介绍 我的零售业务有好多的IT设备，销售给客户的数据原来都是表格管理，不仅查询不方便，客户也会有想要知道设备质保期的信息。由于市面上一直没能够找到符合我预期的产品，所以一直也就这样将就着用着。 前两天心血来潮下载了Cursor，结果在这AI编程器的配合下，竟然花了两天时间手搓出了个不错的资产管理系统，不管是界面、还是功能上，都是非常符合我原先的预期了。 所以这是一套面向 IT 服务商的设备与资产管理平台，包含前端客户自助查询系统和后端资产管理系统两部分。20260525:为简化布署，系统已改为php语言，以下描述是初版，不再更新。稍后有时间会重新编辑功能说明。有兴趣的可以直接点击新版宣传页进行查看： IT设备销售管理系统 ，有购买意向或者定制功能的的可以直接联系站长。二、技术栈层级技术后端Express 5 + Node.js数据库MySQL（mysql2 连接池）Sessionexpress-session + express-mysql-session（MySQL 持久化，24h 有效期）安全helmet（安全响应头）、cors、express-rate-limit（限流）日志winston + winston-daily-rotate-file（按天轮转，保留 30 天）HTTP 日志morgan压缩compression（Gzip）文件上传自定义 multipart 解析数据导出exceljs（Excel）、pdfkit（PDF）前端框架Vue 3 + Vite + Element Plus路由vue-router 4（createWebHistory，懒加载）状态管理PiniaHTTP 客户端Axios图表Chart.js 4 + vue-chartjs三、项目结构├── server/ # 后端 │ ├── index.js # Express 入口，路由注册 │ ├── schema.sql # 数据库建表语句 │ ├── .env # 环境变量配置 │ ├── lib/ # 业务模块 │ │ ├── db.js # 数据库连接池与初始化 │ │ ├── env.js # .env 加载器 │ │ ├── auth.js # 认证（登录/登出/改密/会话校验） │ │ ├── session.js # Session 持久化配置 │ │ ├── rate-limiter.js # 请求限流 │ │ ├── devices.js # 设备 CRUD、公开查询、图片上传 │ │ ├── customers.js # 客户 CRUD、联系人管理 │ │ ├── assets.js # 资产 CRUD（配件/软件/耗材/服务） │ │ ├── todos.js # 维护记录 CRUD │ │ ├── dashboard.js # 仪表盘统计与图表 │ │ ├── config.js # 站点配置读写、LOGO 上传 │ │ ├── audit.js # 操作审计日志 │ │ ├── export.js # Excel / PDF 导出 │ │ ├── faults.js # 故障记录管理（JSON 文件存储） │ │ ├── logger.js # Winston 日志配置 │ │ ├── pagination.js # 分页工具 │ │ └── utils.js # 通用工具函数 │ └── package.json ├── public-vue/ # 前端构建产物（Vite build 输出） │ └── assets/ # 代码分割后的 JS/CSS 文件 └── data/ # 数据文件 └── faults.json # 故障记录（JSON 存储）四、环境要求Node.js >= 18MySQL >= 8.0五、快速开始# 1. 进入服务端目录 cd server # 2. 安装依赖 npm install # 3. 配置环境变量 cp .env.example .env # 编辑 .env，填入数据库连接信息和管理员账号 # 4. 启动服务 npm start # 或指定端口 PORT=8020 npm start启动后访问：前台查询页：http://localhost:3000/管理后台：http://localhost:3000/login六、环境变量配置在 server/.env 文件中配置：变量名说明默认值PORT服务监听端口3000DB_HOSTMySQL 主机地址—DB_PORTMySQL 端口3306DB_NAME数据库名称support_itDB_USER数据库用户名support_itDB_PASSWORD数据库密码自己设置ADMIN_USERNAME管理员用户名adminADMIN…

小米K70 PRO手机检测电池健康度及衰减情况
type: item
date: 2026-05-01T10:47:00+08:00
description: 一、为什么要检测电池健康度我的K70 PRO 购于2023年12月月中，到现在也不过就两年半还不到。但是从春节后就明显感觉到电池不给力了已经。状况就是充电特别快，55W快充半小时不到就充满了显示100%，结果原来能用两天不到的，现在半天就见底了，搞得我到哪儿第一件事都要先把充电线给它插上，很麻烦。于是我想检查一下电池的实际容量还有多少，结果网上找的那些方法，基本上都失效了。MIUI也失了它的初衷，从MIUI不断升级，再迭代到如今 HyperOS，改了又改，升了又升，整天变化。现在的系统臃肿不堪，看上去好多功能，实际我们需要的一些方便的功能反而不愿意给你，藏着掖着，就比如这查看电池实际容量或真正健康程度的功能，你真正显示出来会死啊？然而系统里它就给你显示一个良好就啥也没了。二、提取手机Bug检测报告通过拨号键盘输入 *#*#284#*#*，输入后系统会自动在下拉菜单栏生成手机Bug检测报告，时间要3-5分钟，耐心等它生成完成。生成完成后，想办法把这个报告压缩包拷到电脑端，接下来我们要在电脑端操作。这个压缩包容量大小在90M不到点，在电脑端解压后，里面还有一个子压缩包，每个人的手机显示的名称肯定是不一样的，我这里的是如下图所示，50M左右：再次解压，得到一个容量大小在200M不到的正式Bug报告，文本文件：这就是我们需要的K70 PRO BUG检测报告了，里面有电池的一切数据，接下来就是要从报告中查找电池的数据了。三、从Bug报告中读取电池数据打开这个报告，全文搜索CYCLE_COUNT，我的这份文件在837867行左右，有如下数据：{card-default label="Bug报告第837867行处内容" width="100%"}extras: Bundle[{android.os.extra.CAPACITY_LEVEL=-1, technology=Li-poly, icon-small=17304031, max_charging_voltage=0, health=2, max_charging_current=0, status=3, plugged=0, present=true, android.os.extra.CHARGING_STATUS=0, seq=2678, charge_counter=852000, level=24, scale=100, temperature=351, voltage=3688, android.os.extra.CYCLE_COUNT=819, invalid_charger=0, battery_low=false}]{/card-default}从这段日志里提取的电池核心数据：CYCLE_COUNT=819：电池充电循环次数 = 819 次charge_counter=852000：当前电量（单位 µAh，对应 24% 电量）health=2：电池硬件状态正常（无故障）scale=100：电量百分比的基准值level=24：当前电量 24%，和 charge_counter 对应用这组数据，我们可以测算出当前实际电池容量▶ level=24：当前电量为 24%▶charge_counter=852000：当前电量对应的容量（单位：µAh）▶计算电池实际容量： 实际电池容量=852000 μAh÷24%=3,550,000 μAh=3550 mAh ▶K70 Pro 的出厂设计容量 = 5000 mAh，计算电池健康度： 实际健康度=3550÷5000×100%=71% 好家伙，衰减到这个程度了，出厂5000 mAh，实际只有3550 mAh了，仅为设计容量的 71%，健康度低到这个程度，系统里还TM舔着脸告诉你“良好”，好你妹。并且循环次数也有819了，这个次数已经接近行业标准的 “健康临界值”了（一般 800-1000 次后健康度会明显下滑）。通过这个真实的数据说明，这电池接近报废，可以换了。