提交 80ffe7d4 编写于 作者: G granty1

add operation primary realization

上级 4ca3c2e2
package v1
import (
"fmt"
"gin-vue-admin/global/response"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
resp "gin-vue-admin/model/response"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
)
// @Tags SysOperationRecord
// @Summary 创建SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "创建SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/createSysOperationRecord [post]
func CreateSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
err := service.CreateSysOperationRecord(sysOperationRecord)
if err != nil {
response.FailWithMessage(fmt.Sprintf("创建失败,%v", err), c)
} else {
response.OkWithMessage("创建成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
func DeleteSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
err := service.DeleteSysOperationRecord(sysOperationRecord)
if err != nil {
response.FailWithMessage(fmt.Sprintf("删除失败,%v", err), c)
} else {
response.OkWithMessage("删除成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 更新SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "更新SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysOperationRecord/updateSysOperationRecord [put]
func UpdateSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
_ = c.ShouldBindJSON(&sysOperationRecord)
err := service.UpdateSysOperationRecord(&sysOperationRecord)
if err != nil {
response.FailWithMessage(fmt.Sprintf("更新失败,%v", err), c)
} else {
response.OkWithMessage("更新成功", c)
}
}
// @Tags SysOperationRecord
// @Summary 用id查询SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "用id查询SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysOperationRecord/findSysOperationRecord [get]
func FindSysOperationRecord(c *gin.Context) {
var sysOperationRecord model.SysOperationRecord
_ = c.ShouldBindQuery(&sysOperationRecord)
err, resysOperationRecord := service.GetSysOperationRecord(sysOperationRecord.ID)
if err != nil {
response.FailWithMessage(fmt.Sprintf("查询失败,%v", err), c)
} else {
response.OkWithData(gin.H{"resysOperationRecord": resysOperationRecord}, c)
}
}
// @Tags SysOperationRecord
// @Summary 分页获取SysOperationRecord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.SysOperationRecordSearch true "分页获取SysOperationRecord列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
func GetSysOperationRecordList(c *gin.Context) {
var pageInfo request.SysOperationRecordSearch
_ = c.ShouldBindQuery(&pageInfo)
err, list, total := service.GetSysOperationRecordInfoList(pageInfo)
if err != nil {
response.FailWithMessage(fmt.Sprintf("获取数据失败,%v", err), c)
} else {
response.OkWithData(resp.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, c)
}
}
......@@ -62,4 +62,5 @@ log:
operation:
skip_paths:
- '/base/login'
- '/base/register'
\ No newline at end of file
- '/base/register'
- '/sysOperationRecord/getSysOperationRecordList'
\ No newline at end of file
......@@ -6,7 +6,6 @@ require (
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751
github.com/casbin/casbin v1.9.1
github.com/casbin/gorm-adapter v1.0.0
github.com/dchest/captcha v0.0.0-20170622155422-6a29415a8364
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect
github.com/fsnotify/fsnotify v1.4.9
......
......@@ -21,6 +21,7 @@ func DBTables() {
model.ExaFile{},
model.ExaFileChunk{},
model.ExaCustomer{},
model.SysOperationRecord{},
)
global.GVA_LOG.Debug("register table success")
}
......@@ -14,10 +14,9 @@ import (
func Routers() *gin.Engine {
var Router = gin.Default()
// 操作记录
Router.Use(middleware.RecordRequestBody(), middleware.OperationRecord())
// Router.Use(middleware.LoadTls()) // 打开就能玩https了
global.GVA_LOG.Debug("use middleware logger")
Router.Use(middleware.RecordRequestBody(), middleware.OperationRecord())
// 跨域
Router.Use(middleware.Cors())
global.GVA_LOG.Debug("use middleware cors")
......@@ -39,6 +38,7 @@ func Routers() *gin.Engine {
router.InitAutoCodeRouter(ApiGroup) // 创建自动化代码
router.InitSysDictionaryDetailRouter(ApiGroup) // 字典详情管理
router.InitSysDictionaryRouter(ApiGroup) // 字典管理
router.InitSysOperationRecordRouter(ApiGroup)
global.GVA_LOG.Info("router register success")
return Router
}
......@@ -4,13 +4,16 @@ import (
"bytes"
"fmt"
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"time"
"strings"
)
var body []byte
var userId uint
func RecordRequestBody() gin.HandlerFunc {
return func(c *gin.Context) {
......@@ -20,30 +23,39 @@ func RecordRequestBody() gin.HandlerFunc {
if err != nil {
global.GVA_LOG.Error(err)
}
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
} else {
body = nil
}
//TODO parse token , userId <-
}
}
func OperationRecord() gin.HandlerFunc {
return gin.LoggerWithConfig(gin.LoggerConfig{
Formatter: func(param gin.LogFormatterParams) string {
return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" \"%s\" %s\"\n",
param.ClientIP,
param.TimeStamp.Format(time.RFC1123),
param.Method,
param.Path,
param.Request.Proto,
param.StatusCode,
param.Latency,
param.Request.UserAgent(),
string(body),
param.ErrorMessage,
)
fmt.Println(global.GVA_CONFIG.Operation.SkipPaths)
for _, v := range global.GVA_CONFIG.Operation.SkipPaths {
if strings.Contains(param.Path, v) {
fmt.Println(param.Path)
return ""
}
}
err := service.CreateSysOperationRecord(model.SysOperationRecord{
Ip: param.ClientIP,
Method: param.Method,
Path: param.Path,
Status: param.StatusCode,
Latency: param.Latency,
Agent: param.Request.UserAgent(),
ErrorMessage: string(body),
UserId: int(userId),
})
if err != nil {
global.GVA_LOG.Error(err)
}
return ""
},
// 暂时没考虑好
Output: nil,
......
package request
import "gin-vue-admin/model"
type SysOperationRecordSearch struct {
model.SysOperationRecord
PageInfo
}
// 自动生成模板SysOperationRecord
package model
import (
"github.com/jinzhu/gorm"
"time"
)
// 如果含有time.Time 请自行import time包
type SysOperationRecord struct {
gorm.Model
Ip string `json:"ip" form:"ip" gorm:"column:ip;comment:'请求ip'"`
Method string `json:"method" form:"method" gorm:"column:method;comment:''"`
Path string `json:"path" form:"path" gorm:"column:path;comment:''"`
Status int `json:"status" form:"status" gorm:"column:status;comment:''"`
Latency time.Duration `json:"latency" form:"latency" gorm:"column:latency;comment:''"`
Agent string `json:"agent" form:"agent" gorm:"column:agent;comment:''"`
ErrorMessage string `json:"error_message" form:"error_message" gorm:"column:error_message;comment:''"`
UserId int `json:"user_id" form:"user_id" gorm:"column:user_id;comment:''"`
}
package router
import (
"gin-vue-admin/api/v1"
"gin-vue-admin/middleware"
"github.com/gin-gonic/gin"
)
func InitSysOperationRecordRouter(Router *gin.RouterGroup) {
SysOperationRecordRouter := Router.Group("sysOperationRecord").Use(middleware.JWTAuth()).Use(middleware.CasbinHandler())
{
SysOperationRecordRouter.POST("createSysOperationRecord", v1.CreateSysOperationRecord) // 新建SysOperationRecord
SysOperationRecordRouter.DELETE("deleteSysOperationRecord", v1.DeleteSysOperationRecord) // 删除SysOperationRecord
SysOperationRecordRouter.PUT("updateSysOperationRecord", v1.UpdateSysOperationRecord) // 更新SysOperationRecord
SysOperationRecordRouter.GET("findSysOperationRecord", v1.FindSysOperationRecord) // 根据ID获取SysOperationRecord
SysOperationRecordRouter.GET("getSysOperationRecordList", v1.GetSysOperationRecordList) // 获取SysOperationRecord列表
}
}
package service
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
)
// @title CreateSysOperationRecord
// @description create a SysOperationRecord
// @param sysOperationRecord model.SysOperationRecord
// @auth (2020/04/05 20:22)
// @return err error
func CreateSysOperationRecord(sysOperationRecord model.SysOperationRecord) (err error) {
err = global.GVA_DB.Create(&sysOperationRecord).Error
return err
}
// @title DeleteSysOperationRecord
// @description delete a SysOperationRecord
// @auth (2020/04/05 20:22)
// @param sysOperationRecord model.SysOperationRecord
// @return error
func DeleteSysOperationRecord(sysOperationRecord model.SysOperationRecord) (err error) {
err = global.GVA_DB.Delete(sysOperationRecord).Error
return err
}
// @title UpdateSysOperationRecord
// @description update a SysOperationRecord
// @param sysOperationRecord *model.SysOperationRecord
// @auth (2020/04/05 20:22)
// @return error
func UpdateSysOperationRecord(sysOperationRecord *model.SysOperationRecord) (err error) {
err = global.GVA_DB.Save(sysOperationRecord).Error
return err
}
// @title GetSysOperationRecord
// @description get the info of a SysOperationRecord
// @auth (2020/04/05 20:22)
// @param id uint
// @return error
// @return SysOperationRecord SysOperationRecord
func GetSysOperationRecord(id uint) (err error, sysOperationRecord model.SysOperationRecord) {
err = global.GVA_DB.Where("id = ?", id).First(&sysOperationRecord).Error
return
}
// @title GetSysOperationRecordInfoList
// @description get SysOperationRecord list by pagination, 分页获取用户列表
// @auth (2020/04/05 20:22)
// @param info PageInfo
// @return error
func GetSysOperationRecordInfoList(info request.SysOperationRecordSearch) (err error, list interface{}, total int) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
// 创建db
db := global.GVA_DB.Model(&model.SysOperationRecord{})
var sysOperationRecords []model.SysOperationRecord
// 如果有条件搜索 下方会自动创建搜索语句
if info.Method != "" {
db = db.Where("method = ?", info.Method)
}
if info.Path != "" {
db = db.Where("path LIKE ?", "%"+info.Path+"%")
}
if info.Status != 0 {
db = db.Where("status = ?", info.Status)
}
err = db.Count(&total).Error
err = db.Limit(limit).Offset(offset).Find(&sysOperationRecords).Error
return err, sysOperationRecords, total
}
import service from '@/utils/request'
// @Tags SysOperationRecord
// @Summary 创建SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "创建SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/createSysOperationRecord [post]
export const createSysOperationRecord = (data) => {
return service({
url: "/sysOperationRecord/createSysOperationRecord",
method: 'post',
data
})
}
// @Tags SysOperationRecord
// @Summary 删除SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "删除SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /sysOperationRecord/deleteSysOperationRecord [delete]
export const deleteSysOperationRecord = (data) => {
return service({
url: "/sysOperationRecord/deleteSysOperationRecord",
method: 'delete',
data
})
}
// @Tags SysOperationRecord
// @Summary 更新SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "更新SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /sysOperationRecord/updateSysOperationRecord [put]
export const updateSysOperationRecord = (data) => {
return service({
url: "/sysOperationRecord/updateSysOperationRecord",
method: 'put',
data
})
}
// @Tags SysOperationRecord
// @Summary 用id查询SysOperationRecord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.SysOperationRecord true "用id查询SysOperationRecord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /sysOperationRecord/findSysOperationRecord [get]
export const findSysOperationRecord = (params) => {
return service({
url: "/sysOperationRecord/findSysOperationRecord",
method: 'get',
params
})
}
// @Tags SysOperationRecord
// @Summary 分页获取SysOperationRecord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "分页获取SysOperationRecord列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /sysOperationRecord/getSysOperationRecordList [get]
export const getSysOperationRecordList = (params) => {
return service({
url: "/sysOperationRecord/getSysOperationRecordList",
method: 'get',
params
})
}
\ No newline at end of file
<template>
<div>
<div class="search-term">
<el-form :inline="true" :model="searchInfo" class="demo-form-inline">
<el-form-item label="请求方法">
<el-input placeholder="搜索条件" v-model="searchInfo.method"></el-input>
</el-form-item>
<el-form-item label="请求路径">
<el-input placeholder="搜索条件" v-model="searchInfo.path"></el-input>
</el-form-item>
<el-form-item label="结果状态码">
<el-input placeholder="搜索条件" v-model="searchInfo.status"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
</el-form-item>
<el-form-item>
<el-button @click="openDialog" type="primary">新增操作记录</el-button>
</el-form-item>
</el-form>
</div>
<el-table
:data="tableData"
border
ref="multipleTable"
stripe
style="width: 100%"
tooltip-effect="dark"
>
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
</el-table-column>
<el-table-column label="请求ip" prop="ip" width="120"></el-table-column>
<el-table-column label="请求方法" prop="method" width="120"></el-table-column>
<el-table-column label="请求路径" prop="path" width="120"></el-table-column>
<el-table-column label="结果状态码" prop="status" width="120"></el-table-column>
<el-table-column label="latency" prop="latency" width="120"></el-table-column>
<el-table-column label="agent" prop="agent" width="120"></el-table-column>
<el-table-column label="error_message" prop="error_message" width="120"></el-table-column>
<el-table-column label="user_id" prop="user_id" width="120"></el-table-column>
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-button @click="updateSysOperationRecord(scope.row)" size="small" type="primary">变更</el-button>
<el-popover placement="top" width="160" v-model="scope.row.visible">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="scope.row.visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="deleteSysOperationRecord(scope.row)">确定</el-button>
</div>
<el-button type="danger" icon="el-icon-delete" size="mini" slot="reference">删除</el-button>
</el-popover>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:total="total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
<el-dialog :before-close="closeDialog" :visible.sync="dialogFormVisible" title="弹窗操作">
此处请使用表单生成器生成form填充 表单默认绑定 formData 如手动修改过请自行修改key
<div class="dialog-footer" slot="footer">
<el-button @click="closeDialog">取 消</el-button>
<el-button @click="enterDialog" type="primary">确 定</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import {
createSysOperationRecord,
deleteSysOperationRecord,
updateSysOperationRecord,
findSysOperationRecord,
getSysOperationRecordList
} from "@/api/sys_operation_record"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/data";
import infoList from "@/components/mixins/infoList";
export default {
name: "SysOperationRecord",
mixins: [infoList],
data() {
return {
listApi: getSysOperationRecordList,
dialogFormVisible: false,
visible: false,
type: "",
formData: {
ip:null,method:null,path:null,status:null,latency:null,agent:null,error_message:null,user_id:null,
}
};
},
filters: {
formatDate: function(time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
} else {
return "";
}
},
formatBoolean: function(bool) {
if (bool != null) {
return bool ? "" :"";
} else {
return "";
}
}
},
methods: {
//条件搜索前端看此方法
onSubmit() {
this.page = 1
this.pageSize = 10
this.getTableData()
},
async updateSysOperationRecord(row) {
const res = await findSysOperationRecord({ ID: row.ID });
this.type = "update";
if (res.code == 0) {
this.formData = res.data.resysOperationRecord;
this.dialogFormVisible = true;
}
},
closeDialog() {
this.dialogFormVisible = false;
this.formData = {
ip:null,
method:null,
path:null,
status:null,
latency:null,
agent:null,
error_message:null,
user_id:null,
};
},
async deleteSysOperationRecord(row) {
this.visible = false;
const res = await deleteSysOperationRecord({ ID: row.ID });
if (res.code == 0) {
this.$message({
type: "success",
message: "删除成功"
});
this.getTableData();
}
},
async enterDialog() {
let res;
switch (this.type) {
case "create":
res = await createSysOperationRecord(this.formData);
break;
case "update":
res = await updateSysOperationRecord(this.formData);
break;
default:
res = await createSysOperationRecord(this.formData);
break;
}
if (res.code == 0) {
this.$message({
type:"success",
message:"创建/更改成功"
})
this.closeDialog();
this.getTableData();
}
},
openDialog() {
this.type = "create";
this.dialogFormVisible = true;
}
},
created() {
this.getTableData();
}
};
</script>
<style>
</style>
\ No newline at end of file
......@@ -100,7 +100,7 @@ export default {
structName: [{ required: true, message: '请输入结构体名称', trigger: 'blur' }],
abbreviation: [{ required: true, message: '请输入结构体简称', trigger: 'blur' }],
description: [{ required: true, message: '请输入结构体描述', trigger: 'blur' }],
packageName: [{ required: true, message: '请输入包名称', trigger: 'blur' }],
packageName: [{ required: true, message: '文件名称:sys_xxxx_xxxx', trigger: 'blur' }],
},
dialogMiddle: {},
bk: {},
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册