小赵的技术实践笔记
type: channel
link: https://www.xzhao.vip/
description: 后端开发、AI 提效与数字化折腾实录
items: 宝塔 + Nginx 双端口实现 Java 无感更新，告别发布时的 502 报错
items: 官方筛选不够用，我用油猴给链动小铺货源列表加了增强筛选
items: 用 API Key 登录 Codex 后插件灰色不可用，Codex++ 帮我绕过了这个限制
items: 芋道yudao-ui-admin-vue3 打包从 2 分钟到 1 分钟，我做了这几件事
items: Navicat Premium(数据库管理) v17.3.6 绿色版
items: 误删 .git 目录后怎么恢复远程仓库连接，完整操作记录
items: 清除此电脑中WPS网盘/百度网盘等图标方法
items: sparkle 覆写脚本分享
items: IDEA配置使用mvnd打包
items: LX Music 音乐免费播放工具

宝塔 + Nginx 双端口实现 Java 无感更新，告别发布时的 502 报错
type: item
date: 2026-06-15T01:55:00+00:00
description: 最近在迭代我们公司的材料采购系统时，又遇到了那个让人头疼的老问题：每次后端打包发布，接口总要断开那么十多秒，前端页面轻则转圈圈，重则直接报 502。对于一个正在频繁做数据对账、表单提交的系统来说，这十几秒的中断极易导致用户数据卡死或重复提交。虽然用的是单台服务器，但“服务重启中，请稍候”这种体验，在一线开发眼里确实是不及格的。既然用了宝塔面板加 Nginx 反向代理，其实只需要稍微改变一下思路，用“单机双端口交替部署（蓝绿发布）”的方式，配合 Nginx 的容错机制，就能做到完全不断开、无感的平滑切换。这篇文章我就把亲测通过的 Nginx 配置和全自动 Shell 脚本贴出来，希望能帮同样在做单机运维的兄弟少踩点坑。1. 为什么单实例重启做不到“无感”？之前我们的运维脚本很简单：kill 掉旧进程 -> 替换 Jar 包 -> nohup java -jar ...。这种“先杀后启”的方式，存在两个无法调和的致命伤：服务真空期：旧进程死了，新进程还在 JVM 初始化、加载 Spring 容器。在这漫长的十几秒到一分钟内，Nginx 找不到后端，进来的请求全部铁定遭遇 502。硬切中断：旧进程被干掉时，它手里可能正处理到一半的数据库事务、正在上传的图片会直接被强行掐断，给用户返回网络连接拒绝。所以，要做到接口不断开，核心只有一条：在新版本完全启动并成功监听端口之前，老版本必须死死钉在岗位上继续干活；新版本准备好了，Nginx 无感把流量切过去，老版本再优雅退场。2. 核心思路：单机双端口的“伪滚动更新”我们给项目分配两个内部端口，比如 9821（端口 A）和 9822（端口 B）。常驻状态：平时线上只有其中一个端口（比如 A）在跑，Nginx 把流量正常转给 A。发布时刻：我们上传新 Jar 包，脚本检测到当前是在跑 A，它绝对不去杀 A，而是默默在后台把新版代码在 端口 B 上启动起来。健康检查：脚本在后台不断去探测端口 B，直到 B 的 Spring Boot 完全初始化完毕、Tomcat 端口握手成功。无感切换：Nginx 的 proxy_next_upstream 机制会自动判断。当新请求进来，如果新端口活了，流量自然平滑过渡；同时 Nginx 在检测到老端口关闭时，会自动把未处理完的残余请求悄悄转给新端口。优雅退场：新版完全接管流量后，脚本向老端口发送普通的 kill 信号，触发 Spring Boot 的优雅停机，老版本站完最后一班岗，安全退出。⚠️ 唯一的硬性要求：在发布的这几十秒内，服务器内存要能短暂同时撑起两个 Java 实例（比如平时占 1G，发布时短暂需要 2G，等老的杀了就回落）。如果服务器内存只有 1G 且已经快爆了，请先去加内存，否则系统会因为 OOM 随机乱杀进程。3. 第一步：改造宝塔网站的主配置文件打开宝塔面板 -> 找到你的网站 -> 点击“设置” -> 找到 “配置文件”。在配置文件的 最顶部（也就是 server { 块的外层），加入以下 upstream 负载均衡组的定义。这样 Nginx 才能动态认得这两个端口。# 定义 Java 后端服务组，名字叫 procurement_servers upstream procurement_servers { server 127.0.0.1:9821 max_fails=3 fail_timeout=10s; server 127.0.0.1:9822 max_fails=3 fail_timeout=10s; }加好之后，点击保存即可。4. 第二步：重写宝塔的反向代理规则在宝塔面板的网站设置里，点击左侧的 “反向代理” -> 找到你原本创建好的那个反代条目，点击“配置文件”。把里面原本写死 proxy_pass http://127.0.0.1:9821; 的内容完全清空，用下面这段更健全的反代规则整体覆盖：#PROXY-START/ location ^~ / { # 1. 转发到我们在全局配置中定义的 upstream 服务组 proxy_pass http://procurement_servers; # 2. 核心无感切换机制 # 当其中一个端口被脚本关掉、或正在重启报 502/504 时，Nginx 自动、无感地在 0.1 秒内把请求发给另一个健康的端口 proxy_next_upstream error timeout invalid_header http_502 http_503 http_504; proxy_next_upstream_tries 2; proxy_next_upstream_timeout 10s; # 3. 基础反代透传配置（改为标准的 $host，比宝塔默认写死 127.0.0.1 兼容性更好） p…

官方筛选不够用，我用油猴给链动小铺货源列表加了增强筛选
type: item
date: 2026-05-15T00:13:52+00:00
description: 最近在链动小铺后台找货源时，有个感受比较明显：官方的搜索和筛选功能太少了。原页面能搜商品，也能看到成本价、库存、商家、对接状态这些信息，但真正找货源时，我更关心的是这些问题：哪些商品还有库存我的成本价是不是足够低哪些商品还没有对接某个分类下面有哪些商品能不能一次多看一些结果，而不是一直翻页这些信息页面上其实都有，只是缺少更顺手的筛选方式。我没有链动小铺前端和后端的修改权限，所以最后没有走“改页面源码”的路子，而是写了一个油猴脚本，在现有页面上加一个悬浮的增强筛选面板。这个方案不算正式产品功能，但对自己找货源、比价格、看库存来说，确实能省不少时间。为什么选油猴脚本这种需求有几种做法。如果能改官方系统，最稳的方式肯定是前端加筛选项，后端接口支持条件查询，然后按条件分页返回。但这次没这个条件。我能做的是在浏览器里增强当前页面。Chrome 插件也可以做，但对这个需求来说有点重。油猴脚本更合适：安装简单修改后刷新页面就能验证只针对一个页面生效可以直接复用当前页面的登录态不需要重新打包浏览器插件所以最后我选择 Tampermonkey。它的定位很清楚：不是替代官方功能，而是在自己浏览器里加一层辅助工具。先确认页面到底怎么搜在写脚本前，我先看了一下页面行为。链动小铺这个页面路径是：https://www.ldxp.cn/merchant/my_parent/source_square页面里有两个主要区域：货源广场商品搜索商品搜索不是一打开就直接显示表格，而是先输入关键词，点击搜索后才会展示商品结果。搜索时调用的是这个接口：/merchantApi/MyParent/searchGoodsList请求参数大概是这样：{ "current": 1, "pageSize": 50, "name": "", "goods_type": "card", "keywords": "GPT" }这个接口返回的数据里，已经有脚本需要的大部分字段，比如商品名称、分类、代理价、我的成本价、库存、商家、是否已对接。所以思路就很明确了：先用原接口把搜索结果拉到浏览器本地，再在本地做二次筛选。这里有一个限制要提前说清楚。这个脚本不是后端筛选。它只能筛已经拉到本地的数据。如果只拉了 5 页，那筛选范围就是这 5 页。想看更多，就需要把脚本里的“拉取页数”调大。脚本做了哪些功能最后做出来的辅助面板是一个悬浮窗。它不插入原页面内容区，避免把官方页面布局撑乱。目前主要功能有这些：关键词搜索商品类型筛选：卡密、知识、资源、权益拉取多页结果按我的成本价区间筛选按库存筛选：全部、有库存、缺货按状态筛选：全部、正常、未上架按对接状态筛选：全部、已对接、未对接按分类关键词筛选按商家名称筛选按我的成本价或库存排序每页显示 50、100、200、1000、10000 条首页、上一页、页码跳转、下一页、末页面板支持拖动、调整大小、收起展开最终效果大概是这样：关键代码油猴脚本头部先限制只在链动小铺对应页面生效。// ==UserScript== // @name 链动小铺货源商品增强筛选 // @namespace https://www.ldxp.cn/ // @version 0.4.1 // @description 在货源商品搜索页增加价格区间、库存、分类、对接状态等本地筛选，并支持一次拉取多页结果。 // @match https://www.ldxp.cn/merchant/my_parent/source_square* // @grant none // @run-at document-idle // ==/UserScript==这里我用了 @grant none。原因是这个脚本只请求当前站点自己的接口，不需要跨域，也不需要额外的 GM API。读取当前登录态原页面请求接口时会带 Merchant-Token。脚本里没有把 token 写死，而是从当前页面的 localStorage 里读。function getToken() { try { const raw = localStorage.getItem("auth-token"); if (!raw) return ""; const parsed = JSON.parse(raw); return parsed && parsed.value ? parsed.value : ""; } catch (_) { return ""; } }然后用 fetch 调接口。async function postJson(url, body) { const token = getToken(); const response = await fetch(url, { method: "POST", credentia…

用 API Key 登录 Codex 后插件灰色不可用，Codex++ 帮我绕过了这个限制
type: item
date: 2026-05-13T00:52:01+00:00
description: 用 Codex 的时候，我一直有个特别烦的问题。我是用 API Key 登录的，走的是第三方中转站，没有 ChatGPT 账号。Codex 主体功能都能正常用，但插件入口是灰色的，锁死的，点进去就一行提示：需要登录 ChatGPT 账号。这意味着插件功能跟我完全没关系。说白了，我花了钱买 API Key，主体功能能跑，但插件生态整个被挡在外面了。这个体验挺割裂的——你明明知道 Codex 有插件能力，但就是用不了。后来在 GitHub 上找到了 Codex++，装上之后插件功能终于能用了。下面把整个过程记一下。Codex++ 是什么Codex++ 是一个 Codex 的外部增强工具，GitHub 地址：BigPizzaV3/CodexPlusPlus它不修改 Codex 的原始安装文件，而是通过 Chromium DevTools Protocol（CDP）向 Codex 的渲染进程注入脚本来实现功能增强。简单理解就是：它是一个独立的启动器，从外面"接管" Codex 的启动过程，往里注入解锁逻辑。核心功能有两个：解锁插件入口 — API Key 登录模式下也能正常使用插件会话删除 — Codex 原生只有归档，没有真正的删除按钮，Codex++ 补上了依赖要求：Python 3.11+，已经装好 Codex App。安装步骤第一步：获取代码从 GitHub 克隆仓库到本地：git clone https://github.com/BigPizzaV3/CodexPlusPlus.git cd CodexPlusPlus第二步：安装依赖python -m pip install -e .这一步会把 Codex++ 及其依赖装好。第三步：运行安装Windows 用户可以直接双击项目根目录的 setup.bat，会弹出一个菜单：[1] Install Codex++ [2] Uninstall Codex++ [3] Update Codex++ [4] Exit选 1 就行。安装完成后桌面会生成一个 Codex++.lnk 快捷方式。也可以用命令行安装：python -m codex_session_delete setupmacOS 用户同样用命令行：python -m codex_session_delete setup安装后会在 /Applications/ 下生成 Codex++.app。第四步：通过 Codex++ 启动以后启动 Codex 不要直接点 Codex 的图标，要点 Codex++ 的快捷方式。它的工作流程是：以 --remote-debugging-port=9229 参数启动 Codex App启动本地 helper 服务通过 CDP 注入 renderer-inject.js 到渲染进程插件入口解锁，会话删除按钮出现第五步：验证效果启动后看两个地方：顶部菜单栏多了 Codex++ 菜单插件入口从灰色变成了可点击状态点进插件列表，能正常浏览和安装插件就说明生效了。还有个实用功能：会话删除除了解锁插件，Codex++ 还补了一个 Codex 一直没做的功能——会话删除。原生 Codex 的会话列表只有归档，没有删除。Codex++ 装上之后，鼠标悬停在会话上会显示"删除"按钮，点删除前有确认提示，还支持撤销。删除逻辑会优先走服务端，如果服务端不可用，就直接操作本地的 SQLite 数据库（~/.codex/state_5.sqlite）。删除前会自动备份到 ~/.codex-session-delete/backups，这点比较稳。遇到的问题安装过程中有几个地方要注意：端口冲突：Codex++ 启动时会用到 9229 端口做 CDP 通信。如果这个端口被占了，启动会失败。看一下 ~/.codex-session-delete/launcher.log 日志就能定位。代理问题：如果你的网络环境需要代理，Codex++ 启动时会自动探测常见本地代理端口（比如 127.0.0.1:7897）。如果探测不到，需要手动设置代理环境变量。Codex 更新后不兼容：因为 Codex++ 是通过注入脚本工作的，如果 Codex App 更新后页面结构变了，注入脚本可能失效。这时候需要更新 Codex++ 版本。检查更新：python -m codex_session_delete check-update执行更新：python -m codex_session_delete update卸载如果不想用了，卸载也很干净：Windows：系统设置 → 应用 → 已安装的应用，找到 Codex++ 卸载。或者命令行：python -m codex_session_delete remove如果连日志和备份都想删掉：python…

芋道yudao-ui-admin-vue3 打包从 2 分钟到 1 分钟，我做了这几件事
type: item
date: 2026-05-12T10:27:27+00:00
description: 最近在基于 yudao-ui-admin-vue3（芋道 Vue3 后台管理框架）的项目里做了一次打包优化。芋道这个框架本身功能很全，但依赖也重。src 下 2000 多个文件，除了框架自带的 element-plus、vue-i18n，业务侧还加了 echarts、bpmn-js、form-create 表单设计器、富文本编辑器、甘特图、思维导图这些重型库。打包时间一直在 2 分钟以上，这次优化后降到了 1 分 8 秒。核心就改了四个地方，记录一下。用芋道框架的同学可以直接抄。先说结论优化项改动效果Terser → esbuild去掉 minify: 'terser'压缩阶段快 20-100 倍构建期 ESLintbuild 时不注册 eslint 插件省了约 50 秒压缩大小报告reportCompressedSize: false省掉 gzip 计算chunk 拆分大库单独拆 chunk并行压缩一、最大的一刀：去掉 Terser这是最核心的优化。芋道模板的 vite.config.ts 里默认写了 minify: 'terser'，带着 drop_console 和 drop_debugger 的 terserOptions。这个配置在项目小的时候没什么感觉，但文件一多就成了瓶颈。Terser 是纯 JavaScript 实现的压缩工具，Vite 5 默认用的 esbuild 是 Go 写的，速度差了一个量级。我一开始没注意到这个配置，先去折腾别的了。后来发现压缩阶段占了打包大头，才回头看到这一行。改法很简单，把 minify: 'terser' 和 terserOptions 整段删掉就行：// 芋道模板默认配置 build: { minify: 'terser', terserOptions: { compress: { drop_debugger: env.VITE_DROP_DEBUGGER === 'true', drop_console: env.VITE_DROP_CONSOLE === 'true' } }, } // 改成这样，不写 minify，走 esbuild 默认 build: { // 删掉 minify 和 terserOptions }如果你确实需要 drop_console，可以用 vite-plugin-drop-console 之类的插件在编译阶段处理，不用靠 Terser。另外最新 Vite 8 已经默认用 Oxc Minifier（Rust 实现），官方说比 Terser 快 30-90 倍，压缩率只差 0.5-2%。后续升级 Vite 版本这个问题会自动解决。二、构建时禁用 ESLint 插件芋道模板用了 vite-plugin-eslint，配置了 lintOnStart: false。我一开始以为这个配置能让 build 时跳过 lint。结果不是。vite-plugin-eslint 的 linting 发生在 Vite 的 transform 钩子里，也就是每个文件编译时都会跑一次 ESLint。lintOnStart 只控制 dev server 启动时是否 lint，跟 build 时的 transform 完全没关系。2000 多个文件，每个文件过一遍 ESLint，这个开销非常可观。正确的做法是 build 时不注册这个插件。我改成了条件注册：// build/vite/index.ts export function createVitePlugins(isBuild = false) { return [ Vue(), VueJsx(), // ... 其他插件 // 只在 dev 时注册 ESLint ...(!isBuild ? [EslintPlugin({ cache: false, include: ['src/**/*.vue', 'src/**/*.ts', 'src/**/*.tsx'], })] : []), ] }// vite.config.ts const isBuild = command === 'build' plugins: createVitePlugins(isBuild),这样 dev 时正常 lint，build 时完全跳过。lint 这种事应该在 CI 或 commit 阶段做，不应该拖慢打包。这一个改动单独省了将近 50 秒。三、关闭压缩大小报告Vite 默认会在打包完成后计算每个 chunk 的 gzip 大小，输出到控制台。小项目无所谓，但芋道项目 chunk 多、体积大，这个计算本身也要花好几秒。加一行配置关掉：build: { reportCompressedSize: false, }四、更精细的 chu…

Navicat Premium(数据库管理) v17.3.6 绿色版
type: item
date: 2026-05-09T07:23:00+00:00
description: Navicat Premium 是强大的一体化数据库开发解决方案，可从单一应用程序无缝连接多个数据库，包括 MySQL、PostgreSQL、MongoDB、MariaDB、SQL Server、Oracle、SQLite、Redis 和 Snowflake。同时，它与达梦、金仓、GaussDB、OceanBase、TiDB、IvorySQL、PolarDB 数据库及阿里云、腾讯云和华为云等主流云数据库兼容。你可以快速轻松地创建、管理和维护数据库。Navicat 原生的用户界面为用户带来了简化数据库操作的舒适体验，使数据库的设计、管理和维护比以往任何时候都更加轻松。无论你是执行复杂的查询、执行数据迁移、调整数据库的数据模型，还是利用强大的商业智能工具进行深入分析，Navicat Premium 以丰富的功能和 AI 助手的智能辅助，全方位优化数据库性能并提高生产力。软件截图：下载链接:https://pan.baidu.com/s/1q43jSuHqU9p8YLNQZ9fA_A?pwd=5200 提取码: 5200如果觉得软件好用，建议购买官方正版授权，支持开发者持续更新与维护。

误删 .git 目录后怎么恢复远程仓库连接，完整操作记录
type: item
date: 2026-05-09T01:06:48+00:00
description: 今天操作项目的时候，不小心把 .git 目录删了。代码文件都在，但 git status 已经跑不了了，git 信息全没了。这个项目是一个 Vue3 的后台管理系统，远程仓库在 Gitee 上。我不想重新 git init 然后强推，那样会和远程仓库的历史完全断裂，后面协作会出大问题。所以目标很明确：在不丢失远程提交记录的前提下，重新把本地代码和远程仓库连起来。先说结论四步搞定：git init git remote add origin https://gitee.com/your-org/your-project.git git fetch origin git reset --hard origin/master注意最后一个参数，是 origin/master 不是 origin/main。这个坑下面单独讲。具体操作过程第一步：重新初始化本地仓库git init这一步只是在当前目录重新创建一个空的 .git 目录，不会影响你的代码文件。第二步：重新添加远程仓库地址git remote add origin https://gitee.com/your-org/your-project.git把你的远程仓库地址换成你自己的就行。如果是 GitHub，地址格式一样，只是域名不同。第三步：从远程拉取分支信息git fetch origin这一步会把远程的所有分支和提交记录拉到本地。拉完之后我看到的输出是：* [new branch] master -> origin/master注意这里已经暴露了一个关键信息：远程的主分支叫 master，不叫 main。第四步：重置本地代码到远程分支git reset --hard origin/master执行完之后显示：HEAD is now at af7bc9f first commit到这里代码就已经和远程完全一致了。踩坑：分支名不匹配一开始我本能地写了：git reset --hard origin/main然后报了这个错：fatal: ambiguous argument 'origin/main': unknown revision or path not in the working tree.这个报错不算直观，ambiguous argument 看起来像参数格式问题，但实际原因很简单：远程根本没有 main 分支，只有 master 分支。现在 Git 的默认主分支名确实是 main，但很多老项目、Gitee 上不少项目用的还是 master。所以 git fetch 完之后，先看看拉下来的是什么分支名，再执行 reset。一个简单的判断方法：git fetch 之后，跑一下 git branch -r 就能看到远程有哪些分支。最后设置上游跟踪reset 之后我检查了一下状态，发现 upstream 还没配。执行：git branch --set-upstream-to=origin/master master这样后续 git pull 和 git push 就能正常追踪远程分支了，不用每次手动指定。这次操作的前提有一点要注意：这套操作能成功，是因为远程仓库的代码和我本地删 .git 之前的代码基本一致。如果本地有很多未提交的新改动，git reset --hard 之后这些改动会全部丢掉。所以如果你本地有未提交的代码，建议先备份一份，reset 之后再手动合进去。我这次的情况是本地有两个未跟踪的新目录，是新加的接口和页面文件。因为还没 add 过，所以 git reset --hard 不会影响它们——hard reset 只作用于已经被 git 跟踪的文件。总结步骤命令作用初始化git init创建空 .git 目录添加远程git remote add origin <url>关联远程仓库拉取分支git fetch origin获取远程分支信息重置代码git reset --hard origin/<branch>对齐到远程分支设置跟踪git branch --set-upstream-to=origin/<branch> <branch>配置上下游关系整个过程不到两分钟，代码没丢，历史没断，和直接 git clone 一个新仓库效果一样。以后万一再遇到 .git 被误删的情况，别慌，照着来就行。

清除此电脑中WPS网盘/百度网盘等图标方法
type: item
date: 2026-03-31T02:24:16+00:00
description: 一般来说，这些入口可以通过程序设置关闭，如WPS可以通过右键任务栏图标打开设置关闭，但是这样治标不治本，而且有些软件的设置藏得很隐蔽，不太好找到。通用解决方法Win+R打开运行，输入regedit回车进入注册表编辑器。分别打开以下路径：计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\MyComputer\NameSpace计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace展开NameSpace文件夹，会有若干项。点击每一项，在右侧会提示此项属于哪个软件。根据需要右键删除左侧项即可。注意两个路径都要删除。

sparkle 覆写脚本分享
type: item
date: 2026-02-05T03:12:22+00:00
description: 主要是在使用的时候，发现每个订阅的分组方式都不一样，规则也比较不同。找了一个可以统一的，覆写脚本覆写新建JavaScript// Mihomo Party 覆写 / Clash Verge Rev 扩展脚本 function main(params) { if (!params.proxies) return params; overwriteBasicOptions(params); overwriteDns(params); overwriteFakeIpFilter(params); overwriteNameserverPolicy(params); overwriteHosts(params); overwriteTunnel(params); overwriteProxyGroups(params); overwriteRules(params); return params; } // 覆写Basic Options function overwriteBasicOptions(params) { const otherOptions = { "mixed-port": 7897, "allow-lan": true, mode: "rule", "log-level": "warning", ipv6: false, "find-process-mode": "strict", profile: { "store-selected": true, "store-fake-ip": true, }, "unified-delay": true, "tcp-concurrent": true, "global-client-fingerprint": "chrome", sniffer: { enable: true, sniff: { HTTP: { ports: [80, "8080-8880"], "override-destination": true, }, TLS: { ports: [443, 8443], }, QUIC: { ports: [443, 8443], }, }, "skip-domain": ["Mijia Cloud", "+.push.apple.com"] }, }; Object.keys(otherOptions).forEach((key) => { params[key] = otherOptions[key]; }); } // 覆写DNS function overwriteDns(params) { const dnsList = [ "https://223.5.5.5/dns-query", "https://doh.pub/dns-query", ]; const proxyDnsList = [ "https://223.5.5.5/dns-query", "https://doh.pub/dns-query", ]; const dnsOptions = { enable: true, "prefer-h3": true, ipv6: false, "enhanced-mode": "fake-ip", "fake-ip-range": "198.18.0.1/16", nameserver: dnsList, "proxy-server-nameserver": proxyDnsList, }; params.dns = { ...dnsOptions }; } // 覆写DNS.Fake IP Filter function overwriteFakeIpFilter (params) { const fakeIpFilter = [ "+.m2m", "injections.adguard.org", "local.adguard.org", "+.bogon", "+.local", "+.lan", "+.internal", "+.localdomain", "home.arpa", "127.0.0.1.sslip.io", "127.atlas.skk.moe", "dns.msftncsi.com", "*.srv.nintendo.net", "*.stun.playstation.net", "xbox.*.microsoft.com", "*.xboxlive.com", "*.turn.twilio.com", "*.stun.twilio.com", "stun.syncthing.net", "stun.*", "127.*.*.*.sslip.io", "127-*-*-*.sslip.io", "*.127.*.*.*.…

IDEA配置使用mvnd打包
type: item
date: 2026-01-29T07:36:00+00:00
description: 下载mvndhttps://github.com/apache/maven-mvnd/releases配置mvnd使用maven设置修改D:\soft\maven-mvnd-1.0-m6-m39-windows-amd64\conf中的mvnd.properties配置文件最后一行配置maven setting地址maven.settings=D://soft//apache-maven-3.5.4//conf//settings.xml在环境变量Path中添加mvnd的主目录如D:\soft\maven-mvnd-1.0-m6-m39-windows-amd64\bincmd运行mvnd -v 检验是否成功安装idea安装maven helper插件配置maven helper插件使用mvnd打包，写入mvnd.exe的路径不再使用maven原生命令打包idea配置utf-8编码-encoding utf-8

LX Music 音乐免费播放工具
type: item
date: 2026-01-05T07:08:00+00:00
description: 介绍不多说官网：https://lxmusic.toside.cn/GitHub：https://github.com/lyswhut/lx-music-desktop默认安装后会因为版权问题不能播放，需要自定义音乐源野花：https://liuyang-public.oss-cn-beijing.aliyuncs.com/flower-v1.0.0.js https://raw.githubusercontent.com/OneCodeMonkey/music-sources/master/js/flower-v1.0.0.js