import type { Component } from 'vue' import { ImageIcon, FrameIcon, QrcodeIcon, CodeIcon, TimeIcon, FileIcon, LockOnIcon, CalendarIcon, CalculatorIcon, FingerprintIcon, CreditcardIcon, LocationIcon, LinkIcon, TranslateIcon, BrowseIcon, RefreshIcon, ControlPlatformIcon, Palette1Icon, SwapIcon, FileCodeIcon, ChartIcon, MoneyIcon, InternetIcon, KeyIcon, HeartIcon, WalletIcon, UsergroupIcon, GiftIcon, AlarmIcon, } from 'tdesign-icons-vue-next' /** * 工具注册表:网站内所有工具的“唯一数据源”。 * 侧边导航、首页卡片、路由表均由此文件生成。 * * ⚙️ 新增工具只需三步: * 1. 在 src/views/<工具名>/ 下创建页面组件(可参考现有工具页面); * 2. 在本文件的 tools 数组中追加一条配置(path/name/desc/icon/category/component); * 3. 无需修改路由文件、首页与侧边栏,它们会自动渲染新工具。 * * 🗂️ 分类扩展:在 toolCategories 数组追加一条 { key/label/desc }, * 再把对应工具的 category 指向新 key 即可,导航与首页会自动出现新分组。 */ /** 工具分类定义(数据驱动,顺序即展示顺序) */ export interface ToolCategory { /** 分类唯一标识,与 ToolItem.category 对应 */ key: string /** 分类名称(导航分组标题、首页分区标题) */ label: string /** 一句话描述(首页分区副标题) */ desc: string } export const toolCategories: ToolCategory[] = [ { key: 'work', label: '工作效率', desc: '开发编程、办公文本与文件处理' }, { key: 'life', label: '生活助手', desc: '日常生活中的计算、查询与决策小工具' }, ] export interface ToolItem { /** 路由路径(相对根路径,不含前导斜杠) */ path: string /** 工具名称(菜单、卡片、页面标题使用) */ name: string /** 一句话描述(首页卡片展示) */ desc: string /** 菜单/卡片图标(TDesign 图标组件) */ icon: Component /** 所属分类 key(必须在 toolCategories 中存在),缺省归入第一个分类 */ category?: string /** 页面组件(懒加载,减小首屏体积) */ component: () => Promise } export const tools: ToolItem[] = [ /* ==================== 工作效率 ==================== */ { path: 'image-compress', name: '图片压缩', desc: '本地压缩 JPG/PNG/WebP,可调质量,压缩后直接下载', icon: ImageIcon, category: 'work', component: () => import('@/views/image-compress/ImageCompressView.vue'), }, { path: 'json-format', name: 'JSON 格式化', desc: 'JSON 格式化、压缩、校验,一键复制结果', icon: CodeIcon, category: 'work', component: () => import('@/views/json-format/JsonFormatView.vue'), }, { path: 'timestamp', name: '时间戳转换', desc: '时间戳与北京时间互转,支持秒/毫秒与批量转换', icon: TimeIcon, category: 'work', component: () => import('@/views/timestamp/TimestampView.vue'), }, { path: 'base64', name: 'Base64 编解码', desc: '文本 Base64 编解码,图片文件与 Base64 互转', icon: FileIcon, category: 'work', component: () => import('@/views/base64/Base64View.vue'), }, { path: 'jwt-parse', name: 'JWT 解析', desc: '解析 JWT 的 Header 与 Payload,展示过期时间', icon: LockOnIcon, category: 'work', component: () => import('@/views/jwt-parse/JwtParseView.vue'), }, { path: 'cron', name: 'Cron 表达式', desc: '解析 Cron 下次执行时间,可视化生成表达式', icon: CalendarIcon, category: 'work', component: () => import('@/views/cron/CronView.vue'), }, { path: 'radix-convert', name: '进制转换', desc: '二进制、八进制、十进制、十六进制互转', icon: CalculatorIcon, category: 'work', component: () => import('@/views/radix-convert/RadixConvertView.vue'), }, { path: 'hash', name: '哈希计算', desc: '文本/文件计算 MD5、SHA1、SHA256、SHA512', icon: FingerprintIcon, category: 'work', component: () => import('@/views/hash/HashView.vue'), }, { path: 'url-parse', name: 'URL 解析', desc: '解析协议/域名/路径/参数,也支持构造 URL', icon: LinkIcon, category: 'work', component: () => import('@/views/url-parse/UrlParseView.vue'), }, { path: 'translate', name: '翻译', desc: '中文、英文、韩文、日文互译(免费在线接口)', icon: TranslateIcon, category: 'work', component: () => import('@/views/translate/TranslateView.vue'), }, { path: 'ocr', name: '图片 OCR 识别', desc: '本地识别图片文字,支持中英文(WASM)', icon: BrowseIcon, category: 'work', component: () => import('@/views/ocr/OcrView.vue'), }, { path: 'uuid', name: 'UUID 生成', desc: '批量生成 UUID v4,支持大小写与去连字符', icon: RefreshIcon, category: 'work', component: () => import('@/views/uuid/UuidView.vue'), }, { path: 'regex-test', name: '正则测试', desc: '实时测试正则匹配、分组与替换,匹配高亮显示', icon: ControlPlatformIcon, category: 'work', component: () => import('@/views/regex-test/RegexTestView.vue'), }, { path: 'case-convert', name: '命名转换', desc: '驼峰、蛇形、短横线等命名风格一键互转', icon: CodeIcon, category: 'work', component: () => import('@/views/case-convert/CaseConvertView.vue'), }, { path: 'color-convert', name: '色值转换', desc: 'HEX、RGB、HSL、HSV 互转,取色器 + 预设色板', icon: Palette1Icon, category: 'work', component: () => import('@/views/color-convert/ColorConvertView.vue'), }, { path: 'yaml-json', name: 'YAML ↔ JSON', desc: 'YAML 与 JSON 双向转换,报错定位清晰', icon: FileCodeIcon, category: 'work', component: () => import('@/views/yaml-json/YamlJsonView.vue'), }, { path: 'word-count', name: '字数统计', desc: '统计字符、汉字、单词、段落与阅读时长', icon: ChartIcon, category: 'work', component: () => import('@/views/word-count/WordCountView.vue'), }, { path: 'zh-convert', name: '简繁转换', desc: '简体与繁体中文互转(opencc 词库)', icon: TranslateIcon, category: 'work', component: () => import('@/views/zh-convert/ZhConvertView.vue'), }, /* ==================== 生活助手 ==================== */ { path: 'image-cropper', name: '图片裁剪', desc: '按比例裁剪图片,实时预览,导出 JPG/PNG', icon: FrameIcon, category: 'life', component: () => import('@/views/image-cropper/ImageCropperView.vue'), }, { path: 'qrcode', name: '二维码生成解析', desc: '文本/链接生成二维码,上传图片解析二维码内容', icon: QrcodeIcon, category: 'life', component: () => import('@/views/qrcode/QrcodeView.vue'), }, { path: 'idcard', name: '身份证解析', desc: '校验身份证合法性,解析生日、性别、年龄、地区', icon: CreditcardIcon, category: 'life', component: () => import('@/views/idcard/IdcardView.vue'), }, { path: 'address-parse', name: '地址解析', desc: '拆分中文地址的省、市、区与详细地址', icon: LocationIcon, category: 'life', component: () => import('@/views/address-parse/AddressParseView.vue'), }, { path: 'unit-convert', name: '单位换算', desc: '长度、质量、温度、数据存储等 8 类单位换算', icon: SwapIcon, category: 'life', component: () => import('@/views/unit-convert/UnitConvertView.vue'), }, { path: 'rmb-upper', name: '人民币大写', desc: '数字金额转人民币大写,处理角分与负数', icon: MoneyIcon, category: 'life', component: () => import('@/views/rmb-upper/RmbUpperView.vue'), }, { path: 'date-calc', name: '日期计算', desc: '日期差值、推算与年龄生肖星座计算', icon: CalendarIcon, category: 'life', component: () => import('@/views/date-calc/DateCalcView.vue'), }, { path: 'password-gen', name: '密码生成', desc: '随机强密码批量生成,含强度评估', icon: KeyIcon, category: 'life', component: () => import('@/views/password-gen/PasswordGenView.vue'), }, { path: 'bmi', name: 'BMI 计算器', desc: '计算身体质量指数,中国标准分级与健康体重范围', icon: HeartIcon, category: 'life', component: () => import('@/views/bmi/BmiView.vue'), }, { path: 'mortgage', name: '房贷计算器', desc: '等额本息/等额本金对比,月供、总利息一目了然', icon: WalletIcon, category: 'life', component: () => import('@/views/mortgage/MortgageView.vue'), }, { path: 'bill-split', name: '账单拆分', desc: '多人聚餐 AA 分账,自动生成转账方案', icon: UsergroupIcon, category: 'life', component: () => import('@/views/bill-split/BillSplitView.vue'), }, { path: 'random-decision', name: '随机决定', desc: '选项抽签治选择困难,随机数/骰子一键生成', icon: GiftIcon, category: 'life', component: () => import('@/views/random-decision/RandomDecisionView.vue'), }, { path: 'pomodoro', name: '番茄钟', desc: '专注与休息倒计时,记录完成轮数', icon: AlarmIcon, category: 'life', component: () => import('@/views/pomodoro/PomodoroView.vue'), }, ] /** 工具默认分类:未填写 category 时归入第一个分类 */ export function toolCategoryKey(tool: ToolItem): string { return tool.category ?? toolCategories[0].key } /** * 按分类分组返回工具(按 toolCategories 声明顺序), * 侧边导航与首页分区渲染统一使用该函数,新增分类零改动。 */ export function groupedTools(): Array<{ category: ToolCategory; items: ToolItem[] }> { return toolCategories.map((category) => ({ category, items: tools.filter((t) => toolCategoryKey(t) === category.key), })) }