完善错误监控详情

This commit is contained in:
xiangheng
2024-10-14 11:36:58 +08:00
parent 69b7407ab1
commit a0dac7f75b
9 changed files with 127 additions and 104 deletions

View File

@@ -18,7 +18,6 @@ export type type_monitor_client = {
Height?: number Height?: number
Ua?: string Ua?: string
CreateTime?: string CreateTime?: string
ClientTime?: string
} }
// 查询 // 查询
export type type_monitor_client_query = { export type type_monitor_client_query = {
@@ -48,16 +47,21 @@ export type type_monitor_client_edit = {
Width?: number Width?: number
Height?: number Height?: number
Ua?: string Ua?: string
ClientTime?: string
} }
// 监控-客户端信息列表 // 监控-客户端信息列表
export function monitor_client_list(params?: type_monitor_client_query) { export function monitor_client_list(params?: type_monitor_client_query) {
return request.get<Pages<type_monitor_client>>({ url: '/monitor_client/list', params: clearEmpty(params) }) return request.get<Pages<type_monitor_client>>({
url: '/monitor_client/list',
params: clearEmpty(params)
})
} }
// 监控-客户端信息列表-所有 // 监控-客户端信息列表-所有
export function monitor_client_list_all(params?: type_monitor_client_query) { export function monitor_client_list_all(params?: type_monitor_client_query) {
return request.get<type_monitor_client[]>({ url: '/monitor_client/listAll', params: clearEmpty(params) }) return request.get<type_monitor_client[]>({
url: '/monitor_client/listAll',
params: clearEmpty(params)
})
} }
// 监控-客户端信息详情 // 监控-客户端信息详情
@@ -65,6 +69,10 @@ export function monitor_client_detail(Id: number | string) {
return request.get<type_monitor_client>({ url: '/monitor_client/detail', params: { Id } }) return request.get<type_monitor_client>({ url: '/monitor_client/detail', params: { Id } })
} }
export function monitor_client_errorUsers(Id: number | string) {
return request.get<type_monitor_client[]>({ url: '/monitor_client/errorUsers', params: { Id } })
}
// 监控-客户端信息新增 // 监控-客户端信息新增
export function monitor_client_add(data: type_monitor_client_edit) { export function monitor_client_add(data: type_monitor_client_edit) {
return request.post<null>({ url: '/monitor_client/add', data }) return request.post<null>({ url: '/monitor_client/add', data })
@@ -89,5 +97,7 @@ export const monitor_client_import_file = '/monitor_client/ImportFile'
// 监控-客户端信息导出 // 监控-客户端信息导出
export function monitor_client_export_file(params: any) { export function monitor_client_export_file(params: any) {
return (window.location.href =`${config.baseUrl}${config.urlPrefix}/monitor_client/ExportFile?token=${getToken()}&` + queryString.stringify(clearEmpty(params))) return (window.location.href =
`${config.baseUrl}${config.urlPrefix}/monitor_client/ExportFile?token=${getToken()}&` +
queryString.stringify(clearEmpty(params)))
} }

View File

@@ -126,16 +126,16 @@
<el-table-column label="ua记录" prop="Ua" min-width="130" /> <el-table-column label="ua记录" prop="Ua" min-width="130" />
<el-table-column label="创建时间" prop="CreateTime" min-width="130" /> <el-table-column label="创建时间" prop="CreateTime" min-width="130" />
<el-table-column label="操作" width="120" fixed="right"> <el-table-column label="操作" width="80" fixed="right">
<template #default="{ row }"> <template #default="{ row }">
<el-button <!-- <el-button
v-perms="['admin:monitor_client:edit']" v-perms="['admin:monitor_client:edit']"
type="primary" type="primary"
link link
@click="handleEdit(row)" @click="handleEdit(row)"
> >
编辑 编辑
</el-button> </el-button> -->
<el-button <el-button
v-perms="['admin:monitor_client:del']" v-perms="['admin:monitor_client:del']"
type="danger" type="danger"

View File

@@ -52,9 +52,40 @@
</div> </div>
</template> </template>
<el-scrollbar height="400px"> <el-scrollbar height="400px">
<p v-for="item in 120" :key="item" class="scrollbar-demo-item"> <el-collapse v-model="activeNames">
{{ item }} <el-collapse-item
</p> v-for="(user, index) in users"
:key="user.Id"
:title="user.CreateTime"
:name="index"
>
<template #title>
<div class="flex-1 text-left">
{{ user.UserId }}
</div>
<span class="">
{{ user.CreateTime }}
</span>
</template>
<el-descriptions border>
<el-descriptions-item label="城市:">{{
user.City
}}</el-descriptions-item>
<el-descriptions-item label="OS">{{
user.Os
}}</el-descriptions-item>
<el-descriptions-item label="屏幕尺寸:">
<el-tag size="small"
>{{ user.Width }}*{{ user.Height }}</el-tag
>
</el-descriptions-item>
<el-descriptions-item label="userAgent">
{{ user.Ua }}
</el-descriptions-item>
</el-descriptions>
</el-collapse-item>
</el-collapse>
</el-scrollbar> </el-scrollbar>
</el-card> </el-card>
</el-col> </el-col>
@@ -65,6 +96,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import type { FormInstance } from 'element-plus' import type { FormInstance } from 'element-plus'
import { monitor_error_add, monitor_error_detail } from '@/api/monitor/error' import { monitor_error_add, monitor_error_detail } from '@/api/monitor/error'
import { monitor_client_errorUsers } from '@/api/monitor/client'
import type { type_monitor_client } from '@/api/monitor/client'
import Popup from '@/components/popup/index.vue' import Popup from '@/components/popup/index.vue'
import feedback from '@/utils/feedback' import feedback from '@/utils/feedback'
import type { PropType } from 'vue' import type { PropType } from 'vue'
@@ -86,6 +120,8 @@ const popupTitle = computed(() => {
return '监控详情' return '监控详情'
}) })
const activeNames = ref<string[]>(['1'])
const formData = reactive({ const formData = reactive({
Id: null, Id: null,
ProjectKey: null, ProjectKey: null,
@@ -97,6 +133,7 @@ const formData = reactive({
Md5: null, Md5: null,
ClientTime: null ClientTime: null
}) })
const users = ref<type_monitor_client[]>([])
const handleSubmit = async () => { const handleSubmit = async () => {
try { try {
@@ -126,6 +163,10 @@ const setFormData = async (data: Record<string, any>) => {
const getDetail = async (row: Record<string, any>) => { const getDetail = async (row: Record<string, any>) => {
try { try {
const data = await monitor_error_detail(row.Id) const data = await monitor_error_detail(row.Id)
users.value = await monitor_client_errorUsers(row.Id)
console.log('user', users.value)
setFormData(data) setFormData(data)
} catch (error) {} } catch (error) {}
} }

View File

@@ -76,6 +76,15 @@ func (hd *MonitorClientHandler) ListAll(c *gin.Context) {
response.CheckAndRespWithData(c, res, err) response.CheckAndRespWithData(c, res, err)
} }
func (hd *MonitorClientHandler) ErrorUsers(c *gin.Context) {
var Req MonitorClientDetailReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &Req)) {
return
}
res, err := MonitorClientService.ErrorUsers(Req.Id)
response.CheckAndRespWithData(c, res, err)
}
// @Summary 监控-客户端信息详情 // @Summary 监控-客户端信息详情
// @Tags monitor_client-监控-客户端信息 // @Tags monitor_client-监控-客户端信息
// @Produce json // @Produce json
@@ -136,13 +145,13 @@ func (hd *MonitorClientHandler) Add(c *gin.Context) {
// @Param Ua body string false "ua记录" // @Param Ua body string false "ua记录"
// @Success 200 {object} response.Response "成功" // @Success 200 {object} response.Response "成功"
// @Router /api/admin/monitor_client/edit [post] // @Router /api/admin/monitor_client/edit [post]
func (hd *MonitorClientHandler) Edit(c *gin.Context) { // func (hd *MonitorClientHandler) Edit(c *gin.Context) {
var editReq MonitorClientEditReq // var editReq MonitorClientEditReq
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) { // if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
return // return
} // }
response.CheckAndRespWithData(c, editReq.Id, MonitorClientService.Edit(editReq)) // response.CheckAndRespWithData(c, editReq.Id, MonitorClientService.Edit(editReq))
} // }
// @Summary 监控-客户端信息删除 // @Summary 监控-客户端信息删除
// @Tags monitor_client-监控-客户端信息 // @Tags monitor_client-监控-客户端信息

View File

@@ -160,6 +160,23 @@ func (service monitorClientService) Detail(Id int) (res MonitorClientResp, e err
return return
} }
// ErrorUser 监控-客户端信息详情
func (service monitorClientService) ErrorUsers(error_id int) (res []MonitorClientResp, e error) {
var obj = []model.MonitorClient{}
service.db.Raw("SELECT client.* from x_monitor_error_list as list left join x_monitor_client as client on client.client_id = list.client_id where list.error_id = ? Order by list.id DESC", error_id).Scan(&obj)
// if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
// return
// }
// if e = response.CheckErr(err, "获取失败"); e != nil {
// return
// }
// cacheUtil.SetCache(obj.Id, obj)
util.ConvertUtil.Copy(&res, obj)
return
}
// Add 监控-客户端信息新增 // Add 监控-客户端信息新增
func (service monitorClientService) Add(addReq MonitorClientAddReq) (createId int, e error) { func (service monitorClientService) Add(addReq MonitorClientAddReq) (createId int, e error) {
var obj model.MonitorClient var obj model.MonitorClient
@@ -174,27 +191,27 @@ func (service monitorClientService) Add(addReq MonitorClientAddReq) (createId in
return return
} }
// Edit 监控-客户端信息编辑 // // Edit 监控-客户端信息编辑
func (service monitorClientService) Edit(editReq MonitorClientEditReq) (e error) { // func (service monitorClientService) Edit(editReq MonitorClientEditReq) (e error) {
var obj model.MonitorClient // var obj model.MonitorClient
err := service.db.Where("id = ?", editReq.Id).Limit(1).First(&obj).Error // err := service.db.Where("id = ?", editReq.Id).Limit(1).First(&obj).Error
// 校验 // // 校验
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil { // if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
return // return
} // }
if e = response.CheckErr(err, "查询失败"); e != nil { // if e = response.CheckErr(err, "查询失败"); e != nil {
return // return
} // }
util.ConvertUtil.Copy(&obj, editReq) // util.ConvertUtil.Copy(&obj, editReq)
err = service.db.Model(&obj).Select("*").Updates(obj).Error // err = service.db.Model(&obj).Select("*").Updates(obj).Error
if e = response.CheckErr(err, "编辑失败"); e != nil { // if e = response.CheckErr(err, "编辑失败"); e != nil {
return // return
} // }
cacheUtil.RemoveCache(obj.Id) // cacheUtil.RemoveCache(obj.Id)
service.Detail(obj.Id) // service.Detail(obj.Id)
return // return
} // }
// Del 监控-客户端信息删除 // Del 监控-客户端信息删除
func (service monitorClientService) Del(Id int) (e error) { func (service monitorClientService) Del(Id int) (e error) {

View File

@@ -202,6 +202,7 @@ func CheckMysqlErr(err error) (e error) {
default: default:
// 处理其他错误 // 处理其他错误
core.Logger.WithOptions(zap.AddCallerSkip(1)).Errorf("未知错误: err=[%+v]", err) core.Logger.WithOptions(zap.AddCallerSkip(1)).Errorf("未知错误: err=[%+v]", err)
return err
} }
} }
return return

View File

@@ -17,5 +17,5 @@ type MonitorClient struct {
Height core.NullInt `gorm:"comment:'屏幕高度'"` // 屏幕高度 Height core.NullInt `gorm:"comment:'屏幕高度'"` // 屏幕高度
Ua string `gorm:"comment:'ua记录'"` // ua记录 Ua string `gorm:"comment:'ua记录'"` // ua记录
CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间 CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间
ClientTime core.NullTime `gorm:"comment:'更新时间'"` // 更新时间 // ClientTime core.NullTime `gorm:"comment:'更新时间'"` // 更新时间
} }

View File

@@ -1,9 +1,10 @@
package admin package admin
import ( import (
"github.com/gin-gonic/gin"
"x_admin/middleware"
"x_admin/admin/monitor_client" "x_admin/admin/monitor_client"
"x_admin/middleware"
"github.com/gin-gonic/gin"
) )
/** /**
@@ -41,7 +42,6 @@ INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_sh
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '监控-客户端信息导入excel','admin:monitor_client:ImportFile', 0, 1, 0, now(), now()); INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '监控-客户端信息导入excel','admin:monitor_client:ImportFile', 0, 1, 0, now(), now());
*/ */
// MonitorClientRoute(rg) // MonitorClientRoute(rg)
func MonitorClientRoute(rg *gin.RouterGroup) { func MonitorClientRoute(rg *gin.RouterGroup) {
handle := monitor_client.MonitorClientHandler{} handle := monitor_client.MonitorClientHandler{}
@@ -50,9 +50,10 @@ func MonitorClientRoute(rg *gin.RouterGroup) {
r.GET("/monitor_client/list", handle.List) r.GET("/monitor_client/list", handle.List)
r.GET("/monitor_client/listAll", handle.ListAll) r.GET("/monitor_client/listAll", handle.ListAll)
r.GET("/monitor_client/detail", handle.Detail) r.GET("/monitor_client/detail", handle.Detail)
r.GET("/monitor_client/errorUsers", handle.ErrorUsers)
r.POST("/monitor_client/add",middleware.RecordLog("监控-客户端信息新增"), handle.Add) r.POST("/monitor_client/add", middleware.RecordLog("监控-客户端信息新增"), handle.Add)
r.POST("/monitor_client/edit",middleware.RecordLog("监控-客户端信息编辑"), handle.Edit) // r.POST("/monitor_client/edit",middleware.RecordLog("监控-客户端信息编辑"), handle.Edit)
r.POST("/monitor_client/del", middleware.RecordLog("监控-客户端信息删除"), handle.Del) r.POST("/monitor_client/del", middleware.RecordLog("监控-客户端信息删除"), handle.Del)
r.POST("/monitor_client/delBatch", middleware.RecordLog("监控-客户端信息删除-批量"), handle.DelBatch) r.POST("/monitor_client/delBatch", middleware.RecordLog("监控-客户端信息删除-批量"), handle.DelBatch)

View File

@@ -1,56 +0,0 @@
package admin
import (
"github.com/gin-gonic/gin"
"x_admin/middleware"
"x_admin/admin/user_protocol"
)
/**
集成
1. 导入
- 请先提交git避免文件覆盖!!!
- 下载并解压压缩包后直接复制server、admin文件夹到项目根目录即可
2. 注册路由
请在 router/admin/entry.go 文件引入 UserProtocolRoute 注册路由
3. 后台手动添加菜单和按钮
admin:user_protocol:add
admin:user_protocol:edit
admin:user_protocol:del
admin:user_protocol:list
admin:user_protocol:listAll
admin:user_protocol:detail
admin:user_protocol:ExportFile
admin:user_protocol:ImportFile
// 列表-先添加菜单获取菜单id
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, paths, component, is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'C', '用户协议', 'user/protocol/index', 'user/protocol/index', 0, 1, 0, now(), now());
按钮-替换pid参数为菜单id
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议添加','admin:user_protocol:add', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议编辑','admin:user_protocol:edit', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议删除','admin:user_protocol:del', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议列表','admin:user_protocol:list', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议全部列表','admin:user_protocol:listAll', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议详情','admin:user_protocol:detail', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议导出excel','admin:user_protocol:ExportFile', 0, 1, 0, now(), now());
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) VALUES (0, 'A', '用户协议导入excel','admin:user_protocol:ImportFile', 0, 1, 0, now(), now());
*/
// UserProtocolRoute(rg)
func UserProtocolRoute(rg *gin.RouterGroup) {
handle := user_protocol.UserProtocolHandler{}
r := rg.Group("/", middleware.TokenAuth())
r.GET("/user_protocol/list", handle.List)
r.GET("/user_protocol/listAll", handle.ListAll)
r.GET("/user_protocol/detail", handle.Detail)
r.POST("/user_protocol/add",middleware.RecordLog("用户协议新增"), handle.Add)
r.POST("/user_protocol/edit",middleware.RecordLog("用户协议编辑"), handle.Edit)
r.POST("/user_protocol/del", middleware.RecordLog("用户协议删除"), handle.Del)
r.GET("/user_protocol/ExportFile", middleware.RecordLog("用户协议导出"), handle.ExportFile)
r.POST("/user_protocol/ImportFile", handle.ImportFile)
}