<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>w2solo - 独立开发者社区</title>
    <link>https://w2solo.com/</link>
    <description>w2solo - 独立开发者社区社区最新发帖.</description>
    <language>en-us</language>
    <item>
      <title>经常跟香港业务往来，需要接触大量繁体文档，所以开发 word 繁体文档转换简体文档的工具，彻底解决语言隔阂</title>
      <description>&lt;p&gt;我们看习惯了简体，有些繁体字还是认识的，&lt;/p&gt;

&lt;p&gt;但是遇到大量的繁体字的文档、合同、需求说明，&lt;/p&gt;

&lt;p&gt;看的真的懵逼，还是很多繁体字不认识&lt;/p&gt;

&lt;p&gt;所以，还是做了一些工具，解决这个语言文字的隔阂：&lt;/p&gt;

&lt;p&gt;导入 word.docx 文件，直接把繁体转换为简体 docx 文件，直接文件内容转换，不丢失格式！
&lt;a href="https://it365.janqi.com/chinese/convert/word/docx/zh.html" rel="nofollow" target="_blank"&gt;https://it365.janqi.com/chinese/convert/word/docx/zh.html&lt;/a&gt;
（这个版本是 文件导入，然后就下载转换后的文件）&lt;/p&gt;

&lt;p&gt;这个版本，是复制富文本，转换出富文本：&lt;/p&gt;

&lt;p&gt;复制 word、网页富文本格式，繁体、简体相互转换
&lt;a href="https://it365.janqi.com/chinese/convert/word/zh.html" rel="nofollow" target="_blank"&gt;https://it365.janqi.com/chinese/convert/word/zh.html&lt;/a&gt;&lt;/p&gt;</description>
      <author>dudu365</author>
      <pubDate>Tue, 12 May 2026 22:36:25 +0800</pubDate>
      <link>https://w2solo.com/topics/7319</link>
      <guid>https://w2solo.com/topics/7319</guid>
    </item>
    <item>
      <title>坏了，黑客学会用 AI 写外挂了</title>
      <description>&lt;p&gt;昨天刚聊完程序员为了省那 23 万 Token 账单连夜跑路的事儿，今天又出大事了。&lt;/p&gt;

&lt;p&gt;而且这次不是钱包的问题——是有人在用 AI 造 “数字万能钥匙”，想捅谁家窗户就捅谁家窗户。&lt;/p&gt;

&lt;p&gt;听完你可能会想把家里智能门锁也换成铁锁头。&lt;/p&gt;
&lt;h3 id="连坏人都开始用AI打工了？凌晨，谷歌紧急拉响警报"&gt;连坏人都开始用 AI 打工了？凌晨，谷歌紧急拉响警报&lt;/h3&gt;
&lt;p&gt;昨天深夜（美国时间 5 月 11 日），谷歌旗下专门抓坏人的威胁情报小组发布了一份让人睡不着觉的报告：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;他们第一次抓到网络攻击者用 AI 造出了 “零日漏洞” 攻击工具。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;不懂技术没关系，咱用大白话说：
零日漏洞，就好比你家的门锁有一个你压根不知道存在的缺陷。厂家没发现，修都来不及修。而坏人拿着这个缺陷配了一把万能钥匙，想进就进。&lt;/p&gt;

&lt;p&gt;最要命的是，谷歌说这个 AI 造的漏洞攻击脚本，能直接绕过双重认证！
你辛苦设了密码、绑了手机、开了人脸，结果人家 AI 直接找到了一个你连系统都没想到的后门。&lt;/p&gt;

&lt;p&gt;过去这种级别的攻击，需要顶尖黑客团队花几周甚至几个月研究。
现在呢？一个会用 AI 的普通技术员，可能喝杯咖啡的功夫就搞出来了。&lt;/p&gt;

&lt;p&gt;谷歌自己也承认：AI 确实能帮好人修漏洞，但更可怕的是，它也帮坏人把造 “万能钥匙” 的门槛从研究生水平降到了初中生水平。&lt;/p&gt;

&lt;p&gt;这感觉就像什么？
你辛辛苦苦练了十年散打，结果街上突然开始卖 “一拳超人” 力量手套，谁都能买到。&lt;/p&gt;

&lt;p&gt;而就在谷歌拉响警报的同一天，OpenAI 老板山姆·奥特曼也跳出来说话了。他说他们刚搞了一个叫 “Daybreak”（破晓）的网络安全项目，专门用 AI 帮企业查漏洞、堵后门。&lt;/p&gt;

&lt;p&gt;翻译过来就是：坏人用 AI 造枪，好人赶紧用 AI 做防弹衣。&lt;/p&gt;

&lt;p&gt;一场无声的 “AI 军备竞赛”，就这么在咱们眼皮底下打响了。&lt;/p&gt;
&lt;h3 id="一边降、一边涨，在你看不见的收费单上"&gt;一边降、一边涨，在你看不见的收费单上&lt;/h3&gt;
&lt;p&gt;说完安全问题，咱们回来聊聊对普通人影响更直接的事。&lt;/p&gt;

&lt;p&gt;就在昨天，这周的 AI 圈搞了个大型 “变脸表演”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一边，有人开始收钱了。&lt;/strong&gt; 那个月活 3.45 亿的国民 AI 豆包，突然挂出了三档收费：基础版免费，但标准版 68 元/月，加强版 200 元/月，专业版 500 元/月。&lt;/p&gt;

&lt;p&gt;人家也挺坦诚的，直接摊牌：不是我想割韭菜，是真扛不住了。现在豆包一天要处理 120 万亿 Token，算力账单涨了 1000 倍。母公司字节跳动去年因为疯狂买 AI 算力，净利润跌了 70% 多。于是，收费成了唯一解方。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;另一边，却有人在大甩卖。&lt;/strong&gt; DeepSeek 昨天宣布 V4 模型降价 75%，缓存调用直接打 1 折。有开发者晒单：一天处理了 278 亿 Token，账单居然才 160 美元。换成别家的模型，同一件事没一万美元下不来。&lt;/p&gt;

&lt;p&gt;换句话说，你花一顿火锅的钱，它帮你干了一个十人团队一周的活。&lt;/p&gt;

&lt;p&gt;于是你就看到了一个特别割裂的名场面：
豆包说 “不好意思，我要涨价了”，DeepSeek 说 “没关系，我打骨折”。&lt;/p&gt;

&lt;p&gt;一个最直观的结果就是，这周微信搜索指数显示，&lt;strong&gt;DeepSeek 的搜索热度单周暴涨了 470%&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这波啊，消费者用脚投票的姿势，比任何技术评测都诚实。&lt;/p&gt;
&lt;h3 id="AI编程圈也在变天，新手程序员更难混了"&gt;AI 编程圈也在变天，新手程序员更难混了&lt;/h3&gt;
&lt;p&gt;再把视线转到打工人这边。昨天我们聊了一家公司因为太贵连夜 “搬家” 省了 23 万，而这个 “搬家潮” 在硅谷显然不是个例。&lt;/p&gt;

&lt;p&gt;就在昨天凌晨，JetBrains 的 Resharper（另一个神级编程辅助插件）宣布启动 2026.2 版本的 Early Access 计划，核心就是把更多的 AI Agent 塞进 Visual Studio 里，帮程序员自动干活。&lt;/p&gt;

&lt;p&gt;与此同时，那个 Claude Code 的创始人之一前几天又放了个 “暴论” 引发的余震还在持续：他说现在这个行业约 50% 的编程工作已经被 AI 替代了，他的团队代码 100% 是 AI 写的，他一天能发 150 个 AI 生成的代码合并请求。&lt;/p&gt;

&lt;p&gt;虽然行业大佬吴恩达跑出来往回找补说 “别慌，系统架构设计 AI 还干不了”，但他也承认：&lt;strong&gt;前端开发是重灾区，AI 替代得最彻底。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;所以现在的情况是啥？
AI 编程工具在拼命进化、价格战打得飞起，但 GitHub Copilot 还在下个月开始按 Token 计费收你钱。
一边是生产力彻底解放，一边是 API 账单原地飞升。&lt;/p&gt;

&lt;p&gt;做技术的朋友，现在日子就像在雷区跳芭蕾——一步踩错，要么被淘汰，要么钱包被掏空。&lt;/p&gt;
&lt;h3 id="到最后，我们该咋办？"&gt;到最后，我们该咋办？&lt;/h3&gt;
&lt;p&gt;今天信息量有点大，但三个信号特别强烈：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI 已经不只是工具，它也可以是武器。&lt;/strong&gt; 谷歌首次确认 AI 造的零日漏洞攻击工具，这场 AI 军备竞赛从今天开始正式进入 “全民皆兵” 阶段。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;AI 行业正在两极分化。&lt;/strong&gt; 有人开始收费，有人打骨折。但 “免费永远是最贵的”——现在终于轮到 AI 验证这句话了。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;“会用 AI 的人” 正在和 “不会用 AI 的人” 拉开差距。&lt;/strong&gt; 不管是打工人还是企业，这不是危言耸听，这正在发生。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最后说一句大实话：
当坏人都在用 AI 搞业务的时候，我们这些普通人如果还不去了解一下 AI 能帮自己做什么、省什么，那真的不是在观望，而是在掉队。&lt;/p&gt;

&lt;p&gt;📢 &lt;strong&gt;今日话题&lt;/strong&gt;：你用过最省钱的一次 AI 操作是什么？欢迎在评论区晒出来，一起避雷一起省钱～&lt;/p&gt;</description>
      <author>193577746</author>
      <pubDate>Tue, 12 May 2026 19:37:19 +0800</pubDate>
      <link>https://w2solo.com/topics/7318</link>
      <guid>https://w2solo.com/topics/7318</guid>
    </item>
    <item>
      <title>🔥 711Proxy ⏩ 高纯净住宅代理 ⭐1 亿＋真实住宅 IP ⭐可选择 ASN</title>
      <description>&lt;p&gt;💡 为什么选择 711Proxy？&lt;/p&gt;

&lt;p&gt;✅ 亿级 IP 池&lt;/p&gt;

&lt;p&gt;可靠且符合道德规范的 IP 资源，覆盖全球 200 多个国家/地区，支持地区/ASN 精准定位，好用又省心。&lt;/p&gt;

&lt;p&gt;✅ 高性能 IP&lt;/p&gt;

&lt;p&gt;👉 通过 711Proxy 的 ASN 功能，您可以更精准地获取指定 ISP 的住宅 IP 资源；&lt;/p&gt;

&lt;p&gt;👉 低于 0.3 秒的低延迟和高达 99.9% 的可用性，确保任务运行稳定高效；&lt;/p&gt;

&lt;p&gt;👉 支持无限并发请求，适配大规模采集任务；&lt;/p&gt;

&lt;p&gt;👉 兼容 HTTP 和 SOCKS5 协议，轻松对接各类爬虫框架与指纹浏览器。&lt;/p&gt;

&lt;p&gt;✅ 服务类型全面&lt;/p&gt;

&lt;p&gt;711Proxy 支持动态（GB/IP）、静态、不限量、SOCKS5 多种代理类型，满足从个人开发者到企业级用户的不同业务需求。&lt;/p&gt;

&lt;p&gt;✅ 价格优惠&lt;/p&gt;

&lt;p&gt;711Proxy 计费透明、套餐灵活，价格低至 0.55 美元/GB 和 0.03 美元/IP/天，无隐藏扣费，批量购买还可享受额外折扣！&lt;/p&gt;

&lt;p&gt;📌 711Proxy 适合哪些业务场景？&lt;/p&gt;

&lt;p&gt;· 竞品价格监控&lt;/p&gt;

&lt;p&gt;· 电商数据采集&lt;/p&gt;

&lt;p&gt;· 广告素材验证 &lt;/p&gt;

&lt;p&gt;· SEO 排名追踪&lt;/p&gt;

&lt;p&gt;· 社媒舆情分析&lt;/p&gt;

&lt;p&gt;711Proxy 配置简单、上手零难度，新手也能快速搭建使用。&lt;/p&gt;

&lt;p&gt;🛠️ 如何使用 711Proxy？&lt;/p&gt;

&lt;p&gt;点击购买：&lt;a href="https://www.711proxy.com/zh-TW/?utm_t=1&amp;amp;utm_i=499" rel="nofollow" target="_blank"&gt;https://www.711proxy.com/zh-TW/?utm_t=1&amp;amp;utm_i=499&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💬 有疑问？欢迎咨询&lt;/p&gt;

&lt;p&gt;客服支持：support@711proxy.com&lt;/p&gt;

&lt;p&gt;🔗 更多详情，进入 711Proxy 官网&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.711proxy.com/zh-TW/?utm_t=1&amp;amp;utm_i=499" rel="nofollow" target="_blank"&gt;https://www.711proxy.com/zh-TW/?utm_t=1&amp;amp;utm_i=499&lt;/a&gt;&lt;/p&gt;</description>
      <author>711Proxy</author>
      <pubDate>Tue, 12 May 2026 17:46:46 +0800</pubDate>
      <link>https://w2solo.com/topics/7317</link>
      <guid>https://w2solo.com/topics/7317</guid>
    </item>
    <item>
      <title>这才是真正的 “贾维斯”：Minis 如何让你的 iPhone 变成钢铁侠的战衣？</title>
      <description>&lt;p&gt;在电脑上用 Agents 很爽，但 &lt;strong&gt;Agent 能随身带在手机里，直接调用你手机的所有能力呢？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这就是 &lt;a href="https://openminis.app/" rel="nofollow" target="_blank" title=""&gt;Open Minis&lt;/a&gt; —— 一个真正把「端侧 AI Agent」做明白的产品。&lt;/p&gt;

&lt;p&gt;这不是又一个聊天 App。它是一个完整的 AI Agent 运行时，跑在你的手机上。一句话：&lt;strong&gt;你的 AI 助手，真的能「用」你的手机了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260512163703973.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="开箱即用三步"&gt;开箱即用三步&lt;/h3&gt;
&lt;p&gt;App Store 搜索 Minis 下载：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;配置 AI 提供商（Claude、GPT、Gemini、OpenRouter 或任意 OpenAI 兼容接口）&lt;/li&gt;
&lt;li&gt;选择模型&lt;/li&gt;
&lt;li&gt;开始对话&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/82113b5adf0449adf186fa2ea26301c6.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="核心能力"&gt;核心能力&lt;/h3&gt;&lt;h4 id="1. 完整 Linux 环境，Agent 自己写代码"&gt;1. 完整 Linux 环境，Agent 自己写代码&lt;/h4&gt;
&lt;p&gt;内置 Alpine Linux，Agent 能自己安装包、写脚本、执行命令，一切本地运行。&lt;/p&gt;

&lt;p&gt;我测试让它安装「数字生命卡兹克 AIHOT」skill，它自己克隆仓库、发现缺 Git 就自己装上，全程丝滑。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/56190a24b2d77fa6329c946bc9e6a558.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h4 id="2. 原生 iOS 深度集成"&gt;2. 原生 iOS 深度集成&lt;/h4&gt;
&lt;p&gt;这才是最狠的 —— 直接调用几乎所有 iOS 系统能力，用自然语言就行：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tr&gt;
&lt;th&gt;能力&lt;/th&gt;
&lt;th&gt;你只要说&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;健康数据&lt;/td&gt;
&lt;td&gt;"我这周走了多少步？"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;日历&lt;/td&gt;
&lt;td&gt;"明天我有什么安排？"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;提醒事项&lt;/td&gt;
&lt;td&gt;"下午 3 点提醒我给牙医打电话"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;智能家居&lt;/td&gt;
&lt;td&gt;"把客厅灯关了"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;联系人&lt;/td&gt;
&lt;td&gt;"找一下张三的手机号"&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;蓝牙、剪贴板、照片、闹钟、电池...&lt;/td&gt;
&lt;td&gt;自然语言描述即可&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;h4 id="3. 内置浏览器 + SKILL 兼容"&gt;3. 内置浏览器 + SKILL 兼容&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Agent 自己会浏览网页、填表、截图&lt;/li&gt;
&lt;li&gt;完全兼容 Claude Code 的 SKILL.md 格式，电脑上的技能直接拿来用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/eee01e6c6defe0578def1c8616f3f975.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="为什么重要？"&gt;为什么重要？&lt;/h3&gt;&lt;h4 id="隐私第一"&gt;隐私第一&lt;/h4&gt;
&lt;p&gt;API 密钥存在 Keychain，无数据收集，所有内容本地处理。&lt;/p&gt;
&lt;h4 id="多模型自由"&gt;多模型自由&lt;/h4&gt;
&lt;p&gt;可同时配置多个提供商，支持 Fallback（故障自动切换）、负载均衡模式。&lt;/p&gt;
&lt;h4 id="Agent 自循环"&gt;Agent 自循环&lt;/h4&gt;
&lt;p&gt;可配置专门的「Agent Loop 模型池」，分解子任务或深度推理时自动调用。&lt;/p&gt;
&lt;h3 id="支持平台"&gt;支持平台&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;iOS 16+ / iPadOS 16+&lt;/li&gt;
&lt;li&gt;macOS 13+ (Apple Silicon)&lt;/li&gt;
&lt;li&gt;visionOS 1.0+&lt;/li&gt;
&lt;li&gt;Android（预览版）&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="总结"&gt;总结&lt;/h3&gt;
&lt;p&gt;这不是「手机上的又一个 AI App」，这是 &lt;strong&gt;AI 终于能真正用你的手机了&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;之前的手机 AI 都停留在「聊天」层面，而 Open Minis 直接把 Agent 的触手伸进了系统层。日历、健康数据、智能家居、文件系统 —— AI 终于能以自然的方式访问和操作它们了。&lt;/p&gt;

&lt;p&gt;如果你在电脑上已经体会过 Agents 带来的效率革命，把这种能力装进口袋的感觉，值得立刻去试一下。&lt;/p&gt;</description>
      <author>sphinx30</author>
      <pubDate>Tue, 12 May 2026 16:42:49 +0800</pubDate>
      <link>https://w2solo.com/topics/7316</link>
      <guid>https://w2solo.com/topics/7316</guid>
    </item>
    <item>
      <title>做了一个本地优先的阅读器 + 网页小游戏站 Reader Games</title>
      <description>&lt;p&gt;大家好，最近在维护个人项目 &lt;strong&gt;Reader Games&lt;/strong&gt;（阅读 + 小游戏），想在这里做一次「作品展示」，顺便听听大家对产品定位和增长的看法。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;网站&lt;/strong&gt;：&lt;a href="https://www.readergames.com/" rel="nofollow" target="_blank"&gt;https://www.readergames.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;想解决什么问题&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;阅读：在浏览器里打开本地 TXT / PDF / EPUB，主题、书签、历史尽量 &lt;strong&gt;本地优先&lt;/strong&gt;，不上传书库。&lt;/li&gt;
&lt;li&gt;游戏：2048、扫雷、数独、象棋、五子棋等 &lt;strong&gt;即点即玩&lt;/strong&gt;，同样偏本地记分，无需登录。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;先谢过，接受一切友好吐槽。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/jackylee2099168/06ba1d53-937f-47f7-b6e9-4cf5fcb9a135.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>jackylee2099168</author>
      <pubDate>Tue, 12 May 2026 15:42:13 +0800</pubDate>
      <link>https://w2solo.com/topics/7315</link>
      <guid>https://w2solo.com/topics/7315</guid>
    </item>
    <item>
      <title>独立开发者做 AI 产品，月账单从 4 万降到 X，我只做了三件事</title>
      <description>&lt;p&gt;上个月看到 API 账单的时候，说实话心都在滴血——4 万多，比我租房都贵。&lt;/p&gt;

&lt;p&gt;认真复盘了一下，发现钱主要烧在三个地方：&lt;/p&gt;

&lt;p&gt;1、大模型太 “话痨”：本来只想让它回一句 “是” 或 “不是”，它给我写了一段小作文。话越多，token 越多，钱就越多。
2、同一个问题用户反复问：比如 “怎么注册”，一百个人问，大模型就得回答一百遍，每遍都收钱。
3、简单任务也用了最好的模型：翻译一句话、分个类，这种活儿其实用小模型就能搞定，但我一直用的是旗舰版，等于开着跑车送外卖。&lt;/p&gt;

&lt;p&gt;针对这三点，我做了三件很简单的事：
告诉模型 “给我最简短的答案，别解释”；
把用户常问的问题存起来，下次问同样的话直接给答案，不再调模型；
简单任务自动切到便宜的模型去处理。&lt;/p&gt;

&lt;p&gt;这三招下来，月底账单直接降了一大截。
我现在把这些逻辑都集成在 Tokaify 里了，所有调用一个后台管，省心很多。新用户有免费额度，你可以先去试试，看自己的项目能省多少。&lt;/p&gt;</description>
      <author>Token_wanjia</author>
      <pubDate>Tue, 12 May 2026 14:45:36 +0800</pubDate>
      <link>https://w2solo.com/topics/7314</link>
      <guid>https://w2solo.com/topics/7314</guid>
    </item>
    <item>
      <title>+86 注册 Telegram 提示 smsfee？这个版本直接登录。</title>
      <description>&lt;p&gt;前段时间想用 Telegram 收一些技术资讯，结果卡在注册登录环节。&lt;/p&gt;

&lt;p&gt;+86 手机号登录，提示 smsfee，需要购买一周的会员，缴费购买了以后，短信验证码迟迟不来，反复试了好几次都没登上。网上搜了一圈，说是运营商屏蔽了，网上的各种方法也都试了，还是没有登录，挺无奈的。&lt;/p&gt;

&lt;p&gt;后来找到一款基于官方 12.5.1 版本编译的客户端，用了几天，体验不错。&lt;/p&gt;

&lt;p&gt;直接登录&lt;/p&gt;

&lt;p&gt;下载后按照步骤操作，2 分钟登录上，没有 smsfee 问题，省了不少事。&lt;/p&gt;

&lt;p&gt;中文完整&lt;/p&gt;

&lt;p&gt;界面内容都是中文，看着舒服，没有乱码。&lt;/p&gt;

&lt;p&gt;连接稳定&lt;/p&gt;

&lt;p&gt;网络层做了优化，打开后自动连上，不用手动配置参数，不用魔法梯。&lt;/p&gt;

&lt;p&gt;功能正常&lt;/p&gt;

&lt;p&gt;聊天、看频道、收消息、多账号切换，和官方版一样顺手。消息推送及时，后台也比较稳。&lt;/p&gt;

&lt;p&gt;适合什么人&lt;/p&gt;

&lt;p&gt;适合不想折腾注册环节的人，适合急需使用但卡在登录步骤的，适合需要稳定中文环境的日常使用者。&lt;/p&gt;

&lt;p&gt;总结&lt;/p&gt;

&lt;p&gt;作为一款基于官方代码的本地化方案，它在易用性上做了不错的补充。对于想登录使用 TG 纸飞机的人来说，确实省心很多。&lt;/p&gt;

&lt;p&gt;有同样需求的可以试试，操作简单一键登录。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/saucerfloy/c94c8f96-011b-4e7a-9932-f95216deca4f.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/saucerfloy/a61a9c19-334d-45ac-b236-3cc518c00d4f.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>saucerfloy</author>
      <pubDate>Tue, 12 May 2026 12:19:29 +0800</pubDate>
      <link>https://w2solo.com/topics/7313</link>
      <guid>https://w2solo.com/topics/7313</guid>
    </item>
    <item>
      <title>你写的代码没有测试，就像出门不锁门——Jest + Testing Library 从入门到不慌</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;你改了一行代码，手动点了一遍页面，觉得没问题就上线了。结果用户反馈 “登录按钮点不动了”。你心里咯噔：我根本没改登录相关代码啊。今天我们来给你的代码装一把 “智能门锁”——单元测试。用 Jest + Testing Library，把常见 Bug 锁在门外，让你改代码时不再心惊胆战。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/193577746/8ff0c4e9-f874-48b3-aa89-627f43c1f6cf.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;
&lt;h2 id="前言"&gt;前言&lt;/h2&gt;
&lt;p&gt;很多前端对测试的态度是：项目那么赶，哪有时间写测试？结果修 Bug 的时间比写代码还多。你花 20 分钟写的测试，可能帮你省掉 2 小时的通宵排查。&lt;/p&gt;

&lt;p&gt;测试不是 “额外工作”，而是&lt;strong&gt;安全网&lt;/strong&gt;。当你需要重构、升级依赖、添加新功能时，测试全绿的那一刻，比中彩票还安心。今天我们用 Jest（测试框架）+ Testing Library（渲染组件、模拟用户操作），从零开始给你的 React 项目写第一个测试。不搞复杂概念，只写最实用的断言。&lt;/p&gt;
&lt;h2 id="一、Jest 是啥？Testing Library 又是啥？"&gt;一、Jest 是啥？Testing Library 又是啥？&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jest&lt;/strong&gt;：Facebook 出的测试框架，内置断言、模拟函数、覆盖率报告。开箱即用，零配置。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing Library&lt;/strong&gt;：一套帮助你 “像用户一样测试” 的工具。不测试组件内部 state 或 props，只测试用户能看到和能操作的。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;核心原则&lt;/strong&gt;：测试越接近用户的使用方式，越能给你信心。不要测试实现细节（比如某个函数被调用了几次、某个 state 变了），要测试 UI 上出现了什么、点击后发生了什么变化。&lt;/p&gt;
&lt;h2 id="二、环境搭建（Create React App 用户）"&gt;二、环境搭建（Create React App 用户）&lt;/h2&gt;
&lt;p&gt;如果你用 CRA，Jest 和 Testing Library 已经内置，直接写就行。Vite 用户需要手动安装：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-D&lt;/span&gt; jest @testing-library/react @testing-library/jest-dom @testing-library/user-event vitest
&lt;span class="c"&gt;# 如果用 Vitest（Vite 推荐），配置略不同。这里我们用 Jest 示范&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;配置 &lt;code&gt;jest.config.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;testEnvironment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;jsdom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;setupFilesAfterEnv&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;rootDir&amp;gt;/src/setupTests.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;src/setupTests.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/jest-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="三、第一个测试：测试一个纯函数"&gt;三、第一个测试：测试一个纯函数&lt;/h2&gt;
&lt;p&gt;测试最简单的工具函数，是入门的绝佳方式。比如 &lt;code&gt;utils/formatPrice.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;formatPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;¥&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;}${&lt;/span&gt;&lt;span class="nx"&gt;price&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toFixed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;写测试 &lt;code&gt;utils/formatPrice.test.js&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;formatPrice&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./formatPrice&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;格式化价格带默认货币符号&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.5&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;¥10.50&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;支持自定义货币符号&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatPrice&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;10.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$10.50&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;运行 &lt;code&gt;npm test&lt;/code&gt;，看到绿色通过。这类测试跑得快，你应该写很多。&lt;/p&gt;
&lt;h2 id="四、测试 React 组件：渲染与交互"&gt;四、测试 React 组件：渲染与交互&lt;/h2&gt;
&lt;p&gt;假设我们有一个 &lt;code&gt;Counter&lt;/code&gt; 组件：&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;计数: &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;p&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;onClick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;setCount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;增加&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;写测试 &lt;code&gt;Counter.test.jsx&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/user-event&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./Counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;渲染初始计数为0&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;countElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/计数: 0/i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;countElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;点击按钮后计数增加&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userEvent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setup&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Counter&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;button&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/增加/i&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;button&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/计数: 1/i&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;注意：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;screen.getByRole&lt;/code&gt; 比 &lt;code&gt;getByText&lt;/code&gt; 更语义化，推荐优先使用。&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;userEvent&lt;/code&gt; 模拟真实点击（会触发 focus、blur 等），比 &lt;code&gt;fireEvent&lt;/code&gt; 更接近用户。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="五、测试异步操作：比如数据加载"&gt;五、测试异步操作：比如数据加载&lt;/h2&gt;
&lt;p&gt;一个显示用户列表的组件，从 API 获取数据：&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;UserList&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;([]);&lt;/span&gt;
  &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;setUsers&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt; &lt;span class="na"&gt;key&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;li&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;ul&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;测试时需要 mock &lt;code&gt;fetch&lt;/code&gt;：&lt;/p&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@testing-library/react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserList&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./UserList&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nb"&gt;global&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
  &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;张三&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;李四&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]),&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;加载并显示用户列表&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;UserList&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// 等待数据加载完成&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;张三&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screen&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getByText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;李四&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nx"&gt;toBeInTheDocument&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="六、覆盖率：别盲目追求 100%"&gt;六、覆盖率：别盲目追求 100%&lt;/h2&gt;
&lt;p&gt;运行 &lt;code&gt;npm test -- --coverage&lt;/code&gt;，会生成覆盖率报告。但记住：&lt;strong&gt;100% 覆盖率不代表没有 Bug&lt;/strong&gt;。覆盖率低的地方可能是关键逻辑，需要补测试；但有些样板代码（如常量定义、简单 getter）不测也罢。重点覆盖业务逻辑和复杂交互。&lt;/p&gt;
&lt;h2 id="七、测试最佳实践"&gt;七、测试最佳实践&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;测试行为，不测试实现&lt;/strong&gt;：不要测试组件内部 state 的值（除非必要），而是测试渲染结果。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;一个测试只断言一件事&lt;/strong&gt;：一个 &lt;code&gt;test&lt;/code&gt; 里可以有多个 &lt;code&gt;expect&lt;/code&gt;，但最好只测一个行为。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;模拟外部依赖&lt;/strong&gt;：网络请求、localStorage、计时器都要模拟，避免测试不稳定。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;避免测试快照&lt;/strong&gt;：快照测试（&lt;code&gt;toMatchSnapshot&lt;/code&gt;）容易产生大而脆弱的文件，改个空格就挂。优先用断言。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;让测试快速&lt;/strong&gt;：单元测试应该在几秒内跑完，如果慢，检查是否有真实网络请求或大量渲染。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="八、持续集成：让测试自动跑起来"&gt;八、持续集成：让测试自动跑起来&lt;/h2&gt;
&lt;p&gt;把测试放到 GitHub Actions 里（上篇文章的内容）。每次 PR 自动跑测试，不通过不让合并。这样团队协作时，队友的改动不会悄悄破坏你的代码。&lt;/p&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Test&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm ci&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="九、总结：测试是给未来的自己写信"&gt;九、总结：测试是给未来的自己写信&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;写测试一开始会慢，但能让你后期 “闭着眼睛改代码”。&lt;/li&gt;
&lt;li&gt;Jest + Testing Library 是 React 社区标准，Vue/Vite 对应 Vitest + Testing Library。&lt;/li&gt;
&lt;li&gt;不要被 “测试种类太多” 吓到，从纯函数和简单组件开始，逐步扩大覆盖。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;下次你改了代码，测试全绿，你就可以自信地 push。那种感觉，比手动点一百遍页面踏实多了。&lt;/p&gt;

&lt;p&gt;如果你觉得今天的 “智能门锁” 够踏实，点个赞让更多人看到。评论区聊聊：你被上线后突然出现的 Bug 坑过吗？&lt;/p&gt;</description>
      <author>193577746</author>
      <pubDate>Tue, 12 May 2026 00:02:44 +0800</pubDate>
      <link>https://w2solo.com/topics/7312</link>
      <guid>https://w2solo.com/topics/7312</guid>
    </item>
    <item>
      <title>我怀疑那些抱怨 AI 难用的人，根本没遇见过 WorkBuddy。</title>
      <description>&lt;p&gt;使用 AI Agent 时，两大痛点让人抓狂：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;命令交互反直觉&lt;/strong&gt;：斜杠命令一输就触发，需求还没写完，思路已被打断，反复修正苦不堪言。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;跨工具协作割裂&lt;/strong&gt;：想处理微信消息、整理聊天记录？必须配置插件、折腾接口，门槛高到让人放弃。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;WorkBuddy 一击致命：先写需求、再挂技能，彻底杜绝误触；原生打通微信，零配置自动处理消息——让 AI Agent 不再是玩具，而是你办公和社交中无法离开的本能。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260511220313821.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="下载&amp;amp;安装"&gt;下载&amp;amp;安装&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://www.codebuddy.cn/home/" rel="nofollow" target="_blank"&gt;https://www.codebuddy.cn/home/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;首次打开需要微信登录，手机验证后即可使用&lt;/p&gt;

&lt;p&gt;新用户赠送 2500 个积分：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;基础体验包&lt;/li&gt;
&lt;li&gt;活动赠送包，有效期 30 天&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260511174010897.webp" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;全局记忆文件位置&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;C:\Users\Administrator\.workbuddy\BOOTSTRAP.md
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="API定价&amp;amp;设置"&gt;API 定价&amp;amp;设置&lt;/h3&gt;
&lt;p&gt;他们家的 API 购买地址
&lt;a href="https://www.codebuddy.cn/profile/plan" rel="nofollow" target="_blank"&gt;https://www.codebuddy.cn/profile/plan&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;个人专业版一个月 58 元，一年 696 元。&lt;/p&gt;

&lt;p&gt;也可以接入其他厂商模型&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260511180600420.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="微信集成方法"&gt;微信集成方法&lt;/h3&gt;
&lt;p&gt;官网文档
&lt;a href="https://www.codebuddy.cn/docs/workbuddy/WeixinBot-Guide" rel="nofollow" target="_blank"&gt;https://www.codebuddy.cn/docs/workbuddy/WeixinBot-Guide&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;设置---Claw 设置 --- 微信助手集成 - 配置&lt;/p&gt;

&lt;p&gt;扫码后即可在微信上发消息，电脑端会同步接收，稍后消息也会传到手机上，非常丝滑
⚠️但是你电脑上发消息不会同步到微信&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260511180317180.webp" title="" alt=""&gt;&lt;/p&gt;
&lt;h3 id="导入skills技能"&gt;导入 skills 技能&lt;/h3&gt;
&lt;p&gt;我自己有个中央仓库
C:\Users\Administrator\AISkills，里面有几百个技能&lt;/p&gt;

&lt;p&gt;通过创建目录软链接就可以把 AISkills 给 WorkBuddy 使用。&lt;/p&gt;

&lt;p&gt;执行前需要先处理一个问题：
&lt;strong&gt;&lt;code&gt;.workbuddy\skills&lt;/code&gt; 这个空文件夹必须先删除&lt;/strong&gt;，因为 &lt;code&gt;mklink&lt;/code&gt; 要求链接路径不能已存在。&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:: 1. 先删除空的 skills 文件夹
rmdir "C:\Users\Administrator\.workbuddy\skills"

:: 2. 创建符号链接（让 .workbuddy\skills 指向 AISkills）
mklink /D "C:\Users\Administrator\.workbuddy\skills" "C:\Users\Administrator\AISkills"
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;在这个步骤中：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.workbuddy\skills  →→→  AISkills
   (符号链接)            (真实目录)
&lt;/code&gt;&lt;/pre&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tr&gt;
&lt;th&gt;路径&lt;/th&gt;
&lt;th&gt;角色&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;C:\Users\Administrator\AISkills&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;原始真实目录&lt;/strong&gt;（已有你的技能文件）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;C:\Users\Administrator\.workbuddy\skills&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;符号链接目录&lt;/strong&gt;（指向 AISkills）&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;像 WorkBuddy 这类图形化 Agent，在技能调用的交互设计上非常人性化：你可以&lt;strong&gt;先完整写完需求（比如 “推特上查询最新 Agent 进展”），再从技能列表中点选 &lt;code&gt;web-access&lt;/code&gt; 这类工具触发调用&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;而不是像 Claude Code 那样先输入斜杠触发指令，再回头补充需求。这种「先写需求，后挂技能」的模式，从根本上避免了指令发送不完整、误操作触发无效调用的问题。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://gitee.com/da-qiang-classmate/typora/raw/master/image/20260511184406984.webp" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;以上就是我个人对这款软件的使用感受。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;从「命令误触」到「先写需求再挂技能」，从「跨工具割裂」到「微信零配置打通」——WorkBuddy 把 AI Agent 从折腾的玩具变成了顺手的生产力工具。&lt;/p&gt;

&lt;p&gt;如果你也有什么私藏神器，欢迎在评论区留言推荐，互相种草！觉得有帮助的话，点个赞再走呗～&lt;/p&gt;</description>
      <author>sphinx30</author>
      <pubDate>Mon, 11 May 2026 22:11:07 +0800</pubDate>
      <link>https://w2solo.com/topics/7311</link>
      <guid>https://w2solo.com/topics/7311</guid>
    </item>
    <item>
      <title>+86 手机登录 Telegram 总是遇见 SMSfee 问题的根本跳过方法</title>
      <description>&lt;p&gt;近期发现好多小伙伴和我一样都遇到 +86 手机号登陆 Telegram 难的问题，可以说是直接就登陆不上！这里给大家客观分享一款基于官方原版 12.5.1 源码编译优化的第三方客户端，经过本人多轮实测，整体体验稳定实用，下面做一个中立客观的使用小结。&lt;/p&gt;

&lt;p&gt;版本基础说明&lt;/p&gt;

&lt;p&gt;这个客户端完全基于 Telegram 官方 12.5.1 原版源码编译制作，未删减、未篡改官方原有功能，完整保留官方客户端全部原生特性、交互逻辑，和原版使用习惯完全一致，无额外广告。&lt;/p&gt;

&lt;p&gt;实测核心优势&lt;/p&gt;

&lt;p&gt;内置简体中文，无需额外装翻译包客户端开机默认就是中文界面，不用手动下载、导入中文翻译包，安装打开即可直接上手，对新手非常友好。
网络层面深度优化，连接更稳定针对网络链路做了专属优化，访问速度流畅、延迟低、不易断线，日常收发消息、加载群组频道、查看图片文件都很顺滑。
功能与官方原版完全一致保留官方所有原生功能：私密聊天、自建群组、频道订阅、文件传输、消息撤回，没有阉割任何官方特性，日常使用发现没有任何功能缺失。&lt;/p&gt;

&lt;p&gt;客观小贴士&lt;/p&gt;

&lt;p&gt;这只是基于官方原版编译优化的第三方自用客户端，仅做网络适配、中文内置和登录适配优化，无任何修改源码隐私相关行为；适合苦于官方版登录不了、想省心稳定使用 TG 的普通用户。&lt;/p&gt;

&lt;p&gt;欢迎大家评论区讨论，你们是怎么解决目前这个 TG 出现的 SMSfee 问题的？&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/huo/1dac32ad-f0da-47ed-ab3d-f56e303de886.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/huo/3c5aeb14-b7a8-43ff-8683-6a5618cba0ca.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/huo/b8f64504-3be8-4563-8171-e91722e79a37.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;</description>
      <author>huo</author>
      <pubDate>Mon, 11 May 2026 16:24:48 +0800</pubDate>
      <link>https://w2solo.com/topics/7310</link>
      <guid>https://w2solo.com/topics/7310</guid>
    </item>
    <item>
      <title>为什么我做 Shipstry，不想把它做成「又一个目录站」</title>
      <description>&lt;p&gt;最近在做一个 side project ，叫 Shipstry：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shipstry.com" rel="nofollow" target="_blank"&gt;https://shipstry.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/coryso/79ad324a-c1f4-42f1-8afd-e2ece5d42a56.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;可以把它理解成一个面向独立开发者的产品发布与发现站，但我做它的时候，想的不是「再做一个 Product Hunt clone」，而是想试着解决几个我自己一直不太喜欢的问题：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;很多产品发布站节奏太快，产品发出去几天后就被淹没了&lt;/li&gt;
&lt;li&gt;排名和票数暴露得太早，后面的产品很容易被 “从众效应” 带偏&lt;/li&gt;
&lt;li&gt;做产品的人、认真讨论的人、纯来刷曝光的人，长期很难区分&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;所以 Shipstry 现在做了几件我自己挺在意的事：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ship Week：每个产品都会进入一个明确的发布周，而不是随手扔进时间线&lt;/li&gt;
&lt;li&gt;Fog Mode：每天有一段 blind voting 时间，会隐藏票数和排名提示，也会调整展示顺序，尽量减少「看票投票」&lt;/li&gt;
&lt;li&gt;Wakemark：一个和排名脱钩的 reputation 机制，更看重长期参与、讨论和持续发布&lt;/li&gt;
&lt;li&gt;Reviewed listings：提交不是直接上，会做基础审核，尽量过滤掉纯外链页、空壳页和只为蹭流量的提交&lt;/li&gt;
&lt;li&gt;Registry 而不是一次性榜单：产品过了发布周之后不会立刻消失，后面依然可以继续被浏览和发现&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;另外我还顺手做了一个配套功能：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://shipstry.com/backlinks" rel="nofollow" target="_blank"&gt;https://shipstry.com/backlinks&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;这里整理了一批适合产品提交的目录站 / 反向链接资源，可以按 DR 、免费/付费、是否 dofollow 等条件筛选。这个功能不一定所有人都需要，但如果你本来就在做产品分发和 SEO ，应该会比较直观。&lt;/p&gt;

&lt;p&gt;目前 Shipstry 主要面向 AI 工具、开发者工具、SaaS 这类 maker-built products 。界面现在是英文的，目标用户也更偏全球独立开发者社区。&lt;/p&gt;

&lt;p&gt;商业化这块我尽量做得简单一点：有免费提交路径，也有一次性付费方案，用来换更快审核和更多曝光，没有做订阅制。&lt;/p&gt;

&lt;p&gt;技术上这次用的是：&lt;/p&gt;

&lt;p&gt;TanStack Start + Cloudflare Workers + D1 + Drizzle ORM + Better Auth + Stripe + Resend&lt;/p&gt;

&lt;p&gt;如果大家愿意拍砖，我很想听听这些问题：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;你会愿意把自己的产品发到这种「按周发布」的站里吗？&lt;/li&gt;
&lt;li&gt;Fog Mode 这种隐藏票数的设计，你觉得有意义吗？&lt;/li&gt;
&lt;li&gt;Wakemark 这种 reputation 机制会不会太重了？&lt;/li&gt;
&lt;li&gt;反向链接数据库这种配套功能，对你来说是加分项还是其实没那么重要？&lt;/li&gt;
&lt;li&gt;除了发布和投票，这种站还应该解决什么问题？&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;欢迎直接喷定位、交互、命名、规则设计，或者商业模式都行。&lt;/p&gt;</description>
      <author>coryso</author>
      <pubDate>Mon, 11 May 2026 15:26:37 +0800</pubDate>
      <link>https://w2solo.com/topics/7309</link>
      <guid>https://w2solo.com/topics/7309</guid>
    </item>
    <item>
      <title>段码液晶显示驱动液晶显示驱动 IC 液晶显示驱动厂家 VK0384</title>
      <description>&lt;p&gt;概述
VK0384 是一个点阵式存储映射的 LCD 驱动器，可支持最大 384 点（48SEGx8COM）的 LCD 屏。单片机可通过 3 线串行接口配置显示参数和发送显示数据，也可通过指令进入省电模式。Z113+68&lt;/p&gt;

&lt;p&gt;特点
•工作电压 2.4-5.2V&lt;/p&gt;

&lt;p&gt;•内置 32 kH z RC 振荡器（上电默认）&lt;/p&gt;

&lt;p&gt;•偏置电压（BIA S）固定为 1/4&lt;/p&gt;

&lt;p&gt;•C O M 周期（D U TY）固定为 1/8&lt;/p&gt;

&lt;p&gt;•内置显示 RA M 为 48x8 位&lt;/p&gt;

&lt;p&gt;•蜂鸣器频率可配置为 2kH z、4kH z&lt;/p&gt;

&lt;p&gt;•省电模式（通过关显示和关振荡器进入）&lt;/p&gt;

&lt;p&gt;•3 线串行接口&lt;/p&gt;

&lt;p&gt;•软件配置 LC D 显示参数&lt;/p&gt;

&lt;p&gt;•写命令和写数据 2 种命令格式&lt;/p&gt;

&lt;p&gt;•写显示数据地址自动加 1&lt;/p&gt;

&lt;p&gt;•VLCD 脚提供 LCD 驱动电压（＜VDD）&lt;/p&gt;

&lt;p&gt;•封装 LQ FP64(7.0mm x 7.0mm PP=0.4mm)&lt;/p&gt;

&lt;p&gt;三：应用领域
• 电表/瓦斯表
 • 按摩仪/美容仪
 • 医用仪器 
• 车载设备
 • 冷气机/暖风机&lt;/p&gt;

&lt;p&gt;LCD/LED 控制器及驱动器系列芯片简介如下：
RAM 映射 LCD 控制器和驱动器系列：
VK1024B 2.4V～5.2V 6seg*4com 6*3 6*2 偏置电压 1/2 1/3 S0P16 省电模式&lt;/p&gt;

&lt;p&gt;VK1056B 2.4V～5.2V 14seg*4com 14*3 14*2 偏置电压 1/2 1/3 SOP24 省电模式&lt;/p&gt;

&lt;p&gt;VK1056C 2.4V～5.2V 14seg*4com 14*3 14*2 偏置电压 1/2 1/3 SSOP24 省电模式&lt;/p&gt;

&lt;p&gt;VK1072B 2.4V～5.2V 18seg*4com 18*3 18*2 偏置电压 1/2 1/3 SOP28 省电模式&lt;/p&gt;

&lt;p&gt;VK1072C 2.4V～5.2V 18seg*4com 18*3 18*2 偏置电压 1/2 1/3 SOP28 省电模式&lt;/p&gt;

&lt;p&gt;VK1072D 2.4V～5.2V 18seg*4com 18*3 18*2 偏置电压 1/2 1/3 SSOP28 省电模式&lt;/p&gt;

&lt;p&gt;VK1088B 2.4V～5.2V 22seg*4com 22*3 22*2 偏置电压 1/2 1/3 QFN32（4*4mm PP=0.4mm）超小体积&lt;/p&gt;

&lt;p&gt;VK1128C 2.4V～5.2V 32seg*4com 32*3 32*2 偏置电压 1/2 1/3 QFN48 (5*5mm PP=0.35mm) 超小体积&lt;/p&gt;

&lt;p&gt;VK0192M 2.4V～5.2V 24seg*8com 偏置电压 1/4 LQFP44 省电模式&lt;/p&gt;

&lt;p&gt;VK0256 2.4V～5.2V 32seg*8com 偏置电压 1/4 QFP64 省电模式&lt;/p&gt;

&lt;p&gt;VK0256B 2.4V～5.2V 32seg*8com 偏置电压 1/4 LQFP64 省电模式&lt;/p&gt;

&lt;p&gt;VK0256C 2.4V～5.2V 32seg*8com 偏置电压 1/4 LQFP52 省电模式&lt;/p&gt;

&lt;p&gt;VK0384 2.4V～5.2V 48seg*8com 偏置电压 1/4 LQFP64 省电模式&lt;/p&gt;

&lt;p&gt;VK1621 2.4V～5.2V 32seg*4com 32*3 32*2 偏置电压 1/2 1/3 LQFP44(QFP44 正方形)/LQFP48/SSOP48/SDIP28；DICE/DIE 裸片 (绑定 COB)；COG(绑定玻璃) 省电模式&lt;/p&gt;

&lt;p&gt;VK1622 2.4V～5.2V 32seg*8com 偏置电压 1/4 LQFP44/LQFP48/LQFP52/LQFP64/QFP64；DICE/DIE 裸片 (绑定 COB)；COG(绑定玻璃) 省电模式&lt;/p&gt;

&lt;p&gt;VK1623 2.4V～5.2V 48seg*8com 偏置电压 1/4 LQFP100/QFP100；DICE/DIE&lt;/p&gt;

&lt;p&gt;裸片 (绑定 COB)；COG(绑定玻璃) 省电模式&lt;/p&gt;

&lt;p&gt;VK1625 2.4V～5.2V 64seg*8com 偏置电压 1/4 LQFP100/QFP100；DICE/DIE&lt;/p&gt;

&lt;p&gt;裸片 (绑定 COB)；COG(绑定玻璃) 省电模式&lt;/p&gt;

&lt;p&gt;VK1626 2.4V～5.2V 48seg*16com 偏置电压 1/5 LQFP100/QFP100；DICE/DIE 裸片 (绑定 COB) 省电模式&lt;/p&gt;

&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/18124687938/aaab5245-e6b0-4274-93e1-6501d7d62c0a.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/18124687938/eeed9215-7deb-482d-9d04-cf3573a1e7e0.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/18124687938/70ef6721-0a2b-4c21-bd90-dcf9e093ff05.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/18124687938/7c3f8268-37c0-4214-85ec-6aabc7a34690.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;
&lt;img src="https://img.way2solo.com/photo/18124687938/4966beed-e868-4eec-bf75-2ae5431ae4f9.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;——————————————————————————————————————————————————&lt;/p&gt;</description>
      <author>18124687938</author>
      <pubDate>Mon, 11 May 2026 14:29:09 +0800</pubDate>
      <link>https://w2solo.com/topics/7308</link>
      <guid>https://w2solo.com/topics/7308</guid>
    </item>
    <item>
      <title>独立开发者如何控制大模型 API 成本？我的 3 条实战经验</title>
      <description>&lt;p&gt;先交代背景：我们团队做了一款 AI 小工具，重度依赖 GPT-4o 和 Claude 3.5 Sonnet。上个月账单突然飙到 4 万多，作为一个独立开发者出身的人，我肉疼了好几天。&lt;/p&gt;

&lt;p&gt;复盘之后，我发现了几个很容易被忽视的 “烧钱点”，也总结了一套适合小团队的降本方法。分享给同样在用 API 做产品的朋友。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;别让模型说废话（提示词约束）
模型默认是 “话痨模式”，动不动就 “首先…其次…总的来说”。
我们强制在提示词里加了：“只返回 JSON，不包含任何解释。输出不超过 50 字。”
就这么一句，输出 Token 直接砍半。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;运营心得：定好规矩比优化架构见效快。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;高频问题别重复调用（语义缓存）
用户经常问 “怎么接入”“价格多少” 这类问题，每次都让大模型回答，纯属浪费。
我们接了一个轻量缓存：同样或相似的问题，直接从缓存里拿答案，不再调用 API。
命中率 30% 以上，这部分成本直接归零。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;如果你不想自己搓缓存，我们团队做了一个开箱即用的 API 网关（Tokaify），里面集成了语义缓存、智能路由等功能，并且支持免费用额度体验。感兴趣的可以去看看：&lt;a href="https://tokaify.com" rel="nofollow" target="_blank"&gt;https://tokaify.com&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;简单任务别用旗舰模型（智能路由）
意图识别、分类、翻译这些活儿，用便宜模型就够了。
我们让程序自己判断：简单问题走 GPT-3.5-Turbo（成本 1/5），复杂推理才走 GPT-4o。
综合成本降了 35%。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;最后
独立开发者预算有限，每一分钱都要花在刀刃上。希望我的经验能帮你少踩坑。&lt;/p&gt;

&lt;p&gt;如果你也在为 API 成本发愁，可以试试我们家的网关（有免费额度，不充值也能先用）。也欢迎在评论区交流你的省钱妙招，互相学习。&lt;/p&gt;</description>
      <author>Token_wanjia</author>
      <pubDate>Mon, 11 May 2026 14:28:38 +0800</pubDate>
      <link>https://w2solo.com/topics/7307</link>
      <guid>https://w2solo.com/topics/7307</guid>
    </item>
    <item>
      <title>解决 “理发店翻车” 痛点的出海小工具：AI 虚拟换发型 Hair Filter</title>
      <description>&lt;p&gt;产品链接：&lt;a href="https://hairfilter.net/" rel="nofollow" target="_blank"&gt;https://hairfilter.net/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;【做这个产品的初衷】
最开始的灵感来源于生活痛点：很多人去理发店经常遇到 “拿着网图去找 Tony，剪完出来想砸镜子” 的尴尬。主要原因是我们脑补的发型跟自己真实的脸型完全不搭。所以就想借着 AI 图像生成技术，做一个极简的 Web 工具，让大家在动剪刀前，先用自己的脸 “0 成本试错”。&lt;/p&gt;

&lt;p&gt;【上线一年来的迭代与折腾】
项目是去年上线的，主打海外市场。核心功能就是上传正脸照后，保留用户的五官特征，一键融合各种主流发型和发色。&lt;/p&gt;

&lt;p&gt;这一年来踩了不少坑。早期的 AI 生成效果总像是在头上硬扣了个 “塑料假发”，光影非常违和。为了解决这个问题，我花了大量时间调优换发和融合的算法，尽量保留原图的光照环境和皮肤质感。&lt;/p&gt;

&lt;p&gt;最近项目也更新到了 v3.0 版本，主打一个 “轻量、用完即走”，目前的生成真实感算是比较拿得出手了。&lt;/p&gt;

&lt;p&gt;【目前的现状与探讨】
作为一个跑了一年的老项目，目前虽然陆陆续续积累了一些海外的自然流量，但说实话，在持续增长和商业化变现上，依然觉得挑战很大（目前考虑的是新账号免费试用 + 高级功能付费模式）。
体验地址：&lt;a href="https://hairfilter.net/" rel="nofollow" target="_blank"&gt;https://hairfilter.net/&lt;/a&gt;&lt;/p&gt;</description>
      <author>yanyuzzz</author>
      <pubDate>Mon, 11 May 2026 10:14:43 +0800</pubDate>
      <link>https://w2solo.com/topics/7306</link>
      <guid>https://w2solo.com/topics/7306</guid>
    </item>
    <item>
      <title>Hailuo 3.0 AI 视频生成器 — 基于 Minimax 3.0 的文本转视频和图像转视频</title>
      <description>&lt;p&gt;Hailuo 3.0 AI 视频生成器 — 基于 Minimax 3.0 的文本转视频和图像转视频&lt;/p&gt;

&lt;p&gt;我们想和大家分享一下我们最近推出的 AI 视频工作流程——Hailuo 3。Hailuo 3.0 AI 视频生成器专为快速迭代和生成可用于实际发布流程的实用视频片段而打造。&lt;/p&gt;

&lt;p&gt;它支持文本转视频和图像转视频，提供 720p 高清和 1080p 全高清选项，以及 5 秒/10 秒的短时长，方便您生成多个版本，进行比较和导出，无需在不同工具之间切换。该工具基于 Minimax 3.0 上的 Hailuo 3.0 模型构建，支持多种宽高比（16:9、9:16 等），适用于信息流和落地页。此外，它还提供音乐提示字段，帮助您根据视觉方向调整视频氛围。&lt;/p&gt;

&lt;p&gt;我们日常最关注的是快速迭代：先拟定一个简短的拍摄清单（主题、镜头感、光线、情绪），生成各种版本，保留最佳镜头，然后进行细微的剪辑——这对于广告、解释性视频、社交媒体互动以及快速的电影风格测试都非常实用。&lt;/p&gt;

&lt;p&gt;如果您想尝试一下，请访问：&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.hailuo3.app" rel="nofollow" target="_blank"&gt;https://www.hailuo3.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.hailuo-3.com" rel="nofollow" target="_blank"&gt;https://www.hailuo-3.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;新用户注册即可获得免费积分，用于运行首批视频。&lt;/p&gt;

&lt;p&gt;我们很想知道，与其他视频生成器相比，您在质量、控制和迭代速度方面有何感受——尤其是在短视频和营销循环视频方面。非常期待听到社区的反馈。&lt;/p&gt;</description>
      <author>timi</author>
      <pubDate>Sun, 10 May 2026 17:24:35 +0800</pubDate>
      <link>https://w2solo.com/topics/7305</link>
      <guid>https://w2solo.com/topics/7305</guid>
    </item>
    <item>
      <title>我的作品 YouTube to MP3 converter：我把进度、预览和下载路径单独做成了一页</title>
      <description>&lt;p&gt;最近把一个反复出现的小问题单独做成了一页：YouTube to MP3 converter。&lt;/p&gt;

&lt;p&gt;这个页面不是想做一个很大的视频工具集合，而是先把一条很具体的路径讲清楚：当我只需要从 YouTube 链接拿到 MP3 时，能不能看到进度、先预览结果，再决定要不要下载。&lt;/p&gt;

&lt;p&gt;目前这页主要想把下面这条路径做顺：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;粘贴 YouTube URL、youtu.be 链接、Shorts 链接或 video ID。&lt;/li&gt;
&lt;li&gt;启动 MP3 转换任务。&lt;/li&gt;
&lt;li&gt;在等待时查看任务进度。&lt;/li&gt;
&lt;li&gt;在浏览器里先预览生成的 MP3。&lt;/li&gt;
&lt;li&gt;确认结果可用后再下载 MP3 文件。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;我自己遇到这个需求时，最不想看到的是页面只给一个按钮，然后让我等到最后才知道结果是否可用。对这种小工具来说，进度反馈和预览不是装饰，而是用户判断 “这个 MP3 值不值得保存” 的关键步骤。&lt;/p&gt;

&lt;p&gt;边界也写得很明确：&lt;/p&gt;

&lt;p&gt;MP3 转换依赖第三方转换服务，当前只适合 120 分钟以内的视频，并且只应该用于用户拥有版权或已获得下载权限的内容。&lt;/p&gt;

&lt;p&gt;页面在这里：&lt;a href="https://youtubetowav.io/youtube-to-mp3-converter" rel="nofollow" target="_blank"&gt;https://youtubetowav.io/youtube-to-mp3-converter&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtubetowav.io/youtube-to-mp3-converter" rel="nofollow" target="_blank" title=""&gt;&lt;img src="https://img.way2solo.com/photo/ethanjamescolez/a361b599-5f34-4bd1-bab1-d23614323954.png?imageView2/2/w/1920/q/100" title="" alt="YouTube to MP3 converter screenshot"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;想听听大家建议：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;这种小工具页面，第一屏应该先强调 “下载 MP3”，还是先解释进度和预览路径？&lt;/li&gt;
&lt;li&gt;对转换类工具来说，你更在意最终下载直接，还是保存前能先确认结果？&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>ethanjamescolez</author>
      <pubDate>Sun, 10 May 2026 17:04:29 +0800</pubDate>
      <link>https://w2solo.com/topics/7304</link>
      <guid>https://w2solo.com/topics/7304</guid>
    </item>
    <item>
      <title>我开发的 Chrome 扒图浏览器插件又更新了❗</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;一个月前，我发布了自己第一个 Chrome 插件 Image Harvest——一个能扒出网页所有图片的批量下载工具。收到了很多鼓励和建议，这次 v1.0.2 是第一个「有料」的功能更新。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="这次更新了什么？"&gt;这次更新了什么？&lt;/h2&gt;&lt;h3 id="🌍 全球化：5 种语言，母语体验"&gt;🌍 全球化：5 种语言，母语体验&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/193577746/48ad6b16-a5f7-44c9-ade1-65a63d92a518.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;v1.0.2 最大的工程量投入是国际化。现在 Image Harvest 支持 5 种语言：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;英语 (en)&lt;/li&gt;
&lt;li&gt;简体中文 (zh_CN)&lt;/li&gt;
&lt;li&gt;繁体中文 (zh_TW)&lt;/li&gt;
&lt;li&gt;日语 (ja)&lt;/li&gt;
&lt;li&gt;西班牙语 (es)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不需要手动切换，跟着浏览器语言自动适配。所有界面文案——侧边栏、弹窗、设置页、收藏夹、反向搜图页、toast 提示、模态框、按钮——全部走 chrome.i18n 标准方案。&lt;/p&gt;

&lt;p&gt;做这个决定的原因很简单：Chrome Web Store 是全球市场，如果只有英文界面，日本和西语区的用户根本不会点安装。&lt;/p&gt;
&lt;h3 id="💎 7 天 Pro 免费试用：零门槛体验全部高级功能"&gt;💎 7 天 Pro 免费试用：零门槛体验全部高级功能&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/193577746/8c8bd7e7-6594-4147-8a34-102d9a5a7b3a.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;之前很多人在评论区问「Pro 到底值不值得买？」，我觉得与其我说值，不如让大家自己体验。&lt;/p&gt;

&lt;p&gt;现在新安装的用户会自动获得 7 天 Pro 试用，期间所有高级功能全部解锁：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;多标签页同时批量扒图&lt;/li&gt;
&lt;li&gt;pHash 相似图片自动检测去重&lt;/li&gt;
&lt;li&gt;批量高亮定位&lt;/li&gt;
&lt;li&gt;图片收藏夹（IndexedDB 本地存储）&lt;/li&gt;
&lt;li&gt;格式转换（PNG ↔ JPG ↔ WebP）&lt;/li&gt;
&lt;li&gt;自定义命名模板（12 个占位符）&lt;/li&gt;
&lt;li&gt;TinEye / Baidu / Yandex 反向搜图&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;不绑卡、不套路。试用到期前一天会温和提醒一次，过期后自动降级为免费版，免费版的核心功能照常使用。&lt;/p&gt;
&lt;h3 id="📋 批量复制图片链接"&gt;📋 批量复制图片链接&lt;/h3&gt;
&lt;p&gt;&lt;img src="https://img.way2solo.com/photo/193577746/2b34df4a-8680-4105-943d-9553fe779ea3.png?imageView2/2/w/1920/q/100" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;这个功能是用户反馈最多的：「我不想下载图片，我只想拿到 URL」。&lt;/p&gt;

&lt;p&gt;现在选中任意张图片，点一下就能把所有 URL 复制到剪贴板（换行分隔）。单图卡片右键也有「复制链接」。复制成功会显示具体条数（"已复制 12 个链接"），失败时给出权限提示。&lt;/p&gt;

&lt;p&gt;适用场景：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;写文档时批量引用图片链接&lt;/li&gt;
&lt;li&gt;聊天里分享多张图的来源&lt;/li&gt;
&lt;li&gt;SEO 调研时批量采集竞品图片 URL&lt;/li&gt;
&lt;li&gt;开发调试时快速拿到资源路径&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="没用过？30 秒了解 Image Harvest"&gt;没用过？30 秒了解 Image Harvest&lt;/h2&gt;
&lt;p&gt;Image Harvest 是一个隐私优先的 Chrome 图片批量下载插件。它能扒出网页里所有图片——包括大多数下载器会漏掉的 CSS 背景图、懒加载源、Shadow DOM、同源 iframe 里的图片。&lt;/p&gt;

&lt;p&gt;零追踪、零远程代码、100% 本地处理。源码已在 GitHub 开源（MIT 协议）。&lt;/p&gt;

&lt;p&gt;🛒 Chrome 商店安装：&lt;a href="https://chromewebstore.google.com/detail/iecgnjidmogebokcfnejncgnelcepffo" rel="nofollow" target="_blank"&gt;https://chromewebstore.google.com/detail/iecgnjidmogebokcfnejncgnelcepffo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🌐 官网：&lt;a href="https://image-harvest.kyriewen.cn" rel="nofollow" target="_blank"&gt;https://image-harvest.kyriewen.cn&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🎬 演示视频：&lt;a href="https://www.youtube.com/watch?v=o5KdX--l-yw" rel="nofollow" target="_blank"&gt;https://www.youtube.com/watch?v=o5KdX--l-yw&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💻 GitHub：&lt;a href="https://github.com/zbw-zbw/image-harvest" rel="nofollow" target="_blank"&gt;https://github.com/zbw-zbw/image-harvest&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;有任何 bug 或功能建议，欢迎在评论区留言或去 GitHub 提 issue。独立开发者一个人在做，每条反馈我都会看 🙏&lt;/p&gt;</description>
      <author>193577746</author>
      <pubDate>Sun, 10 May 2026 14:02:11 +0800</pubDate>
      <link>https://w2solo.com/topics/7303</link>
      <guid>https://w2solo.com/topics/7303</guid>
    </item>
    <item>
      <title>做了个 AI 视频生成工具出海，分享一些踩坑经验</title>
      <description>&lt;p&gt;大家好，我是 Ethan，独立开发者。最近上线了个面向海外用户的 AI 视频生成工具 HappyHorse AI Video，分享一些做出海产品踩过的坑和心得。&lt;/p&gt;
&lt;h2 id="产品背景"&gt;产品背景&lt;/h2&gt;
&lt;p&gt;做的是 AI 视频生成工具，支持文本转视频、图片转视频。目标用户是内容创作者、营销人员、独立开发者。&lt;/p&gt;

&lt;p&gt;地址：&lt;a href="https://happyhorse-ai.video" rel="nofollow" target="_blank"&gt;https://happyhorse-ai.video&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="踩过的坡"&gt;踩过的坡&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. SEO 冷启动期别再等搜索自然流量&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;上线初期最大的错误是等著 SEO 收录。对于新站上线后的 3-6 个月，Google 对新站有信任度建立期。这段时间更应该主动提交外链、入驻 AI 目录站，建立基础信权。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. AI 工具目录站有真正免费和小额付费之分&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;很多 AI 目录站标注 “免费提交”，但实际上是安转门、设备要加 badge、审核有时要几周。真正干净利落的免费外链目录其实比你想象的少。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Product Hunt 准备期至少要 2-3 周&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;第一次上 PH，没有提前经营账号和粉丝直接冲击效果很差。&lt;/p&gt;
&lt;h2 id="有效的处事"&gt;有效的处事&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;收录进 AI 工具目录站（已提交 60+ 个平台）&lt;/li&gt;
&lt;li&gt;发布开发者博客文章（velog、dev.to、telegra.ph）&lt;/li&gt;
&lt;li&gt;在 Product Hunt 上排期发布（已排期 5/12）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果你也在做出海 AI 工具，欢迎交流！&lt;/p&gt;</description>
      <author>happyhorse_ai</author>
      <pubDate>Sun, 10 May 2026 00:12:35 +0800</pubDate>
      <link>https://w2solo.com/topics/7302</link>
      <guid>https://w2solo.com/topics/7302</guid>
    </item>
    <item>
      <title>善待自己，从定期离开屏幕开始</title>
      <description>&lt;p&gt;作为知识工作者，我常常一打开屏幕，就扎进无止境的任务中去，停不下来。但最后发现实际早已偏离了目标。&lt;/p&gt;

&lt;p&gt;与其这样，不如去喝口水，放松下肩膀。离开，是为了更好地回来。&lt;/p&gt;

&lt;p&gt;&lt;img src="https://huayemao.run/api/files/184d97547fc931ef.webp" title="" alt="haveabreak—计时间休息工具，一场关于离开屏幕的温柔暴政"&gt;&lt;/p&gt;

&lt;p&gt;于是，我做了  &lt;a href="https://break.white-noise.online/zh" rel="nofollow" target="_blank" title=""&gt;haveabreak&lt;/a&gt;。用一个全屏计时器，迫使让视线移开屏幕，休息完足够多的时间再重新投入专注。&lt;/p&gt;</description>
      <author>huayemao</author>
      <pubDate>Sat, 09 May 2026 17:06:55 +0800</pubDate>
      <link>https://w2solo.com/topics/7301</link>
      <guid>https://w2solo.com/topics/7301</guid>
    </item>
    <item>
      <title>【国际会议】第二届智能技术与电力能源系统国际研讨会（ITPES 2026）</title>
      <description>&lt;p&gt;第二届智能技术与电力能源系统国际研讨会 (ITPES 2026) 将于2026年10月19日至 21 日在英国格拉斯哥及线上同步举办。会议旨在为研究人员、专业人士和爱好者提供一个高水平的学术交流平台，探讨能源系统领域的最新研究进展、创新思路与实践经验。会议包括精彩的特邀演讲、学术论文交流以及引人入胜的口头报告，力求促进学术合作与技术创新。&lt;/p&gt;

&lt;p&gt;会议主题 (包括但不限于)：
Artificial Intelligence for Energy Systems
Energy Internet and Internet of Things
Computing Technology for Energy Regeneration
Smart Grid Technology&lt;/p&gt;

&lt;p&gt;收录检索：
所有通过审稿并完成注册的论文都将被收录到 ITPES 2026 会议论文集由 Springer LNNS 系列出版。会议论文集将由 EI Compendex 和 Scopus 等检索。&lt;/p&gt;

&lt;p&gt;投稿方式：
投稿系统：&lt;a href="https://itpes.org/openconf/openconf.php" rel="nofollow" target="_blank"&gt;https://itpes.org/openconf/openconf.php&lt;/a&gt;
电子邮件：cfp@itpes.org &lt;/p&gt;

&lt;p&gt;会议重要日期：
截稿时间：2026年7月20日（在此之前欢迎随时提交文章）
会议时间：2026 年 10 月 19-21 日
会议地点：英国格拉斯哥&lt;/p&gt;

&lt;p&gt;联系方式：
Email：cfp@itpes.org&lt;br&gt;
联系人：Evelyn 
电话（微信同步）：+86 13917384169&lt;/p&gt;

&lt;p&gt;更多会议信息详见会议官网。&lt;/p&gt;</description>
      <author>danrui</author>
      <pubDate>Fri, 08 May 2026 10:43:37 +0800</pubDate>
      <link>https://w2solo.com/topics/7300</link>
      <guid>https://w2solo.com/topics/7300</guid>
    </item>
  </channel>
</rss>
