mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-05-25 08:00:16 +08:00
init
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<UApp>
|
||||
<router-view />
|
||||
</UApp>
|
||||
</template>
|
||||
@@ -0,0 +1,8 @@
|
||||
@import "tailwindcss";
|
||||
@import "@nuxt/ui";
|
||||
|
||||
/* 配置主题颜色 */
|
||||
:root {
|
||||
--ui-primary: var(--color-green-500);
|
||||
--ui-neutral: var(--color-slate-500);
|
||||
}
|
||||
Vendored
+32
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable */
|
||||
// @ts-nocheck
|
||||
// biome-ignore lint: disable
|
||||
// oxlint-disable
|
||||
// ------
|
||||
// Generated by unplugin-vue-components
|
||||
// Read more: https://github.com/vuejs/core/pull/3399
|
||||
|
||||
export {}
|
||||
|
||||
/* prettier-ignore */
|
||||
declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
RouterView: typeof import('vue-router')['RouterView']
|
||||
UApp: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/App.vue')['default']
|
||||
UBadge: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Badge.vue')['default']
|
||||
UButton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Button.vue')['default']
|
||||
UCard: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Card.vue')['default']
|
||||
UCheckbox: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Checkbox.vue')['default']
|
||||
UFormField: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/FormField.vue')['default']
|
||||
UInput: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Input.vue')['default']
|
||||
UModal: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Modal.vue')['default']
|
||||
UProgress: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Progress.vue')['default']
|
||||
USelect: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Select.vue')['default']
|
||||
USkeleton: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Skeleton.vue')['default']
|
||||
USwitch: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Switch.vue')['default']
|
||||
UTabs: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Tabs.vue')['default']
|
||||
UTextarea: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Textarea.vue')['default']
|
||||
UToaster: typeof import('./../node_modules/.pnpm/@nuxt+ui@4.2.1_@babel+parser@7.28.5_axios@1.13.2_embla-carousel@8.6.0_typescript@5.9.2__26fe4596361b2ba7cfd995b4ae348088/node_modules/@nuxt/ui/dist/runtime/components/Toaster.vue')['default']
|
||||
}
|
||||
}
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
declare module '*.vue' {
|
||||
import type { DefineComponent } from 'vue'
|
||||
const component: DefineComponent<{}, {}, any>
|
||||
export default component
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>ChatLens</title>
|
||||
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
|
||||
<link rel="icon" href="/assets/imgs/favicon.ico" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<script type="module" src="/main.ts"></script>
|
||||
</body>
|
||||
</html>
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { router } from './routes/'
|
||||
import { createPinia } from 'pinia'
|
||||
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
|
||||
import './assets/styles/main.css'
|
||||
|
||||
const app = createApp(App)
|
||||
|
||||
const pinia = createPinia()
|
||||
pinia.use(piniaPluginPersistedstate)
|
||||
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
@@ -0,0 +1,55 @@
|
||||
<script setup lang="ts">
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-50 dark:bg-gray-900 flex flex-col items-center justify-center p-8">
|
||||
<div class="text-center max-w-2xl">
|
||||
<!-- Logo / 标题 -->
|
||||
<div class="mb-8">
|
||||
<div class="w-20 h-20 mx-auto mb-6 bg-primary-500 rounded-2xl flex items-center justify-center">
|
||||
<span class="text-4xl">💬</span>
|
||||
</div>
|
||||
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
ChatLens
|
||||
</h1>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400">
|
||||
聊天记录分析工具 - 让你更好地了解你的聊天数据
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 功能入口 -->
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
|
||||
<UCard class="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<div class="text-center p-4">
|
||||
<div class="text-3xl mb-3">📁</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-2">导入聊天记录</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">支持多种格式的聊天记录导入</p>
|
||||
</div>
|
||||
</UCard>
|
||||
<UCard class="hover:shadow-lg transition-shadow cursor-pointer">
|
||||
<div class="text-center p-4">
|
||||
<div class="text-3xl mb-3">📊</div>
|
||||
<h3 class="font-semibold text-gray-900 dark:text-white mb-2">数据分析</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">可视化展示聊天数据统计</p>
|
||||
</div>
|
||||
</UCard>
|
||||
</div>
|
||||
|
||||
<!-- 快速开始按钮 -->
|
||||
<div class="flex flex-col sm:flex-row gap-4 justify-center">
|
||||
<UButton size="lg" color="primary">
|
||||
开始使用
|
||||
</UButton>
|
||||
<UButton size="lg" variant="outline" to="/ui">
|
||||
组件演示
|
||||
</UButton>
|
||||
</div>
|
||||
|
||||
<!-- 版本信息 -->
|
||||
<p class="mt-12 text-sm text-gray-400">
|
||||
v0.1.0 · Built with Vue 3 + Electron + Nuxt UI
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
|
||||
// 表单数据
|
||||
const formData = ref({
|
||||
name: '',
|
||||
email: '',
|
||||
message: '',
|
||||
})
|
||||
|
||||
// 开关状态
|
||||
const isDarkMode = ref(false)
|
||||
const isEnabled = ref(true)
|
||||
|
||||
// 下拉选择
|
||||
const selectedOption = ref('')
|
||||
const options = [
|
||||
{ label: '选项一', value: 'option1' },
|
||||
{ label: '选项二', value: 'option2' },
|
||||
{ label: '选项三', value: 'option3' },
|
||||
]
|
||||
|
||||
// 标签页
|
||||
const activeTab = ref('tab1')
|
||||
const tabs = [
|
||||
{ label: '概览', value: 'tab1' },
|
||||
{ label: '分析', value: 'tab2' },
|
||||
{ label: '设置', value: 'tab3' },
|
||||
]
|
||||
|
||||
// Toast 通知
|
||||
const toast = useToast()
|
||||
|
||||
const showToast = (type: 'success' | 'error' | 'warning' | 'info') => {
|
||||
const messages = {
|
||||
success: '操作成功!',
|
||||
error: '操作失败,请重试',
|
||||
warning: '请注意此操作',
|
||||
info: '这是一条提示信息',
|
||||
}
|
||||
toast.add({
|
||||
title: messages[type],
|
||||
color: type === 'error' ? 'red' : type === 'warning' ? 'yellow' : type === 'success' ? 'green' : 'blue',
|
||||
})
|
||||
}
|
||||
|
||||
// 模态框
|
||||
const isModalOpen = ref(false)
|
||||
|
||||
// 加载状态
|
||||
const isLoading = ref(false)
|
||||
const handleSubmit = async () => {
|
||||
isLoading.value = true
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000))
|
||||
isLoading.value = false
|
||||
toast.add({ title: '表单提交成功!', color: 'green' })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="min-h-screen bg-gray-50 dark:bg-gray-900 p-8">
|
||||
<!-- 标题区域 -->
|
||||
<div class="max-w-6xl mx-auto">
|
||||
<div class="text-center mb-12">
|
||||
<h1 class="text-4xl font-bold text-gray-900 dark:text-white mb-4">
|
||||
🎉 Nuxt UI 组件演示
|
||||
</h1>
|
||||
<p class="text-lg text-gray-600 dark:text-gray-400">
|
||||
ChatLens - 聊天记录分析工具
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- 按钮组 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">按钮 Buttons</h2>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<UButton>默认按钮</UButton>
|
||||
<UButton color="primary">主要按钮</UButton>
|
||||
<UButton color="green">成功按钮</UButton>
|
||||
<UButton color="red">危险按钮</UButton>
|
||||
<UButton color="yellow">警告按钮</UButton>
|
||||
<UButton variant="outline">描边按钮</UButton>
|
||||
<UButton variant="ghost">幽灵按钮</UButton>
|
||||
<UButton variant="soft">柔和按钮</UButton>
|
||||
<UButton :loading="isLoading" @click="handleSubmit">
|
||||
{{ isLoading ? '加载中...' : '带加载状态' }}
|
||||
</UButton>
|
||||
<UButton icon="i-heroicons-arrow-path" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 表单输入 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">表单 Forms</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 gap-6 max-w-2xl">
|
||||
<UFormField label="用户名">
|
||||
<UInput v-model="formData.name" placeholder="请输入用户名" />
|
||||
</UFormField>
|
||||
<UFormField label="邮箱">
|
||||
<UInput v-model="formData.email" type="email" placeholder="请输入邮箱" />
|
||||
</UFormField>
|
||||
<UFormField label="选择选项" class="md:col-span-2">
|
||||
<USelect v-model="selectedOption" :items="options" placeholder="请选择" />
|
||||
</UFormField>
|
||||
<UFormField label="留言" class="md:col-span-2">
|
||||
<UTextarea v-model="formData.message" placeholder="请输入留言内容" :rows="4" />
|
||||
</UFormField>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 开关与复选框 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">开关 Toggles</h2>
|
||||
<div class="flex flex-wrap items-center gap-8">
|
||||
<div class="flex items-center gap-3">
|
||||
<USwitch v-model="isDarkMode" />
|
||||
<span class="text-gray-700 dark:text-gray-300">深色模式: {{ isDarkMode ? '开' : '关' }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<USwitch v-model="isEnabled" color="green" />
|
||||
<span class="text-gray-700 dark:text-gray-300">启用功能: {{ isEnabled ? '是' : '否' }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<UCheckbox label="记住我" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 标签页 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">标签页 Tabs</h2>
|
||||
<UTabs v-model="activeTab" :items="tabs" class="w-full max-w-xl">
|
||||
<template #tab1>
|
||||
<div class="p-4 bg-white dark:bg-gray-800 rounded-lg">
|
||||
<h3 class="font-medium text-gray-900 dark:text-white mb-2">概览内容</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">这里是概览页面的内容区域。</p>
|
||||
</div>
|
||||
</template>
|
||||
<template #tab2>
|
||||
<div class="p-4 bg-white dark:bg-gray-800 rounded-lg">
|
||||
<h3 class="font-medium text-gray-900 dark:text-white mb-2">分析内容</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">这里是分析页面的内容区域。</p>
|
||||
</div>
|
||||
</template>
|
||||
<template #tab3>
|
||||
<div class="p-4 bg-white dark:bg-gray-800 rounded-lg">
|
||||
<h3 class="font-medium text-gray-900 dark:text-white mb-2">设置内容</h3>
|
||||
<p class="text-gray-600 dark:text-gray-400">这里是设置页面的内容区域。</p>
|
||||
</div>
|
||||
</template>
|
||||
</UTabs>
|
||||
</section>
|
||||
|
||||
<!-- Toast 通知 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">通知 Toast</h2>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<UButton color="green" @click="showToast('success')">成功通知</UButton>
|
||||
<UButton color="red" @click="showToast('error')">错误通知</UButton>
|
||||
<UButton color="yellow" @click="showToast('warning')">警告通知</UButton>
|
||||
<UButton color="blue" @click="showToast('info')">信息通知</UButton>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 模态框 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">模态框 Modal</h2>
|
||||
<UButton @click="isModalOpen = true">打开模态框</UButton>
|
||||
<UModal v-model:open="isModalOpen">
|
||||
<template #header>
|
||||
<h3 class="text-lg font-semibold">模态框标题</h3>
|
||||
</template>
|
||||
<template #body>
|
||||
<p class="text-gray-600 dark:text-gray-400">
|
||||
这是模态框的内容区域,可以放置任何内容。
|
||||
</p>
|
||||
</template>
|
||||
<template #footer>
|
||||
<div class="flex justify-end gap-3">
|
||||
<UButton variant="ghost" @click="isModalOpen = false">取消</UButton>
|
||||
<UButton color="primary" @click="isModalOpen = false">确认</UButton>
|
||||
</div>
|
||||
</template>
|
||||
</UModal>
|
||||
</section>
|
||||
|
||||
<!-- 徽章 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">徽章 Badge</h2>
|
||||
<div class="flex flex-wrap gap-4">
|
||||
<UBadge>默认</UBadge>
|
||||
<UBadge color="green">成功</UBadge>
|
||||
<UBadge color="red">错误</UBadge>
|
||||
<UBadge color="yellow">警告</UBadge>
|
||||
<UBadge color="blue">信息</UBadge>
|
||||
<UBadge variant="outline">描边</UBadge>
|
||||
<UBadge variant="soft">柔和</UBadge>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 卡片 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">卡片 Card</h2>
|
||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||
<UCard>
|
||||
<template #header>
|
||||
<h3 class="font-semibold">卡片标题</h3>
|
||||
</template>
|
||||
<p class="text-gray-600 dark:text-gray-400">这是卡片的内容区域。</p>
|
||||
<template #footer>
|
||||
<UButton size="sm">查看详情</UButton>
|
||||
</template>
|
||||
</UCard>
|
||||
<UCard>
|
||||
<template #header>
|
||||
<h3 class="font-semibold">功能卡片</h3>
|
||||
</template>
|
||||
<p class="text-gray-600 dark:text-gray-400">支持自定义头部和底部。</p>
|
||||
<template #footer>
|
||||
<div class="flex gap-2">
|
||||
<UButton size="sm" variant="ghost">取消</UButton>
|
||||
<UButton size="sm">确认</UButton>
|
||||
</div>
|
||||
</template>
|
||||
</UCard>
|
||||
<UCard>
|
||||
<template #header>
|
||||
<h3 class="font-semibold">简洁卡片</h3>
|
||||
</template>
|
||||
<p class="text-gray-600 dark:text-gray-400">简洁的卡片展示样式。</p>
|
||||
</UCard>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">进度 Progress</h2>
|
||||
<div class="space-y-4 max-w-md">
|
||||
<UProgress :value="30" />
|
||||
<UProgress :value="60" color="green" />
|
||||
<UProgress :value="90" color="red" />
|
||||
<UProgress :value="100" color="blue" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- 骨架屏 -->
|
||||
<section class="mb-12">
|
||||
<h2 class="text-2xl font-semibold text-gray-800 dark:text-white mb-6">骨架屏 Skeleton</h2>
|
||||
<div class="flex items-center gap-4 max-w-md">
|
||||
<USkeleton class="w-12 h-12 rounded-full" />
|
||||
<div class="space-y-2 flex-1">
|
||||
<USkeleton class="h-4 w-3/4" />
|
||||
<USkeleton class="h-4 w-1/2" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<!-- Toast 容器 -->
|
||||
<UToaster />
|
||||
</div>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
import { createRouter, createWebHashHistory } from 'vue-router'
|
||||
|
||||
export const router = createRouter({
|
||||
routes: [
|
||||
{
|
||||
path: '/',
|
||||
name: 'index',
|
||||
component: () => import('@/pages/index.vue'),
|
||||
},
|
||||
{
|
||||
path: '/ui',
|
||||
name: 'ui',
|
||||
component: () => import('@/pages/ui.vue'),
|
||||
},
|
||||
],
|
||||
history: createWebHashHistory(),
|
||||
})
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
next()
|
||||
})
|
||||
|
||||
router.afterEach((to) => {
|
||||
document.body.id = `page-${to.name as string}`
|
||||
})
|
||||
Reference in New Issue
Block a user