index.html 63 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956
  1. <!DOCTYPE html>
  2. <html lang="zh-CN">
  3. <head>
  4. <meta charset="UTF-8"/>
  5. <link rel="icon" type="image/svg+xml" href="/wails.png"/>
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover"/>
  7. <link rel="stylesheet" href="/style.css"/>
  8. <title>腾图工具箱</title>
  9. <!-- 首屏前置应用主题,避免暗色/亮色切换时闪烁 -->
  10. <script>document.documentElement.dataset.theme = localStorage.getItem('tengtu-theme') || 'dark';</script>
  11. </head>
  12. <body data-file-drop-target>
  13. <div class="tab-container">
  14. <!-- 标签栏(兼作标题栏):左侧 tab,右侧窗口关闭按钮 -->
  15. <div class="tab-buttons">
  16. <button class="tab-btn active" data-tab="links">网址</button>
  17. <button class="tab-btn" data-tab="news">新闻</button>
  18. <button class="tab-btn" data-tab="github">Github</button>
  19. <button class="tab-btn" data-tab="stock">股市</button>
  20. <button class="tab-btn" data-tab="todo">待办</button>
  21. <button class="tab-btn" data-tab="record">记录</button>
  22. <button class="tab-btn" data-tab="tools">工具</button>
  23. <button class="tab-btn" data-tab="host">服务</button>
  24. <button class="tab-btn" data-tab="settings">设置</button>
  25. <div class="win-spacer"></div>
  26. <button class="win-close" id="win-close" title="关闭到托盘">×</button>
  27. </div>
  28. <!-- 内容面板 -->
  29. <div class="tab-content">
  30. <!-- 常用网址:设置中配置,点击卡片在浏览器打开 -->
  31. <div class="tab-panel active" id="tab-links">
  32. <div class="card-grid" id="links-grid"></div>
  33. </div>
  34. <!-- 新闻:煎蛋 + 头条热榜,命中关键词的排在前面并高亮 -->
  35. <div class="tab-panel" id="tab-news">
  36. <div class="panel-head">
  37. <div>
  38. <h2>新闻</h2>
  39. </div>
  40. <div class="panel-head-actions">
  41. <span class="github-refresh-time" id="news-refresh-time" title="最后一次成功刷新的时间"></span>
  42. <button class="btn-ghost" id="news-read" title="朗读未点击过的新闻标题">阅读</button>
  43. <button class="btn-ghost" id="news-refresh">刷新</button>
  44. </div>
  45. </div>
  46. <div class="news-list" id="news-list">
  47. <div class="empty-state">
  48. <div class="empty-mark">◈</div>
  49. <div class="empty-title">正在获取新闻…</div>
  50. <div class="empty-text">首次加载需要几秒</div>
  51. </div>
  52. </div>
  53. </div>
  54. <!-- Github:监听设置中仓库的最新提交 -->
  55. <div class="tab-panel" id="tab-github">
  56. <div class="panel-head">
  57. <div class="panel-head-actions">
  58. <span class="github-refresh-time" id="github-refresh-time" title="最后一次成功刷新的时间"></span>
  59. <button class="btn-ghost" id="github-refresh">刷新</button>
  60. </div>
  61. </div>
  62. <div class="repo-list" id="repo-list">
  63. <div class="empty-state">
  64. <div class="empty-mark">◈</div>
  65. <div class="empty-title">正在获取仓库动态…</div>
  66. <div class="empty-text">通过 GitHub API 拉取提交与最新版本</div>
  67. </div>
  68. </div>
  69. <div class="trending-block">
  70. <div class="trending-head">
  71. <h3 class="trending-title">热门仓库 <span class="trending-sub">GitHub Trending</span></h3>
  72. <span class="github-refresh-time" id="trending-refresh-time" title="最后一次成功刷新的时间"></span>
  73. <button class="btn-ghost" id="trending-refresh">刷新</button>
  74. </div>
  75. <div class="trending-list" id="trending-list">
  76. <div class="empty-state">
  77. <div class="empty-mark">◈</div>
  78. <div class="empty-title">正在获取热门仓库…</div>
  79. <div class="empty-text">抓取 github.com/trending,英文简介自动翻译为中文</div>
  80. </div>
  81. </div>
  82. </div>
  83. </div>
  84. <!-- 股市:按设置的代码展示行情 -->
  85. <div class="tab-panel" id="tab-stock">
  86. <div class="panel-head">
  87. <div class="panel-head-actions">
  88. <span class="market-status" id="market-status"><span class="dot"></span>加载中…</span>
  89. <span class="github-refresh-time" id="stock-refresh-time" title="最后一次成功刷新的时间"></span>
  90. <button class="btn-ghost" id="stock-refresh">刷新</button>
  91. </div>
  92. </div>
  93. <div class="stock-list" id="stock-list">
  94. <div class="empty-state">
  95. <div class="empty-mark">◈</div>
  96. <div class="empty-title">正在获取行情…</div>
  97. <div class="empty-text">首次加载需要几秒</div>
  98. </div>
  99. </div>
  100. </div>
  101. <!-- 待办:每行记录一个待完成任务,可勾选完成 / 编辑 / 删除 -->
  102. <div class="tab-panel panel-todo" id="tab-todo">
  103. <div class="panel-head">
  104. <div class="todo-path-desc" id="todo-path-desc"></div>
  105. <button class="btn-ghost" id="todo-save">保存</button>
  106. </div>
  107. <div class="todo-list" id="todo-list"></div>
  108. <div class="todo-actions">
  109. <button class="btn-ghost" id="todo-add">添加任务</button>
  110. </div>
  111. <div class="todo-status" id="todo-status"></div>
  112. </div>
  113. <!-- 记录:每行一条「姓名|名称|值」,保存到 SQLite 数据库;姓名/名称输入可自动补全历史值 -->
  114. <div class="tab-panel panel-record" id="tab-record">
  115. <div class="panel-head">
  116. <div class="record-path-desc" id="record-path-desc"></div>
  117. <button class="btn-ghost" id="record-save">保存</button>
  118. </div>
  119. <div class="record-toolbar">
  120. <label class="record-label">姓名
  121. <select class="input record-select" id="record-name-filter"><option value="">全部</option></select>
  122. </label>
  123. <label class="record-label">名称
  124. <select class="input record-select" id="record-item-filter"><option value="">全部</option></select>
  125. </label>
  126. <label class="record-label">从
  127. <input class="input record-date" id="record-date-from" type="date">
  128. </label>
  129. <label class="record-label">到
  130. <input class="input record-date" id="record-date-to" type="date">
  131. </label>
  132. <button class="btn-ghost" id="record-filter-clear" title="清除时间过滤">清除</button>
  133. <span class="record-count" id="record-count"></span>
  134. </div>
  135. <div class="record-chart-wrap">
  136. <canvas class="record-chart" id="record-chart"></canvas>
  137. <div class="record-chart-tooltip" id="record-chart-tooltip" hidden></div>
  138. <div class="record-chart-empty" id="record-chart-empty">请先选择姓名,才显示柱状图(可选名称进一步筛选)</div>
  139. </div>
  140. <!-- 自动补全候选:姓名/名称输入框通过 list 属性引用;随数据库历史值刷新。
  141. 必须放在 record-list 容器之外,避免 loadRecords() 的 innerHTML='' 把它们清空 -->
  142. <datalist id="record-names-dl"></datalist>
  143. <datalist id="record-items-dl"></datalist>
  144. <div class="record-list" id="record-list"></div>
  145. <div class="record-actions">
  146. <button class="btn-ghost" id="record-add">添加记录</button>
  147. </div>
  148. <div class="record-status" id="record-status"></div>
  149. </div>
  150. <!-- 工具:本地开发/运维辅助工具集 -->
  151. <div class="tab-panel" id="tab-tools">
  152. <!-- 工具 1:Web 服务——选择目录,开启本地浏览服务 -->
  153. <div class="tool-card is-collapsed" data-tool="websvc">
  154. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  155. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>Web 服务</span>
  156. <span class="tool-status" id="websvc-status"></span>
  157. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  158. </div>
  159. <div class="tool-card-body">
  160. <p class="tool-desc">选择任意目录,在本机开启浏览服务,默认页为 <code>index.html</code> 或 <code>readme.md</code>。</p>
  161. <div class="tool-row">
  162. <input class="input tool-dir" id="websvc-dir" type="text" placeholder="未选择目录" readonly>
  163. <button class="btn-ghost" id="websvc-pick">选择目录</button>
  164. </div>
  165. <div class="tool-row tool-actions">
  166. <button class="btn-primary" id="websvc-toggle">开启浏览服务</button>
  167. <span class="tool-hint" id="websvc-hint"></span>
  168. </div>
  169. <div class="websvc-preview" id="websvc-preview" hidden>
  170. <iframe id="websvc-frame" title="Web 服务预览"></iframe>
  171. </div>
  172. </div>
  173. </div>
  174. <!-- 工具 2:翻译——中文→英文 / 英文→中文,自动检测 -->
  175. <div class="tool-card is-collapsed" data-tool="translate">
  176. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  177. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>翻译</span>
  178. <span class="tool-status" id="tr-status"></span>
  179. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  180. </div>
  181. <div class="tool-card-body">
  182. <p class="tool-desc">输入中文自动翻译为英文,输入英文自动翻译为中文。免费接口有每日配额,超额请稍后再试。</p>
  183. <textarea class="input tr-input" id="tr-source" rows="3" placeholder="输入要翻译的中文或英文……"></textarea>
  184. <div class="tool-row tool-actions">
  185. <button class="btn-primary" id="tr-go">翻译</button>
  186. <span class="tool-hint" id="tr-hint"></span>
  187. </div>
  188. <div class="tr-result" id="tr-result" hidden></div>
  189. </div>
  190. </div>
  191. <!-- 工具 3:二维码生成——输入字符串生成二维码图片 -->
  192. <div class="tool-card is-collapsed" data-tool="qrcode">
  193. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  194. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>二维码生成</span>
  195. <span class="tool-status" id="qr-status"></span>
  196. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  197. </div>
  198. <div class="tool-card-body">
  199. <p class="tool-desc">输入任意字符串,即时生成二维码图片。可用于网址、文本、联系方式等。</p>
  200. <textarea class="input tr-input" id="qr-input" rows="3" placeholder="输入要生成二维码的内容……"></textarea>
  201. <div class="tool-row tool-actions">
  202. <button class="btn-primary" id="qr-go">生成二维码</button>
  203. <span class="tool-hint" id="qr-hint"></span>
  204. </div>
  205. <div class="qr-box" id="qr-box" hidden>
  206. <img id="qr-img" alt="二维码" title="点击下载 PNG">
  207. <button class="btn-ghost" id="qr-save">下载 PNG</button>
  208. </div>
  209. </div>
  210. </div>
  211. <!-- 工具 4:发送 ntfy 消息——输入主题 / 标题 / 内容,推送到 ntfy 频道 -->
  212. <div class="tool-card is-collapsed" data-tool="ntfy">
  213. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  214. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>发送 ntfy 消息</span>
  215. <span class="tool-status" id="ntfy-status"></span>
  216. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  217. </div>
  218. <div class="tool-card-body">
  219. <p class="tool-desc">向 ntfy 服务推送通知,用于手机 / 浏览器 / 其他设备即时提醒。主题(Topic)为监听频道名,输入过的主题会自动记忆。</p>
  220. <div class="tool-row">
  221. <input class="input" id="ntfy-topic" type="text" placeholder="主题(Topic),如 my-alerts" list="ntfy-topic-list" autocomplete="off">
  222. <datalist id="ntfy-topic-list"></datalist>
  223. </div>
  224. <input class="input" id="ntfy-title" type="text" placeholder="标题(可留空)">
  225. <textarea class="input tr-input" id="ntfy-message" rows="3" placeholder="输入要发送的消息内容……"></textarea>
  226. <div class="tool-row tool-actions">
  227. <button class="btn-primary" id="ntfy-go">发送</button>
  228. <span class="tool-hint" id="ntfy-hint"></span>
  229. </div>
  230. </div>
  231. </div>
  232. <!-- 工具 5:ntfy 聊天室——输入昵称与主题,订阅并实时收发消息(QQ 气泡风格) -->
  233. <div class="tool-card is-collapsed" data-tool="chat">
  234. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  235. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>ntfy 聊天室</span>
  236. <span class="tool-status" id="chat-status"></span>
  237. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  238. </div>
  239. <div class="tool-card-body">
  240. <p class="tool-desc">输入昵称(作为发送方标识,记忆上次使用)与聊天室名称(ntfy 主题)后开始监听,像 QQ 一样左右气泡收发消息。</p>
  241. <div class="tool-row">
  242. <input class="input" id="chat-nickname" type="text" placeholder="昵称(作为发送方标题)" list="ntfy-nickname-list" autocomplete="off">
  243. <input class="input" id="chat-topic" type="text" placeholder="聊天室名称(ntfy 主题),留空则不监听" list="ntfy-topic-list" autocomplete="off">
  244. <button class="btn-ghost" id="chat-toggle">开始监听</button>
  245. </div>
  246. <div class="chat-box" id="chat-box" hidden>
  247. <div class="chat-list" id="chat-list"></div>
  248. <div class="chat-input-row">
  249. <input class="input" id="chat-message" type="text" placeholder="输入消息,回车发送" autocomplete="off">
  250. <button class="btn-ghost" id="chat-send">发送</button>
  251. </div>
  252. </div>
  253. </div>
  254. </div>
  255. <!-- 工具 6:古诗词——显示 footer 最近获取的古诗,可刷新获取新诗 -->
  256. <div class="tool-card is-collapsed" data-tool="poem">
  257. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  258. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>古诗词</span>
  259. <span class="tool-status" id="poem-status"></span>
  260. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  261. </div>
  262. <div class="tool-card-body">
  263. <p class="tool-desc">显示主窗口 footer 最近获取到的古诗词内容,可手动刷新获取新的一首。数据来自古诗词网随机接口。</p>
  264. <div class="tool-row tool-actions">
  265. <button class="btn-primary" id="poem-tool-refresh">刷新获取</button>
  266. <button class="btn-ghost" id="poem-tool-read">朗读</button>
  267. <span class="tool-hint" id="poem-tool-hint"></span>
  268. </div>
  269. <div class="poem-tool" id="poem-tool-box" hidden>
  270. <div class="poem-tool-title" id="poem-tool-title"></div>
  271. <div class="poem-tool-author" id="poem-tool-author"></div>
  272. <div class="poem-tool-content" id="poem-tool-content"></div>
  273. </div>
  274. </div>
  275. </div>
  276. <!-- 工具 7:屏幕截图——隐藏本程序后截取全屏,完成后重新显示 -->
  277. <div class="tool-card is-collapsed" data-tool="screenshot">
  278. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  279. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>屏幕截图</span>
  280. <span class="tool-status" id="shot-status"></span>
  281. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  282. </div>
  283. <div class="tool-card-body">
  284. <p class="tool-desc">点击截屏后自动隐藏本程序窗口,截取整个屏幕(全部显示器),完成后重新显示并预览。截到的画面不含本程序自身。</p>
  285. <div class="tool-row tool-actions">
  286. <button class="btn-primary" id="shot-capture">截屏</button>
  287. <span class="tool-hint" id="shot-hint"></span>
  288. </div>
  289. <div class="screenshot-box" id="screenshot-box" hidden>
  290. <div class="screenshot-head">
  291. <span class="card-title"><span class="dot"></span>屏幕截图</span>
  292. <span class="screenshot-hint" id="screenshot-hint"></span>
  293. </div>
  294. <img id="screenshot-img" alt="屏幕截图预览">
  295. </div>
  296. </div>
  297. </div>
  298. <!-- 工具 8:延时关机——输入多少分钟后关机,交给系统倒计时 -->
  299. <div class="tool-card is-collapsed" data-tool="shutdown">
  300. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  301. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>延时关机</span>
  302. <span class="tool-status" id="sd-status"></span>
  303. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  304. </div>
  305. <div class="tool-card-body">
  306. <p class="tool-desc">输入多少分钟后关机,确认后交给系统倒计时(即使本程序退出仍会执行),也可随时取消。</p>
  307. <div class="tool-row">
  308. <input class="input" id="sd-minutes" type="number" min="1" max="1440" step="1" placeholder="分钟数" style="width:120px">
  309. <button class="btn-primary" id="sd-go">延时关机</button>
  310. <button class="btn-ghost" id="sd-cancel">取消</button>
  311. <span class="tool-hint" id="sd-hint"></span>
  312. </div>
  313. </div>
  314. </div>
  315. <!-- 工具 9:MD5 加密——输入字符串,生成 32 位 MD5 摘要 -->
  316. <div class="tool-card is-collapsed" data-tool="md5">
  317. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  318. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>MD5 加密</span>
  319. <span class="tool-status" id="md5-status"></span>
  320. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  321. </div>
  322. <div class="tool-card-body">
  323. <p class="tool-desc">输入任意字符串,计算其 32 位小写十六进制 MD5 摘要。常用于文件/字符串校验,注意 MD5 已不适合密码存储。</p>
  324. <textarea class="input tr-input" id="md5-input" rows="3" placeholder="输入要计算 MD5 的字符串……"></textarea>
  325. <div class="tool-row tool-actions">
  326. <button class="btn-primary" id="md5-go">计算 MD5</button>
  327. <span class="tool-hint" id="md5-hint"></span>
  328. </div>
  329. <div class="hash-result" id="md5-result" hidden></div>
  330. </div>
  331. </div>
  332. <!-- 工具 10:SHA256 编码——输入字符串,生成 SHA256 摘要 -->
  333. <div class="tool-card is-collapsed" data-tool="sha256">
  334. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  335. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>SHA256 编码</span>
  336. <span class="tool-status" id="sha-status"></span>
  337. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  338. </div>
  339. <div class="tool-card-body">
  340. <p class="tool-desc">输入任意字符串,计算其 64 位小写十六进制 SHA256 摘要。适用于校验、签名与安全存储。</p>
  341. <textarea class="input tr-input" id="sha-input" rows="3" placeholder="输入要计算 SHA256 的字符串……"></textarea>
  342. <div class="tool-row tool-actions">
  343. <button class="btn-primary" id="sha-go">计算 SHA256</button>
  344. <span class="tool-hint" id="sha-hint"></span>
  345. </div>
  346. <div class="hash-result" id="sha-result" hidden></div>
  347. </div>
  348. </div>
  349. <!-- 工具 11:LED 滚动文字——输入文字(可汉字),转换为 LED 点阵独立窗口滚动显示 -->
  350. <div class="tool-card is-collapsed" data-tool="led">
  351. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  352. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>LED 滚动文字</span>
  353. <span class="tool-status" id="led-status"></span>
  354. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  355. </div>
  356. <div class="tool-card-body">
  357. <p class="tool-desc">输入文字(支持中文),转换为 LED 点阵,在独立的无边框置顶透明窗口中横向滚动显示。窗口可拖动、可关闭。</p>
  358. <input class="input" id="led-text" type="text" placeholder="输入要滚动的文字,如 你好 世界">
  359. <div class="tool-row tool-actions">
  360. <label class="color-field" title="点阵颜色">
  361. <input type="color" id="led-color" value="#ff4d4d">
  362. <span>颜色</span>
  363. </label>
  364. <label class="speed-field" title="滚动速度(像素/秒)">
  365. <input type="number" id="led-speed" value="60" min="10" max="600" step="10">
  366. <span>速度</span>
  367. </label>
  368. <button class="btn-primary" id="led-go">打开 LED 窗口</button>
  369. <button class="btn-ghost" id="led-close">关闭窗口</button>
  370. <span class="tool-hint" id="led-hint"></span>
  371. </div>
  372. </div>
  373. </div>
  374. <!-- 工具 12:定时提醒——输入提醒信息与间隔分钟数,每 xx 分钟提醒一次直到取消 -->
  375. <div class="tool-card is-collapsed" data-tool="reminder">
  376. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  377. <span class="tool-card-title"><span class="tool-arrow">▸</span><span class="dot"></span>定时提醒</span>
  378. <span class="tool-status" id="remind-status"></span>
  379. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  380. </div>
  381. <div class="tool-card-body">
  382. <p class="tool-desc">输入提醒信息与间隔分钟数,每 xx 分钟弹出一次提醒,直到手动取消。适合定时喝水、休息、吃药等。</p>
  383. <input class="input" id="remind-message" type="text" placeholder="提醒信息,如:该喝水了">
  384. <div class="tool-row tool-actions">
  385. <input class="input" id="remind-minutes" type="number" min="1" max="1440" step="1" placeholder="间隔(分钟)" style="width:120px">
  386. <button class="btn-primary" id="remind-go">开始提醒</button>
  387. <button class="btn-ghost" id="remind-stop">取消提醒</button>
  388. <span class="tool-hint" id="remind-hint"></span>
  389. </div>
  390. </div>
  391. </div>
  392. <!-- 工具 13:LocalSend 文件互传——组播发现设备,HTTPS 接收文件 -->
  393. <div class="tool-card is-collapsed" data-tool="localsend">
  394. <div class="tool-card-head" role="button" tabindex="0" aria-expanded="false">
  395. <span class="tool-card-title" title="与局域网内的 LocalSend 客户端(手机 / 电脑)互相发现并互传文件。启动后:其他设备可发送文件到本机(按设置中的「接收模式」自动或手动接收);也可从本机选择文件发送给发现的设备。本机名、接收位置、接收模式在「设置 → LocalSend」中配置。"><span class="tool-arrow">▸</span><span class="dot"></span>LocalSend 互传</span>
  396. <span class="tool-status" id="localsend-status"></span>
  397. <span class="tool-order-btns"><button class="tool-order-btn tool-up" type="button" title="上移">↑</button><button class="tool-order-btn tool-down" type="button" title="下移">↓</button></span>
  398. </div>
  399. <div class="tool-card-body">
  400. <div class="tool-row">
  401. <button class="btn-primary" id="localsend-toggle">启动服务</button>
  402. <span class="tool-hint" id="localsend-hint"></span>
  403. </div>
  404. <div class="localsend-devices" id="localsend-devices" hidden>
  405. <div class="card-title"><span class="dot"></span>发现设备</div>
  406. <span class="tool-hint" id="localsend-send-hint"></span>
  407. <ul class="localsend-device-list" id="localsend-device-list"></ul>
  408. </div>
  409. </div>
  410. </div>
  411. </div>
  412. <div class="tab-panel" id="tab-host">
  413. <div class="host-cards">
  414. <div class="card">
  415. <div class="card-title-row">
  416. <span class="card-title"><span class="dot"></span>API 服务</span>
  417. <button class="btn-ghost" id="api-toggle">停止服务</button>
  418. </div>
  419. <p id="api-status">检查中…</p>
  420. </div>
  421. <!-- 文件上传:需密码,上传成功显示二维码 -->
  422. <div class="card" id="upload-card">
  423. <div class="card-title-row">
  424. <span class="card-title"><span class="dot"></span>文件上传</span>
  425. </div>
  426. <div>
  427. <p class="tool-hint">手机等设备访问 http://&lt;服务地址&gt;/upload 上传页,输入密码即可上传文件。</p>
  428. </div>
  429. <div class="upload-box">
  430. <div class="upload-row">
  431. <button class="btn-ghost" id="upload-btn">选择文件并上传</button>
  432. <span class="upload-name" id="upload-name"></span>
  433. </div>
  434. <div class="upload-progress" id="upload-progress" hidden><div class="upload-bar"></div></div>
  435. <div class="upload-result" id="upload-result" hidden>
  436. <div class="upload-qr" id="upload-qr"></div>
  437. <div class="upload-meta">
  438. <div class="upload-name" id="upload-name2"></div>
  439. <a class="upload-link" id="upload-link" href="#" target="_blank">下载地址</a>
  440. </div>
  441. </div>
  442. </div>
  443. </div>
  444. <div class="card">
  445. <div class="card-title"><span class="dot"></span>电源命令</div>
  446. <p id="pc-status">暂无请求</p>
  447. </div>
  448. </div>
  449. <h3 class="section-title">提供的功能</h3>
  450. <ul class="api-list" id="api-list">
  451. <li><code>GET /health</code>健康检查</li>
  452. <li><code>POST /api/notify</code>弹出系统通知</li>
  453. <li><code>POST /api/window/show</code>显示主窗口</li>
  454. <li><code>GET /api/settings</code>读取配置</li>
  455. <li><code>POST /api/settings</code>保存配置</li>
  456. <li><code>GET /api/stocks</code>股票行情(?codes= 可临时指定)</li>
  457. <li><code>GET /api/screenshot</code>屏幕截图(?display= 指定显示器)</li>
  458. <li><code>POST /api/upload</code>上传文件(字段 password+file,密码正确才保存)</li>
  459. <li><code>GET /api/download/:filename</code>下载已上传文件(?password= 校验密码)</li>
  460. <li><code>GET /api/pc/poweroff</code>30 秒后关机</li>
  461. <li><code>GET /api/pc/restart</code>30 秒后重启</li>
  462. <li><code>GET /api/pc/sleep</code>30 秒后休眠</li>
  463. <li><code>GET /api/pc/lock</code>立即锁屏</li>
  464. <li><code>GET /api/pc/cancel</code>取消待执行命令</li>
  465. <li><code>GET /api/pc/status</code>查询命令状态</li>
  466. <li><code>GET /api/pc/timesync</code>同步系统时间</li>
  467. </ul>
  468. <div class="section-title section-title-row">
  469. <span>Gin 日志</span>
  470. <button class="btn-ghost" id="log-clear">清空日志</button>
  471. </div>
  472. <pre class="log-view" id="log-view">暂无日志</pre>
  473. </div>
  474. <!-- 设置 -->
  475. <div class="tab-panel" id="tab-settings">
  476. <h2>设置</h2>
  477. <div class="setting-list">
  478. <!-- 界面样式:暗色 / 亮色 -->
  479. <div class="setting-row">
  480. <div class="setting-info">
  481. <div class="setting-title">界面样式</div>
  482. <div class="setting-hint">在暗色与亮色主题之间切换</div>
  483. </div>
  484. <div class="segmented" id="theme-seg">
  485. <button class="seg-btn active" data-theme-value="dark">暗色</button>
  486. <button class="seg-btn" data-theme-value="light">亮色</button>
  487. </div>
  488. </div>
  489. <!-- 界面字号:全局 +- 调整 -->
  490. <div class="setting-row">
  491. <div class="setting-info">
  492. <div class="setting-title">界面字号</div>
  493. <div class="setting-hint">统一调整全部文字大小,范围 +-3</div>
  494. </div>
  495. <div class="stepper">
  496. <button class="step-btn" id="font-minus" title="减小字号">−</button>
  497. <span class="step-value" id="font-delta-value">0</span>
  498. <button class="step-btn" id="font-plus" title="增大字号">+</button>
  499. </div>
  500. </div>
  501. <!-- 系统启动时运行:默认勾选 -->
  502. <div class="setting-row">
  503. <div class="setting-info">
  504. <div class="setting-title">系统启动时运行</div>
  505. <div class="setting-hint">开机后自动启动腾图工具箱(默认开启)</div>
  506. </div>
  507. <label class="switch">
  508. <input type="checkbox" id="autostart" checked>
  509. <span class="switch-track"></span>
  510. </label>
  511. </div>
  512. <!-- 窗口置顶 -->
  513. <div class="setting-row">
  514. <div class="setting-info">
  515. <div class="setting-title">窗口置顶</div>
  516. <div class="setting-hint">主窗口始终显示在其他窗口之上</div>
  517. </div>
  518. <label class="switch">
  519. <input type="checkbox" id="always-on-top">
  520. <span class="switch-track"></span>
  521. </label>
  522. </div>
  523. <!-- 呼出窗口热键 -->
  524. <div class="setting-row">
  525. <div class="setting-info">
  526. <div class="setting-title">呼出窗口热键</div>
  527. <div class="setting-hint">点击输入框后按下组合键,例如 Ctrl+Shift+G</div>
  528. </div>
  529. <input class="input hotkey-input" id="hotkey" readonly placeholder="按下组合键">
  530. </div>
  531. <!-- 指定浏览器:留空则用系统默认浏览器打开网址 -->
  532. <div class="setting-row">
  533. <div class="setting-info">
  534. <div class="setting-title">指定浏览器</div>
  535. <div class="setting-hint">点击网址时用该浏览器打开;留空则使用系统默认浏览器</div>
  536. </div>
  537. <div class="browser-path-group">
  538. <input class="input" id="browser-path" type="text" placeholder="留空=系统默认浏览器" spellcheck="false">
  539. <button class="btn-ghost" id="browser-pick" type="button" title="选择浏览器可执行文件">选择…</button>
  540. <button class="btn-ghost" id="browser-clear" type="button" title="恢复系统默认浏览器">清除</button>
  541. </div>
  542. </div>
  543. <!-- Tab 显示顺序(归入「系统」组) -->
  544. <div class="setting-row" data-tab-group="system">
  545. <div class="setting-info">
  546. <div class="setting-title">Tab 显示顺序</div>
  547. <div class="setting-hint">用逗号分隔 Tab 名称,从左到右依次显示;未列出的追加到末尾</div>
  548. </div>
  549. <input class="input" id="tab-order" type="text" placeholder="网址, 新闻, Github, 股市, 待办, 工具, 服务">
  550. </div>
  551. <!-- 自定义 Tab 页面(归入「系统」组) -->
  552. <div class="setting-row setting-row-col" data-tab-group="system">
  553. <div class="setting-info">
  554. <div class="setting-title">自定义 Tab 页面</div>
  555. <div class="setting-hint">每行一条,格式:页面名称|地址|备注(备注可空)。地址以 http:// 或 https:// 开头则内嵌网页;否则按本地文件路径读取,Markdown 自动渲染。名称用于 Tab 显示顺序,备注显示为 Tab 说明</div>
  556. </div>
  557. <textarea class="input textarea" id="custom-tabs" rows="3" placeholder="文档|D:\My\notes\readme.md|个人笔记&#10;示例|https://example.com"></textarea>
  558. </div>
  559. <!-- 股市代码 -->
  560. <div class="setting-row" data-tab-group="stock">
  561. <div class="setting-info">
  562. <div class="setting-title">股市代码</div>
  563. <div class="setting-hint">多个代码用逗号分隔,纯数字会自动补市场前缀</div>
  564. </div>
  565. <input class="input" id="stock-codes" type="text" placeholder="600519, 000001">
  566. </div>
  567. <!-- 涨跌颜色 -->
  568. <div class="setting-row" data-tab-group="stock">
  569. <div class="setting-info">
  570. <div class="setting-title">涨跌颜色</div>
  571. <div class="setting-hint">上涨 / 下跌在列表、图表与滚动条中的显示颜色</div>
  572. </div>
  573. <div class="ticker-controls">
  574. <span class="num-unit">涨</span>
  575. <input class="input-color" id="stock-up-color" type="color" title="上涨颜色">
  576. <span class="num-unit">跌</span>
  577. <input class="input-color" id="stock-down-color" type="color" title="下跌颜色">
  578. </div>
  579. </div>
  580. <!-- 股市刷新间隔 -->
  581. <div class="setting-row" data-tab-group="stock">
  582. <div class="setting-info">
  583. <div class="setting-title">股市刷新间隔</div>
  584. <div class="setting-hint">自动刷新行情的间隔,默认 30 秒</div>
  585. </div>
  586. <div class="num-group">
  587. <input class="input input-num" id="stock-refresh-secs" type="number" min="5" max="3600">
  588. <span class="num-unit">秒</span>
  589. </div>
  590. </div>
  591. <!-- 休市刷新间隔 -->
  592. <div class="setting-row" data-tab-group="stock">
  593. <div class="setting-info">
  594. <div class="setting-title">休市刷新间隔</div>
  595. <div class="setting-hint">休市时自动刷新行情的间隔,默认 2 小时</div>
  596. </div>
  597. <div class="num-group">
  598. <input class="input input-num" id="stock-closed-refresh-secs" type="number" min="60" max="86400">
  599. <span class="num-unit">秒</span>
  600. </div>
  601. </div>
  602. <!-- 常用网址 -->
  603. <div class="setting-row setting-row-col" data-tab-group="links">
  604. <div class="setting-info">
  605. <div class="setting-title">常用网址</div>
  606. <div class="setting-hint">每行一条,格式:名称|网址,例如 煎蛋|https://jandan.net/</div>
  607. </div>
  608. <textarea class="input textarea" id="links-text" rows="4" placeholder="名称|网址,每行一条"></textarea>
  609. </div>
  610. <!-- 新闻关键词 -->
  611. <div class="setting-row" data-tab-group="news">
  612. <div class="setting-info">
  613. <div class="setting-title">新闻关键词</div>
  614. <div class="setting-hint">逗号分隔;命中关键词的新闻在「新闻」页置顶高亮</div>
  615. </div>
  616. <input class="input" id="news-keywords" type="text" placeholder="AI, 芯片, 苹果">
  617. </div>
  618. <!-- B站登录 cookie -->
  619. <div class="setting-row setting-row-col" data-tab-group="news">
  620. <div class="setting-info">
  621. <div class="setting-title">B站 cookie</div>
  622. <div class="setting-hint">登录 bilibili.com 后从浏览器 Cookie 复制 SESSDATA=xxx(整个 cookie 串)。用于在「新闻」页展示你关注的人的最新动态;为空或失效时回退热门视频。cookie 会过期,需定期更新。</div>
  623. </div>
  624. <input class="input" id="bili-cookie" type="text" placeholder="SESSDATA=xxxxxxxx; bili_jct=xxxx" spellcheck="false">
  625. </div>
  626. <!-- 新闻刷新间隔 -->
  627. <div class="setting-row" data-tab-group="news">
  628. <div class="setting-info">
  629. <div class="setting-title">新闻刷新间隔</div>
  630. <div class="setting-hint">自动抓取新闻的间隔,默认 2 小时</div>
  631. </div>
  632. <div class="num-group">
  633. <input class="input input-num" id="news-refresh-mins" type="number" min="5" max="1440">
  634. <span class="num-unit">分钟</span>
  635. </div>
  636. </div>
  637. <!-- 新闻显示条数 -->
  638. <div class="setting-row" data-tab-group="news">
  639. <div class="setting-info">
  640. <div class="setting-title">新闻显示条数</div>
  641. <div class="setting-hint">「新闻」页最多显示的条目数,默认 30 条</div>
  642. </div>
  643. <div class="num-group">
  644. <input class="input input-num" id="news-count" type="number" min="5" max="200">
  645. <span class="num-unit">条</span>
  646. </div>
  647. </div>
  648. <!-- Github 项目 -->
  649. <div class="setting-row setting-row-col" data-tab-group="github">
  650. <div class="setting-info">
  651. <div class="setting-title">Github 项目</div>
  652. <div class="setting-hint">每行一条,格式:仓库地址|项目说明|本地版本(版本可选,用于提示更新)</div>
  653. </div>
  654. <textarea class="input textarea" id="github-repos" rows="4" placeholder="https://github.com/wailsapp/wails|Wails 框架|3.0.0"></textarea>
  655. </div>
  656. <!-- Github 刷新间隔 -->
  657. <div class="setting-row" data-tab-group="github">
  658. <div class="setting-info">
  659. <div class="setting-title">Github 刷新间隔</div>
  660. <div class="setting-hint">自动监听仓库更新的间隔,默认 2 小时</div>
  661. </div>
  662. <div class="num-group">
  663. <input class="input input-num" id="github-refresh-mins" type="number" min="5" max="1440">
  664. <span class="num-unit">分钟</span>
  665. </div>
  666. </div>
  667. <!-- 服务自动启动:应用启动时自动开启内置 API 服务(默认勾选) -->
  668. <div class="setting-row" data-tab-group="host">
  669. <div class="setting-info">
  670. <div class="setting-title">服务自动启动</div>
  671. <div class="setting-hint">启动腾图工具箱时自动开启内置 API 服务(默认开启)</div>
  672. </div>
  673. <label class="switch">
  674. <input type="checkbox" id="api-auto-start" checked>
  675. <span class="switch-track"></span>
  676. </label>
  677. </div>
  678. <!-- API 监听地址 -->
  679. <div class="setting-row" data-tab-group="host">
  680. <div class="setting-info">
  681. <div class="setting-title">API 监听地址</div>
  682. <div class="setting-hint">内置 API 服务监听地址,保存后自动重启服务</div>
  683. </div>
  684. <input class="input" id="api-addr" type="text" placeholder="127.0.0.1:17890">
  685. </div>
  686. <!-- 上传密码 -->
  687. <div class="setting-row" data-tab-group="host">
  688. <div class="setting-info">
  689. <div class="setting-title">上传密码</div>
  690. <div class="setting-hint">服务页文件上传需输入该密码;留空则不启用上传/下载接口</div>
  691. </div>
  692. <input class="input" id="upload-password" type="password" placeholder="留空=不启用上传">
  693. </div>
  694. <!-- 上传保存目录 -->
  695. <div class="setting-row" data-tab-group="host">
  696. <div class="setting-info">
  697. <div class="setting-title">上传保存目录</div>
  698. <div class="setting-hint">上传文件的保存目录,留空则保存到用户配置目录/uploads</div>
  699. </div>
  700. <input class="input" id="upload-dir" type="text" placeholder="D:\My\腾图\上传">
  701. </div>
  702. <!-- 上传大小上限 -->
  703. <div class="setting-row" data-tab-group="host">
  704. <div class="setting-info">
  705. <div class="setting-title">上传大小上限</div>
  706. <div class="setting-hint">单个上传文件允许的最大大小(MB),超出会被拒绝</div>
  707. </div>
  708. <input class="input" id="upload-max-size" type="number" min="1" step="1" placeholder="默认 512MB">
  709. </div>
  710. <!-- LocalSend 本机名称 -->
  711. <div class="setting-row" data-tab-group="tools">
  712. <div class="setting-info">
  713. <div class="setting-title">LocalSend 本机名称</div>
  714. <div class="setting-hint">局域网内其他 LocalSend 设备看到的名称;留空则随机生成,如「工具箱-3F8A」</div>
  715. </div>
  716. <input class="input" id="localsend-alias" type="text" placeholder="留空=随机生成" autocomplete="off">
  717. </div>
  718. <!-- LocalSend 接收模式 -->
  719. <div class="setting-row" data-tab-group="tools">
  720. <div class="setting-info">
  721. <div class="setting-title">LocalSend 接收模式</div>
  722. <div class="setting-hint">自动接收:直接保存到接收位置;手动确认:收到文件请求时弹窗由你决定</div>
  723. </div>
  724. <label class="radio-field"><input type="radio" name="localsend-mode" id="localsend-auto" value="auto"><span>自动接收</span></label>
  725. <label class="radio-field"><input type="radio" name="localsend-mode" id="localsend-manual" value="manual" checked><span>手动确认</span></label>
  726. </div>
  727. <!-- LocalSend 接收位置 -->
  728. <div class="setting-row" data-tab-group="tools">
  729. <div class="setting-info">
  730. <div class="setting-title">LocalSend 接收位置</div>
  731. <div class="setting-hint">接收文件保存目录,留空则保存到用户配置目录/TengTuToolbox/LocalSend接收</div>
  732. </div>
  733. <div class="browser-path-group">
  734. <input class="input" id="localsend-recvdir" type="text" placeholder="留空=默认接收目录" spellcheck="false">
  735. <button class="btn-ghost" id="localsend-pickdir" type="button" title="选择接收目录">选择目录</button>
  736. </div>
  737. </div>
  738. <!-- 待办文件路径 -->
  739. <div class="setting-row" data-tab-group="todo">
  740. <div class="setting-info">
  741. <div class="setting-title">待办文件路径</div>
  742. <div class="setting-hint">「待办」标签每行一个任务,保存到该文本文件</div>
  743. </div>
  744. <input class="input" id="todo-path" type="text" placeholder="D:\My\腾图\待办.txt">
  745. </div>
  746. <!-- 记录数据库路径 -->
  747. <div class="setting-row" data-tab-group="record">
  748. <div class="setting-info">
  749. <div class="setting-title">记录数据库路径</div>
  750. <div class="setting-hint">「记录」标签全部「姓名|名称|值」保存到该 SQLite 数据库文件;姓名/名称输入自动补全历史值,选择姓名与名称后按值绘柱状图</div>
  751. </div>
  752. <input class="input" id="record-db-path" type="text" placeholder="D:\My\腾图\记录.db">
  753. </div>
  754. <!-- 文本备份目录 -->
  755. <div class="setting-row">
  756. <div class="setting-info">
  757. <div class="setting-title">文本备份目录</div>
  758. <div class="setting-hint">文件类自定义 Tab 的「备份」按钮按当前时间备份文件到该目录,文件名带时间戳</div>
  759. </div>
  760. <input class="input" id="backup-dir" type="text" placeholder="D:\My\腾图\备份">
  761. </div>
  762. <!-- 股票滚动条 -->
  763. <div class="setting-row" data-tab-group="stock">
  764. <div class="setting-info">
  765. <div class="setting-title">股票滚动条</div>
  766. <div class="setting-hint">屏幕顶部一行置顶滚动显示实时行情,可拖动位置</div>
  767. </div>
  768. <div class="ticker-controls">
  769. <label class="switch" title="显示滚动条">
  770. <input type="checkbox" id="stock-ticker-enabled">
  771. <span class="switch-track"></span>
  772. </label>
  773. <label class="mini-label" title="背景透明"><input type="checkbox" id="stock-ticker-transparent">透明</label>
  774. <input class="input input-num" id="stock-ticker-width" type="number" min="200" max="6000" title="宽度 px">
  775. <input class="input input-num" id="stock-ticker-size" type="number" min="10" max="40" title="字号 px">
  776. <input class="input-color" id="stock-ticker-color" type="color" title="文字颜色">
  777. <input class="input input-num" id="stock-ticker-speed" type="number" min="20" max="400" title="滚动速度 px/s">
  778. </div>
  779. </div>
  780. <!-- 新闻滚动条 -->
  781. <div class="setting-row" data-tab-group="news">
  782. <div class="setting-info">
  783. <div class="setting-title">新闻滚动条</div>
  784. <div class="setting-hint">屏幕顶部一行置顶滚动显示新闻标题,点击标题打开详情</div>
  785. </div>
  786. <div class="ticker-controls">
  787. <label class="switch" title="显示滚动条">
  788. <input type="checkbox" id="news-ticker-enabled">
  789. <span class="switch-track"></span>
  790. </label>
  791. <label class="mini-label" title="背景透明"><input type="checkbox" id="news-ticker-transparent">透明</label>
  792. <input class="input input-num" id="news-ticker-width" type="number" min="200" max="6000" title="宽度 px">
  793. <input class="input input-num" id="news-ticker-size" type="number" min="10" max="40" title="字号 px">
  794. <input class="input-color" id="news-ticker-color" type="color" title="文字颜色">
  795. <input class="input input-num" id="news-ticker-speed" type="number" min="20" max="400" title="滚动速度 px/s">
  796. </div>
  797. </div>
  798. <!-- 随机古诗(归入「系统」组) -->
  799. <div class="setting-row" data-tab-group="system">
  800. <div class="setting-info">
  801. <div class="setting-title">随机古诗</div>
  802. <div class="setting-hint">footer 版本后面水平滚动显示一首随机古诗,可点击换一首、朗读(TTS)</div>
  803. </div>
  804. <div class="ticker-controls">
  805. <label class="switch" title="显示古诗">
  806. <input type="checkbox" id="poem-enabled">
  807. <span class="switch-track"></span>
  808. </label>
  809. <input class="input-color" id="poem-color" type="color" title="文字颜色">
  810. <input class="input input-num" id="poem-size" type="number" min="12" max="48" title="字号 px">
  811. <label class="mini-label" title="滚动速度(秒/轮),数值越小滚动越快"><input type="number" id="poem-speed" class="input input-num" min="5" max="120" title="滚动速度(秒/轮)">速度</label>
  812. <label class="mini-label" title="显示朗读按钮"><input type="checkbox" id="poem-tts">朗读</label>
  813. </div>
  814. </div>
  815. <!-- 鼠标提醒(系统级气泡) -->
  816. <div class="setting-row" data-tab-group="host">
  817. <div class="setting-info">
  818. <div class="setting-title">鼠标提醒</div>
  819. <div class="setting-hint">触发提醒时在鼠标旁浮出透明气泡文字,可调字号、宽度、滚动速度、颜色与描边(描边形成反差,避免背景看不清)</div>
  820. </div>
  821. <div class="ticker-controls">
  822. <input class="input input-num" id="mouse-alert-size" type="number" min="10" max="48" title="字号 px">
  823. <input class="input input-num" id="mouse-alert-width" type="number" min="120" max="1200" title="窗口宽度 px">
  824. <input class="input input-num" id="mouse-alert-speed" type="number" min="5" max="300" title="滚动速度 px/s">
  825. <input class="input-color" id="mouse-alert-color" type="color" title="文字颜色">
  826. <input class="input input-num" id="mouse-alert-outline-width" type="number" min="0" max="6" title="文字描边宽度 px(0 关闭)">
  827. <input class="input-color" id="mouse-alert-outline-color" type="color" title="文字描边颜色(与文字形成反差)">
  828. <input class="input input-num" id="mouse-alert-duration" type="number" min="2" max="60" title="显示时长(秒)">
  829. </div>
  830. </div>
  831. </div>
  832. <!-- 保存栏 -->
  833. <div class="save-bar">
  834. <button class="btn-primary" id="save-settings">保存设置</button>
  835. <span class="save-status" id="save-status"></span>
  836. </div>
  837. </div>
  838. </div>
  839. </div>
  840. <!-- 股票图表弹窗:点击股市行打开,可切换分时图 / 日K图 -->
  841. <div class="chart-modal" id="chart-modal" hidden>
  842. <div class="chart-mask" id="chart-mask"></div>
  843. <div class="chart-dialog" role="dialog" aria-modal="true" aria-label="股票图表">
  844. <div class="chart-head">
  845. <div class="chart-title-wrap">
  846. <div class="chart-title" id="chart-title">--</div>
  847. <div class="chart-sub" id="chart-sub"></div>
  848. </div>
  849. <div class="segmented" id="chart-kind">
  850. <button class="seg-btn active" data-chart-kind="minute">分时</button>
  851. <button class="seg-btn" data-chart-kind="kline">日K</button>
  852. </div>
  853. <button class="chart-close" id="chart-close" title="关闭">×</button>
  854. </div>
  855. <canvas id="chart-canvas"></canvas>
  856. <div class="chart-legend" id="chart-legend"></div>
  857. </div>
  858. </div>
  859. <!-- 待办提醒弹窗:到点时弹出,置顶显示 -->
  860. <div class="remind-modal" id="remind-modal" hidden>
  861. <div class="remind-mask" id="remind-mask"></div>
  862. <div class="remind-dialog" role="alertdialog" aria-modal="true" aria-label="待办提醒">
  863. <div class="remind-icon">⏰</div>
  864. <div class="remind-title">待办提醒</div>
  865. <div class="remind-text" id="remind-text"></div>
  866. <div class="remind-time" id="remind-time"></div>
  867. <div class="remind-actions">
  868. <button class="btn-primary" id="remind-ok">知道了</button>
  869. </div>
  870. </div>
  871. </div>
  872. <!-- LocalSend 文件接收确认弹窗(手动接收模式) -->
  873. <div class="ls-offer-mask" id="ls-offer-mask" hidden>
  874. <div class="ls-offer-dialog">
  875. <div class="ls-offer-title">收到文件发送请求</div>
  876. <div class="ls-offer-sender" id="ls-offer-sender"></div>
  877. <ul class="ls-offer-files" id="ls-offer-files"></ul>
  878. <div class="ls-offer-actions">
  879. <button class="btn-ghost" id="ls-offer-reject">拒绝</button>
  880. <button class="btn-primary" id="ls-offer-accept">接受</button>
  881. </div>
  882. </div>
  883. </div>
  884. <footer class="footer">
  885. <span class="footer-version"><span class="dot"></span>腾图工具箱 <span id="footer-version-text"></span></span>
  886. <div class="footer-desc" id="footer-desc">
  887. <span class="footer-marquee" id="footer-marquee"></span>
  888. <button class="poem-read" id="poem-read" title="朗读古诗" hidden>🔊</button>
  889. </div>
  890. <span class="footer-time" id="time">--:--:--</span>
  891. <a class="footer-docs" data-wml-openURL="https://v3.wails.io" aria-label="Wails documentation">官方文档</a>
  892. </footer>
  893. <script type="module" src="/src/main.js"></script>
  894. </body>
  895. </html>