vue3-admin-gpt 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 (118) hide show
  1. package/.env.development +14 -0
  2. package/.env.production +14 -0
  3. package/LICENSE +21 -0
  4. package/README.en.md +106 -0
  5. package/README.md +104 -0
  6. package/build-zip.cjs +53 -0
  7. package/cli.js +110 -0
  8. package/jsconfig.json +9 -0
  9. package/package.json +92 -0
  10. package/public/index.html +20 -0
  11. package/public/robots.txt +2 -0
  12. package/rspack.config.js +282 -0
  13. package/rspack.js +162 -0
  14. package/src/App.vue +9 -0
  15. package/src/api/icon.js +9 -0
  16. package/src/api/router.js +9 -0
  17. package/src/api/table.js +25 -0
  18. package/src/api/tree.js +9 -0
  19. package/src/api/user.js +34 -0
  20. package/src/assets/error_images/401.png +0 -0
  21. package/src/assets/error_images/404.png +0 -0
  22. package/src/assets/error_images/cloud.png +0 -0
  23. package/src/assets/login_images/background.jpg +0 -0
  24. package/src/assets/logo.png +0 -0
  25. package/src/assets/qr_logo/lqr_logo.png +0 -0
  26. package/src/assets/vuejs-fill.svg +4 -0
  27. package/src/components/VabPageHeader/index.vue +133 -0
  28. package/src/config/index.js +7 -0
  29. package/src/config/net.config.js +20 -0
  30. package/src/config/permission.js +136 -0
  31. package/src/config/setting.config.js +62 -0
  32. package/src/config/settings.js +6 -0
  33. package/src/config/theme.config.js +14 -0
  34. package/src/layouts/EmptyLayout.vue +3 -0
  35. package/src/layouts/components/VabAppMain/index.vue +109 -0
  36. package/src/layouts/components/VabAvatar/index.vue +255 -0
  37. package/src/layouts/components/VabBreadcrumb/index.vue +61 -0
  38. package/src/layouts/components/VabFullScreen/index.vue +61 -0
  39. package/src/layouts/components/VabLogo/index.vue +94 -0
  40. package/src/layouts/components/VabNav/index.vue +176 -0
  41. package/src/layouts/components/VabSide/components/VabMenuItem.vue +80 -0
  42. package/src/layouts/components/VabSide/components/VabSideItem.vue +100 -0
  43. package/src/layouts/components/VabSide/components/VabSubmenu.vue +56 -0
  44. package/src/layouts/components/VabSide/index.vue +123 -0
  45. package/src/layouts/components/VabTabs/index.vue +500 -0
  46. package/src/layouts/components/VabTheme/index.vue +603 -0
  47. package/src/layouts/components/VabTop/index.vue +286 -0
  48. package/src/layouts/export.js +29 -0
  49. package/src/layouts/index.vue +339 -0
  50. package/src/main.js +40 -0
  51. package/src/plugins/echarts.js +4 -0
  52. package/src/plugins/index.js +44 -0
  53. package/src/plugins/support.js +16 -0
  54. package/src/router/index.js +400 -0
  55. package/src/store/index.js +26 -0
  56. package/src/store/modules/errorLog.js +27 -0
  57. package/src/store/modules/routes.js +60 -0
  58. package/src/store/modules/settings.js +73 -0
  59. package/src/store/modules/table.js +22 -0
  60. package/src/store/modules/tabsBar.js +109 -0
  61. package/src/store/modules/user.js +131 -0
  62. package/src/styles/element-variables.scss +13 -0
  63. package/src/styles/loading.scss +345 -0
  64. package/src/styles/nav-icons.scss +52 -0
  65. package/src/styles/normalize.scss +353 -0
  66. package/src/styles/spinner/dots.css +68 -0
  67. package/src/styles/spinner/gauge.css +104 -0
  68. package/src/styles/spinner/inner-circles.css +51 -0
  69. package/src/styles/spinner/plus.css +341 -0
  70. package/src/styles/themes/default.scss +1 -0
  71. package/src/styles/transition.scss +18 -0
  72. package/src/styles/vab.scss +476 -0
  73. package/src/styles/variables.scss +69 -0
  74. package/src/utils/accessToken.js +56 -0
  75. package/src/utils/eventBus.js +8 -0
  76. package/src/utils/handleRoutes.js +100 -0
  77. package/src/utils/index.js +231 -0
  78. package/src/utils/message.js +67 -0
  79. package/src/utils/pageTitle.js +11 -0
  80. package/src/utils/password.js +43 -0
  81. package/src/utils/permission.js +19 -0
  82. package/src/utils/request.js +187 -0
  83. package/src/utils/static.js +81 -0
  84. package/src/utils/vab.js +218 -0
  85. package/src/utils/validate.js +48 -0
  86. package/src/views/401.vue +302 -0
  87. package/src/views/404.vue +302 -0
  88. package/src/views/demo/index.vue +591 -0
  89. package/src/views/index/index.vue +1489 -0
  90. package/src/views/login/index.vue +456 -0
  91. package/src/views/register/index.vue +524 -0
  92. package/src/views/vab/calendar.vue +488 -0
  93. package/src/views/vab/campaign.vue +1006 -0
  94. package/src/views/vab/chart.vue +189 -0
  95. package/src/views/vab/customer.vue +666 -0
  96. package/src/views/vab/editor.vue +84 -0
  97. package/src/views/vab/form.vue +151 -0
  98. package/src/views/vab/help.vue +390 -0
  99. package/src/views/vab/icon.vue +113 -0
  100. package/src/views/vab/knowledge.vue +820 -0
  101. package/src/views/vab/nested/menu1/menu2/menu3.vue +29 -0
  102. package/src/views/vab/nested/menu1/menu2.vue +33 -0
  103. package/src/views/vab/nested/menu1.vue +33 -0
  104. package/src/views/vab/nested.vue +97 -0
  105. package/src/views/vab/notification.vue +416 -0
  106. package/src/views/vab/order.vue +507 -0
  107. package/src/views/vab/permissions.vue +214 -0
  108. package/src/views/vab/product.vue +724 -0
  109. package/src/views/vab/project.vue +559 -0
  110. package/src/views/vab/settings.vue +319 -0
  111. package/src/views/vab/statistics.vue +431 -0
  112. package/src/views/vab/table.vue +110 -0
  113. package/src/views/vab/task.vue +613 -0
  114. package/src/views/vab/team.vue +662 -0
  115. package/src/views/vab/tree.vue +44 -0
  116. package/src/views/vab/upload.vue +180 -0
  117. package/src/views/vab/vue3Demo/index.vue +103 -0
  118. package/src/views/vab/workflow.vue +863 -0
@@ -0,0 +1,431 @@
1
+ <template>
2
+ <div class="statistics-container">
3
+ <el-card shadow="never">
4
+ <template #header>
5
+ <div class="card-header">
6
+ <span>数据统计</span>
7
+ <div class="header-actions">
8
+ <el-date-picker
9
+ v-model="dateRange"
10
+ type="daterange"
11
+ range-separator="至"
12
+ start-placeholder="开始日期"
13
+ end-placeholder="结束日期"
14
+ format="YYYY年MM月DD日"
15
+ value-format="YYYY-MM-DD"
16
+ @change="handleDateRangeChange"
17
+ style="width: 300px; margin-right: 10px"
18
+ />
19
+ <el-button type="primary" @click="refreshData">刷新数据</el-button>
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <!-- 统计概览 -->
25
+ <el-row :gutter="20" style="margin-bottom: 20px">
26
+ <el-col :span="6">
27
+ <el-card class="stat-card" shadow="hover">
28
+ <div class="stat-content">
29
+ <div class="stat-icon" style="background-color: #409EFF">
30
+ <el-icon><User /></el-icon>
31
+ </div>
32
+ <div class="stat-info">
33
+ <div class="stat-value">{{ statistics.userCount }}</div>
34
+ <div class="stat-label">用户总数</div>
35
+ </div>
36
+ </div>
37
+ </el-card>
38
+ </el-col>
39
+
40
+ <el-col :span="6">
41
+ <el-card class="stat-card" shadow="hover">
42
+ <div class="stat-content">
43
+ <div class="stat-icon" style="background-color: #67C23A">
44
+ <el-icon><Document /></el-icon>
45
+ </div>
46
+ <div class="stat-info">
47
+ <div class="stat-value">{{ statistics.taskCount }}</div>
48
+ <div class="stat-label">任务总数</div>
49
+ </div>
50
+ </div>
51
+ </el-card>
52
+ </el-col>
53
+
54
+ <el-col :span="6">
55
+ <el-card class="stat-card" shadow="hover">
56
+ <div class="stat-content">
57
+ <div class="stat-icon" style="background-color: #E6A23C">
58
+ <el-icon><TrendCharts /></el-icon>
59
+ </div>
60
+ <div class="stat-info">
61
+ <div class="stat-value">{{ statistics.completedTaskCount }}</div>
62
+ <div class="stat-label">已完成任务</div>
63
+ </div>
64
+ </div>
65
+ </el-card>
66
+ </el-col>
67
+
68
+ <el-col :span="6">
69
+ <el-card class="stat-card" shadow="hover">
70
+ <div class="stat-content">
71
+ <div class="stat-icon" style="background-color: #F56C6C">
72
+ <el-icon><Bell /></el-icon>
73
+ </div>
74
+ <div class="stat-info">
75
+ <div class="stat-value">{{ statistics.notificationCount }}</div>
76
+ <div class="stat-label">通知总数</div>
77
+ </div>
78
+ </div>
79
+ </el-card>
80
+ </el-col>
81
+ </el-row>
82
+
83
+ <!-- 图表区域 -->
84
+ <el-row :gutter="20">
85
+ <el-col :span="16">
86
+ <el-card shadow="never" style="margin-bottom: 20px">
87
+ <template #header>
88
+ <span>用户增长趋势</span>
89
+ </template>
90
+ <div ref="userGrowthChart" style="height: 300px"></div>
91
+ </el-card>
92
+
93
+ <el-card shadow="never">
94
+ <template #header>
95
+ <span>任务完成情况</span>
96
+ </template>
97
+ <div ref="taskCompletionChart" style="height: 300px"></div>
98
+ </el-card>
99
+ </el-col>
100
+
101
+ <el-col :span="8">
102
+ <el-card shadow="never" style="margin-bottom: 20px">
103
+ <template #header>
104
+ <span>任务优先级分布</span>
105
+ </template>
106
+ <div ref="taskPriorityChart" style="height: 200px"></div>
107
+ </el-card>
108
+
109
+ <el-card shadow="never">
110
+ <template #header>
111
+ <span>用户活跃度</span>
112
+ </template>
113
+ <div ref="userActivityChart" style="height: 200px"></div>
114
+ </el-card>
115
+ </el-col>
116
+ </el-row>
117
+
118
+ <!-- 数据表格 -->
119
+ <el-card shadow="never" style="margin-top: 20px">
120
+ <template #header>
121
+ <span>详细数据</span>
122
+ </template>
123
+ <el-table :data="detailData" style="width: 100%">
124
+ <el-table-column prop="name" label="指标名称" />
125
+ <el-table-column prop="value" label="数值" />
126
+ <el-table-column prop="change" label="较昨日变化">
127
+ <template #default="{ row }">
128
+ <span :class="row.change > 0 ? 'increase' : 'decrease'">
129
+ <el-icon v-if="row.change > 0"><Top /></el-icon>
130
+ <el-icon v-else-if="row.change < 0"><Bottom /></el-icon>
131
+ {{ Math.abs(row.change) }}%
132
+ </span>
133
+ </template>
134
+ </el-table-column>
135
+ </el-table>
136
+ </el-card>
137
+ </el-card>
138
+ </div>
139
+ </template>
140
+
141
+ <script>
142
+ import * as echarts from "echarts";
143
+ import {
144
+ User,
145
+ Document,
146
+ TrendCharts,
147
+ Bell,
148
+ Top,
149
+ Bottom
150
+ } from "@element-plus/icons-vue";
151
+
152
+ export default {
153
+ name: "Statistics",
154
+ components: {
155
+ User,
156
+ Document,
157
+ TrendCharts,
158
+ Bell,
159
+ Top,
160
+ Bottom
161
+ },
162
+ data() {
163
+ return {
164
+ dateRange: [
165
+ this.formatDate(new Date(new Date().getTime() - 30 * 24 * 60 * 60 * 1000)), // 30天前
166
+ this.formatDate(new Date())
167
+ ],
168
+ statistics: {
169
+ userCount: 1286,
170
+ taskCount: 342,
171
+ completedTaskCount: 218,
172
+ notificationCount: 56
173
+ },
174
+ detailData: [
175
+ { name: "新增用户数", value: "24", change: 5.2 },
176
+ { name: "活跃用户数", value: "863", change: -2.1 },
177
+ { name: "新增任务数", value: "12", change: 8.7 },
178
+ { name: "完成任务数", value: "8", change: 3.4 },
179
+ { name: "系统访问量", value: "1,245", change: 12.3 },
180
+ { name: "平均响应时间", value: "128ms", change: -5.6 }
181
+ ],
182
+ userGrowthChart: null,
183
+ taskCompletionChart: null,
184
+ taskPriorityChart: null,
185
+ userActivityChart: null
186
+ };
187
+ },
188
+ mounted() {
189
+ this.initCharts();
190
+ },
191
+ beforeUnmount() {
192
+ // 销毁图表实例
193
+ if (this.userGrowthChart) this.userGrowthChart.dispose();
194
+ if (this.taskCompletionChart) this.taskCompletionChart.dispose();
195
+ if (this.taskPriorityChart) this.taskPriorityChart.dispose();
196
+ if (this.userActivityChart) this.userActivityChart.dispose();
197
+ },
198
+ methods: {
199
+ formatDate(date) {
200
+ const d = new Date(date);
201
+ const year = d.getFullYear();
202
+ const month = String(d.getMonth() + 1).padStart(2, '0');
203
+ const day = String(d.getDate()).padStart(2, '0');
204
+ return `${year}-${month}-${day}`;
205
+ },
206
+ handleDateRangeChange(value) {
207
+ this.dateRange = value;
208
+ this.refreshData();
209
+ },
210
+ refreshData() {
211
+ this.$message.success("数据已刷新");
212
+ // 模拟数据刷新
213
+ },
214
+ initCharts() {
215
+ // 用户增长趋势图
216
+ this.userGrowthChart = echarts.init(this.$refs.userGrowthChart);
217
+ this.userGrowthChart.setOption(this.getUserGrowthChartOption());
218
+
219
+ // 任务完成情况图
220
+ this.taskCompletionChart = echarts.init(this.$refs.taskCompletionChart);
221
+ this.taskCompletionChart.setOption(this.getTaskCompletionChartOption());
222
+
223
+ // 任务优先级分布图
224
+ this.taskPriorityChart = echarts.init(this.$refs.taskPriorityChart);
225
+ this.taskPriorityChart.setOption(this.getTaskPriorityChartOption());
226
+
227
+ // 用户活跃度图
228
+ this.userActivityChart = echarts.init(this.$refs.userActivityChart);
229
+ this.userActivityChart.setOption(this.getUserActivityChartOption());
230
+ },
231
+ getUserGrowthChartOption() {
232
+ return {
233
+ tooltip: {
234
+ trigger: "axis"
235
+ },
236
+ xAxis: {
237
+ type: "category",
238
+ data: ["1月", "2月", "3月", "4月", "5月", "6月"]
239
+ },
240
+ yAxis: {
241
+ type: "value"
242
+ },
243
+ series: [
244
+ {
245
+ name: "新增用户",
246
+ type: "line",
247
+ data: [120, 132, 101, 134, 90, 230],
248
+ smooth: true
249
+ },
250
+ {
251
+ name: "活跃用户",
252
+ type: "line",
253
+ data: [220, 182, 191, 234, 290, 330],
254
+ smooth: true
255
+ }
256
+ ]
257
+ };
258
+ },
259
+ getTaskCompletionChartOption() {
260
+ return {
261
+ tooltip: {
262
+ trigger: "axis"
263
+ },
264
+ legend: {
265
+ data: ["已创建", "已完成"]
266
+ },
267
+ xAxis: {
268
+ type: "category",
269
+ data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"]
270
+ },
271
+ yAxis: {
272
+ type: "value"
273
+ },
274
+ series: [
275
+ {
276
+ name: "已创建",
277
+ type: "bar",
278
+ data: [120, 200, 150, 80, 70, 110, 130]
279
+ },
280
+ {
281
+ name: "已完成",
282
+ type: "bar",
283
+ data: [80, 150, 100, 60, 50, 90, 100]
284
+ }
285
+ ]
286
+ };
287
+ },
288
+ getTaskPriorityChartOption() {
289
+ return {
290
+ tooltip: {
291
+ trigger: "item"
292
+ },
293
+ legend: {
294
+ bottom: "0%"
295
+ },
296
+ series: [
297
+ {
298
+ name: "任务优先级",
299
+ type: "pie",
300
+ radius: ["40%", "70%"],
301
+ avoidLabelOverlap: false,
302
+ itemStyle: {
303
+ borderRadius: 10,
304
+ borderColor: "#fff",
305
+ borderWidth: 2
306
+ },
307
+ label: {
308
+ show: false,
309
+ position: "center"
310
+ },
311
+ emphasis: {
312
+ label: {
313
+ show: true,
314
+ fontSize: "14",
315
+ fontWeight: "bold"
316
+ }
317
+ },
318
+ labelLine: {
319
+ show: false
320
+ },
321
+ data: [
322
+ { value: 32, name: "高优先级" },
323
+ { value: 48, name: "中优先级" },
324
+ { value: 20, name: "低优先级" }
325
+ ]
326
+ }
327
+ ]
328
+ };
329
+ },
330
+ getUserActivityChartOption() {
331
+ return {
332
+ tooltip: {
333
+ trigger: "item"
334
+ },
335
+ legend: {
336
+ bottom: "0%"
337
+ },
338
+ series: [
339
+ {
340
+ name: "用户活跃度",
341
+ type: "pie",
342
+ radius: ["40%", "70%"],
343
+ avoidLabelOverlap: false,
344
+ itemStyle: {
345
+ borderRadius: 10,
346
+ borderColor: "#fff",
347
+ borderWidth: 2
348
+ },
349
+ label: {
350
+ show: false,
351
+ position: "center"
352
+ },
353
+ emphasis: {
354
+ label: {
355
+ show: true,
356
+ fontSize: "14",
357
+ fontWeight: "bold"
358
+ }
359
+ },
360
+ labelLine: {
361
+ show: false
362
+ },
363
+ data: [
364
+ { value: 65, name: "活跃用户" },
365
+ { value: 35, name: "非活跃用户" }
366
+ ]
367
+ }
368
+ ]
369
+ };
370
+ }
371
+ }
372
+ };
373
+ </script>
374
+
375
+ <style lang="scss" scoped>
376
+ .statistics-container {
377
+ padding: 20px;
378
+
379
+ .card-header {
380
+ display: flex;
381
+ justify-content: space-between;
382
+ align-items: center;
383
+ font-weight: bold;
384
+ }
385
+
386
+ .stat-card {
387
+ .stat-content {
388
+ display: flex;
389
+ align-items: center;
390
+
391
+ .stat-icon {
392
+ width: 50px;
393
+ height: 50px;
394
+ border-radius: 50%;
395
+ display: flex;
396
+ align-items: center;
397
+ justify-content: center;
398
+ margin-right: 15px;
399
+
400
+ .el-icon {
401
+ font-size: 24px;
402
+ color: white;
403
+ }
404
+ }
405
+
406
+ .stat-info {
407
+ .stat-value {
408
+ font-size: 24px;
409
+ font-weight: bold;
410
+ color: #333;
411
+ }
412
+
413
+ .stat-label {
414
+ font-size: 14px;
415
+ color: #999;
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ .increase {
422
+ color: #67C23A;
423
+ font-weight: bold;
424
+ }
425
+
426
+ .decrease {
427
+ color: #F56C6C;
428
+ font-weight: bold;
429
+ }
430
+ }
431
+ </style>
@@ -0,0 +1,110 @@
1
+ <template>
2
+ <div class="table-container">
3
+ <el-card shadow="never">
4
+ <el-table v-loading="listLoading" :data="list" style="width: 100%">
5
+ <el-table-column label="ID" prop="id" />
6
+ <el-table-column label="标题" prop="title" show-overflow-tooltip />
7
+ <el-table-column label="作者" prop="author" />
8
+ <el-table-column label="状态" width="100">
9
+ <template #default="{ row }">
10
+ <el-tag :type="row.status | statusFilter">
11
+ {{ row.status }}
12
+ </el-tag>
13
+ </template>
14
+ </el-table-column>
15
+ <el-table-column label="页面浏览量" prop="pageViews" />
16
+ <el-table-column
17
+ label="日期"
18
+ prop="datetime"
19
+ show-overflow-tooltip
20
+ width="160"
21
+ />
22
+ <el-table-column fixed="right" label="操作" width="180">
23
+ <template #default="{ row }">
24
+ <el-button type="text" @click="handleEdit(row)">编辑</el-button>
25
+ <el-button type="text" @click="handleDelete(row)">删除</el-button>
26
+ </template>
27
+ </el-table-column>
28
+ </el-table>
29
+ <div class="pagination-container">
30
+ <el-pagination
31
+ v-model:currentPage="listQuery.pageNo"
32
+ background
33
+ layout="total, sizes, prev, pager, next, jumper"
34
+ :page-size="listQuery.pageSize"
35
+ :page-sizes="[10, 20, 30, 50]"
36
+ :total="totalCount"
37
+ @size-change="handleSizeChange"
38
+ @current-change="handleCurrentChange"
39
+ />
40
+ </div>
41
+ </el-card>
42
+ </div>
43
+ </template>
44
+
45
+ <script>
46
+ import { getList } from "@/api/table";
47
+
48
+ export default {
49
+ name: "Table",
50
+ filters: {
51
+ statusFilter(status) {
52
+ const statusMap = {
53
+ published: "success",
54
+ draft: "info",
55
+ deleted: "danger",
56
+ };
57
+ return statusMap[status];
58
+ },
59
+ },
60
+ data() {
61
+ return {
62
+ list: null,
63
+ totalCount: 0,
64
+ listLoading: true,
65
+ listQuery: {
66
+ pageNo: 1,
67
+ pageSize: 20,
68
+ title: undefined,
69
+ },
70
+ };
71
+ },
72
+ created() {
73
+ this.getList();
74
+ },
75
+ methods: {
76
+ async getList() {
77
+ this.listLoading = true;
78
+ const { data, totalCount } = await getList(this.listQuery);
79
+ this.list = data;
80
+ this.totalCount = totalCount;
81
+ this.listLoading = false;
82
+ },
83
+ handleEdit(row) {
84
+ this.$message.info("编辑操作:" + row.title);
85
+ },
86
+ handleDelete(row) {
87
+ this.$message.info("删除操作:" + row.title);
88
+ },
89
+ handleSizeChange(val) {
90
+ this.listQuery.pageSize = val;
91
+ this.getList();
92
+ },
93
+ handleCurrentChange(val) {
94
+ this.listQuery.pageNo = val;
95
+ this.getList();
96
+ },
97
+ },
98
+ };
99
+ </script>
100
+
101
+ <style lang="scss" scoped>
102
+ .table-container {
103
+ padding: 20px;
104
+
105
+ .pagination-container {
106
+ margin-top: 20px;
107
+ text-align: center;
108
+ }
109
+ }
110
+ </style>