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,488 @@
1
+ <template>
2
+ <div class="calendar-container">
3
+ <el-card shadow="never">
4
+ <template #header>
5
+ <div class="card-header">
6
+ <span>日历</span>
7
+ <div class="header-actions">
8
+ <el-button @click="prevMonth">上个月</el-button>
9
+ <el-button @click="nextMonth">下个月</el-button>
10
+ <el-button type="primary" @click="goToToday">今天</el-button>
11
+ <el-date-picker
12
+ v-model="currentDate"
13
+ type="month"
14
+ placeholder="选择月份"
15
+ format="YYYY年MM月"
16
+ value-format="YYYY-MM"
17
+ @change="handleMonthChange"
18
+ style="margin-left: 10px; width: 150px"
19
+ />
20
+ </div>
21
+ </div>
22
+ </template>
23
+
24
+ <div class="calendar-wrapper">
25
+ <div class="weekdays">
26
+ <div class="weekday" v-for="day in weekdays" :key="day">{{ day }}</div>
27
+ </div>
28
+
29
+ <div class="calendar-grid">
30
+ <!-- 空白日期格子(上个月) -->
31
+ <div
32
+ class="calendar-day empty"
33
+ v-for="n in firstDayOfMonth"
34
+ :key="`empty-${n}`"
35
+ ></div>
36
+
37
+ <!-- 当前月的日期 -->
38
+ <div
39
+ class="calendar-day"
40
+ v-for="day in daysInMonth"
41
+ :key="`day-${day}`"
42
+ :class="{
43
+ today: isToday(day),
44
+ selected: isSelected(day),
45
+ hasEvents: hasEvents(day)
46
+ }"
47
+ @click="selectDay(day)"
48
+ >
49
+ <div class="day-number">{{ day }}</div>
50
+ <div class="events-indicator">
51
+ <div
52
+ class="event-dot"
53
+ v-for="(event, index) in getEventsForDay(day)"
54
+ :key="index"
55
+ :style="{ backgroundColor: event.color }"
56
+ :title="event.title"
57
+ ></div>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </div>
62
+
63
+ <!-- 事件列表 -->
64
+ <div class="events-panel" v-if="selectedDateEvents.length > 0">
65
+ <h3>{{ selectedDateString }} 的事件</h3>
66
+ <el-table :data="selectedDateEvents" style="width: 100%">
67
+ <el-table-column prop="title" label="事件标题" />
68
+ <el-table-column prop="time" label="时间" width="120" />
69
+ <el-table-column prop="description" label="描述" />
70
+ <el-table-column label="操作" width="120">
71
+ <template #default="{ row }">
72
+ <el-button type="text" @click="editEvent(row)">编辑</el-button>
73
+ <el-button type="text" @click="deleteEvent(row)">删除</el-button>
74
+ </template>
75
+ </el-table-column>
76
+ </el-table>
77
+
78
+ <div style="margin-top: 20px; text-align: center">
79
+ <el-button type="primary" @click="showAddEventDialog">添加事件</el-button>
80
+ </div>
81
+ </div>
82
+
83
+ <div class="events-panel no-events" v-else>
84
+ <p>请选择一个日期来查看或添加事件</p>
85
+ <el-button type="primary" @click="showAddEventDialog" :disabled="!selectedDate">
86
+ 添加事件
87
+ </el-button>
88
+ </div>
89
+ </el-card>
90
+
91
+ <!-- 添加/编辑事件对话框 -->
92
+ <el-dialog
93
+ v-model="eventDialogVisible"
94
+ :title="editingEvent ? '编辑事件' : '添加事件'"
95
+ width="500px"
96
+ >
97
+ <el-form
98
+ ref="eventFormRef"
99
+ :model="eventForm"
100
+ :rules="eventRules"
101
+ label-width="80px"
102
+ >
103
+ <el-form-item label="标题" prop="title">
104
+ <el-input v-model="eventForm.title" />
105
+ </el-form-item>
106
+
107
+ <el-form-item label="日期" prop="date">
108
+ <el-date-picker
109
+ v-model="eventForm.date"
110
+ type="date"
111
+ placeholder="选择日期"
112
+ format="YYYY年MM月DD日"
113
+ value-format="YYYY-MM-DD"
114
+ style="width: 100%"
115
+ />
116
+ </el-form-item>
117
+
118
+ <el-form-item label="时间" prop="time">
119
+ <el-time-picker
120
+ v-model="eventForm.time"
121
+ placeholder="选择时间"
122
+ format="HH:mm"
123
+ value-format="HH:mm"
124
+ style="width: 100%"
125
+ />
126
+ </el-form-item>
127
+
128
+ <el-form-item label="描述" prop="description">
129
+ <el-input
130
+ v-model="eventForm.description"
131
+ type="textarea"
132
+ :rows="3"
133
+ />
134
+ </el-form-item>
135
+
136
+ <el-form-item label="颜色">
137
+ <el-color-picker v-model="eventForm.color" />
138
+ </el-form-item>
139
+ </el-form>
140
+
141
+ <template #footer>
142
+ <span class="dialog-footer">
143
+ <el-button @click="eventDialogVisible = false">取消</el-button>
144
+ <el-button
145
+ type="primary"
146
+ @click="saveEvent"
147
+ >
148
+ 保存
149
+ </el-button>
150
+ </span>
151
+ </template>
152
+ </el-dialog>
153
+ </div>
154
+ </template>
155
+
156
+ <script>
157
+ export default {
158
+ name: "Calendar",
159
+ data() {
160
+ return {
161
+ currentDate: this.formatDate(new Date(), 'YYYY-MM'), // 当前选中的月份
162
+ selectedDate: null, // 当前选中的日期
163
+ weekdays: ['日', '一', '二', '三', '四', '五', '六'],
164
+ events: [
165
+ {
166
+ id: 1,
167
+ title: '项目会议',
168
+ date: this.formatDate(new Date(), 'YYYY-MM-DD'),
169
+ time: '14:00',
170
+ description: '讨论项目进度和下一步计划',
171
+ color: '#409EFF'
172
+ },
173
+ {
174
+ id: 2,
175
+ title: '团队聚餐',
176
+ date: this.formatDate(this.addDays(new Date(), 2), 'YYYY-MM-DD'),
177
+ time: '18:30',
178
+ description: '季度团队聚餐活动',
179
+ color: '#67C23A'
180
+ },
181
+ {
182
+ id: 3,
183
+ title: '产品发布',
184
+ date: this.formatDate(this.addDays(new Date(), 5), 'YYYY-MM-DD'),
185
+ time: '10:00',
186
+ description: '新产品正式发布',
187
+ color: '#E6A23C'
188
+ }
189
+ ],
190
+ eventDialogVisible: false,
191
+ editingEvent: null,
192
+ eventForm: {
193
+ title: '',
194
+ date: '',
195
+ time: '',
196
+ description: '',
197
+ color: '#409EFF'
198
+ },
199
+ eventRules: {
200
+ title: [
201
+ { required: true, message: '请输入事件标题', trigger: 'blur' }
202
+ ],
203
+ date: [
204
+ { required: true, message: '请选择日期', trigger: 'change' }
205
+ ]
206
+ }
207
+ };
208
+ },
209
+ computed: {
210
+ // 当前月份的第一天是星期几 (0-6, 0表示星期日)
211
+ firstDayOfMonth() {
212
+ const date = new Date(`${this.currentDate}-01`);
213
+ return date.getDay();
214
+ },
215
+ // 当前月份的天数
216
+ daysInMonth() {
217
+ const date = new Date(this.currentDate);
218
+ return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
219
+ },
220
+ // 选中日期的事件
221
+ selectedDateEvents() {
222
+ if (!this.selectedDate) return [];
223
+ return this.events.filter(event => event.date === this.selectedDate);
224
+ },
225
+ // 选中日期的显示字符串
226
+ selectedDateString() {
227
+ if (!this.selectedDate) return '';
228
+ const date = new Date(this.selectedDate);
229
+ return `${date.getFullYear()}年${date.getMonth() + 1}月${date.getDate()}日`;
230
+ }
231
+ },
232
+ methods: {
233
+ // 格式化日期
234
+ formatDate(date, format) {
235
+ const year = date.getFullYear();
236
+ const month = String(date.getMonth() + 1).padStart(2, '0');
237
+ const day = String(date.getDate()).padStart(2, '0');
238
+
239
+ return format
240
+ .replace('YYYY', year)
241
+ .replace('MM', month)
242
+ .replace('DD', day);
243
+ },
244
+ // 添加天数
245
+ addDays(date, days) {
246
+ const result = new Date(date);
247
+ result.setDate(result.getDate() + days);
248
+ return result;
249
+ },
250
+ // 上个月
251
+ prevMonth() {
252
+ const date = new Date(this.currentDate);
253
+ date.setMonth(date.getMonth() - 1);
254
+ this.currentDate = this.formatDate(date, 'YYYY-MM');
255
+ },
256
+ // 下个月
257
+ nextMonth() {
258
+ const date = new Date(this.currentDate);
259
+ date.setMonth(date.getMonth() + 1);
260
+ this.currentDate = this.formatDate(date, 'YYYY-MM');
261
+ },
262
+ // 回到今天
263
+ goToToday() {
264
+ this.currentDate = this.formatDate(new Date(), 'YYYY-MM');
265
+ this.selectedDate = this.formatDate(new Date(), 'YYYY-MM-DD');
266
+ },
267
+ // 月份改变
268
+ handleMonthChange(value) {
269
+ this.currentDate = value;
270
+ },
271
+ // 判断是否是今天
272
+ isToday(day) {
273
+ const today = new Date();
274
+ const currentMonth = new Date(this.currentDate);
275
+ return (
276
+ today.getFullYear() === currentMonth.getFullYear() &&
277
+ today.getMonth() === currentMonth.getMonth() &&
278
+ today.getDate() === day
279
+ );
280
+ },
281
+ // 判断是否是选中的日期
282
+ isSelected(day) {
283
+ if (!this.selectedDate) return false;
284
+ const selected = new Date(this.selectedDate);
285
+ const currentMonth = new Date(this.currentDate);
286
+ return (
287
+ selected.getFullYear() === currentMonth.getFullYear() &&
288
+ selected.getMonth() === currentMonth.getMonth() &&
289
+ selected.getDate() === day
290
+ );
291
+ },
292
+ // 判断是否有事件
293
+ hasEvents(day) {
294
+ const dateStr = `${this.currentDate}-${String(day).padStart(2, '0')}`;
295
+ return this.events.some(event => event.date === dateStr);
296
+ },
297
+ // 获取某天的事件
298
+ getEventsForDay(day) {
299
+ const dateStr = `${this.currentDate}-${String(day).padStart(2, '0')}`;
300
+ return this.events.filter(event => event.date === dateStr);
301
+ },
302
+ // 选择日期
303
+ selectDay(day) {
304
+ this.selectedDate = `${this.currentDate}-${String(day).padStart(2, '0')}`;
305
+ },
306
+ // 显示添加事件对话框
307
+ showAddEventDialog() {
308
+ this.editingEvent = null;
309
+ this.eventForm = {
310
+ title: '',
311
+ date: this.selectedDate || this.formatDate(new Date(), 'YYYY-MM-DD'),
312
+ time: '',
313
+ description: '',
314
+ color: '#409EFF'
315
+ };
316
+ this.eventDialogVisible = true;
317
+ this.$nextTick(() => {
318
+ this.$refs.eventFormRef.resetFields();
319
+ });
320
+ },
321
+ // 编辑事件
322
+ editEvent(event) {
323
+ this.editingEvent = event;
324
+ this.eventForm = { ...event };
325
+ this.eventDialogVisible = true;
326
+ },
327
+ // 删除事件
328
+ deleteEvent(event) {
329
+ this.$confirm(`确定要删除事件"${event.title}"吗?`, '提示', {
330
+ confirmButtonText: '确定',
331
+ cancelButtonText: '取消',
332
+ type: 'warning'
333
+ }).then(() => {
334
+ const index = this.events.findIndex(e => e.id === event.id);
335
+ if (index !== -1) {
336
+ this.events.splice(index, 1);
337
+ this.$message.success('事件删除成功');
338
+ }
339
+ }).catch(() => {
340
+ this.$message.info('已取消删除');
341
+ });
342
+ },
343
+ // 保存事件
344
+ saveEvent() {
345
+ this.$refs.eventFormRef.validate((valid) => {
346
+ if (valid) {
347
+ if (this.editingEvent) {
348
+ // 编辑事件
349
+ const index = this.events.findIndex(e => e.id === this.editingEvent.id);
350
+ if (index !== -1) {
351
+ this.events[index] = { ...this.editingEvent, ...this.eventForm };
352
+ this.$message.success('事件更新成功');
353
+ }
354
+ } else {
355
+ // 添加事件
356
+ const newEvent = {
357
+ id: Date.now(), // 简单的ID生成方式
358
+ ...this.eventForm
359
+ };
360
+ this.events.push(newEvent);
361
+ this.$message.success('事件添加成功');
362
+ }
363
+ this.eventDialogVisible = false;
364
+ }
365
+ });
366
+ }
367
+ }
368
+ };
369
+ </script>
370
+
371
+ <style lang="scss" scoped>
372
+ .calendar-container {
373
+ padding: 20px;
374
+
375
+ .card-header {
376
+ display: flex;
377
+ justify-content: space-between;
378
+ align-items: center;
379
+ font-weight: bold;
380
+
381
+ .header-actions {
382
+ display: flex;
383
+ align-items: center;
384
+ }
385
+ }
386
+
387
+ .calendar-wrapper {
388
+ margin: 20px 0;
389
+
390
+ .weekdays {
391
+ display: flex;
392
+ border: 1px solid #EBEEF5;
393
+ border-bottom: 0;
394
+
395
+ .weekday {
396
+ flex: 1;
397
+ text-align: center;
398
+ padding: 10px 0;
399
+ background-color: #F2F6FC;
400
+ font-weight: bold;
401
+ }
402
+ }
403
+
404
+ .calendar-grid {
405
+ display: flex;
406
+ flex-wrap: wrap;
407
+ border: 1px solid #EBEEF5;
408
+ border-top: 0;
409
+
410
+ .calendar-day {
411
+ flex: 0 0 calc(100% / 7);
412
+ min-height: 100px;
413
+ border-right: 1px solid #EBEEF5;
414
+ border-bottom: 1px solid #EBEEF5;
415
+ padding: 5px;
416
+ cursor: pointer;
417
+ transition: background-color 0.2s;
418
+ position: relative;
419
+
420
+ &:nth-child(7n) {
421
+ border-right: 0;
422
+ }
423
+
424
+ &:hover {
425
+ background-color: #F2F6FC;
426
+ }
427
+
428
+ &.today {
429
+ background-color: #E6F2FF;
430
+
431
+ .day-number {
432
+ color: #409EFF;
433
+ font-weight: bold;
434
+ }
435
+ }
436
+
437
+ &.selected {
438
+ background-color: #E6F2FF;
439
+ border: 2px solid #409EFF;
440
+ padding: 3px;
441
+ }
442
+
443
+ &.empty {
444
+ background-color: #FAFAFA;
445
+ cursor: default;
446
+
447
+ &:hover {
448
+ background-color: #FAFAFA;
449
+ }
450
+ }
451
+
452
+ .day-number {
453
+ font-size: 16px;
454
+ margin-bottom: 5px;
455
+ }
456
+
457
+ .events-indicator {
458
+ display: flex;
459
+ flex-wrap: wrap;
460
+ gap: 2px;
461
+
462
+ .event-dot {
463
+ width: 8px;
464
+ height: 8px;
465
+ border-radius: 50%;
466
+ }
467
+ }
468
+ }
469
+ }
470
+ }
471
+
472
+ .events-panel {
473
+ margin-top: 30px;
474
+ padding-top: 20px;
475
+ border-top: 1px solid #EBEEF5;
476
+
477
+ &.no-events {
478
+ text-align: center;
479
+ padding: 40px 0;
480
+
481
+ p {
482
+ margin-bottom: 20px;
483
+ color: #909399;
484
+ }
485
+ }
486
+ }
487
+ }
488
+ </style>