@sugarat/easypicker2-client 2.4.1

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 (145) hide show
  1. package/.env +6 -0
  2. package/.env.production +3 -0
  3. package/.env.test +4 -0
  4. package/.eslintignore +0 -0
  5. package/.eslintrc.json +57 -0
  6. package/.github/workflows/main.yml +61 -0
  7. package/.prettierrc.js +9 -0
  8. package/LICENSE +21 -0
  9. package/README.md +86 -0
  10. package/auto-imports.d.ts +6 -0
  11. package/components.d.ts +56 -0
  12. package/docker/ep_backup/easypicker2.sql +214 -0
  13. package/docker/ep_backup/mongodb/easypicker2/action.bson +0 -0
  14. package/docker/ep_backup/mongodb/easypicker2/action.metadata.json +1 -0
  15. package/docker/ep_backup/mongodb/easypicker2/log.bson +0 -0
  16. package/docker/ep_backup/mongodb/easypicker2/log.metadata.json +1 -0
  17. package/docker/ep_backup/user-config.json +176 -0
  18. package/docs/.env +1 -0
  19. package/docs/.env.production +2 -0
  20. package/docs/.vitepress/config.ts +204 -0
  21. package/docs/.vitepress/theme/bg.png +0 -0
  22. package/docs/.vitepress/theme/index.scss +41 -0
  23. package/docs/.vitepress/theme/index.ts +5 -0
  24. package/docs/author.md +24 -0
  25. package/docs/auto-imports.d.ts +6 -0
  26. package/docs/components.d.ts +17 -0
  27. package/docs/deploy/design/api.md +3 -0
  28. package/docs/deploy/design/db.md +3 -0
  29. package/docs/deploy/design/index.md +3 -0
  30. package/docs/deploy/design/shell.md +9 -0
  31. package/docs/deploy/faq.md +86 -0
  32. package/docs/deploy/index.md +9 -0
  33. package/docs/deploy/local.md +275 -0
  34. package/docs/deploy/online-new.md +610 -0
  35. package/docs/deploy/online.md +683 -0
  36. package/docs/deploy/qiniu.md +183 -0
  37. package/docs/index.md +40 -0
  38. package/docs/introduction/about/code.md +26 -0
  39. package/docs/introduction/about/index.md +33 -0
  40. package/docs/introduction/feature/index.md +3 -0
  41. package/docs/plan/log.md +333 -0
  42. package/docs/plan/todo.md +127 -0
  43. package/docs/plan/wish.md +29 -0
  44. package/docs/praise/index.md +45 -0
  45. package/docs/public/favicon.ico +0 -0
  46. package/docs/public/logo.png +0 -0
  47. package/docs/public/robots.txt +2 -0
  48. package/docs/src/apis/ajax.ts +66 -0
  49. package/docs/src/apis/index.ts +1 -0
  50. package/docs/src/apis/modules/wish.ts +20 -0
  51. package/docs/src/components/Avatar.vue +60 -0
  52. package/docs/src/components/Home.vue +85 -0
  53. package/docs/src/components/Picture.vue +13 -0
  54. package/docs/src/components/Praise.vue +52 -0
  55. package/docs/src/components/WishBtn.vue +98 -0
  56. package/docs/src/components/WishPanel.vue +170 -0
  57. package/docs/src/components/callme/index.vue +72 -0
  58. package/docs/vite.config.ts +42 -0
  59. package/index.html +127 -0
  60. package/package.json +52 -0
  61. package/public/favicon.ico +0 -0
  62. package/public/logo.png +0 -0
  63. package/scripts/deploy/docs.mjs +24 -0
  64. package/scripts/deploy/prod.mjs +24 -0
  65. package/scripts/deploy/test.mjs +26 -0
  66. package/src/@types/ajax.d.ts +5 -0
  67. package/src/@types/api.d.ts +305 -0
  68. package/src/@types/lib.d.ts +26 -0
  69. package/src/@types/page.d.ts +18 -0
  70. package/src/App.vue +36 -0
  71. package/src/apis/ajax.ts +70 -0
  72. package/src/apis/index.ts +20 -0
  73. package/src/apis/modules/action.ts +17 -0
  74. package/src/apis/modules/category.ts +20 -0
  75. package/src/apis/modules/config.ts +19 -0
  76. package/src/apis/modules/file.ts +150 -0
  77. package/src/apis/modules/people.ts +81 -0
  78. package/src/apis/modules/public.ts +49 -0
  79. package/src/apis/modules/super/overview.ts +56 -0
  80. package/src/apis/modules/super/user.ts +62 -0
  81. package/src/apis/modules/task.ts +67 -0
  82. package/src/apis/modules/user.ts +56 -0
  83. package/src/apis/modules/wish.ts +31 -0
  84. package/src/assets/i/EasyPicker.png +0 -0
  85. package/src/assets/logo.png +0 -0
  86. package/src/assets/styles/app.css +69 -0
  87. package/src/components/HomeFooter/index.vue +134 -0
  88. package/src/components/HomeHeader/index.vue +156 -0
  89. package/src/components/InfosForm/index.vue +73 -0
  90. package/src/components/MessageList/index.vue +155 -0
  91. package/src/components/MessagePanel/index.vue +42 -0
  92. package/src/components/Praise/index.vue +102 -0
  93. package/src/components/QrCode.vue +44 -0
  94. package/src/components/linkDialog.vue +104 -0
  95. package/src/components/loginPanel.vue +92 -0
  96. package/src/constants/index.ts +83 -0
  97. package/src/env.d.ts +8 -0
  98. package/src/main.ts +19 -0
  99. package/src/pages/404/index.vue +59 -0
  100. package/src/pages/about/index.vue +152 -0
  101. package/src/pages/callme/index.vue +155 -0
  102. package/src/pages/dashboard/config/index.vue +264 -0
  103. package/src/pages/dashboard/files/index.vue +1152 -0
  104. package/src/pages/dashboard/index.vue +335 -0
  105. package/src/pages/dashboard/manage/config/index.vue +97 -0
  106. package/src/pages/dashboard/manage/index.vue +105 -0
  107. package/src/pages/dashboard/manage/overview/index.vue +488 -0
  108. package/src/pages/dashboard/manage/user/index.vue +679 -0
  109. package/src/pages/dashboard/manage/wish/index.vue +257 -0
  110. package/src/pages/dashboard/tasks/components/CategoryPanel.vue +208 -0
  111. package/src/pages/dashboard/tasks/components/CreateTask.vue +93 -0
  112. package/src/pages/dashboard/tasks/components/TaskInfo.vue +129 -0
  113. package/src/pages/dashboard/tasks/components/infoPanel/ddl.vue +96 -0
  114. package/src/pages/dashboard/tasks/components/infoPanel/file.vue +175 -0
  115. package/src/pages/dashboard/tasks/components/infoPanel/info.vue +477 -0
  116. package/src/pages/dashboard/tasks/components/infoPanel/people.vue +567 -0
  117. package/src/pages/dashboard/tasks/components/infoPanel/template.vue +146 -0
  118. package/src/pages/dashboard/tasks/components/infoPanel/tip.vue +55 -0
  119. package/src/pages/dashboard/tasks/components/infoPanel/tipInfo.vue +196 -0
  120. package/src/pages/dashboard/tasks/index.vue +302 -0
  121. package/src/pages/dashboard/tasks/public.ts +32 -0
  122. package/src/pages/disabled/index.vue +47 -0
  123. package/src/pages/feedback/index.vue +5 -0
  124. package/src/pages/home/index.vue +72 -0
  125. package/src/pages/login/index.vue +270 -0
  126. package/src/pages/register/index.vue +211 -0
  127. package/src/pages/reset/index.vue +186 -0
  128. package/src/pages/task/index.vue +897 -0
  129. package/src/pages/wish/index.vue +152 -0
  130. package/src/router/Interceptor/index.ts +112 -0
  131. package/src/router/index.ts +13 -0
  132. package/src/router/routes/index.ts +197 -0
  133. package/src/shims-vue.d.ts +6 -0
  134. package/src/store/index.ts +17 -0
  135. package/src/store/modules/category.ts +44 -0
  136. package/src/store/modules/public.ts +27 -0
  137. package/src/store/modules/task.ts +55 -0
  138. package/src/store/modules/user.ts +57 -0
  139. package/src/utils/elementUI.ts +8 -0
  140. package/src/utils/networkUtil.ts +236 -0
  141. package/src/utils/other.ts +25 -0
  142. package/src/utils/regExp.ts +11 -0
  143. package/src/utils/stringUtil.ts +242 -0
  144. package/tsconfig.json +24 -0
  145. package/vite.config.ts +55 -0
@@ -0,0 +1,488 @@
1
+ <template>
2
+ <div class="overview">
3
+ <div
4
+ class="card-list"
5
+ v-loading="isLoadingOverview"
6
+ element-loading-text="Loading..."
7
+ >
8
+ <div v-for="c in cardList" :key="c.type" class="card">
9
+ <div class="logo">
10
+ <el-icon :color="c.color">
11
+ <component :is="c.icon"></component>
12
+ </el-icon>
13
+ </div>
14
+ <div class="content">
15
+ <div class="title">{{ c.title }}</div>
16
+ <div class="text">{{ c.value }}</div>
17
+ <div class="supplement">{{ c.supplement }}</div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ <div class="panel">
22
+ <div class="p10 log-filter">
23
+ <span class="item">
24
+ <span class="label">类型</span>
25
+ <el-select
26
+ v-model="filterLogType"
27
+ size="default"
28
+ placeholder="请选择日志类型"
29
+ >
30
+ <el-option
31
+ v-for="(item, idx) in logTypeList"
32
+ :key="idx"
33
+ :label="item.label"
34
+ :value="item.type"
35
+ ></el-option>
36
+ </el-select>
37
+ </span>
38
+ <span class="item">
39
+ <el-input
40
+ size="default"
41
+ clearable
42
+ placeholder="请输入要检索的内容"
43
+ :prefix-icon="Search"
44
+ v-model="searchWord"
45
+ >
46
+ </el-input>
47
+ </span>
48
+ <span class="item">
49
+ <el-button size="default" :icon="Refresh" @click="refreshLogs"
50
+ >刷新</el-button
51
+ >
52
+ </span>
53
+ <span class="item">
54
+ <el-button
55
+ size="default"
56
+ type="primary"
57
+ :icon="DataAnalysis"
58
+ @click="exportLogData"
59
+ >导出日志 {{ logs.length }} 条</el-button
60
+ >
61
+ </span>
62
+ <span class="item">
63
+ <el-button
64
+ size="default"
65
+ type="danger"
66
+ :icon="TakeawayBox"
67
+ :disabled="disableDelete"
68
+ @click="clearExpiredCompressFile"
69
+ v-loading="disableDelete"
70
+ >清理无效文件</el-button
71
+ >
72
+ </span>
73
+ </div>
74
+ <el-table
75
+ tooltip-effect="dark"
76
+ height="400"
77
+ stripe
78
+ border
79
+ :default-sort="{ prop: 'date', order: 'descending' }"
80
+ :data="logs"
81
+ style="width: 100%"
82
+ >
83
+ <el-table-column sortable prop="date" label="日期" width="180">
84
+ <template #default="scope">{{
85
+ formatDate(new Date(scope.row.date))
86
+ }}</template>
87
+ </el-table-column>
88
+ <!-- <el-table-column prop="type" label="类型" width="100">
89
+ <template #default="scope">{{ getLogsTypeText(scope.row.type) }}</template>
90
+ </el-table-column>-->
91
+ <el-table-column
92
+ sortable
93
+ prop="ip"
94
+ label="IP"
95
+ width="100"
96
+ ></el-table-column>
97
+ <el-table-column
98
+ min-width="160"
99
+ prop="msg"
100
+ label="内容"
101
+ ></el-table-column>
102
+ <el-table-column fixed="right" label="操作" width="100">
103
+ <template #default="scope">
104
+ <el-button
105
+ @click="handleDetail(scope.row.id)"
106
+ type="primary"
107
+ text
108
+ size="small"
109
+ >查看详情</el-button
110
+ >
111
+ </template>
112
+ </el-table-column>
113
+ </el-table>
114
+
115
+ <div class="flex fc p10">
116
+ <el-pagination
117
+ :current-page="pageCurrent"
118
+ @current-change="handlePageChange"
119
+ background
120
+ :page-count="pageCount"
121
+ :page-sizes="[10, 50, 100, 200, 500, 1000]"
122
+ :page-size="pageSize"
123
+ @size-change="handleSizeChange"
124
+ :total="logSumCount"
125
+ layout="total, sizes, prev, pager, next, jumper"
126
+ ></el-pagination>
127
+ </div>
128
+ </div>
129
+ <el-dialog
130
+ v-model="showDetail"
131
+ title="详细信息"
132
+ width="50%"
133
+ center
134
+ :fullscreen="isMobile"
135
+ >
136
+ <!-- TODO: 展示优化 -->
137
+ <!-- <pre style="overflow: hidden;">{{ showData }}</pre> -->
138
+ <json-viewer
139
+ :value="jsonData"
140
+ :expand-depth="5"
141
+ copyable
142
+ boxed
143
+ sort
144
+ ></json-viewer>
145
+ <template #footer>
146
+ <span class="dialog-footer">
147
+ <el-button type="default" @click="handleCopyDetail">复制</el-button>
148
+ <el-button type="primary" @click="showDetail = false">确定</el-button>
149
+ </span>
150
+ </template>
151
+ </el-dialog>
152
+ </div>
153
+ </template>
154
+ <script lang="ts" setup>
155
+ import { computed, onMounted, reactive, ref, watchEffect } from 'vue'
156
+ import {
157
+ User,
158
+ Document,
159
+ Tickets,
160
+ DataBoard,
161
+ Search,
162
+ Refresh,
163
+ DataAnalysis,
164
+ Coin,
165
+ TakeawayBox
166
+ } from '@element-plus/icons-vue'
167
+ import { useStore } from 'vuex'
168
+ import { ElMessage } from 'element-plus'
169
+ import { SuperOverviewApi } from '@/apis'
170
+ import { copyRes, formatDate } from '@/utils/stringUtil'
171
+ import { tableToExcel } from '@/utils/networkUtil'
172
+ import { debounce } from '@/utils/other'
173
+
174
+ const $store = useStore()
175
+
176
+ const isMobile = computed(() => $store.getters['public/isMobile'])
177
+
178
+ const isLoadingOverview = ref(false)
179
+ const cardList = reactive([
180
+ {
181
+ type: 'user',
182
+ title: '用户数量',
183
+ value: '0',
184
+ supplement: '较昨日 +0',
185
+ icon: User,
186
+ color: '#40c9c6'
187
+ },
188
+ {
189
+ type: 'file',
190
+ title: '记录/OSS',
191
+ value: '0',
192
+ supplement: '记录较昨日 +0',
193
+ icon: Document,
194
+ color: '#36a3f7'
195
+ },
196
+ {
197
+ type: 'log',
198
+ title: '日志数量',
199
+ value: '0',
200
+ supplement: '较昨日 +0',
201
+ icon: Tickets,
202
+ color: '#f4516c'
203
+ },
204
+ {
205
+ type: 'pv',
206
+ title: 'PV/UV',
207
+ value: '0/0',
208
+ supplement: '',
209
+ icon: DataBoard,
210
+ color: '#34bfa3'
211
+ },
212
+ {
213
+ type: 'compress',
214
+ title: '归档&无效文件',
215
+ value: '0/0KB',
216
+ supplement: '已失效0个',
217
+ icon: Coin,
218
+ color: '#e38013'
219
+ }
220
+ ])
221
+ // 刷新记录条数
222
+ const refreshCount = () => {
223
+ isLoadingOverview.value = true
224
+ SuperOverviewApi.getCount().then((res) => {
225
+ const { user, file, log, pv, compress } = res.data
226
+ cardList[0].value = `${user.sum}`
227
+ cardList[0].supplement = `较昨日 +${user.recent}`
228
+ cardList[1].value = `${file.server.sum}/${file.oss.sum} (${file.oss.size})`
229
+ cardList[1].supplement = `记录较昨日 +${file.server.recent}`
230
+ cardList[2].value = `${log.sum}`
231
+ cardList[2].supplement = `较昨日 +${log.recent}`
232
+ cardList[3].value = `${pv.today.sum}/${pv.today.uv}`
233
+ cardList[3].supplement = `历史: ${pv.all.sum}/${pv.all.uv}`
234
+ cardList[4].value = `${compress.all.sum}/${compress.all.size}`
235
+ cardList[4].supplement = `已失效 ${compress.expired.sum}/${compress.expired.size}`
236
+ isLoadingOverview.value = false
237
+ })
238
+ }
239
+
240
+ const disableDelete = ref(false)
241
+ const clearExpiredCompressFile = () => {
242
+ disableDelete.value = true
243
+ SuperOverviewApi.clearExpiredCompressFile().then(() => {
244
+ setTimeout(() => {
245
+ ElMessage.success('清理成功,数据同步可能有延迟')
246
+ disableDelete.value = false
247
+ refreshCount()
248
+ }, 2000)
249
+ })
250
+ }
251
+
252
+ // 日志
253
+ const logs: any[] = reactive([])
254
+
255
+ // function getLogsTypeText(type: string) {
256
+ // const logsTypeText: any = {
257
+ // request: '网络请求',
258
+ // behavior: '用户行为',
259
+ // error: '错误',
260
+ // pv: '页面访问',
261
+ // }
262
+ // return logsTypeText[type]
263
+ // }
264
+ // 筛选的日志
265
+ const filterLogType = ref('behavior')
266
+ const searchWord = ref('')
267
+ const logTypeList = reactive([
268
+ {
269
+ label: '用户行为',
270
+ type: 'behavior'
271
+ },
272
+ {
273
+ label: '网络请求',
274
+ type: 'request'
275
+ },
276
+ {
277
+ label: '服务端错误',
278
+ type: 'error'
279
+ },
280
+ {
281
+ label: '页面访问',
282
+ type: 'pv'
283
+ }
284
+ ])
285
+
286
+ // 分页
287
+ // 页大小
288
+ const pageSize = ref(10)
289
+ const handleSizeChange = (v: number) => {
290
+ pageSize.value = v
291
+ }
292
+ // 总条数
293
+ const logSumCount = ref(0)
294
+ const pageCount = computed(() => {
295
+ const t = Math.ceil(logSumCount.value / pageSize.value)
296
+ return t
297
+ })
298
+ const pageCurrent = ref(1)
299
+ const handlePageChange = (idx: number) => {
300
+ pageCurrent.value = idx
301
+ }
302
+
303
+ const refreshLogs = debounce(
304
+ () => {
305
+ SuperOverviewApi.getLogMsg(
306
+ pageSize.value,
307
+ pageCurrent.value,
308
+ filterLogType.value,
309
+ searchWord.value
310
+ ).then((res) => {
311
+ logs.splice(0, logs.length)
312
+ logs.push(...res.data.logs)
313
+ logSumCount.value = res.data.sum
314
+ })
315
+ },
316
+ 100,
317
+ false
318
+ )
319
+
320
+ watchEffect(() => {
321
+ if (filterLogType.value) {
322
+ pageCurrent.value = 1
323
+ }
324
+ })
325
+
326
+ watchEffect(() => {
327
+ if (searchWord.value !== undefined) {
328
+ refreshLogs()
329
+ }
330
+ })
331
+
332
+ watchEffect(() => {
333
+ if (filterLogType.value) {
334
+ refreshLogs()
335
+ }
336
+ })
337
+
338
+ watchEffect(() => {
339
+ if (pageCurrent.value || pageSize.value) {
340
+ refreshLogs()
341
+ }
342
+ })
343
+
344
+ const showDetail = ref(false)
345
+ const showData = ref('')
346
+ const handleDetail = (id) => {
347
+ SuperOverviewApi.getLogMsgDetail(id).then((res) => {
348
+ showDetail.value = true
349
+ showData.value = JSON.stringify(res.data, null, 2)
350
+ })
351
+ }
352
+ const jsonData = computed(() => {
353
+ try {
354
+ return JSON.parse(showData.value)
355
+ } catch (e) {
356
+ return {}
357
+ }
358
+ })
359
+ const handleCopyDetail = () => {
360
+ copyRes(showData.value)
361
+ }
362
+
363
+ const exportLogData = () => {
364
+ if (logs.length === 0) {
365
+ return
366
+ }
367
+ const headers = ['日期', 'IP', '内容']
368
+ const body = logs.map((v) => {
369
+ const { date, ip, msg } = v
370
+ return [formatDate(new Date(date)), ip, msg]
371
+ })
372
+ tableToExcel(
373
+ headers,
374
+ body,
375
+ `导出日志_${logs.length}条${formatDate(
376
+ new Date(),
377
+ 'yyyy年MM月日hh时mm分ss秒'
378
+ )}.xlsx`
379
+ )
380
+ ElMessage.success('导出成功')
381
+ }
382
+ onMounted(() => {
383
+ refreshCount()
384
+ })
385
+ </script>
386
+
387
+ <style scoped lang="scss">
388
+ @media screen and (max-width: 700px) {
389
+ .card-list {
390
+ margin-top: 40px;
391
+ }
392
+
393
+ .card {
394
+ min-width: 300px;
395
+ }
396
+
397
+ .log-filter {
398
+ justify-content: center;
399
+ }
400
+ }
401
+
402
+ .overview {
403
+ margin: 0 auto;
404
+ }
405
+
406
+ .card-list {
407
+ display: flex;
408
+ margin-top: 20px;
409
+ justify-content: center;
410
+ flex-wrap: wrap;
411
+ }
412
+
413
+ .card {
414
+ margin: 10px;
415
+ cursor: pointer;
416
+ font-size: 12px;
417
+ position: relative;
418
+ overflow: hidden;
419
+ color: #666;
420
+ background: #fff;
421
+ box-shadow: 4px 4px 40px rgb(0 0 0 / 5%);
422
+ border-color: rgba(0, 0, 0, 0.05);
423
+ min-width: 300px;
424
+
425
+ .logo {
426
+ float: left;
427
+ margin: 4px 10px 0 10px;
428
+ -webkit-transition: all 0.38s ease-out;
429
+ transition: all 0.38s ease-out;
430
+ border-radius: 6px;
431
+ font-size: 48px;
432
+
433
+ i {
434
+ padding: 10px;
435
+ }
436
+ }
437
+
438
+ .content {
439
+ float: right;
440
+ font-weight: 700;
441
+ margin: 10px;
442
+ margin-left: 0;
443
+
444
+ .title {
445
+ line-height: 18px;
446
+ color: rgba(0, 0, 0, 0.45);
447
+ font-size: 14px;
448
+ text-align: right;
449
+ }
450
+
451
+ .text {
452
+ font-size: 16px;
453
+ text-align: right;
454
+ }
455
+
456
+ .supplement {
457
+ font-size: 12px;
458
+ font-weight: lighter;
459
+ text-align: right;
460
+ }
461
+ }
462
+ }
463
+
464
+ .panel {
465
+ max-width: 1024px;
466
+ padding: 1em;
467
+ background-color: #fff;
468
+ margin: 10px auto;
469
+ box-sizing: border-box;
470
+ box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
471
+ border-radius: 4px;
472
+ }
473
+
474
+ .log-filter {
475
+ display: flex;
476
+ flex-wrap: wrap;
477
+
478
+ .item {
479
+ margin-right: 10px;
480
+ margin-bottom: 10px;
481
+
482
+ .label {
483
+ margin-right: 10px;
484
+ font-size: 12px;
485
+ }
486
+ }
487
+ }
488
+ </style>