<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>星光下的赶路人</title><link>https://forstyle.cc/zblog/</link><description></description><item><title>Windows 精确触摸板实现 Mac 同款三指拖拽完整教程 </title><link>https://forstyle.cc/zblog/post/129.html</link><description>&lt;blockquote&gt;&lt;p&gt;很多用惯 Mac 的用户换到 Windows 笔记本后，最不习惯的就是触摸板缺少&lt;strong&gt;三指拖移&lt;/strong&gt;——三根手指轻放触控板直接拖动窗口、框选文字、拖拽文件，不用用力按压触摸板。
本文使用开源免费工具 &lt;code&gt;ThreeFingerDragOnWindows&lt;/code&gt;，仅适用于 &lt;strong&gt;Windows Precision 精确触摸板（PTP）&lt;/strong&gt;，老款 Synaptics/ELAN 非PTP触控板不支持该方案。&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;一、前置检查：确认你的电脑是否支持&lt;/h2&gt;&lt;h3&gt;1. 检测精确触摸板&lt;/h3&gt;&lt;p&gt;按下快捷键 &lt;code&gt;Win + I&lt;/code&gt; 打开设置 → &lt;strong&gt;蓝牙和设备 → 触摸板&lt;/strong&gt;页面顶部出现文字：&lt;strong&gt;你的电脑有一个精确式触摸板&lt;/strong&gt;，才可以继续。&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;如果没有该提示，代表是老旧触控板，底层不支持PTP手势，本方案无效。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608261051413766073.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;2. 确认系统架构（选择对应安装包）&lt;/h3&gt;&lt;p&gt;任务栏右键打开&lt;strong&gt;任务管理器 → 性能 → CPU&lt;/strong&gt;&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;普通AMD/Intel处理器（如R5 4600U、i5-1135G7等）→ &lt;strong&gt;x64&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Surface Pro X、国产ARM笔记本 → &lt;strong&gt;arm64&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;古董32位系统 → &lt;strong&gt;x86&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;绝大多数新款笔记本直接选择 &lt;code&gt;x64&lt;/code&gt; 版本。&lt;/p&gt;&lt;/blockquote&gt;&lt;h2&gt;二、准备工作：关闭系统原生三指手势（关键！防止冲突）&lt;/h2&gt;&lt;p&gt;同样在 &lt;code&gt;Win+I → 蓝牙和设备 → 触摸板&lt;/code&gt;&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;找到&lt;strong&gt;三指手势&lt;/strong&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;li&gt;&lt;p&gt;✅ 四指手势不受影响，可以保留「四指左右切换虚拟桌面」等原生功能&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;三、下载与安装 ThreeFingerDragOnWindows&lt;/h2&gt;&lt;h3&gt;方式1：GitHub 离线安装包（推荐，无网络商店限制）&lt;/h3&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608261054042827491.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;项目开源地址：&lt;a href=&quot;https://github.com/ClementGre/ThreeFingerDragOnWindows&quot;&gt;https://github.com/ClementGre/ThreeFingerDragOnWindows&lt;/a&gt;在 Releases → Assets 里选择对应架构文件：&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;x64架构：&lt;code&gt;ThreeFingersDragOnWindows_2.0.7_x64.Msix&lt;/code&gt;（绝大多数用户）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;arm64架构：&lt;code&gt;ThreeFingersDragOnWindows_2.0.7_arm64.Msix&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;x86(32位)：&lt;code&gt;ThreeFingersDragOnWindows_2.0.7_x86.Msix&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;blockquote&gt;&lt;p&gt;&lt;code&gt;.msix&lt;/code&gt; 是微软官方安装包，双击即可安装；如果提示安装策略拦截：右键文件 → 属性 → 勾选【解除锁定】后重试。&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;方式2：微软商店一键安装（最简单，自动更新）&lt;/h3&gt;&lt;p&gt;直接打开微软商店，搜索 &lt;code&gt;ThreeFingerDragOnWindows&lt;/code&gt;，一键安装，和离线包内容完全一致。&lt;/p&gt;&lt;h2&gt;四、软件基础配置（安装完成后打开软件设置）&lt;/h2&gt;&lt;p&gt;打开 ThreeFingerDragOnWindows，按照下面参数配置：&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Enable three finger drag&lt;/strong&gt;：开启三指拖拽总开关&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Mouse button to be held while dragging：选择 &lt;code&gt;Left button&lt;/code&gt;（模拟左键拖拽）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Delay before drag starts（触发延迟）：推荐 &lt;code&gt;200~500ms&lt;/code&gt;，数值越高越不容易误触&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Run on startup&lt;/strong&gt;：勾选开机自启&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ &lt;strong&gt;Elevated mode（管理员模式）&lt;/strong&gt;：勾选后可以拖动任务管理器、安装弹窗这类管理员权限窗口（强烈建议开启）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;查看检测状态：显示绿色文字 &lt;code&gt;Touchpad exists and is registered!&lt;/code&gt; = 触摸板识别成功&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;拖拽灵敏度、鼠标加速默认即可，新手无需额外调整&lt;/p&gt;&lt;/blockquote&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;五、使用方法（和Mac完全一致）&lt;/h2&gt;&lt;p&gt;三根手指同时轻放在触摸板上直接滑动：&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;拖动窗口位置&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&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;/ul&gt;&lt;h2&gt;六、常见故障排查&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;三根手指放上去没有任何反应&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;确认是Precision精确触摸板&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;系统三指手势已经全部设置为【无】&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;软件检测提示成功识别触摸板，必要时开启管理员模式&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;频繁误触，随便放三根手指就触发拖拽&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;调高触发延迟（调到400~500ms），降低拖拽灵敏度&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;普通窗口可以拖动，任务管理器/安装弹窗拖不动&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;在软件设置里开启 &lt;code&gt;Elevated mode&lt;/code&gt;，重启软件生效&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;&lt;p&gt;msix安装包无法安装&lt;/p&gt;&lt;/li&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;优先改用微软商店直接安装&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;h2&gt;七、拓展方案（可选，丰富更多Mac手势）&lt;/h2&gt;&lt;p&gt;ThreeFingerDragOnWindows&lt;strong&gt;只专注实现三指拖移&lt;/strong&gt;，如果你想要更多自定义手势（四指收拢打开开始菜单、媒体控制等），可以搭配下面工具：&lt;/p&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;GestureSign&lt;/strong&gt;：免费可视化手势自定义工具，功能丰富，适合需要大量自定义手势的用户&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;AutoHotkey&lt;/strong&gt;：脚本级自定义，自由度天花板，适合有基础的进阶玩家&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;外接妙控板Magic Trackpad&lt;/strong&gt;：搭配开源驱动，可以实现无限接近原生Mac触摸板完整体验&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;八、局限说明（硬件底层限制，无法完美复刻Mac）&lt;/h2&gt;&lt;ol style=&quot;list-style-type: decimal;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;普通Windows触摸板&lt;strong&gt;没有Force Touch压力感应、线性马达触觉反馈&lt;/strong&gt;，无法实现按压预览、力度反馈&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Windows底层滚动惯性算法和macOS不同，即便全部设置完成，顺滑度依然存在细微差距&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;老旧Win32软件对手势支持不一致，部分程序会吞掉触摸板手势，识别稳定性不如Mac全局统一&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2&gt;补充：原生触摸板基础Mac风格配置（搭配三指拖移一起用）&lt;/h2&gt;&lt;p&gt;在系统触摸板设置中额外开启：&lt;/p&gt;&lt;ul style=&quot;list-style-type: disc;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;✅ 轻点来点按（单指轻触=左键，不用按下去）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ 双指轻点=右键&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ 自然滚动（滚动方向和Mac保持一致）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ 双指捏合缩放、双指左右滑动网页前进后退&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;✅ 四指左右滑动切换虚拟桌面&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 26 Aug 2026 10:09:55 +0800</pubDate></item><item><title>NyaTerm 最近发现的一款好用的运维工具分享</title><link>https://forstyle.cc/zblog/post/128.html</link><description>&lt;p&gt;NyaTerm 是国产的&lt;span style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;免费开源、跨平台现代化一站式终端运维客户端&lt;/span&gt;，对标 Xshell、MobaXterm、WindTerm，由 Rust+Tauri+React 开发，全平台无付费阉割功能，主打一套软件搞定服务器远程登录、文件传输、设备调试、服务器监控等全流程运维工作。&lt;span style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; display: inline-block; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;h3 style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-size: 16px; font-weight: 400; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;span style=&quot;text-decoration: none;&quot;&gt;1. 支持连接协议&lt;/span&gt;&lt;/h3&gt;&lt;/div&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; display: flex; flex: 0 1 auto; flex-direction: column; justify-content: normal; align-items: normal; padding: 0px; margin: 0px 0px 8px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;div messageid=&quot;52234514504670466&quot; pluginconfig=&quot;[object Object]&quot; style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px 0px 8px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;table&gt;&lt;thead style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot; class=&quot;firstRow&quot;&gt;&lt;th style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; text-align: center; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);&quot;&gt;协议类型&lt;/th&gt;&lt;th style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; text-align: center; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);&quot;&gt;适用场景&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;SSH（核心）&lt;/td&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;Linux 服务器远程登录、跳板机、端口转发、OTP 二次验证&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;内置 SFTP&lt;/td&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;服务器文件上传下载，无需单独装 WinSCP&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;本地 Shell&lt;/td&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;Windows CMD/PowerShell、macOS/Linux 原生终端&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;Telnet&lt;/td&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;老旧交换机、工业老旧设备调试&lt;/td&gt;&lt;/tr&gt;&lt;tr style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;Serial 串口&lt;/td&gt;&lt;td style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;嵌入式开发板、网络交换机 Console 调试&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;h3 style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-size: 16px; font-weight: 400; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;2. 核心特色功能&lt;/h3&gt;&lt;/div&gt;&lt;div style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; font-family: ui-sans-serif, system-ui, sans-serif, &amp;quot;Apple Color Emoji&amp;quot;, &amp;quot;Segoe UI Emoji&amp;quot;, &amp;quot;Segoe UI Symbol&amp;quot;, &amp;quot;Noto Color Emoji&amp;quot;; line-height: 24px; text-wrap: wrap; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; margin: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot;&gt;&lt;ol style=&quot;font-variant-numeric: normal; font-variant-east-asian: normal; font-variant-alternates: normal; font-kerning: auto; font-optical-sizing: auto; font-feature-settings: normal; font-variation-settings: normal; font-variant-position: normal; font-stretch: normal; line-height: 24px; flex: 0 1 auto; flex-direction: row; justify-content: normal; align-items: normal; padding: 0px; background-image: none; background-position: 0% 0%; background-size: auto; background-repeat: repeat; background-attachment: scroll; background-origin: padding-box; background-clip: border-box;&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;多标签、横竖分屏，单界面同时管理多台服务器；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;侧边一键查看服务器 CPU / 内存 / 磁盘 / GPU 实时监控、Docker 可视化管理；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;内置 AI 终端助手：选中报错自动解析、自然语言生成运维命令；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;一键导入 Xshell、MobaXterm、WindTerm 旧会话配置；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;连接配置本地加密、云同步备份；&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;终端操作录制回放、快捷命令模板、SSH 隧道内网穿透。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;下载地址&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;官网：&lt;a title=&quot;autolink&quot; current=&quot;[object Object]&quot; chatability=&quot;{}&quot; messageextra=&quot;[object Object]&quot; href=&quot;https://link.wtturl.cn/?target=https%3A%2F%2Fnyaterm.app&amp;scene=im&amp;aid=497858&amp;lang=zh&quot; target=&quot;_blank&quot; style=&quot;color: rgb(0, 87, 255);font-variant-numeric: normal;font-variant-east-asian: normal;font-variant-alternates: normal;font-kerning: auto;font-optical-sizing: auto;font-feature-settings: normal;font-variation-settings: normal;font-variant-position: normal;font-stretch: normal;line-height: 24px;display: inline;flex: 0 1 auto;flex-direction: row;justify-content: normal;align-items: normal;padding: 0px;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box&quot;&gt;https://nyaterm.app&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;a title=&quot;autolink&quot; current=&quot;[object Object]&quot; chatability=&quot;{}&quot; messageextra=&quot;[object Object]&quot; href=&quot;https://link.wtturl.cn/?target=https%3A%2F%2Fnyaterm.app&amp;scene=im&amp;aid=497858&amp;lang=zh&quot; target=&quot;_blank&quot; style=&quot;color: rgb(0, 87, 255);font-variant-numeric: normal;font-variant-east-asian: normal;font-variant-alternates: normal;font-kerning: auto;font-optical-sizing: auto;font-feature-settings: normal;font-variation-settings: normal;font-variant-position: normal;font-stretch: normal;line-height: 24px;display: inline;flex: 0 1 auto;flex-direction: row;justify-content: normal;align-items: normal;padding: 0px;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box&quot;&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101012073536896.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/a&gt;&lt;/p&gt;&lt;ul class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p&gt;GitHub 发行页：&lt;a title=&quot;autolink&quot; current=&quot;[object Object]&quot; chatability=&quot;{}&quot; messageextra=&quot;[object Object]&quot; href=&quot;https://link.wtturl.cn/?target=https%3A%2F%2Fgithub.com%2Fnyakang%2Fnyaterm%2Freleases&amp;scene=im&amp;aid=497858&amp;lang=zh&quot; target=&quot;_blank&quot; style=&quot;color: rgb(0, 87, 255);font-variant-numeric: normal;font-variant-east-asian: normal;font-variant-alternates: normal;font-kerning: auto;font-optical-sizing: auto;font-feature-settings: normal;font-variation-settings: normal;font-variant-position: normal;font-stretch: normal;line-height: 24px;display: inline;flex: 0 1 auto;flex-direction: row;justify-content: normal;align-items: normal;padding: 0px;background-image: none;background-position: 0% 0%;background-size: auto;background-repeat: repeat;background-attachment: scroll;background-origin: padding-box;background-clip: border-box&quot;&gt;https://github.com/nyakang/nyaterm/releases&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;p style=&quot;text-align: center;&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;界面&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101012192002570.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;显卡进程查看&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101012472963986.png&quot; alt=&quot;image.png&quot;/&gt;硬件资源查看&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101012587122679.png&quot; alt=&quot;image.png&quot;/&gt;docker管理&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101013161050095.png&quot; alt=&quot;image.png&quot;/&gt;AI集成&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/08/202608101013309067228.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 10 Aug 2026 10:07:50 +0800</pubDate></item><item><title>windows端口转发，可转发WSL端口</title><link>https://forstyle.cc/zblog/post/127.html</link><description>&lt;p&gt;windows自带有端口转发命令，没必要安装其他管理软件&lt;br/&gt;&lt;/p&gt;&lt;p&gt;命令如下，将8003端口转发到WSL中的 8003 端口&lt;/p&gt;&lt;pre class=&quot;brush:ps;toolbar:false;&quot;&gt;netsh&amp;nbsp;interface&amp;nbsp;portproxy&amp;nbsp;add&amp;nbsp;v4tov4&amp;nbsp;listenport=8003&amp;nbsp;listenaddress=0.0.0.0&amp;nbsp;connectport=8003&amp;nbsp;connectaddress=127.0.0.1&lt;/pre&gt;&lt;p&gt;查看全部的已配置的转发端口&lt;/p&gt;&lt;pre class=&quot;brush:ps;toolbar:false;&quot;&gt;netsh&amp;nbsp;interface&amp;nbsp;portproxy&amp;nbsp;show&amp;nbsp;all&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;有个服务必须启动&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607271551552036848.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;服务启动后执行以下命令设置开机启动&lt;/p&gt;&lt;pre class=&quot;brush:ps;toolbar:false&quot;&gt;::&amp;nbsp;立即启动&amp;nbsp;IP&amp;nbsp;Helper&amp;nbsp;服务
sc&amp;nbsp;start&amp;nbsp;iphlpsvc

::&amp;nbsp;设置服务开机自动启动（注意&amp;nbsp;start=&amp;nbsp;后面有空格，语法硬性要求）
sc&amp;nbsp;config&amp;nbsp;iphlpsvc&amp;nbsp;start=&amp;nbsp;auto&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 27 Jul 2026 15:48:06 +0800</pubDate></item><item><title>windwos和linux下获取当前使用的麦克风型号</title><link>https://forstyle.cc/zblog/post/126.html</link><description>&lt;p&gt;&lt;span style=&quot;white-space-collapse: preserve;&quot;&gt;需求是浏览器获取当前麦克风型号，对不支持的型号做限制，&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;white-space-collapse: preserve;&quot;&gt;最开始想的通过js后去麦克风型号，但是在windows下测试的没问题，到linux系统下就不行了&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;white-space-collapse: preserve;&quot;&gt;历览器输入以下地址可以看到支持的硬件信息&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;brush:as3;toolbar:false&quot;&gt;chrome://media-internals/&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607241784874164512468.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;在windows下可以看到支持的型号，&lt;/p&gt;&lt;p&gt;但是在linux下看不到&lt;/p&gt;&lt;p style=&quot;text-align: left;&quot;&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607241784874332449398.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;white-space-collapse: preserve;&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMndpbmR3byVFNCVCOCU4QiVFOSU5QyU4MCVFOCVBNiU4MSVFNCVCRCVCRiVFNyU5NCVBOCUyMHNvdW5kZGV2aWNlJTIwJUU1JUJBJTkzJUVGJUJDJThDbGludXglRTQlQjglOEIlRTQlQkQlQkYlRTclOTQlQTglMjBwdWxzZWN0bCUyMiU3RCU1RCU3RCU1RA==&quot;&gt;windwo下需要使用 sounddevice 库，linux下使用 pulsectl&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;white-space-collapse: preserve;&quot; data-slate-fragment=&quot;JTVCJTdCJTIydHlwZSUyMiUzQSUyMnBhcmFncmFwaCUyMiUyQyUyMmNoaWxkcmVuJTIyJTNBJTVCJTdCJTIydGV4dCUyMiUzQSUyMndpbmR3byVFNCVCOCU4QiVFOSU5QyU4MCVFOCVBNiU4MSVFNCVCRCVCRiVFNyU5NCVBOCUyMHNvdW5kZGV2aWNlJTIwJUU1JUJBJTkzJUVGJUJDJThDbGludXglRTQlQjglOEIlRTQlQkQlQkYlRTclOTQlQTglMjBwdWxzZWN0bCUyMiU3RCU1RCU3RCU1RA==&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;brush:python;toolbar:false&quot;&gt;import&amp;nbsp;sys

def&amp;nbsp;get_windows_active_mic():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;Windows&amp;nbsp;系统：通过&amp;nbsp;COM/pycaw&amp;nbsp;接口精确获取当前默认输入的麦克风型号&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;import&amp;nbsp;sounddevice&amp;nbsp;as&amp;nbsp;sd

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;devices&amp;nbsp;=&amp;nbsp;sd.query_devices()

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default_in_id&amp;nbsp;=&amp;nbsp;sd.default.device[0]
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;print(&amp;quot;默认录音设备ID：&amp;quot;,&amp;nbsp;default_in_id)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;print(&amp;quot;默认录音设备ID：&amp;quot;,&amp;nbsp;devices[default_in_id])
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;devices[default_in_id][&amp;#39;name&amp;#39;]

def&amp;nbsp;get_active_mic_pulsectl():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;import&amp;nbsp;pulsectl
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;with&amp;nbsp;pulsectl.Pulse(&amp;#39;get-mic-script&amp;#39;)&amp;nbsp;as&amp;nbsp;pulse:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;1.&amp;nbsp;获取默认&amp;nbsp;Source&amp;nbsp;的名称
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;server_info&amp;nbsp;=&amp;nbsp;pulse.server_info()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;default_source_name&amp;nbsp;=&amp;nbsp;server_info.default_source_name

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;2.&amp;nbsp;遍历&amp;nbsp;Source&amp;nbsp;寻找描述信息
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for&amp;nbsp;source&amp;nbsp;in&amp;nbsp;pulse.source_list():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;source.name&amp;nbsp;==&amp;nbsp;default_source_name:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;#&amp;nbsp;获取&amp;nbsp;friendly&amp;nbsp;名称
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;desc&amp;nbsp;=&amp;nbsp;source.proplist.get(&amp;#39;device.description&amp;#39;)&amp;nbsp;or&amp;nbsp;source.description
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;desc
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;&amp;quot;未找到设备&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;except&amp;nbsp;Exception&amp;nbsp;as&amp;nbsp;e:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f&amp;quot;获取失败:&amp;nbsp;{e}&amp;quot;

def&amp;nbsp;get_active_mic():
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(sys.platform)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;&amp;quot;&amp;quot;根据操作系统自动路由&amp;quot;&amp;quot;&amp;quot;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&amp;nbsp;sys.platform.startswith(&amp;quot;win&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;get_windows_active_mic()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;elif&amp;nbsp;sys.platform.startswith(&amp;quot;linux&amp;quot;):
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;get_active_mic_pulsectl()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&amp;nbsp;f&amp;quot;暂不支持的操作系统:&amp;nbsp;{sys.platform}&amp;quot;

if&amp;nbsp;__name__&amp;nbsp;==&amp;nbsp;&amp;quot;__main__&amp;quot;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;print(&amp;quot;当前正在使用的麦克风型号:&amp;quot;,&amp;nbsp;get_active_mic())&lt;/pre&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607241784873900250372.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607241784873938115984.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Fri, 24 Jul 2026 14:17:39 +0800</pubDate></item><item><title>VLLM服务端启动ChineseErrorCorrector3-4B模型</title><link>https://forstyle.cc/zblog/post/125.html</link><description>&lt;p&gt;先贴命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;vllm&amp;nbsp;serve&amp;nbsp;/www/models/Qwen/ChineseErrorCorrector3-4B&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--max-model-len&amp;nbsp;10240&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--dtype&amp;nbsp;float16&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--max-num-batched-tokens&amp;nbsp;10240&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--gpu-memory-utilization&amp;nbsp;0.4&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--max-num-seqs&amp;nbsp;512&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--host&amp;nbsp;0.0.0.0&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--port&amp;nbsp;8004&amp;nbsp;\
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;--served-model-name&amp;nbsp;csc-3B&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这条命令的作用：&lt;span style=&quot;font-size: 16px;&quot;&gt;用 vLLM 高性能推理框架，把中文纠错模型 ChineseErrorCorrector3-4B 启动成兼容 OpenAI 接口格式的 HTTP 推理服务&lt;/span&gt;，外部程序可通过 8004 端口调用文本纠错能力。&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607121783864288474784.png&quot; alt=&quot;image-20260611145021-dksod7v.png&quot; data-href=&quot;&quot; /&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/07/202607121783864369730328.png&quot; alt=&quot;image-20260611145026-v1xrszm.png&quot; data-href=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;vllm servevLLM 提供的服务启动子命令，自动内置 OpenAI 兼容 REST API（/v1/completions、/v1/chat/completions），无需自己封装接口。&lt;/p&gt;
&lt;p&gt;/www/models/Qwen/ChineseErrorCorrector3-4B本地模型权重文件路径，指向 4B 参数中文文本纠错模型（CSC 错别字校对模型）。&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;code&gt;--max-model-len 10240&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;模型最大支持输入 + 输出总 token 长度 10240。&lt;/p&gt;
&lt;p&gt;适合长文本纠错场景（长篇文档、案卷、文章批量校对），超过长度会截断输入。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;--dtype float16模型权重 / 推理计算使用 FP16 半精度：&lt;/p&gt;
&lt;blockquote&gt;显存占用减半，相比 FP32 节省大量显存；速度更快，绝大多数 Nvidia GPU 原生支持 FP16 加速；纠错类模型对精度不敏感，FP16 不会明显降低校对准确率。&lt;/blockquote&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;code&gt;--max-num-batched-tokens 10240&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;单次推理批处理中，所有并发请求的 token 总和上限 10240。&lt;/p&gt;
&lt;p&gt;用来防止瞬间大量长文本请求撑爆显存，和 &lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;code&gt;max-model-len&lt;/code&gt;&lt;/span&gt; 配套管控显存负载。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;--gpu-memory-utilization 0.4限制模型 + KV 缓存最多占用40% GPU 显存（0.4 = 40%）。&lt;/p&gt;
&lt;p&gt;预留 60% 显存给系统、其他进程、突发 KV 缓存；多模型混跑、显卡同时跑其他任务时常用低利用率；纯单模型独占显卡可调高至 0.8~0.95 提升并发。&lt;/p&gt;
&lt;p&gt;--max-num-seqs 512服务同时允许最多 512 条并行推理序列（并发请求）。&lt;/p&gt;
&lt;p&gt;短文本纠错场景可拉高，支持高 QPS；长文本场景建议降低，避免 KV 缓存暴涨 OOM。&lt;/p&gt;
&lt;p&gt;--host 0.0.0.0监听本机所有网卡地址，允许局域网 / 其他服务器远程访问接口；若写 127.0.0.1 则仅本机可调用，外部无法连接。&lt;/p&gt;
&lt;p&gt;--port 8004HTTP 服务监听端口，调用地址示例：http://服务器IP:8004/v1/chat/completions&lt;/p&gt;
&lt;p&gt;&lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;code&gt;--served-model-name csc-3B&lt;/code&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;API 请求时需要指定的 &lt;span style=&quot;font-size: 16px;&quot;&gt;&lt;code&gt;model&lt;/code&gt;&lt;/span&gt; 参数名称，不用填冗长模型路径。&lt;/p&gt;
&lt;p&gt;调用示例请求体片段：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
&amp;nbsp;&amp;nbsp;&quot;model&quot;:&amp;nbsp;&quot;csc-3B&quot;,
&amp;nbsp;&amp;nbsp;&quot;prompt&quot;:&amp;nbsp;&quot;需要纠错的原文&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description><pubDate>Sun, 12 Jul 2026 21:46:23 +0800</pubDate></item><item><title>windows右键管理</title><link>https://forstyle.cc/zblog/post/124.html</link><description>&lt;p&gt;windows11设计之初是为了简化右键，但是很多功能都隐藏起来了，要不通过shift + 右键出来详细右键，要不就得点详情来看，通过以下方法可以直接换为旧版的右键菜单。&lt;/p&gt;&lt;p&gt;开始菜单搜索cmd，以管理员身份打开&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605271779845975404304.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;运行以下命令&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false&quot;&gt;reg.exe&amp;nbsp;add&amp;nbsp;&amp;quot;HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}&amp;quot;&amp;nbsp;/f
reg.exe&amp;nbsp;add&amp;nbsp;&amp;quot;HKCU\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32&amp;quot;&amp;nbsp;/f&amp;nbsp;/ve&lt;/pre&gt;&lt;p&gt;再执行&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false&quot;&gt;taskkill&amp;nbsp;/f&amp;nbsp;/im&amp;nbsp;explorer.exe
start&amp;nbsp;explorer.exe&lt;/pre&gt;&lt;p&gt;然后点右键就是旧版的菜单了。&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605271779846029938472.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;还有一个好用的右键菜单管理工具推荐。&lt;/p&gt;&lt;p&gt;ContextMenuManager&lt;/p&gt;&lt;p&gt;&lt;a href=&quot;https://github.com/BluePointLilac/ContextMenuManager/releases/tag/3.3.3.1&quot; target=&quot;_blank&quot; textvalue=&quot;下载链接&quot;&gt;下载链接&lt;/a&gt;&lt;/p&gt;&lt;p&gt;下载完后不需要安装直接打开就能用&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605271779846115155709.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;可以管理文件、文件夹、目录等等各种右键菜单。&lt;/p&gt;&lt;p&gt;我现在在目录里面右键就只剩下这些了。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605271779846186351198.png&quot; alt=&quot;image.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;简化了很多。&lt;br/&gt;&lt;/p&gt;</description><pubDate>Wed, 27 May 2026 09:35:57 +0800</pubDate></item><item><title>从其他linux服务器拉取文件到当前服务器</title><link>https://forstyle.cc/zblog/post/123.html</link><description>&lt;p&gt;项目需要，当前服务器通过堡垒机连接，不知道密码，但是其他服务器密码知道，也不能上传文件，所以，只能通过其他服务器将文件传输到当前服务器，其他服务器也没有安装nginx等网络服务，因此只能从过scp命令传输文件&lt;/p&gt;&lt;p&gt;拉取单个文件&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false&quot;&gt;scp&amp;nbsp;root@192.168.1.100:/data/test.txt&amp;nbsp;./&lt;/pre&gt;&lt;p&gt;拉取整个文件夹&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false&quot;&gt;scp&amp;nbsp;-r&amp;nbsp;root@192.168.1.100:/data/abc&amp;nbsp;/home/&lt;/pre&gt;&lt;p style=&quot;text-indent: 0em; text-align: left;&quot;&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605181779072732822744.png&quot; alt=&quot;image.png&quot; style=&quot;float: left;&quot;/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;把当前文件推送到远程服务器&lt;br/&gt;&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false&quot;&gt;scp&amp;nbsp;./test.txt&amp;nbsp;root@192.168.1.100:/data/&lt;/pre&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Mon, 18 May 2026 10:48:16 +0800</pubDate></item><item><title>从一台doris导入表结构和数据到另一台doris</title><link>https://forstyle.cc/zblog/post/119.html</link><description>&lt;p id=&quot;w-e-element-25&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-18&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt; Apache Doris 是一款开源、分布式、MPP 架构的 OLAP（在线分析型）数据库&lt;/span&gt;&lt;/span&gt;&lt;span id=&quot;w-e-text-19&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;，主打&lt;/span&gt;&lt;/span&gt;&lt;span id=&quot;w-e-text-20&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;海量数据实时多维分析、秒级 / 亚秒级查询、高并发报表与即席查询&lt;/span&gt;&lt;/span&gt;&lt;span id=&quot;w-e-text-21&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;，非常适合构建&lt;/span&gt;&lt;/span&gt;&lt;span id=&quot;w-e-text-22&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;实时数据仓库、BI 看板、用户行为分析、日志分析、湖仓融合&lt;/span&gt;&lt;/span&gt;&lt;span id=&quot;w-e-text-23&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;等场景。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-32&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-27&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt; 需要将数据从一台doris集群迁移到另一台doris服务器中，以下是操作步骤&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;h2 id=&quot;w-e-element-33&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-34&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt; 一、迁移表结构&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p id=&quot;w-e-element-37&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-36&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt; 首先将数据库导出sql文件。在一台可以连接doris的linux服务器上执行以下命令&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false;&quot;&gt;mysqldump&amp;nbsp;-h192.168.1.10&amp;nbsp;-P9030&amp;nbsp;-uroot&amp;nbsp;-p&amp;nbsp;\
--no-tablespaces&amp;nbsp;\
--no-data&amp;nbsp;\
--skip-column-statistics&amp;nbsp;\
--databases&amp;nbsp;test_db&amp;nbsp;\
&amp;gt;&amp;nbsp;doris_ok.sql&lt;/pre&gt;&lt;p id=&quot;w-e-element-59&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-49&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt; 接下来需要借助一点点AI的力量，把导出的文件交给AI，让它把sql修改成兼容doris数据库的语法，并且支持单个节点doris的（我这里新的doris是单节点的所以这么改，按照实际情况修改提示词），我使用的claude模型，效果比较好，一次就成功了，也可以使用国内模型试试。修改完后的代码保存成sql文件。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-68&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-61&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;最后执行以下命令，导入到新库中&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;brush:bash;toolbar:false;&quot;&gt;mysql&amp;nbsp;-h192.168.1.45&amp;nbsp;-P9030&amp;nbsp;-uroot&amp;nbsp;-p&amp;nbsp;&amp;lt;&amp;nbsp;doris_fixed.sql&lt;/pre&gt;&lt;p id=&quot;w-e-element-69&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;h2 id=&quot;w-e-element-70&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-71&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;二、同步数据&lt;/span&gt;&lt;/span&gt;&lt;/h2&gt;&lt;p id=&quot;w-e-element-79&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-78&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;同步数据需要借助doris的CATALOG。“外部数据源的统一入口和命名空间”&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-86&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-82&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;它的作用是让 Doris 不只是查询自己内部的数据，还能像一个“数据中台”一样，直接访问 Hive、Iceberg、Hudi、MySQL、PostgreSQL、Elasticsearch 等外部数据源。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-95&quot; data-slate-node=&quot;element&quot;&gt;&lt;span id=&quot;w-e-text-88&quot; data-slate-node=&quot;text&quot;&gt;&lt;span data-slate-leaf=&quot;true&quot;&gt;在新doris库中执行以下命令，将旧库作为外部数据库连接到doris中。&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false;&quot;&gt;CREATE&amp;nbsp;CATALOG&amp;nbsp;doris_source&amp;nbsp;PROPERTIES&amp;nbsp;(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;type&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;jdbc&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;user&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;root&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;password&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;mysql.7334453&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;jdbc_url&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;jdbc:mysql://192.168.1.10:9030/&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;driver_url&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.25/mysql-connector-java-8.0.25.jar&amp;quot;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;quot;driver_class&amp;quot;&amp;nbsp;=&amp;nbsp;&amp;quot;com.mysql.cj.jdbc.Driver&amp;quot;
);&lt;/pre&gt;&lt;p&gt;执行&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false;&quot;&gt;SHOW&amp;nbsp;CATALOGS;&lt;/pre&gt;&lt;p&gt;看到以下doris_source，表示已经连接成功。&lt;/p&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/20260515091525177880772535964.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;然后就可以像操作一个数据库的方式导入数据了&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false;&quot;&gt;INSERT&amp;nbsp;INTO&amp;nbsp;hx_theme_data.t_license
SELECT&amp;nbsp;*&amp;nbsp;FROM&amp;nbsp;doris_source.hx_theme_data.t_license&lt;/pre&gt;&lt;p&gt;运行以下sql生成所有需要导入表sql。&lt;/p&gt;&lt;pre class=&quot;brush:sql;toolbar:false;&quot;&gt;SELECT&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;CONCAT(
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;INSERT&amp;nbsp;INTO&amp;nbsp;hx_theme_data.`&amp;#39;,&amp;nbsp;TABLE_NAME,&amp;nbsp;&amp;#39;`&amp;nbsp;&amp;#39;,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;#39;SELECT&amp;nbsp;*&amp;nbsp;FROM&amp;nbsp;doris_source.hx_theme_data.`&amp;#39;,&amp;nbsp;TABLE_NAME,&amp;nbsp;&amp;#39;`;&amp;#39;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;)&amp;nbsp;AS&amp;nbsp;sync_sql
FROM&amp;nbsp;information_schema.TABLES
WHERE&amp;nbsp;TABLE_SCHEMA&amp;nbsp;=&amp;nbsp;&amp;#39;hx_theme_data&amp;#39;
&amp;nbsp;&amp;nbsp;AND&amp;nbsp;TABLE_TYPE&amp;nbsp;=&amp;nbsp;&amp;#39;BASE&amp;nbsp;TABLE&amp;#39;;&lt;/pre&gt;&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/20260515091759177880787975256.png&quot;/&gt;&lt;/p&gt;&lt;p&gt;直接复制所有sql运行就可以导入全部数据了。&lt;/p&gt;&lt;p id=&quot;w-e-element-96&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-99&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-102&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-105&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-106&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;&lt;p id=&quot;w-e-element-73&quot; data-slate-node=&quot;element&quot;&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 15 May 2026 09:14:47 +0800</pubDate></item><item><title>千万别用sql查询经纬度数据了，有更快的方式</title><link>https://forstyle.cc/zblog/post/116.html</link><description>&lt;p&gt;最近需要查询学校周边的零售户有哪些，几千个学校，几十万零售户，用sql查询费了十几分钟才查询出来，后来问的AI，使用python代码，十几秒就能搞定。以下是完整的代码，可以作为参考。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/20260509174711177832003193716.png&quot; /&gt;&lt;/p&gt;
&lt;pre class=&quot;language-markup&quot;&gt;&lt;code&gt;def aaaaa():
    import numpy as np
    import pandas as pd
    from sklearn.neighbors import BallTree
    from time import time
    # 1. 从 Doris 读取数据
    from sqlalchemy import create_engine
    engine = create_engine(
        &quot;mysql+pymysql://root:mysql.7334453@192.168.1.10:9030/hx_theme_data?charset=utf8mb4&quot;
    )
    start_time = time()
    merchants = pd.read_sql(&quot;&quot;&quot;
        SELECT retailer_uuid, label_ids, label_names, company_name,
               label_list_fields, lic_no,
               CAST(latitude AS DOUBLE) AS lat_d,
               CAST(longitude AS DOUBLE) AS lng_d
        FROM t_license
        WHERE longitude IS NOT NULL AND longitude != 0
          AND latitude  IS NOT NULL AND latitude  != 0
          AND lic_status IN (&#039;01&#039;,&#039;02&#039;,&#039;10&#039;)
    &quot;&quot;&quot;, engine)

    schools = pd.read_sql(&quot;&quot;&quot;
        SELECT name, type,
               CAST(lat AS DOUBLE) AS lat_d,
               CAST(lng AS DOUBLE) AS lng_d
        FROM t_data_school_info
        WHERE lat IS NOT NULL AND lat != &#039;&#039; AND lat != &#039;0&#039;
          AND lng IS NOT NULL AND lng != &#039;&#039; AND lng != &#039;0&#039;
    &quot;&quot;&quot;, engine)

    # 2. 构建 BallTree（使用弧度，haversine 距离）
    school_coords = np.radians(schools[[&#039;lat_d&#039;, &#039;lng_d&#039;]].values)
    tree = BallTree(school_coords, metric=&#039;haversine&#039;)

    # 3. 批量查询每个商家最近的学校，距离阈值 200m
    merchant_coords = np.radians(merchants[[&#039;lat_d&#039;, &#039;lng_d&#039;]].values)
    DISTANCE_M = 200
    EARTH_RADIUS = 6371000

    distances, indices = tree.query(merchant_coords, k=1)  # 找最近1所
    distances_m = distances[:, 0] * EARTH_RADIUS           # 转换为米

    # 4. 过滤距离 &amp;lt; 200m 的结果
    mask = distances_m &amp;lt; DISTANCE_M
    result = merchants[mask].copy()
    result[&#039;distance&#039;]   = distances_m[mask]
    result[&#039;school_name&#039;] = schools.iloc[indices[mask, 0]][&#039;name&#039;].values
    result[&#039;school_type&#039;] = schools.iloc[indices[mask, 0]][&#039;type&#039;].values
    result[&#039;school_lat&#039;]  = schools.iloc[indices[mask, 0]][&#039;lat_d&#039;].values
    result[&#039;school_lng&#039;]  = schools.iloc[indices[mask, 0]][&#039;lng_d&#039;].values

    # 5. 结果写回 Doris
    # result.to_sql(&#039;t_merchant_nearest_school&#039;, engine, if_exists=&#039;replace&#039;)
    print(f&quot;耗时 {time() - start_time:.2f} 秒&quot;)
    print(f&quot;找到 {len(result)} 个200m内有学校的商家&quot;)&lt;/code&gt;&lt;/pre&gt;</description><pubDate>Sat, 09 May 2026 17:27:05 +0800</pubDate></item><item><title>Django + Doris CRC32 分表实战：问题汇总与解决方案</title><link>https://forstyle.cc/zblog/post/115.html</link><description>&lt;blockquote&gt;
&lt;p&gt;一次从零到一的 Django 分表实践，记录踩过的所有坑&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&quot;h2-u524Du8A00&quot;&gt;&lt;a name=&quot;前言&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;前言&lt;/h2&gt;&lt;p&gt;最近在做一个零售户管理系统，需要处理十亿级的数据。考虑到 Doris 的强大分析能力，使用 Doris 作为数据库，并基于 CRC32 算法实现自动分表。过程并不顺利，遇到了各种各样的问题。记录这些问题及解决方案，希望能帮助到有类似需求的开发者。&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://forstyle.cc/zblog/zb_users/upload/2026/05/202605061637497499847.png&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;h3--1-doris-&quot;&gt;&lt;a name=&quot;问题1：Doris 数据库连接失败&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题1：Doris 数据库连接失败&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;django.db.utils.OperationalError: (2003, &amp;quot;Can&amp;#39;t connect to MySQL server on &amp;#39;xxx&amp;#39;&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题原因：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Doris 使用 MySQL 协议，但端口不是默认的 3306&lt;/li&gt;&lt;li&gt;防火墙未开放 Doris 端口&lt;/li&gt;&lt;li&gt;未安装 PyMySQL 驱动&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# settings.py
DATABASES = {
    &amp;#39;doris&amp;#39;: {
        &amp;#39;ENGINE&amp;#39;: &amp;#39;django.db.backends.mysql&amp;#39;,
        &amp;#39;NAME&amp;#39;: &amp;#39;your_database&amp;#39;,
        &amp;#39;USER&amp;#39;: &amp;#39;your_user&amp;#39;,
        &amp;#39;PASSWORD&amp;#39;: &amp;#39;your_password&amp;#39;,
        &amp;#39;HOST&amp;#39;: &amp;#39;your_doris_host&amp;#39;,
        &amp;#39;PORT&amp;#39;: &amp;#39;9030&amp;#39;,  # Doris 默认 MySQL 协议端口
        &amp;#39;OPTIONS&amp;#39;: {
            &amp;#39;init_command&amp;#39;: &amp;quot;SET sql_mode=&amp;#39;STRICT_TRANS_TABLES&amp;#39;&amp;quot;,
            &amp;#39;charset&amp;#39;: &amp;#39;utf8mb4&amp;#39;,
        },
    }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;关键点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Doris 的 MySQL 协议端口通常是 9030（不是 3306）&lt;/li&gt;&lt;li&gt;需要安装 &lt;code&gt;pymysql&lt;/code&gt;：&lt;code&gt;pip install pymysql&lt;/code&gt;&lt;/li&gt;&lt;li&gt;在 &lt;code&gt;__init__.py&lt;/code&gt; 中添加：&lt;code&gt;import pymysql; pymysql.install_as_MySQLdb()&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--2-nameerror-name-baselicense-is-not-defined&quot;&gt;&lt;a name=&quot;问题2：NameError: name ‘BaseLicense’ is not defined&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题2：NameError: name ‘BaseLicense’ is not defined&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NameError: name &amp;#39;BaseLicense&amp;#39; is not defined&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题原因：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;在 &lt;code&gt;router.py&lt;/code&gt; 中使用了 &lt;code&gt;BaseLicense&lt;/code&gt; 但没有导入或定义&lt;/li&gt;&lt;li&gt;模型定义顺序导致引用问题&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案一：在 router.py 中定义（简单但不推荐）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# router.py
class BaseLicense(models.Model):
    class Meta:
        abstract = True&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;方案二：分离模型和路由逻辑（推荐）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# models.py
class BaseLicense(models.Model):
    # 字段定义...
    class Meta:
        abstract = True

# router.py
from .models import BaseLicense  # 正确导入&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;最佳实践：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;将所有模型定义在 &lt;code&gt;models.py&lt;/code&gt; 中&lt;/li&gt;&lt;li&gt;路由逻辑单独放在 &lt;code&gt;router.py&lt;/code&gt; 或 &lt;code&gt;shard_router.py&lt;/code&gt;&lt;/li&gt;&lt;li&gt;使用明确的导入路径&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--3-no-such-table-t_license_8&quot;&gt;&lt;a name=&quot;问题3：no such table: t_license_8&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题3：no such table: t_license_8&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;django.db.utils.OperationalError: no such table: t_license_8&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题原因：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Django 默认使用 &lt;code&gt;default&lt;/code&gt; 数据库连接&lt;/li&gt;&lt;li&gt;&lt;code&gt;default&lt;/code&gt; 配置的是 SQLite，但实际表在 Doris 中&lt;/li&gt;&lt;li&gt;未指定使用 Doris 数据库&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;方案一：每次查询指定数据库（简单直接）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;result = model.objects.using(&amp;#39;doris&amp;#39;).get(lic_no=lic_no)&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;方案二：配置数据库路由器（优雅）&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# db_router.py
class DorisRouter:
    def db_for_read(self, model, **hints):
        if model.__name__.startswith(&amp;#39;License_&amp;#39;):
            return &amp;#39;doris&amp;#39;
        return None

# settings.py
DATABASE_ROUTERS = [&amp;#39;your_app.db_router.DorisRouter&amp;#39;]&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;知识点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;using()&lt;/code&gt; 方法用于指定数据库&lt;/li&gt;&lt;li&gt;数据库路由器可以实现自动化路由&lt;/li&gt;&lt;li&gt;记得在 settings 中注册路由器&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--4-unknown-column-id-in-t_license_8-&quot;&gt;&lt;a name=&quot;问题4：Unknown column ‘id’ in ‘t_license_8’&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题4：Unknown column ‘id’ in ‘t_license_8’&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;django.db.utils.OperationalError: (1054, &amp;quot;errCode = 2, detailMessage = Unknown column &amp;#39;id&amp;#39; in &amp;#39;t_license_8&amp;#39;&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题原因：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Django 模型默认会自动添加一个名为 &lt;code&gt;id&lt;/code&gt; 的自增主键字段&lt;/li&gt;&lt;li&gt;Doris 表使用 &lt;code&gt;retailer_uuid&lt;/code&gt; 作为主键，没有 &lt;code&gt;id&lt;/code&gt; 字段&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解决方案：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;class BaseLicense(models.Model):
    # ✅ 必须明确指定主键字段
    retailer_uuid = models.CharField(
        max_length=96, 
        primary_key=True,  # 关键：指定为主键
        verbose_name=&amp;#39;零售户UUID&amp;#39;
    )
    lic_no = models.CharField(max_length=60, null=True)
    # ... 其他字段

    class Meta:
        abstract = True
        managed = False  # 禁止 Django 管理表结构&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;关键点：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;必须用 &lt;code&gt;primary_key=True&lt;/code&gt; 标记主键字段&lt;/li&gt;&lt;li&gt;设置 &lt;code&gt;managed = False&lt;/code&gt; 避免 Django 尝试创建/修改表&lt;/li&gt;&lt;li&gt;&lt;code&gt;abstract = True&lt;/code&gt; 让基类不创建实际表&lt;/li&gt;&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;h3--5-object-of-type-license_t_license_8-is-not-json-serializable&quot;&gt;&lt;a name=&quot;问题5：Object of type License_t_license_8 is not JSON serializable&quot; class=&quot;reference-link&quot; href=&quot;#&quot;&gt;&lt;/a&gt;&lt;span class=&quot;header-link octicon octicon-link&quot;&gt;&lt;/span&gt;问题5：Object of type License_t_license_8 is not JSON serializable&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;错误信息：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TypeError: Object of type License_t_license_8 is not JSON serializable&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;问题原因：&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Django ORM 返回的是模型对象，不是字典&lt;/li&gt;&lt;li&gt;JSON 序列化器无法处理 Django 模型实例&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;解决方案对比：&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;方案&lt;/th&gt;
&lt;th&gt;代码&lt;/th&gt;
&lt;th&gt;优点&lt;/th&gt;
&lt;th&gt;缺点&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;使用 values()&lt;/td&gt;
&lt;td&gt;&lt;code&gt;model.objects.filter().values().first()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;直接返回字典，性能好&lt;/td&gt;
&lt;td&gt;返回的是字典，不是模型实例&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使用 model_to_dict&lt;/td&gt;
&lt;td&gt;&lt;code&gt;model_to_dict(obj)&lt;/code&gt;&lt;/td&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;code&gt;{&amp;#39;field&amp;#39;: obj.field}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;完全可控&lt;/td&gt;
&lt;td&gt;代码冗长&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;使用 Django 序列化器&lt;/td&gt;
&lt;td&gt;&lt;code&gt;serializers.serialize(&amp;#39;json&amp;#39;, queryset)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;功能完整&lt;/td&gt;
&lt;td&gt;返回格式特殊&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;推荐方案：&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# 方案一：直接使用 values()（推荐）
@router.get(&amp;quot;/license&amp;quot;)
def get_license(request, lic_no: str):
    model = get_model_for_license(lic_no)
    result = model.objects.using(&amp;#39;doris&amp;#39;).filter(
        lic_no=lic_no
    ).values().first()  # 直接返回字典
    return result

# 方案二：使用 model_to_dict
from django.forms.models import model_to_dict

@router.get(&amp;quot;/license&amp;quot;)
def get_license(request, lic_no: str):
    model = get_model_for_license(lic_no)
    obj = model.objects.using(&amp;#39;doris&amp;#39;).get(lic_no=lic_no)
    return model_to_dict(obj)  # 转换为字典&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
</description><pubDate>Wed, 06 May 2026 16:32:46 +0800</pubDate></item></channel></rss>