fdb2 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/.dockerignore +21 -0
  2. package/.editorconfig +11 -0
  3. package/.eslintrc.cjs +14 -0
  4. package/.eslintrc.json +7 -0
  5. package/.prettierrc.js +3 -0
  6. package/.tpl.env +22 -0
  7. package/README.md +260 -0
  8. package/bin/build.sh +28 -0
  9. package/bin/deploy.sh +8 -0
  10. package/bin/dev.sh +10 -0
  11. package/bin/docker/.env +4 -0
  12. package/bin/docker/dev-docker-compose.yml +43 -0
  13. package/bin/docker/dev.Dockerfile +24 -0
  14. package/bin/docker/prod-docker-compose.yml +17 -0
  15. package/bin/docker/prod.Dockerfile +29 -0
  16. package/bin/fdb2.js +142 -0
  17. package/data/connections.demo.json +32 -0
  18. package/env.d.ts +1 -0
  19. package/nw-build.js +120 -0
  20. package/nw-dev.js +65 -0
  21. package/package.json +114 -0
  22. package/public/favicon.ico +0 -0
  23. package/public/index.html +9 -0
  24. package/public/modules/header.tpl +14 -0
  25. package/public/modules/initial_state.tpl +55 -0
  26. package/server/index.ts +677 -0
  27. package/server/model/connection.entity.ts +66 -0
  28. package/server/model/database.entity.ts +246 -0
  29. package/server/service/connection.service.ts +334 -0
  30. package/server/service/database/base.service.ts +363 -0
  31. package/server/service/database/database.service.ts +510 -0
  32. package/server/service/database/index.ts +7 -0
  33. package/server/service/database/mssql.service.ts +723 -0
  34. package/server/service/database/mysql.service.ts +761 -0
  35. package/server/service/database/oracle.service.ts +839 -0
  36. package/server/service/database/postgres.service.ts +744 -0
  37. package/server/service/database/sqlite.service.ts +559 -0
  38. package/server/service/session.service.ts +158 -0
  39. package/server.js +128 -0
  40. package/src/adapter/ajax.ts +135 -0
  41. package/src/assets/base.css +1 -0
  42. package/src/assets/database.css +950 -0
  43. package/src/assets/images/collapse.png +0 -0
  44. package/src/assets/images/no-login.png +0 -0
  45. package/src/assets/images/svg/illustrations/illustration-1.svg +1 -0
  46. package/src/assets/images/svg/illustrations/illustration-2.svg +2 -0
  47. package/src/assets/images/svg/illustrations/illustration-3.svg +50 -0
  48. package/src/assets/images/svg/illustrations/illustration-4.svg +1 -0
  49. package/src/assets/images/svg/illustrations/illustration-5.svg +73 -0
  50. package/src/assets/images/svg/illustrations/illustration-6.svg +89 -0
  51. package/src/assets/images/svg/illustrations/illustration-7.svg +39 -0
  52. package/src/assets/images/svg/illustrations/illustration-8.svg +1 -0
  53. package/src/assets/images/svg/separators/curve-2.svg +3 -0
  54. package/src/assets/images/svg/separators/curve.svg +3 -0
  55. package/src/assets/images/svg/separators/line.svg +3 -0
  56. package/src/assets/images/theme/light/screen-1-1000x800.jpg +0 -0
  57. package/src/assets/images/theme/light/screen-2-1000x800.jpg +0 -0
  58. package/src/assets/login/bg.jpg +0 -0
  59. package/src/assets/login/bg.png +0 -0
  60. package/src/assets/login/left.jpg +0 -0
  61. package/src/assets/logo.svg +73 -0
  62. package/src/assets/logo.webp +0 -0
  63. package/src/assets/main.css +1 -0
  64. package/src/base/config.ts +20 -0
  65. package/src/base/detect.ts +134 -0
  66. package/src/base/entity.ts +92 -0
  67. package/src/base/eventBus.ts +37 -0
  68. package/src/base//345/237/272/347/241/200/345/261/202.md +7 -0
  69. package/src/components/connection-editor/index.vue +590 -0
  70. package/src/components/dataGrid/index.vue +105 -0
  71. package/src/components/dataGrid/pagination.vue +106 -0
  72. package/src/components/loading/index.vue +43 -0
  73. package/src/components/modal/index.ts +181 -0
  74. package/src/components/modal/index.vue +560 -0
  75. package/src/components/toast/index.ts +44 -0
  76. package/src/components/toast/toast.vue +58 -0
  77. package/src/components/user/name.vue +104 -0
  78. package/src/components/user/selector.vue +416 -0
  79. package/src/domain/SysConfig.ts +74 -0
  80. package/src/platform/App.vue +8 -0
  81. package/src/platform/database/components/connection-detail.vue +1154 -0
  82. package/src/platform/database/components/data-editor.vue +478 -0
  83. package/src/platform/database/components/data-import-export.vue +1602 -0
  84. package/src/platform/database/components/database-detail.vue +1173 -0
  85. package/src/platform/database/components/database-monitor.vue +1086 -0
  86. package/src/platform/database/components/db-tools.vue +577 -0
  87. package/src/platform/database/components/query-history.vue +1349 -0
  88. package/src/platform/database/components/sql-executor.vue +738 -0
  89. package/src/platform/database/components/sql-query-editor.vue +1046 -0
  90. package/src/platform/database/components/table-detail.vue +1376 -0
  91. package/src/platform/database/components/table-editor.vue +690 -0
  92. package/src/platform/database/explorer.vue +1840 -0
  93. package/src/platform/database/index.vue +1193 -0
  94. package/src/platform/database/layout.vue +367 -0
  95. package/src/platform/database/router.ts +37 -0
  96. package/src/platform/database/styles/common.scss +602 -0
  97. package/src/platform/database/types/common.ts +445 -0
  98. package/src/platform/database/utils/export.ts +232 -0
  99. package/src/platform/database/utils/helpers.ts +437 -0
  100. package/src/platform/index.ts +33 -0
  101. package/src/platform/router.ts +41 -0
  102. package/src/service/base.ts +128 -0
  103. package/src/service/database.ts +500 -0
  104. package/src/service/login.ts +121 -0
  105. package/src/shims-vue.d.ts +7 -0
  106. package/src/stores/connection.ts +266 -0
  107. package/src/stores/session.ts +87 -0
  108. package/src/typings/database-types.ts +413 -0
  109. package/src/typings/database.ts +364 -0
  110. package/src/typings/global.d.ts +58 -0
  111. package/src/typings/pinia.d.ts +8 -0
  112. package/src/utils/clipboard.ts +30 -0
  113. package/src/utils/database-types.ts +243 -0
  114. package/src/utils/modal.ts +124 -0
  115. package/src/utils/request.ts +55 -0
  116. package/src/utils/sleep.ts +4 -0
  117. package/src/utils/toast.ts +73 -0
  118. package/src/utils/util.ts +171 -0
  119. package/src/utils/xlsx.ts +228 -0
  120. package/tsconfig.json +33 -0
  121. package/tsconfig.server.json +19 -0
  122. package/view/index.html +9 -0
  123. package/view/modules/header.tpl +14 -0
  124. package/view/modules/initial_state.tpl +20 -0
  125. package/vite.config.ts +384 -0
@@ -0,0 +1,367 @@
1
+ <template>
2
+ <div class="database-layout">
3
+ <!-- 主要内容区域 -->
4
+ <main class="main-content-modern">
5
+ <div class="content-wrapper">
6
+ <router-view />
7
+ </div>
8
+ </main>
9
+ </div>
10
+ </template>
11
+
12
+ <script lang="ts" setup>
13
+ // 空的script标签用于保持组件结构
14
+ </script>
15
+
16
+ <style scoped>
17
+ /* 主布局样式 */
18
+ .database-layout {
19
+ height: 100vh;
20
+ display: flex;
21
+ flex-direction: column;
22
+ background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
23
+ }
24
+
25
+ /* 现代导航栏样式 */
26
+ .navbar-modern {
27
+ background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
28
+ border-bottom: 1px solid #e2e8f0;
29
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
30
+ padding: 0.75rem 0;
31
+ position: sticky;
32
+ top: 0;
33
+ z-index: 1030;
34
+ backdrop-filter: blur(10px);
35
+ }
36
+
37
+ /* 品牌区域 */
38
+ .navbar-brand-wrapper {
39
+ margin-right: 2rem;
40
+ }
41
+
42
+ .navbar-brand-modern {
43
+ display: flex;
44
+ align-items: center;
45
+ gap: 1rem;
46
+ text-decoration: none;
47
+ color: #1e293b;
48
+ transition: all 0.3s ease;
49
+ }
50
+
51
+ .navbar-brand-modern:hover {
52
+ color: #667eea;
53
+ transform: translateX(2px);
54
+ }
55
+
56
+ .brand-icon {
57
+ width: 45px;
58
+ height: 45px;
59
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
60
+ border-radius: 12px;
61
+ display: flex;
62
+ align-items: center;
63
+ justify-content: center;
64
+ color: white;
65
+ font-size: 1.5rem;
66
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
67
+ transition: all 0.3s ease;
68
+ }
69
+
70
+ .brand-icon:hover {
71
+ transform: rotate(5deg) scale(1.05);
72
+ box-shadow: 0 6px 16px rgba(102, 126, 234, 0.4);
73
+ }
74
+
75
+ .brand-text {
76
+ display: flex;
77
+ flex-direction: column;
78
+ gap: 2px;
79
+ }
80
+
81
+ .brand-name {
82
+ font-size: 1.25rem;
83
+ font-weight: 700;
84
+ color: #1e293b;
85
+ letter-spacing: -0.025em;
86
+ }
87
+
88
+ .brand-subtitle {
89
+ font-size: 0.75rem;
90
+ color: #64748b;
91
+ font-weight: 500;
92
+ letter-spacing: 0.05em;
93
+ text-transform: uppercase;
94
+ }
95
+
96
+ /* 移动端切换按钮 */
97
+ .navbar-toggler-modern {
98
+ background: none;
99
+ border: none;
100
+ padding: 0.5rem;
101
+ cursor: pointer;
102
+ display: none;
103
+ flex-direction: column;
104
+ gap: 4px;
105
+ }
106
+
107
+ .navbar-toggler-line {
108
+ width: 25px;
109
+ height: 3px;
110
+ background: linear-gradient(90deg, #667eea, #764ba2);
111
+ border-radius: 2px;
112
+ transition: all 0.3s ease;
113
+ }
114
+
115
+ /* 导航折叠区域 */
116
+ .navbar-collapse-modern {
117
+ background: transparent;
118
+ }
119
+
120
+ /* 主导航样式 */
121
+ .navbar-nav-modern {
122
+ display: flex;
123
+ align-items: center;
124
+ gap: 0.5rem;
125
+ }
126
+
127
+ .nav-item-modern {
128
+ position: relative;
129
+ }
130
+
131
+ .nav-link-modern {
132
+ display: flex;
133
+ align-items: center;
134
+ gap: 0.75rem;
135
+ padding: 0.75rem 1.25rem;
136
+ border-radius: 12px;
137
+ color: #64748b;
138
+ text-decoration: none;
139
+ font-weight: 500;
140
+ transition: all 0.3s ease;
141
+ position: relative;
142
+ overflow: hidden;
143
+ }
144
+
145
+ .nav-link-modern:hover {
146
+ background: rgba(102, 126, 234, 0.1);
147
+ color: #667eea;
148
+ transform: translateY(-1px);
149
+ }
150
+
151
+ .nav-link-modern.active {
152
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
153
+ color: white;
154
+ box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3);
155
+ }
156
+
157
+ .nav-icon {
158
+ font-size: 1.25rem;
159
+ display: flex;
160
+ align-items: center;
161
+ justify-content: center;
162
+ min-width: 24px;
163
+ }
164
+
165
+ .nav-text {
166
+ font-size: 0.95rem;
167
+ font-weight: 600;
168
+ letter-spacing: 0.025em;
169
+ }
170
+
171
+ .nav-indicator {
172
+ position: absolute;
173
+ bottom: 0;
174
+ left: 50%;
175
+ transform: translateX(-50%);
176
+ width: 4px;
177
+ height: 4px;
178
+ background: white;
179
+ border-radius: 50%;
180
+ opacity: 0;
181
+ transition: all 0.3s ease;
182
+ }
183
+
184
+ .nav-link-modern.active .nav-indicator {
185
+ opacity: 1;
186
+ }
187
+
188
+ /* 用户菜单样式 */
189
+ .nav-icon-only {
190
+ padding: 0.75rem;
191
+ min-width: auto;
192
+ }
193
+
194
+ .notification-dot {
195
+ position: absolute;
196
+ top: 8px;
197
+ right: 8px;
198
+ width: 8px;
199
+ height: 8px;
200
+ background: #ef4444;
201
+ border-radius: 50%;
202
+ border: 2px solid white;
203
+ animation: pulse 2s ease-in-out infinite;
204
+ }
205
+
206
+ .user-menu-toggle {
207
+ display: flex;
208
+ align-items: center;
209
+ gap: 0.75rem;
210
+ padding: 0.5rem;
211
+ border-radius: 12px;
212
+ transition: all 0.3s ease;
213
+ }
214
+
215
+ .user-menu-toggle:hover {
216
+ background: rgba(102, 126, 234, 0.1);
217
+ }
218
+
219
+ .user-avatar {
220
+ width: 40px;
221
+ height: 40px;
222
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
223
+ border-radius: 50%;
224
+ display: flex;
225
+ align-items: center;
226
+ justify-content: center;
227
+ color: white;
228
+ font-size: 1.25rem;
229
+ box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
230
+ }
231
+
232
+ .user-info {
233
+ display: flex;
234
+ flex-direction: column;
235
+ gap: 2px;
236
+ }
237
+
238
+ .user-name {
239
+ font-size: 0.9rem;
240
+ font-weight: 600;
241
+ color: #1e293b;
242
+ }
243
+
244
+ .user-role {
245
+ font-size: 0.75rem;
246
+ color: #64748b;
247
+ font-weight: 500;
248
+ }
249
+
250
+ .dropdown-arrow {
251
+ color: #94a3b8;
252
+ font-size: 0.75rem;
253
+ transition: all 0.3s ease;
254
+ }
255
+
256
+ .user-menu-toggle:hover .dropdown-arrow {
257
+ color: #667eea;
258
+ transform: translateY(1px);
259
+ }
260
+
261
+ /* 现代下拉菜单样式 */
262
+ .dropdown-menu-modern {
263
+ background: white;
264
+ border: 1px solid #e2e8f0;
265
+ border-radius: 16px;
266
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1), 0 4px 10px rgba(0, 0, 0, 0.05);
267
+ padding: 0.75rem;
268
+ min-width: 280px;
269
+ backdrop-filter: blur(10px);
270
+ margin-top: 0.75rem;
271
+ }
272
+
273
+ .dropdown-header {
274
+ padding: 0.5rem 0.75rem;
275
+ font-size: 0.75rem;
276
+ font-weight: 700;
277
+ color: #94a3b8;
278
+ text-transform: uppercase;
279
+ letter-spacing: 0.05em;
280
+ border-bottom: 1px solid #f1f5f9;
281
+ margin-bottom: 0.5rem;
282
+ }
283
+
284
+ .dropdown-item-modern {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 0.75rem;
288
+ padding: 0.75rem;
289
+ border-radius: 8px;
290
+ color: #374151;
291
+ text-decoration: none;
292
+ transition: all 0.2s ease;
293
+ margin-bottom: 2px;
294
+ }
295
+
296
+ .dropdown-item-modern:hover {
297
+ background: linear-gradient(135deg, #f8fafc 0%, #f1f5f9 100%);
298
+ color: #667eea;
299
+ transform: translateX(4px);
300
+ }
301
+
302
+ .dropdown-item-modern.text-danger:hover {
303
+ background: linear-gradient(135deg, #fef2f2 0%, #fee2e2 100%);
304
+ color: #dc2626;
305
+ }
306
+
307
+ .dropdown-item-content {
308
+ display: flex;
309
+ flex-direction: column;
310
+ gap: 2px;
311
+ }
312
+
313
+ .dropdown-item-title {
314
+ font-size: 0.9rem;
315
+ font-weight: 600;
316
+ color: inherit;
317
+ }
318
+
319
+ .dropdown-item-desc {
320
+ font-size: 0.75rem;
321
+ color: #94a3b8;
322
+ }
323
+
324
+ .dropdown-divider-modern {
325
+ margin: 0.75rem -0.75rem;
326
+ border: none;
327
+ border-top: 1px solid #f1f5f9;
328
+ }
329
+
330
+ /* 主要内容区域 */
331
+ .main-content-modern {
332
+ flex: 1;
333
+ display: flex;
334
+ flex-direction: column;
335
+ background: transparent;
336
+ overflow: hidden;
337
+ }
338
+
339
+ .content-wrapper {
340
+ flex: 1;
341
+ background: rgba(255, 255, 255, 0.3);
342
+ backdrop-filter: blur(8px);
343
+ overflow-y: auto;
344
+ height: 100%;
345
+ }
346
+
347
+
348
+
349
+ /* 动画效果 */
350
+ @keyframes pulse {
351
+ 0%, 100% { opacity: 1; transform: scale(1); }
352
+ 50% { opacity: 0.6; transform: scale(1.2); }
353
+ }
354
+
355
+ /* 响应式设计 */
356
+ @media (max-width: 768px) {
357
+ .content-wrapper {
358
+ padding: 0.5rem;
359
+ }
360
+ }
361
+
362
+ @media (max-width: 480px) {
363
+ .content-wrapper {
364
+ padding: 0.25rem;
365
+ }
366
+ }
367
+ </style>
@@ -0,0 +1,37 @@
1
+
2
+ const routes = [
3
+ {
4
+ path: '/database',
5
+ component: () => import('./layout.vue'),
6
+ redirect: '/database/index',
7
+ meta: {
8
+ title: '数据库管理',
9
+ icon: 'bi-database',
10
+ needAuth: false
11
+ },
12
+ children: [
13
+ {
14
+ path: 'index',
15
+ name: 'database-index',
16
+ component: () => import('./explorer.vue'),
17
+ meta: {
18
+ title: '数据库管理首页',
19
+ icon: 'bi-house',
20
+ needAuth: false
21
+ }
22
+ },
23
+ {
24
+ path: 'explorer',
25
+ name: 'database-explorer',
26
+ component: () => import('./explorer.vue'),
27
+ meta: {
28
+ title: '数据库浏览器',
29
+ icon: 'bi-diagram-3',
30
+ needAuth: false
31
+ }
32
+ },
33
+ ]
34
+ }
35
+ ];
36
+
37
+ export default routes;