Files
Thing/src/modules/quickpanel/providers/system.ts
T
2026-08-31 18:05:27 +08:00

187 lines
5.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* system Provider:系统操作。
* 内置常用系统命令(regedit / cmd / powershell 等),title 为中文主名,
* keywords 补充英文/别名;拼音全拼与首字母由引擎从 title 的 CJK 部分自动推导。
* 「退出 Thing」为本程序相关条目,归入设置分类(空查询不显示)。
*/
import { invoke } from '@tauri-apps/api/core'
import { bestScore, type TextForms } from '../engine'
import type { QPItem, QPProvider } from './types'
import { buildItemForms } from './utils'
// Rust 端通过 tauri-specta 生成的命令绑定(bindings.ts
import { commands } from '@/lib/bindings'
interface SystemCommandDef {
id: string
title: string
subtitle: string
/** 额外关键词(英文命令名、中文别名等,用于匹配) */
keywords: string[]
command: string
args: string[]
}
const SYSTEM_COMMANDS: SystemCommandDef[] = [
{
id: 'sys-regedit',
title: '注册表编辑器',
subtitle: 'regedit',
keywords: ['regedit', '注册表', 'registry'],
command: 'regedit',
args: [],
},
{
id: 'sys-cmd',
title: '命令提示符',
subtitle: 'cmd',
keywords: ['cmd', '命令行', '终端', 'command'],
command: 'cmd',
args: [],
},
{
id: 'sys-powershell',
title: 'PowerShell',
subtitle: 'powershell',
keywords: ['powershell', 'pwsh'],
command: 'powershell',
args: [],
},
{
id: 'sys-taskmgr',
title: '任务管理器',
subtitle: 'taskmgr',
keywords: ['taskmgr', '任务管理', '进程'],
command: 'taskmgr',
args: [],
},
{
id: 'sys-devmgmt',
title: '设备管理器',
subtitle: 'devmgmt.msc',
keywords: ['devmgmt', '设备管理', '硬件', '驱动', 'sheb'],
command: 'devmgmt.msc',
args: [],
},
{
id: 'sys-explorer',
title: '资源管理器',
subtitle: 'explorer',
keywords: ['explorer', '文件管理器', '资源管理'],
command: 'explorer',
args: [],
},
{
id: 'sys-control',
title: '控制面板',
subtitle: 'control',
keywords: ['control', '控制面板', '设置'],
command: 'control',
args: [],
},
{
id: 'sys-shutdown',
title: '关机',
subtitle: 'shutdown /s /t 0',
keywords: ['shutdown', '关闭计算机', '关闭电脑', 'guanji'],
command: 'shutdown',
args: ['/s', '/t', '0'],
},
{
id: 'sys-restart',
title: '重启',
subtitle: 'shutdown /r /t 0',
keywords: ['restart', 'reboot', '重新启动', '重启电脑', 'chongqi'],
command: 'shutdown',
args: ['/r', '/t', '0'],
},
{
id: 'sys-shutdown-cancel',
title: '取消关机/重启',
subtitle: 'shutdown /a',
keywords: ['cancel', '取消', 'quxiao', 'abort'],
command: 'shutdown',
args: ['/a'],
},
{
id: 'sys-hibernate',
title: '休眠',
subtitle: 'shutdown /h',
keywords: ['hibernate', '睡眠', 'xiu', 'mian'],
command: 'shutdown',
args: ['/h'],
},
]
export class SystemProvider implements QPProvider {
id = 'system'
label = '系统'
priority = 40
private buildItems(): QPItem[] {
const items: QPItem[] = SYSTEM_COMMANDS.map(def => ({
id: def.id,
title: def.title,
subtitle: def.subtitle,
group: '系统',
action: async () => {
try {
await commands.quickpanelRunSystemCommand(def.command, def.args)
} catch (e) {
console.error('[quickpanel] 系统命令失败:', e)
}
},
}))
// 锁屏(系统操作)+ 退出应用(本程序相关 → 设置分类,默认视图不显示)
items.push(
{
id: 'sys-lock',
title: '锁定屏幕',
subtitle: '立即锁定计算机',
group: '系统',
action: async () => {
try {
await commands.quickpanelLockScreen()
} catch (e) {
console.error('[quickpanel] 锁屏失败:', e)
}
},
},
{
id: 'sys-quit',
title: '退出 Thing',
subtitle: '关闭应用程序',
group: '设置',
action: async () => {
try {
await invoke('quit_app')
} catch (e) {
console.error('[quickpanel] 退出失败:', e)
}
},
},
)
return items
}
/** 为带 keywords 的 item 构建匹配形态(title + keywords 合并) */
private itemForms(item: QPItem): TextForms {
const def = SYSTEM_COMMANDS.find(d => d.id === item.id)
return buildItemForms(item.title, def?.keywords ?? [])
}
search(query: string): QPItem[] {
const items = this.buildItems()
// 空查询:只返回系统相关条目(「退出 Thing」等程序相关项归入设置分类,不默认显示)
if (!query.trim()) return items.filter(i => i.group === '系统')
const scored: Array<{ item: QPItem; score: number }> = []
for (const item of items) {
const forms = this.itemForms(item)
const score = bestScore(query, forms)
if (score >= 0) scored.push({ item, score })
}
scored.sort((a, b) => b.score - a.score)
return scored.map(s => ({ ...s.item, score: s.score }))
}
}