refactor: 标准化项目结构 frontend/ + backend/ + SQLite + run.sh

- 目录重构: app/ -> frontend/,与 backend/ 并列
- 数据库: 默认 SQLite(零配置),修复 DSN() bug
- run.sh: 一键启动前后端,支持 start/stop/restart/status
- Makefile: install/dev/build/lint/clean 快捷命令
- vite.config.ts: 配置 dev server 端口 5173 + API 代理到 8080
- config.yaml: SQLite 默认配置,开箱即用
- docs/: 完整开发文档(项目结构/API/数据库/规范/部署)
- 修复: GORM foreign key 关联声明
- 修复: go get gorm.io/driver/sqlite 依赖
This commit is contained in:
attacker committed 2026-06-13 23:34:23 +08:00
1 parent 7d6674bddd
commit 97c4207ff8
132 files changed
+1572 -34

No files matched your search

+233
View File
@@ -0,0 +1,233 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 222 47% 4%;
--foreground: 210 40% 98%;
--card: 222 47% 6%;
--card-foreground: 210 40% 98%;
--popover: 222 47% 6%;
--popover-foreground: 210 40% 98%;
--primary: 217 91% 60%;
--primary-foreground: 210 40% 98%;
--secondary: 217 33% 17%;
--secondary-foreground: 210 40% 98%;
--muted: 217 33% 17%;
--muted-foreground: 215 20% 65%;
--accent: 217 33% 17%;
--accent-foreground: 210 40% 98%;
--destructive: 0 84% 60%;
--destructive-foreground: 210 40% 98%;
--border: 217 33% 15%;
--input: 217 33% 15%;
--ring: 217 91% 60%;
--radius: 0.5rem;
--sidebar-background: 222 47% 6%;
--sidebar-foreground: 210 40% 98%;
--sidebar-primary: 217 91% 60%;
--sidebar-primary-foreground: 210 40% 98%;
--sidebar-accent: 217 33% 17%;
--sidebar-accent-foreground: 210 40% 98%;
--sidebar-border: 217 33% 15%;
--sidebar-ring: 217 91% 60%;
}
}
@layer base {
* {
@apply border-border;
}
html {
scroll-behavior: smooth;
}
body {
@apply bg-slate-950 text-slate-100 antialiased;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
@layer utilities {
/* Custom scrollbar */
.scrollbar-thin {
scrollbar-width: thin;
scrollbar-color: rgba(100, 116, 139, 0.5) transparent;
}
.scrollbar-thin::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.scrollbar-thin::-webkit-scrollbar-track {
background: transparent;
}
.scrollbar-thin::-webkit-scrollbar-thumb {
background-color: rgba(100, 116, 139, 0.5);
border-radius: 3px;
}
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
background-color: rgba(100, 116, 139, 0.7);
}
/* Animation utilities */
@keyframes pulse-ring {
0% {
transform: scale(0.8);
opacity: 0.5;
}
100% {
transform: scale(1.2);
opacity: 0;
}
}
.animate-pulse-ring {
animation: pulse-ring 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}
/* Glass effect */
.glass {
background: rgba(15, 23, 42, 0.8);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
}
/* Gradient text */
.gradient-text {
background: linear-gradient(135deg, #3b82f6 0%, #06b6d4 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Status indicator */
.status-dot {
@apply w-2 h-2 rounded-full;
}
.status-dot-running {
@apply bg-emerald-400 animate-pulse;
}
.status-dot-stopped {
@apply bg-slate-400;
}
.status-dot-warning {
@apply bg-amber-400;
}
.status-dot-error {
@apply bg-red-400;
}
}
/* Code block styling */
pre {
@apply bg-slate-950 rounded-lg p-4 overflow-x-auto;
}
code {
@apply font-mono text-sm;
}
/* Table styling */
table {
@apply w-full;
}
th {
@apply text-left font-medium text-slate-400 text-xs uppercase tracking-wider;
}
td {
@apply text-sm;
}
/* Form element focus states */
input:focus,
textarea:focus,
select:focus {
@apply outline-none ring-2 ring-blue-500/30 border-blue-500/50;
}
/* Button hover transitions */
button {
@apply transition-all duration-200;
}
/* Card hover effect */
.card-hover {
@apply transition-all duration-300 hover:shadow-lg hover:shadow-slate-900/50 hover:-translate-y-0.5;
}
/* Terminal styling */
.terminal {
@apply bg-slate-950 font-mono text-sm text-slate-300;
}
.terminal .prompt {
@apply text-emerald-400;
}
.terminal .command {
@apply text-slate-100;
}
.terminal .output {
@apply text-slate-400;
}
/* Chart tooltip styling */
.recharts-tooltip-wrapper {
@apply z-50;
}
/* Dialog overlay */
[data-state="open"] > [data-radix-dialog-overlay] {
@apply bg-slate-950/80 backdrop-blur-sm;
}
/* Dropdown menu styling */
[role="menuitem"] {
@apply cursor-pointer;
}
/* Badge variants */
.badge-critical {
@apply border-red-500/30 text-red-400 bg-red-500/10;
}
.badge-warning {
@apply border-amber-500/30 text-amber-400 bg-amber-500/10;
}
.badge-success {
@apply border-emerald-500/30 text-emerald-400 bg-emerald-500/10;
}
.badge-info {
@apply border-blue-500/30 text-blue-400 bg-blue-500/10;
}
/* Progress bar animation */
@keyframes progress-indeterminate {
0% {
transform: translateX(-100%);
}
100% {
transform: translateX(100%);
}
}
.progress-indeterminate::after {
content: '';
@apply absolute inset-0 bg-current;
animation: progress-indeterminate 1.5s ease-in-out infinite;
}