diff --git a/server/admin/api_set_audit.go b/server/admin/api_set_audit.go index 465f9cf..872c7a6 100644 --- a/server/admin/api_set_audit.go +++ b/server/admin/api_set_audit.go @@ -5,6 +5,7 @@ import ( "strconv" "github.com/bjdgyc/anylink/dbdata" + "github.com/gocarina/gocsv" ) func SetAuditList(w http.ResponseWriter, r *http.Request) { @@ -29,3 +30,24 @@ func SetAuditList(w http.ResponseWriter, r *http.Request) { RespSucess(w, data) } + +func SetAuditExport(w http.ResponseWriter, r *http.Request) { + var datas []dbdata.AccessAudit + maxNum := 1000000 + session := dbdata.GetAuditSession(r.FormValue("search")) + count, err := dbdata.FindAndCount(session, &datas, maxNum, 0) + if err != nil && !dbdata.CheckErrNotFound(err) { + RespError(w, RespInternalErr, err) + return + } + if count == 0 { + RespError(w, RespParamErr, "你导出的总数量为0条,请调整搜索条件,再导出") + return + } + if count > int64(maxNum) { + RespError(w, RespParamErr, "你导出的数据量超过100万条,请调整搜索条件,再导出") + return + } + gocsv.Marshal(datas, w) + +} diff --git a/server/admin/server.go b/server/admin/server.go index 75b6ac9..807efbd 100644 --- a/server/admin/server.go +++ b/server/admin/server.go @@ -39,6 +39,7 @@ func StartAdmin() { r.HandleFunc("/set/other/smtp", SetOtherSmtp) r.HandleFunc("/set/other/smtp/edit", SetOtherSmtpEdit) r.HandleFunc("/set/audit/list", SetAuditList) + r.HandleFunc("/set/audit/export", SetAuditExport) r.HandleFunc("/user/list", UserList) r.HandleFunc("/user/detail", UserDetail) diff --git a/server/go.mod b/server/go.mod index 55df247..7065a25 100644 --- a/server/go.mod +++ b/server/go.mod @@ -7,6 +7,7 @@ require ( github.com/go-ldap/ldap v3.0.3+incompatible // indirect github.com/go-ldap/ldap/v3 v3.4.3 // indirect github.com/go-sql-driver/mysql v1.6.0 + github.com/gocarina/gocsv v0.0.0-20220712153207-8b2118da4570 // indirect github.com/golang-jwt/jwt/v4 v4.0.0 github.com/google/gopacket v1.1.19 github.com/gorilla/mux v1.8.0 diff --git a/web/src/pages/set/Audit.vue b/web/src/pages/set/Audit.vue index 1740881..bbad51e 100644 --- a/web/src/pages/set/Audit.vue +++ b/web/src/pages/set/Audit.vue @@ -48,6 +48,11 @@ icon="el-icon-refresh" @click="rest">重置搜索 </el-button> + <el-button + size="small" + icon="el-icon-download" + @click="handleExport">导出 + </el-button> </el-form-item> </div> </el-form> @@ -55,6 +60,9 @@ <el-table ref="multipleTable" :data="tableData" + v-loading="loading" + element-loading-text="玩命搜索中" + element-loading-spinner="el-icon-loading" border> <el-table-column @@ -171,6 +179,7 @@ export default { { text: 'HTTPS', value: '3' }, { text: 'HTTP', value: '4' }, ], + loading: false, rules: { username: [ {max: 30, message: '长度小于 30 个字符', trigger: 'blur'} @@ -204,6 +213,7 @@ export default { } }, getData(p) { + this.loading = true if (! this.searchForm.date) { this.searchForm.date = ["", ""]; } @@ -217,6 +227,7 @@ export default { console.log(data); this.tableData = data.datas; this.count = data.count + this.loading = false }).catch(error => { this.$message.error('哦,请求出错'); console.log(error); @@ -241,6 +252,45 @@ export default { console.log(error); }); }, + handleExport() { + if (! this.searchForm.date) { + this.searchForm.date = ["", ""]; + } + const exporting = this.$loading({ + lock: true, + text: '玩命导出中,请稍等片刻...', + spinner: 'el-icon-loading', + background: 'rgba(0, 0, 0, 0.7)' + }); + axios.get('/set/audit/export', { + params: { + search: this.searchForm, + } + }).then(resp => { + var rdata = resp.data + if (rdata.code && rdata.code != 0) { + exporting.close(); + this.$message.error(rdata.msg); + return ; + } + exporting.close(); + this.$message.success("成功导出CSV文件") + let csvData = 'data:text/csv;charset=utf-8,\uFEFF' + rdata + this.createDownLoadClick(csvData, `anylink_audit_log_` + Date.parse(new Date()) + `.csv`) + }).catch(error => { + exporting.close(); + this.$message.error('哦,请求出错'); + console.log(error); + }); + }, + createDownLoadClick(content, fileName) { + const link = document.createElement('a') + link.href = encodeURI(content) + link.download = fileName + document.body.appendChild(link) + link.click() + document.body.removeChild(link) + }, protoFormat(row) { var access_proto = row.access_proto if (row.access_proto == 0) {