提交 1c2b1b75 编写于 作者: G Grantyin

add sensitive word filter

上级 0d65d257
package v1
import (
"gin-vue-admin/global"
"gin-vue-admin/middleware"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/model/response"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// @Tags ExaSensitiveWord
// @Summary 创建ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "创建ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /exaSensitiveWord/createExaSensitiveWord [post]
func CreateExaSensitiveWord(c *gin.Context) {
var exaSensitiveWord model.ExaSensitiveWord
_ = c.ShouldBindJSON(&exaSensitiveWord)
if err := service.CreateExaSensitiveWord(exaSensitiveWord); err != nil {
global.GVA_LOG.Error("创建失败!", zap.Any("err", err))
response.FailWithMessage("创建失败", c)
} else {
middleware.Library.Build()
response.OkWithMessage("创建成功", c)
}
}
// @Tags ExaSensitiveWord
// @Summary 删除ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "删除ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /exaSensitiveWord/deleteExaSensitiveWord [delete]
func DeleteExaSensitiveWord(c *gin.Context) {
var exaSensitiveWord model.ExaSensitiveWord
_ = c.ShouldBindJSON(&exaSensitiveWord)
if err := service.DeleteExaSensitiveWord(exaSensitiveWord); err != nil {
global.GVA_LOG.Error("删除失败!", zap.Any("err", err))
response.FailWithMessage("删除失败", c)
} else {
middleware.Library.Build()
response.OkWithMessage("删除成功", c)
}
}
// @Tags ExaSensitiveWord
// @Summary 批量删除ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"批量删除成功"}"
// @Router /exaSensitiveWord/deleteExaSensitiveWordByIds [delete]
func DeleteExaSensitiveWordByIds(c *gin.Context) {
var IDS request.IdsReq
_ = c.ShouldBindJSON(&IDS)
if err := service.DeleteExaSensitiveWordByIds(IDS); err != nil {
global.GVA_LOG.Error("批量删除失败!", zap.Any("err", err))
response.FailWithMessage("批量删除失败", c)
} else {
middleware.Library.Build()
response.OkWithMessage("批量删除成功", c)
}
}
// @Tags ExaSensitiveWord
// @Summary 更新ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "更新ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /exaSensitiveWord/updateExaSensitiveWord [put]
func UpdateExaSensitiveWord(c *gin.Context) {
var exaSensitiveWord model.ExaSensitiveWord
_ = c.ShouldBindJSON(&exaSensitiveWord)
if err := service.UpdateExaSensitiveWord(exaSensitiveWord); err != nil {
global.GVA_LOG.Error("更新失败!", zap.Any("err", err))
response.FailWithMessage("更新失败", c)
} else {
middleware.Library.Build()
response.OkWithMessage("更新成功", c)
}
}
// @Tags ExaSensitiveWord
// @Summary 用id查询ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "用id查询ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /exaSensitiveWord/findExaSensitiveWord [get]
func FindExaSensitiveWord(c *gin.Context) {
var exaSensitiveWord model.ExaSensitiveWord
_ = c.ShouldBindQuery(&exaSensitiveWord)
if err, reexaSensitiveWord := service.GetExaSensitiveWord(exaSensitiveWord.ID); err != nil {
global.GVA_LOG.Error("查询失败!", zap.Any("err", err))
response.FailWithMessage("查询失败", c)
} else {
response.OkWithData(gin.H{"reexaSensitiveWord": reexaSensitiveWord}, c)
}
}
// @Tags ExaSensitiveWord
// @Summary 分页获取ExaSensitiveWord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.ExaSensitiveWordSearch true "分页获取ExaSensitiveWord列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /exaSensitiveWord/getExaSensitiveWordList [get]
func GetExaSensitiveWordList(c *gin.Context) {
var pageInfo request.ExaSensitiveWordSearch
_ = c.ShouldBindQuery(&pageInfo)
if err, list, total := service.GetExaSensitiveWordInfoList(pageInfo); err != nil {
global.GVA_LOG.Error("获取失败", zap.Any("err", err))
response.FailWithMessage("获取失败", c)
} else {
response.OkWithDetailed(response.PageResult{
List: list,
Total: total,
Page: pageInfo.Page,
PageSize: pageInfo.PageSize,
}, "获取成功", c)
}
}
......@@ -45,6 +45,7 @@ system:
db-type: 'mysql'
oss-type: 'local' # 控制oss选择走本期还是 七牛等其他仓 自行增加其他oss仓可以在 server/utils/upload/upload.go 中 NewOss函数配置
use-multipoint: false
use-sensitive-word-filter: true
# captcha configuration
captcha:
......
package config
type System struct {
Env string `mapstructure:"env" json:"env" yaml:"env"`
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"`
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"`
OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"`
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"`
Env string `mapstructure:"env" json:"env" yaml:"env"`
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"`
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"`
OssType string `mapstructure:"oss-type" json:"ossType" yaml:"oss-type"`
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"`
UseSensitiveWordFilter bool `mapstructure:"use-sensitive-word-filter" json:"use-sensitive-word-filter" yaml:"use-sensitive-word-filter"`
}
......@@ -50,6 +50,7 @@ func MysqlTables(db *gorm.DB) {
model.SysOperationRecord{},
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
model.ExaSensitiveWord{},
// Code generated by gin-vue-admin End; DO NOT EDIT.
)
if err != nil {
......
......@@ -8,7 +8,7 @@ import (
"net/http"
"github.com/gin-gonic/gin"
"github.com/swaggo/gin-swagger"
ginSwagger "github.com/swaggo/gin-swagger"
"github.com/swaggo/gin-swagger/swaggerFiles"
)
......@@ -51,6 +51,7 @@ func Routers() *gin.Engine {
router.InitExcelRouter(PrivateGroup) // 表格导入导出
// Code generated by gin-vue-admin Begin; DO NOT EDIT.
router.InitExaSensitiveWordRouter(PrivateGroup)
// Code generated by gin-vue-admin End; DO NOT EDIT.
}
global.GVA_LOG.Info("router register success")
......
package initialize
import (
"gin-vue-admin/global"
"gin-vue-admin/middleware"
"gin-vue-admin/misc/sensitive_word"
)
func WordFilter() {
if global.GVA_CONFIG.System.UseSensitiveWordFilter {
middleware.Library = sensitive_word.NewLibrary()
middleware.Library.Build()
}
}
......@@ -17,6 +17,7 @@ func main() {
global.GVA_VP = core.Viper() // 初始化Viper
global.GVA_LOG = core.Zap() // 初始化zap日志库
global.GVA_DB = initialize.Gorm() // gorm连接数据库
initialize.WordFilter()
if global.GVA_DB != nil {
initialize.MysqlTables(global.GVA_DB) // 初始化表
// 程序结束前关闭数据库链接
......
......@@ -2,16 +2,23 @@ package middleware
import (
"bytes"
"encoding/json"
"gin-vue-admin/global"
"gin-vue-admin/misc/sensitive_word"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"gin-vue-admin/service"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
"io/ioutil"
"net/http"
"strconv"
"time"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
var (
Library *sensitive_word.Library
)
func OperationRecord() gin.HandlerFunc {
......@@ -24,8 +31,21 @@ func OperationRecord() gin.HandlerFunc {
if err != nil {
global.GVA_LOG.Error("read body from request error:", zap.Any("err", err))
} else {
if Library != nil {
res, has := Library.HandleWord(string(body), '*')
if has {
body = []byte(res)
}
}
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(body))
}
} else {
c.Request.URL.Query().Encode()
qd, err := json.Marshal(c.Request.URL.Query())
if err == nil {
body = qd
}
// TODO GET request are not filtered for the time being
}
if claims, ok := c.Get("claims"); ok {
waitUse := claims.(*request.CustomClaims)
......
package sensitive_word
import (
"gin-vue-admin/global"
"sync"
"unicode/utf8"
"go.uber.org/zap"
)
type Library struct {
root *trieNode
mu *sync.RWMutex
}
func (this *Library) insertWord(word []rune) {
currNode := this.root
for _, c := range word {
if cildNode, exist := currNode.children[c]; !exist {
cildNode = newtrieNode()
currNode.children[c] = cildNode
currNode = cildNode
} else {
currNode = cildNode
}
}
currNode.isEndOfWord = true
}
func (this *Library) startsWith(prefix []rune) bool {
currNode := this.root
for _, c := range prefix {
if cildNode, exist := currNode.children[c]; !exist {
return false
} else {
currNode = cildNode
}
}
return true
}
func (this *Library) searcWord(word []rune) bool {
currNode := this.root
for _, c := range word {
if cildNode, exist := currNode.children[c]; !exist {
return false
} else {
currNode = cildNode
}
}
return currNode.isEndOfWord
}
func (this *Library) searcSentence(sentence string) (matchIndexList []*matchIndex) {
start, end := 0, 1
sentenceRuneList := []rune(sentence)
startsWith := false
for end <= len(sentenceRuneList) {
if this.startsWith(sentenceRuneList[start:end]) {
startsWith = true
end += 1
} else {
flag := false
if startsWith == true {
for index := end - 1; index > start; index-- {
if this.searcWord(sentenceRuneList[start:index]) {
flag = true
matchIndexList = append(matchIndexList, newMatchIndex(start, index-1))
break
}
}
}
if flag {
start = end - 1
} else {
start = start + 1
}
end = start + 1
startsWith = false
}
}
if startsWith {
for index := end - 1; index > start; index-- {
if this.searcWord(sentenceRuneList[start:index]) {
matchIndexList = append(matchIndexList, newMatchIndex(start, index-1))
break
}
}
}
return
}
func (this *Library) HandleWord(sentence string, replaceCh rune) (string, bool) {
this.mu.RLock()
defer this.mu.RUnlock()
matchIndexList := this.searcSentence(sentence)
var check bool
if len(matchIndexList) == 0 {
return sentence, check
}
sentenceList := []rune(sentence)
if len(matchIndexList) > 0 {
check = true
} else {
check = false
}
for _, matchIndexObj := range matchIndexList {
for index := matchIndexObj.start; index <= matchIndexObj.end; index++ {
sentenceList[index] = replaceCh
}
}
return string(sentenceList), check
}
func (this *Library) Contains(k string) bool {
this.mu.RLock()
defer this.mu.RUnlock()
match := this.searcSentence(k)
if len(match) == 1 {
if item := match[0]; item.end-item.start == utf8.RuneCountInString(k)-1 {
return true
}
}
return false
}
func (l *Library) Build() *Library {
// TODO read from redis
list, err := LoadMySQLWords()
if err != nil {
global.GVA_LOG.Error("query sensitive words fail", zap.Any("error", err.Error()))
return nil
}
l.mu.Lock()
defer l.mu.Unlock()
l.root = newtrieNode()
for _, v := range list {
wordRuneList := []rune(v.Word)
if len(wordRuneList) > 0 {
l.insertWord(wordRuneList)
}
}
return l
}
type matchIndex struct {
start int
end int
}
func newMatchIndex(start, end int) *matchIndex {
return &matchIndex{
start: start,
end: end,
}
}
package sensitive_word
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"sync"
)
func NewLibrary() *Library {
return &Library{
root: nil,
mu: &sync.RWMutex{},
}
}
func LoadMySQLWords() ([]model.ExaSensitiveWord, error) {
var words []model.ExaSensitiveWord
if err := global.GVA_DB.Find(&words).Error; err != nil {
return nil, err
}
return words, nil
}
package sensitive_word
const (
// 每个字符map的初始化容量
INIT_TRIE_CHILDREN_NUM = 128
)
type trieNode struct {
// 是否为字符尾
isEndOfWord bool
// 后续字符map
children map[rune]*trieNode
}
func newtrieNode() *trieNode {
return &trieNode{
isEndOfWord: false,
children: make(map[rune]*trieNode, INIT_TRIE_CHILDREN_NUM),
}
}
// 自动生成模板ExaSensitiveWord
package model
import (
"gin-vue-admin/global"
)
// 如果含有time.Time 请自行import time包
type ExaSensitiveWord struct {
global.GVA_MODEL
Word string `json:"word" form:"word" gorm:"column:word;comment:;type:varchar(1024);size:1024;"`
}
func (ExaSensitiveWord) TableName() string {
return "exa_sensitive_word"
}
package request
import "gin-vue-admin/model"
type ExaSensitiveWordSearch struct{
model.ExaSensitiveWord
PageInfo
}
\ No newline at end of file
package router
import (
"gin-vue-admin/api/v1"
"gin-vue-admin/middleware"
"github.com/gin-gonic/gin"
)
func InitExaSensitiveWordRouter(Router *gin.RouterGroup) {
ExaSensitiveWordRouter := Router.Group("exaSensitiveWord").Use(middleware.OperationRecord())
{
ExaSensitiveWordRouter.POST("createExaSensitiveWord", v1.CreateExaSensitiveWord) // 新建ExaSensitiveWord
ExaSensitiveWordRouter.DELETE("deleteExaSensitiveWord", v1.DeleteExaSensitiveWord) // 删除ExaSensitiveWord
ExaSensitiveWordRouter.DELETE("deleteExaSensitiveWordByIds", v1.DeleteExaSensitiveWordByIds) // 批量删除ExaSensitiveWord
ExaSensitiveWordRouter.PUT("updateExaSensitiveWord", v1.UpdateExaSensitiveWord) // 更新ExaSensitiveWord
ExaSensitiveWordRouter.GET("findExaSensitiveWord", v1.FindExaSensitiveWord) // 根据ID获取ExaSensitiveWord
ExaSensitiveWordRouter.GET("getExaSensitiveWordList", v1.GetExaSensitiveWordList) // 获取ExaSensitiveWord列表
}
}
package service
import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
)
//@author: [piexlmax](https://github.com/piexlmax)
//@function: CreateExaSensitiveWord
//@description: 创建ExaSensitiveWord记录
//@param: exaSensitiveWord model.ExaSensitiveWord
//@return: err error
func CreateExaSensitiveWord(exaSensitiveWord model.ExaSensitiveWord) (err error) {
err = global.GVA_DB.Create(&exaSensitiveWord).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteExaSensitiveWord
//@description: 删除ExaSensitiveWord记录
//@param: exaSensitiveWord model.ExaSensitiveWord
//@return: err error
func DeleteExaSensitiveWord(exaSensitiveWord model.ExaSensitiveWord) (err error) {
err = global.GVA_DB.Delete(&exaSensitiveWord).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: DeleteExaSensitiveWordByIds
//@description: 批量删除ExaSensitiveWord记录
//@param: ids request.IdsReq
//@return: err error
func DeleteExaSensitiveWordByIds(ids request.IdsReq) (err error) {
err = global.GVA_DB.Delete(&[]model.ExaSensitiveWord{},"id in ?",ids.Ids).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: UpdateExaSensitiveWord
//@description: 更新ExaSensitiveWord记录
//@param: exaSensitiveWord *model.ExaSensitiveWord
//@return: err error
func UpdateExaSensitiveWord(exaSensitiveWord model.ExaSensitiveWord) (err error) {
err = global.GVA_DB.Save(&exaSensitiveWord).Error
return err
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetExaSensitiveWord
//@description: 根据id获取ExaSensitiveWord记录
//@param: id uint
//@return: err error, exaSensitiveWord model.ExaSensitiveWord
func GetExaSensitiveWord(id uint) (err error, exaSensitiveWord model.ExaSensitiveWord) {
err = global.GVA_DB.Where("id = ?", id).First(&exaSensitiveWord).Error
return
}
//@author: [piexlmax](https://github.com/piexlmax)
//@function: GetExaSensitiveWordInfoList
//@description: 分页获取ExaSensitiveWord记录
//@param: info request.ExaSensitiveWordSearch
//@return: err error, list interface{}, total int64
func GetExaSensitiveWordInfoList(info request.ExaSensitiveWordSearch) (err error, list interface{}, total int64) {
limit := info.PageSize
offset := info.PageSize * (info.Page - 1)
// 创建db
db := global.GVA_DB.Model(&model.ExaSensitiveWord{})
var exaSensitiveWords []model.ExaSensitiveWord
// 如果有条件搜索 下方会自动创建搜索语句
err = db.Count(&total).Error
err = db.Limit(limit).Offset(offset).Find(&exaSensitiveWords).Error
return err, exaSensitiveWords, total
}
\ No newline at end of file
......@@ -5,11 +5,13 @@ import (
"gin-vue-admin/global"
"gin-vue-admin/model"
"gin-vue-admin/model/request"
"strings"
"github.com/casbin/casbin/util"
"github.com/casbin/casbin/v2"
gormadapter "github.com/casbin/gorm-adapter/v3"
_ "github.com/go-sql-driver/mysql"
"strings"
"go.uber.org/zap"
)
//@author: [piexlmax](https://github.com/piexlmax)
......@@ -58,7 +60,6 @@ func UpdateCasbinApi(oldPath string, newPath string, oldMethod string, newMethod
//@param: authorityId string
//@return: pathMaps []request.CasbinInfo
func GetPolicyPathByAuthorityId(authorityId string) (pathMaps []request.CasbinInfo) {
e := Casbin()
list := e.GetFilteredPolicy(0, authorityId)
......@@ -91,7 +92,10 @@ func ClearCasbin(v int, p ...string) bool {
func Casbin() *casbin.Enforcer {
admin := global.GVA_CONFIG.Mysql
a, _ := gormadapter.NewAdapter(global.GVA_CONFIG.System.DbType, admin.Username+":"+admin.Password+"@("+admin.Path+")/"+admin.Dbname, true)
a, err := gormadapter.NewAdapter(global.GVA_CONFIG.System.DbType, admin.Username+":"+admin.Password+"@("+admin.Path+")/"+admin.Dbname, true)
if err != nil {
global.GVA_LOG.Error("create adapter fail:", zap.Any("error", err))
}
e, _ := casbin.NewEnforcer(global.GVA_CONFIG.Casbin.ModelPath, a)
e.AddFunction("ParamsMatch", ParamsMatchFunc)
_ = e.LoadPolicy()
......
......@@ -9,10 +9,11 @@ import (
"gin-vue-admin/model/request"
"gin-vue-admin/source"
"gin-vue-admin/utils"
"path/filepath"
"github.com/spf13/viper"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"path/filepath"
)
//@author: [songzhibin97](https://github.com/songzhibin97)
......@@ -140,6 +141,8 @@ func InitDB(conf request.InitDB) error {
model.ExaSimpleUploader{},
model.ExaCustomer{},
model.SysOperationRecord{},
model.ExaSensitiveWord{},
)
if err != nil {
return err
......
import service from '@/utils/request'
// @Tags ExaSensitiveWord
// @Summary 创建ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "创建ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /exaSensitiveWord/createExaSensitiveWord [post]
export const createExaSensitiveWord = (data) => {
return service({
url: "/exaSensitiveWord/createExaSensitiveWord",
method: 'post',
data
})
}
// @Tags ExaSensitiveWord
// @Summary 删除ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "删除ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /exaSensitiveWord/deleteExaSensitiveWord [delete]
export const deleteExaSensitiveWord = (data) => {
return service({
url: "/exaSensitiveWord/deleteExaSensitiveWord",
method: 'delete',
data
})
}
// @Tags ExaSensitiveWord
// @Summary 删除ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.IdsReq true "批量删除ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
// @Router /exaSensitiveWord/deleteExaSensitiveWord [delete]
export const deleteExaSensitiveWordByIds = (data) => {
return service({
url: "/exaSensitiveWord/deleteExaSensitiveWordByIds",
method: 'delete',
data
})
}
// @Tags ExaSensitiveWord
// @Summary 更新ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "更新ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"更新成功"}"
// @Router /exaSensitiveWord/updateExaSensitiveWord [put]
export const updateExaSensitiveWord = (data) => {
return service({
url: "/exaSensitiveWord/updateExaSensitiveWord",
method: 'put',
data
})
}
// @Tags ExaSensitiveWord
// @Summary 用id查询ExaSensitiveWord
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body model.ExaSensitiveWord true "用id查询ExaSensitiveWord"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
// @Router /exaSensitiveWord/findExaSensitiveWord [get]
export const findExaSensitiveWord = (params) => {
return service({
url: "/exaSensitiveWord/findExaSensitiveWord",
method: 'get',
params
})
}
// @Tags ExaSensitiveWord
// @Summary 分页获取ExaSensitiveWord列表
// @Security ApiKeyAuth
// @accept application/json
// @Produce application/json
// @Param data body request.PageInfo true "分页获取ExaSensitiveWord列表"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"获取成功"}"
// @Router /exaSensitiveWord/getExaSensitiveWordList [get]
export const getExaSensitiveWordList = (params) => {
return service({
url: "/exaSensitiveWord/getExaSensitiveWordList",
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>
<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-item>
<el-popover placement="top" v-model="deleteVisible" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button @click="deleteVisible = false" size="mini" type="text"
>取消</el-button
>
<el-button @click="onDelete" size="mini" type="primary"
>确定</el-button
>
</div>
<el-button
icon="el-icon-delete"
size="mini"
slot="reference"
type="danger"
>批量删除</el-button
>
</el-popover>
</el-form-item>
</el-form>
</div>
<el-table
:data="tableData"
@selection-change="handleSelectionChange"
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="word字段"
prop="word"
width="120"
></el-table-column>
<el-table-column label="按钮组">
<template slot-scope="scope">
<el-button
class="table-button"
@click="updateExaSensitiveWord(scope.row)"
size="small"
type="primary"
icon="el-icon-edit"
>变更</el-button
>
<el-button
type="danger"
icon="el-icon-delete"
size="mini"
@click="deleteRow(scope.row)"
>删除</el-button
>
</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="弹窗操作"
>
<el-form :model="formData" label-position="right" label-width="80px">
<el-form-item label="word字段:">
<el-input
v-model="formData.word"
clearable
placeholder="请输入"
></el-input>
</el-form-item>
</el-form>
<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 {
createExaSensitiveWord,
deleteExaSensitiveWord,
deleteExaSensitiveWordByIds,
updateExaSensitiveWord,
findExaSensitiveWord,
getExaSensitiveWordList,
} from "@/api/exa_sensitive_word"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
export default {
name: "ExaSensitiveWord",
mixins: [infoList],
data() {
return {
listApi: getExaSensitiveWordList,
dialogFormVisible: false,
type: "",
deleteVisible: false,
multipleSelection: [],
formData: {
word: "",
},
};
},
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();
},
handleSelectionChange(val) {
this.multipleSelection = val;
},
deleteRow(row) {
this.$confirm("确定要删除吗?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(() => {
this.deleteExaSensitiveWord(row);
});
},
async onDelete() {
const ids = [];
if (this.multipleSelection.length == 0) {
this.$message({
type: "warning",
message: "请选择要删除的数据",
});
return;
}
this.multipleSelection &&
this.multipleSelection.map((item) => {
ids.push(item.ID);
});
const res = await deleteExaSensitiveWordByIds({ ids });
if (res.code == 0) {
this.$message({
type: "success",
message: "删除成功",
});
if (this.tableData.length == ids.length) {
this.page--;
}
this.deleteVisible = false;
this.getTableData();
}
},
async updateExaSensitiveWord(row) {
const res = await findExaSensitiveWord({ ID: row.ID });
this.type = "update";
if (res.code == 0) {
this.formData = res.data.reexaSensitiveWord;
this.dialogFormVisible = true;
}
},
closeDialog() {
this.dialogFormVisible = false;
this.formData = {
word: "",
};
},
async deleteExaSensitiveWord(row) {
const res = await deleteExaSensitiveWord({ ID: row.ID });
if (res.code == 0) {
this.$message({
type: "success",
message: "删除成功",
});
if (this.tableData.length == 1) {
this.page--;
}
this.getTableData();
}
},
async enterDialog() {
let res;
switch (this.type) {
case "create":
res = await createExaSensitiveWord(this.formData);
break;
case "update":
res = await updateExaSensitiveWord(this.formData);
break;
default:
res = await createExaSensitiveWord(this.formData);
break;
}
if (res.code == 0) {
this.$message({
type: "success",
message: "创建/更改成功",
});
this.closeDialog();
this.getTableData();
}
},
openDialog() {
this.type = "create";
this.dialogFormVisible = true;
},
},
async created() {
await this.getTableData();
},
};
</script>
<style>
</style>
<template>
<div>
<el-form :model="formData" label-position="right" label-width="80px">
<el-form-item label="word字段:">
<el-input v-model="formData.word" clearable placeholder="请输入" ></el-input>
</el-form-item>
<el-form-item>
<el-button @click="save" type="primary">保存</el-button>
<el-button @click="back" type="primary">返回</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import {
createExaSensitiveWord,
updateExaSensitiveWord,
findExaSensitiveWord
} from "@/api/exa_sensitive_word"; // 此处请自行替换地址
import infoList from "@/mixins/infoList";
export default {
name: "ExaSensitiveWord",
mixins: [infoList],
data() {
return {
type: "",formData: {
word:"",
}
};
},
methods: {
async save() {
let res;
switch (this.type) {
case "create":
res = await createExaSensitiveWord(this.formData);
break;
case "update":
res = await updateExaSensitiveWord(this.formData);
break;
default:
res = await createExaSensitiveWord(this.formData);
break;
}
if (res.code == 0) {
this.$message({
type:"success",
message:"创建/更改成功"
})
}
},
back(){
this.$router.go(-1)
}
},
async created() {
// 建议通过url传参获取目标数据ID 调用 find方法进行查询数据操作 从而决定本页面是create还是update 以下为id作为url参数示例
if(this.$route.query.id){
const res = await findExaSensitiveWord({ ID: this.$route.query.id })
if(res.code == 0){
this.formData = res.data.reexaSensitiveWord
this.type = "update"
}
}else{
this.type = "create"
}
}
};
</script>
<style>
</style>
\ No newline at end of file
<template>
<div>
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
</div>
</template>
<script>
export default {
name: "Misc",
};
</script>
<style lang="scss"></style>
......@@ -3,13 +3,19 @@
<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-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-input
placeholder="搜索条件"
v-model="searchInfo.status"
></el-input>
</el-form-item>
<el-form-item>
<el-button @click="onSubmit" type="primary">查询</el-button>
......@@ -18,10 +24,20 @@
<el-popover placement="top" v-model="deleteVisible" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button @click="deleteVisible = false" size="mini" type="text">取消</el-button>
<el-button @click="onDelete" size="mini" type="primary">确定</el-button>
<el-button @click="deleteVisible = false" size="mini" type="text"
>取消</el-button
>
<el-button @click="onDelete" size="mini" type="primary"
>确定</el-button
>
</div>
<el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">批量删除</el-button>
<el-button
icon="el-icon-delete"
size="mini"
slot="reference"
type="danger"
>批量删除</el-button
>
</el-popover>
</el-form-item>
</el-form>
......@@ -38,11 +54,15 @@
<el-table-column type="selection" width="55"></el-table-column>
<el-table-column label="操作人" width="140">
<template slot-scope="scope">
<div>{{scope.row.user.userName}}({{scope.row.user.nickName}})</div>
<div>
{{ scope.row.user.userName }}({{ scope.row.user.nickName }})
</div>
</template>
</el-table-column>
<el-table-column label="日期" width="180">
<template slot-scope="scope">{{scope.row.CreatedAt|formatDate}}</template>
<template slot-scope="scope">{{
scope.row.CreatedAt | formatDate
}}</template>
</el-table-column>
<el-table-column label="状态码" prop="status" width="120">
<template slot-scope="scope">
......@@ -52,16 +72,32 @@
</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="240"></el-table-column>
<el-table-column
label="请求方法"
prop="method"
width="120"
></el-table-column>
<el-table-column
label="请求路径"
prop="path"
width="240"
></el-table-column>
<el-table-column label="请求" prop="path" width="80">
<template slot-scope="scope">
<div>
<el-popover placement="top-start" trigger="hover" v-if="scope.row.body">
<el-popover
placement="top-start"
trigger="hover"
v-if="scope.row.body"
>
<div class="popover-box">
<pre>{{fmtBody(scope.row.body)}}</pre>
<pre>{{ fmtBody(scope.row.body) }}</pre>
</div>
<i class="el-icon-view" slot="reference"></i>
<i
class="el-icon-view"
style="cursor: pointer"
slot="reference"
></i>
</el-popover>
<span v-else></span>
......@@ -71,11 +107,19 @@
<el-table-column label="响应" prop="path" width="80">
<template slot-scope="scope">
<div>
<el-popover placement="top-start" trigger="hover" v-if="scope.row.resp">
<el-popover
placement="top-start"
trigger="hover"
v-if="scope.row.resp"
>
<div class="popover-box">
<pre>{{fmtBody(scope.row.resp)}}</pre>
<pre>{{ fmtBody(scope.row.resp) }}</pre>
</div>
<i class="el-icon-view" slot="reference"></i>
<i
class="el-icon-view"
style="cursor: pointer"
slot="reference"
></i>
</el-popover>
<span v-else></span>
</div>
......@@ -86,10 +130,26 @@
<el-popover placement="top" v-model="scope.row.visible" width="160">
<p>确定要删除吗?</p>
<div style="text-align: right; margin: 0">
<el-button @click="scope.row.visible = false" size="mini" type="text">取消</el-button>
<el-button @click="deleteSysOperationRecord(scope.row)" size="mini" type="primary">确定</el-button>
<el-button
@click="scope.row.visible = false"
size="mini"
type="text"
>取消</el-button
>
<el-button
@click="deleteSysOperationRecord(scope.row)"
size="mini"
type="primary"
>确定</el-button
>
</div>
<el-button icon="el-icon-delete" size="mini" slot="reference" type="danger">删除</el-button>
<el-button
icon="el-icon-delete"
size="mini"
slot="reference"
type="danger"
>删除</el-button
>
</el-popover>
</template>
</el-table-column>
......@@ -98,7 +158,7 @@
:current-page="page"
:page-size="pageSize"
:page-sizes="[10, 30, 50, 100]"
:style="{float:'right',padding:'20px'}"
:style="{ float: 'right', padding: '20px' }"
:total="total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
......@@ -111,7 +171,7 @@
import {
deleteSysOperationRecord,
getSysOperationRecordList,
deleteSysOperationRecordByIds
deleteSysOperationRecordByIds,
} from "@/api/sysOperationRecord"; // 此处请自行替换地址
import { formatTimeToStr } from "@/utils/date";
import infoList from "@/mixins/infoList";
......@@ -134,12 +194,12 @@ export default {
latency: null,
agent: null,
error_message: null,
user_id: null
}
user_id: null,
},
};
},
filters: {
formatDate: function(time) {
formatDate: function (time) {
if (time != null && time != "") {
var date = new Date(time);
return formatTimeToStr(date, "yyyy-MM-dd hh:mm:ss");
......@@ -147,13 +207,13 @@ export default {
return "";
}
},
formatBoolean: function(bool) {
formatBoolean: function (bool) {
if (bool != null) {
return bool ? "" : "";
} else {
return "";
}
}
},
},
methods: {
//条件搜索前端看此方法
......@@ -168,14 +228,14 @@ export default {
async onDelete() {
const ids = [];
this.multipleSelection &&
this.multipleSelection.map(item => {
this.multipleSelection.map((item) => {
ids.push(item.ID);
});
const res = await deleteSysOperationRecordByIds({ ids });
if (res.code == 0) {
this.$message({
type: "success",
message: "删除成功"
message: "删除成功",
});
if (this.tableData.length == ids.length) {
this.page--;
......@@ -190,7 +250,7 @@ export default {
if (res.code == 0) {
this.$message({
type: "success",
message: "删除成功"
message: "删除成功",
});
if (this.tableData.length == 1) {
this.page--;
......@@ -204,11 +264,11 @@ export default {
} catch (err) {
return value;
}
}
},
},
created() {
this.getTableData();
}
},
};
</script>
......@@ -229,8 +289,8 @@ export default {
.popover-box {
background: #112435;
color: #f08047;
height: 600px;
width: 420px;
max-width: 420px;
max-height: 600px;
overflow: auto;
}
.popover-box::-webkit-scrollbar {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册