ljw 1 год назад
Родитель
Сommit
df3209b576

+ 15 - 0
src/api/audit.js

@@ -14,3 +14,18 @@ export function remove (data) {
14
     data,
14
     data,
15
   })
15
   })
16
 }
16
 }
17
+
18
+export function fileList (params) {
19
+  return request({
20
+    url: '/audit_file/list',
21
+    params,
22
+  })
23
+}
24
+
25
+export function fileRemove (data) {
26
+  return request({
27
+    url: '/audit_file/delete',
28
+    method: 'post',
29
+    data,
30
+  })
31
+}

+ 6 - 0
src/router/index.js

@@ -136,6 +136,12 @@ export const asyncRoutes = [
136
         meta: { title: 'AuditConnLog', icon: 'Tickets' /*keepAlive: true*/ },
136
         meta: { title: 'AuditConnLog', icon: 'Tickets' /*keepAlive: true*/ },
137
         component: () => import('@/views/audit/connList.vue'),
137
         component: () => import('@/views/audit/connList.vue'),
138
       },
138
       },
139
+      {
140
+        path: '/auditFile',
141
+        name: 'AuditFile',
142
+        meta: { title: 'AuditFileLog', icon: 'Files' /*keepAlive: true*/ },
143
+        component: () => import('@/views/audit/fileList.vue'),
144
+      },
139
     ],
145
     ],
140
   },
146
   },
141
 ]
147
 ]

+ 12 - 0
src/utils/file.js

@@ -55,3 +55,15 @@ export function downBlob (blob, filename) {
55
     document.body.removeChild(a)
55
     document.body.removeChild(a)
56
   })
56
   })
57
 }
57
 }
58
+
59
+export function sizeFormat (size) {
60
+  if (size < 1024) {
61
+    return size + 'B'
62
+  } else if (size < 1024 * 1024) {
63
+    return (size / 1024).toFixed(2) + 'KB'
64
+  } else if (size < 1024 * 1024 * 1024) {
65
+    return (size / 1024 / 1024).toFixed(2) + 'MB'
66
+  } else {
67
+    return (size / 1024 / 1024 / 1024).toFixed(2) + 'GB'
68
+  }
69
+}

+ 33 - 0
src/utils/i18n/en.json

@@ -366,5 +366,38 @@
366
   },
366
   },
367
   "CloseTime": {
367
   "CloseTime": {
368
     "One": "Close Time"
368
     "One": "Close Time"
369
+  },
370
+  "AuditFileLog": {
371
+    "One": "File Log"
372
+  },
373
+  "Common": {
374
+    "One": "Common"
375
+  },
376
+  "File": {
377
+    "One": "File"
378
+  },
379
+  "Num": {
380
+    "One": "Num"
381
+  },
382
+  "Ip": {
383
+    "One": "Ip"
384
+  },
385
+  "FileName": {
386
+    "One": "File Name"
387
+  },
388
+  "FileInfo": {
389
+    "One": "File Info"
390
+  },
391
+  "Path": {
392
+    "One": "Path"
393
+  },
394
+  "IndexNum": {
395
+    "One": "Index Num"
396
+  },
397
+  "ToRemote": {
398
+    "One": "To Remote"
399
+  },
400
+  "ToLocal": {
401
+    "One": "To Local"
369
   }
402
   }
370
 }
403
 }

+ 33 - 0
src/utils/i18n/zh_CN.json

@@ -352,5 +352,38 @@
352
   },
352
   },
353
   "CloseTime": {
353
   "CloseTime": {
354
     "One": "关闭时间"
354
     "One": "关闭时间"
355
+  },
356
+  "AuditFileLog": {
357
+    "One": "文件日志"
358
+  },
359
+  "Common": {
360
+    "One": "普通"
361
+  },
362
+  "File": {
363
+    "One": "文件"
364
+  },
365
+  "Num": {
366
+    "One": "数量"
367
+  },
368
+  "Ip": {
369
+    "One": "IP"
370
+  },
371
+  "FileName": {
372
+    "One": "文件名"
373
+  },
374
+  "FileInfo": {
375
+    "One": "文件信息"
376
+  },
377
+  "Path": {
378
+    "One": "路径"
379
+  },
380
+  "IndexNum": {
381
+    "One": "序号"
382
+  },
383
+  "ToRemote": {
384
+    "One": "到远程"
385
+  },
386
+  "ToLocal": {
387
+    "One": "到本地"
355
   }
388
   }
356
 }
389
 }

+ 8 - 2
src/views/audit/connList.vue

@@ -14,16 +14,22 @@
14
       </el-form>
14
       </el-form>
15
     </el-card>
15
     </el-card>
16
     <el-card class="list-body" shadow="hover">
16
     <el-card class="list-body" shadow="hover">
17
-      <!--      <el-tag type="danger" style="margin-bottom: 10px">不建议在此操作地址簿,可能会造成数据不同步</el-tag>-->
18
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
17
       <el-table :data="listRes.list" v-loading="listRes.loading" border>
19
         <el-table-column prop="id" label="id" align="center" width="100"/>
18
         <el-table-column prop="id" label="id" align="center" width="100"/>
20
         <el-table-column :label="T('Peer')" prop="peer_id" align="center" width="120"/>
19
         <el-table-column :label="T('Peer')" prop="peer_id" align="center" width="120"/>
21
         <el-table-column :label="T('FromPeer')" prop="from_peer" align="center" width="120"/>
20
         <el-table-column :label="T('FromPeer')" prop="from_peer" align="center" width="120"/>
22
         <el-table-column :label="T('FromName')" prop="from_name" align="center" width="120"/>
21
         <el-table-column :label="T('FromName')" prop="from_name" align="center" width="120"/>
22
+        <el-table-column :label="T('Ip')" prop="ip" align="center" width="120"/>
23
+        <el-table-column pop="type" :label="T('Type')" align="center" width="120">
24
+          <template #default="{row}">
25
+            <el-tag v-if="row.type === 1" type="warning">{{ T('File') }}</el-tag>
26
+            <el-tag v-else>{{ T('Common') }}</el-tag>
27
+          </template>
28
+        </el-table-column>
23
         <el-table-column prop="uuid" label="uuid" align="center" width="120" show-overflow-tooltip/>
29
         <el-table-column prop="uuid" label="uuid" align="center" width="120" show-overflow-tooltip/>
24
         <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
30
         <el-table-column prop="created_at" :label="T('CreatedAt')" align="center"/>
25
         <el-table-column :label="T('CloseTime')" prop="close_time" align="center"/>
31
         <el-table-column :label="T('CloseTime')" prop="close_time" align="center"/>
26
-        <el-table-column :label="T('Actions')" align="center" width="400">
32
+        <el-table-column :label="T('Actions')" align="center" width="150">
27
           <template #default="{row}">
33
           <template #default="{row}">
28
             <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
34
             <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
29
           </template>
35
           </template>

+ 118 - 0
src/views/audit/fileList.vue

@@ -0,0 +1,118 @@
1
+<template>
2
+  <div>
3
+    <el-card class="list-query" shadow="hover">
4
+      <el-form inline label-width="80px">
5
+        <el-form-item :label="T('Peer')">
6
+          <el-input v-model="listQuery.peer_id" clearable></el-input>
7
+        </el-form-item>
8
+        <el-form-item :label="T('FromPeer')">
9
+          <el-input v-model="listQuery.from_peer" clearable></el-input>
10
+        </el-form-item>
11
+        <el-form-item>
12
+          <el-button type="primary" @click="handlerQuery">筛选</el-button>
13
+        </el-form-item>
14
+      </el-form>
15
+    </el-card>
16
+    <el-card class="list-body" shadow="hover">
17
+      <el-table :data="listRes.list" v-loading="listRes.loading" border max-height="750">
18
+        <el-table-column prop="id" label="id" align="center" width="100"/>
19
+        <el-table-column :label="T('Peer')" prop="peer_id" align="center" width="120"/>
20
+        <el-table-column :label="T('FromPeer')" prop="from_peer" align="center" width="120"/>
21
+        <el-table-column :label="T('FromName')" prop="from_name" align="center" width="120"/>
22
+        <el-table-column :label="T('Ip')" prop="ip" align="center" width="120"/>
23
+        <el-table-column prop="type" :label="T('Type')" align="center" width="200">
24
+          <template #default="{row}">
25
+            <el-tag v-if="row.type === 1" type="warning"> {{T('ToRemote')}}: <el-icon><Right/></el-icon> {{row.peer_id}}</el-tag>
26
+            <el-tag v-else>{{T('ToLocal')}}: <el-icon><Right/></el-icon> {{row.from_peer}}</el-tag>
27
+          </template>
28
+        </el-table-column>
29
+        <el-table-column prop="num" :label="T('Num')" align="center" width="100"/>
30
+        <el-table-column :label="T('FileInfo')" align="center" width="300">
31
+          <template #default="{row}">
32
+            <template v-if="!row.is_file">
33
+              <el-table size="small" :data="row.info?.files?.filter((v,k) => k<showDirFileNum)" fit>
34
+                <el-table-column prop="0" :label="T('FileName')" align="center" width="150" show-overflow-tooltip></el-table-column>
35
+                <el-table-column prop="1" :label="T('Size')" align="center">
36
+                  <template #default="{row:_row}">
37
+                    {{ sizeFormat(_row[1]) }}
38
+                  </template>
39
+                </el-table-column>
40
+              </el-table>
41
+              <el-button size="small" v-if="row.info.files.length>showDirFileNum" style="width: 100%;margin-top: 5px" type="primary" @click="showAllFile(row.info.files)">
42
+                {{ T('More') }}({{ row.info.files.length - showDirFileNum }})
43
+              </el-button>
44
+            </template>
45
+            <div v-else>
46
+              {{ sizeFormat(row.info.files[0][1]) }}
47
+            </div>
48
+
49
+          </template>
50
+        </el-table-column>
51
+        <el-table-column prop="path" :label="T('Path')" align="center" width="150" show-overflow-tooltip/>
52
+        <el-table-column prop="uuid" label="uuid" align="center" width="120" show-overflow-tooltip/>
53
+        <el-table-column prop="created_at" :label="T('CreatedAt')" align="center" min-width="120"/>
54
+        <el-table-column :label="T('Actions')" align="center" width="150" fixed="right">
55
+          <template #default="{row}">
56
+            <el-button type="danger" @click="del(row)">{{ T('Delete') }}</el-button>
57
+          </template>
58
+        </el-table-column>
59
+      </el-table>
60
+    </el-card>
61
+    <el-card class="list-page" shadow="hover">
62
+      <el-pagination background
63
+                     layout="prev, pager, next, sizes, jumper"
64
+                     :page-sizes="[10,20,50,100]"
65
+                     v-model:page-size="listQuery.page_size"
66
+                     v-model:current-page="listQuery.page"
67
+                     :total="listRes.total">
68
+      </el-pagination>
69
+    </el-card>
70
+    <el-dialog v-model="allFilesVisible" :title="T('File')">
71
+      <el-table :data="showFiles" max-height="800px">
72
+        <el-table-column type="index" :label="T('IndexNum')" width="120" align="center"></el-table-column>
73
+        <el-table-column prop="0" :label="T('FileName')" align="center"></el-table-column>
74
+        <el-table-column prop="1" :label="T('Size')" align="center">
75
+          <template #default="{row:_row}">
76
+            {{ sizeFormat(_row[1]) }}
77
+          </template>
78
+        </el-table-column>
79
+      </el-table>
80
+      <el-button @click="allFilesVisible=false" style="margin-top: 20px;width: 100%" type="primary">{{ T('Close') }}</el-button>
81
+    </el-dialog>
82
+  </div>
83
+</template>
84
+
85
+<script setup>
86
+  import { onActivated, onMounted, ref, watch } from 'vue'
87
+  import { useFileRepositories } from '@/views/audit/reponsitories'
88
+  import { T } from '@/utils/i18n'
89
+  import { sizeFormat } from '@/utils/file'
90
+  import { Right } from '@element-plus/icons'
91
+
92
+  const showDirFileNum = 3
93
+  const {
94
+    listRes,
95
+    listQuery,
96
+    getList,
97
+    handlerQuery,
98
+    del,
99
+  } = useFileRepositories()
100
+
101
+  onMounted(getList)
102
+  onActivated(getList)
103
+
104
+  watch(() => listQuery.page, getList)
105
+
106
+  watch(() => listQuery.page_size, handlerQuery)
107
+
108
+  const allFilesVisible = ref(false)
109
+  const showFiles = ref([])
110
+  const showAllFile = (files) => {
111
+    showFiles.value = files
112
+    allFilesVisible.value = true
113
+  }
114
+</script>
115
+
116
+<style scoped lang="scss">
117
+
118
+</style>

+ 66 - 7
src/views/audit/reponsitories.js

@@ -1,8 +1,10 @@
1
 import { reactive } from 'vue'
1
 import { reactive } from 'vue'
2
-import { list, remove } from '@/api/audit'
2
+import { list, remove, fileList, fileRemove } from '@/api/audit'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { useRoute } from 'vue-router'
4
 import { useRoute } from 'vue-router'
5
-import {formatTime} from '@/utils/time'
5
+import { formatTime } from '@/utils/time'
6
+import { T } from '@/utils/i18n'
7
+
6
 export function useRepositories () {
8
 export function useRepositories () {
7
   const listRes = reactive({
9
   const listRes = reactive({
8
     list: [], total: 0, loading: false,
10
     list: [], total: 0, loading: false,
@@ -20,7 +22,7 @@ export function useRepositories () {
20
     listRes.loading = false
22
     listRes.loading = false
21
     if (res) {
23
     if (res) {
22
       listRes.list = res.data.list.map(item => {
24
       listRes.list = res.data.list.map(item => {
23
-        item.close_time = item.close_time ? formatTime(item.close_time*1000) : '-'
25
+        item.close_time = item.close_time ? formatTime(item.close_time * 1000) : '-'
24
         return item
26
         return item
25
       })
27
       })
26
       listRes.total = res.data.total
28
       listRes.total = res.data.total
@@ -35,9 +37,9 @@ export function useRepositories () {
35
   }
37
   }
36
 
38
 
37
   const del = async (row) => {
39
   const del = async (row) => {
38
-    const cf = await ElMessageBox.confirm('确定删除么?', {
39
-      confirmButtonText: '确定',
40
-      cancelButtonText: '取消',
40
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
41
+      confirmButtonText: T('Confirm'),
42
+      cancelButtonText: T('Cancel'),
41
       type: 'warning',
43
       type: 'warning',
42
     }).catch(_ => false)
44
     }).catch(_ => false)
43
     if (!cf) {
45
     if (!cf) {
@@ -46,7 +48,64 @@ export function useRepositories () {
46
 
48
 
47
     const res = await remove({ id: row.id }).catch(_ => false)
49
     const res = await remove({ id: row.id }).catch(_ => false)
48
     if (res) {
50
     if (res) {
49
-      ElMessage.success('操作成功')
51
+      ElMessage.success(T('OperationSuccess'))
52
+      getList()
53
+    }
54
+  }
55
+
56
+  return {
57
+    listRes,
58
+    listQuery,
59
+    getList,
60
+    handlerQuery,
61
+    del,
62
+  }
63
+}
64
+
65
+export function useFileRepositories () {
66
+  const listRes = reactive({
67
+    list: [], total: 0, loading: false,
68
+  })
69
+  const listQuery = reactive({
70
+    page: 1,
71
+    page_size: 10,
72
+    peer_id: null,
73
+    from_peer: null,
74
+  })
75
+
76
+  const getList = async () => {
77
+    listRes.loading = true
78
+    const res = await fileList(listQuery).catch(_ => false)
79
+    listRes.loading = false
80
+    if (res) {
81
+      listRes.list = res.data.list.map(item => {
82
+        item.info = item.info ? JSON.parse(item.info) : '-'
83
+        return item
84
+      })
85
+      listRes.total = res.data.total
86
+    }
87
+  }
88
+  const handlerQuery = () => {
89
+    if (listQuery.page === 1) {
90
+      getList()
91
+    } else {
92
+      listQuery.page = 1
93
+    }
94
+  }
95
+
96
+  const del = async (row) => {
97
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
98
+      confirmButtonText: T('Confirm'),
99
+      cancelButtonText: T('Cancel'),
100
+      type: 'warning',
101
+    }).catch(_ => false)
102
+    if (!cf) {
103
+      return false
104
+    }
105
+
106
+    const res = await fileRemove({ id: row.id }).catch(_ => false)
107
+    if (res) {
108
+      ElMessage.success(T('OperationSuccess'))
50
       getList()
109
       getList()
51
     }
110
     }
52
   }
111
   }

+ 5 - 4
src/views/login/log.js

@@ -2,6 +2,7 @@ import { reactive } from 'vue'
2
 import { list, remove } from '@/api/login_log'
2
 import { list, remove } from '@/api/login_log'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
3
 import { ElMessage, ElMessageBox } from 'element-plus'
4
 import { useRoute } from 'vue-router'
4
 import { useRoute } from 'vue-router'
5
+import { T } from '@/utils/i18n'
5
 
6
 
6
 export function useRepositories () {
7
 export function useRepositories () {
7
   const route = useRoute()
8
   const route = useRoute()
@@ -35,9 +36,9 @@ export function useRepositories () {
35
   }
36
   }
36
 
37
 
37
   const del = async (row) => {
38
   const del = async (row) => {
38
-    const cf = await ElMessageBox.confirm('确定删除么?', {
39
-      confirmButtonText: '确定',
40
-      cancelButtonText: '取消',
39
+    const cf = await ElMessageBox.confirm(T('Confirm?', { param: T('Delete') }), {
40
+      confirmButtonText: T('Confirm'),
41
+      cancelButtonText: T('Cancel'),
41
       type: 'warning',
42
       type: 'warning',
42
     }).catch(_ => false)
43
     }).catch(_ => false)
43
     if (!cf) {
44
     if (!cf) {
@@ -46,7 +47,7 @@ export function useRepositories () {
46
 
47
 
47
     const res = await remove({ id: row.id }).catch(_ => false)
48
     const res = await remove({ id: row.id }).catch(_ => false)
48
     if (res) {
49
     if (res) {
49
-      ElMessage.success('操作成功')
50
+      ElMessage.success(T('OperationSuccess'))
50
       getList()
51
       getList()
51
     }
52
     }
52
   }
53
   }