mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-09-27 04:26:24 +08:00
慢接口
This commit is contained in:
77
admin/src/api/monitor/slow.ts
Normal file
77
admin/src/api/monitor/slow.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
import type { Pages } from '@/utils/request'
|
||||||
|
|
||||||
|
import config from '@/config'
|
||||||
|
import queryString from 'query-string'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
|
import { clearEmpty } from '@/utils/util'
|
||||||
|
|
||||||
|
export type type_monitor_slow = {
|
||||||
|
Id?: number
|
||||||
|
ProjectKey?: string
|
||||||
|
ClientId?: string
|
||||||
|
UserId?: string
|
||||||
|
Path?: string
|
||||||
|
Time?: number
|
||||||
|
CreateTime?: string
|
||||||
|
}
|
||||||
|
// 查询
|
||||||
|
export type type_monitor_slow_query = {
|
||||||
|
ProjectKey?: string
|
||||||
|
ClientId?: string
|
||||||
|
UserId?: string
|
||||||
|
Path?: string
|
||||||
|
Time?: number
|
||||||
|
CreateTimeStart?: string
|
||||||
|
CreateTimeEnd?: string
|
||||||
|
}
|
||||||
|
// 添加编辑
|
||||||
|
export type type_monitor_slow_edit = {
|
||||||
|
Id?: number
|
||||||
|
ProjectKey?: string
|
||||||
|
ClientId?: string
|
||||||
|
UserId?: string
|
||||||
|
Path?: string
|
||||||
|
Time?: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列列表
|
||||||
|
export function monitor_slow_list(params?: type_monitor_slow_query) {
|
||||||
|
return request.get<Pages<type_monitor_slow>>({ url: '/monitor_slow/list', params: clearEmpty(params) })
|
||||||
|
}
|
||||||
|
// 监控-错误列列表-所有
|
||||||
|
export function monitor_slow_list_all(params?: type_monitor_slow_query) {
|
||||||
|
return request.get<type_monitor_slow[]>({ url: '/monitor_slow/listAll', params: clearEmpty(params) })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列详情
|
||||||
|
export function monitor_slow_detail(Id: number | string) {
|
||||||
|
return request.get<type_monitor_slow>({ url: '/monitor_slow/detail', params: { Id } })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列新增
|
||||||
|
export function monitor_slow_add(data: type_monitor_slow_edit) {
|
||||||
|
return request.post<null>({ url: '/monitor_slow/add', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列编辑
|
||||||
|
export function monitor_slow_edit(data: type_monitor_slow_edit) {
|
||||||
|
return request.post<null>({ url: '/monitor_slow/edit', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列删除
|
||||||
|
export function monitor_slow_delete(Id: number | string) {
|
||||||
|
return request.post<null>({ url: '/monitor_slow/del', data: { Id } })
|
||||||
|
}
|
||||||
|
// 监控-错误列删除-批量
|
||||||
|
export function monitor_slow_delete_batch(data: { Ids: string }) {
|
||||||
|
return request.post<null>({ url: '/monitor_slow/delBatch', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监控-错误列导入
|
||||||
|
export const monitor_slow_import_file = '/monitor_slow/ImportFile'
|
||||||
|
|
||||||
|
// 监控-错误列导出
|
||||||
|
export function monitor_slow_export_file(params: any) {
|
||||||
|
return (window.location.href =`${config.baseUrl}${config.urlPrefix}/monitor_slow/ExportFile?token=${getToken()}&` + queryString.stringify(clearEmpty(params)))
|
||||||
|
}
|
@@ -13,16 +13,17 @@ import VForm3 from 'vform3-builds' //引入VForm3库
|
|||||||
|
|
||||||
import { XErr, XErrWeb } from '../../x_err_sdk/web/index'
|
import { XErr, XErrWeb } from '../../x_err_sdk/web/index'
|
||||||
// { XErr, XErrWeb }
|
// { XErr, XErrWeb }
|
||||||
new XErr(
|
const xErr = new XErr(
|
||||||
{
|
{
|
||||||
Dns: 'http://localhost:5174/api',
|
Dns: `${location.origin}/api`,
|
||||||
Pid: 'e19e3be20de94f49b68fafb4c30668bc',
|
Pid: 'e19e3be20de94f49b68fafb4c30668bc',
|
||||||
Uid: '10'
|
Uid: ''
|
||||||
},
|
},
|
||||||
new XErrWeb({
|
new XErrWeb({
|
||||||
onloadTimeOut: 3000
|
onloadTimeOut: 3000
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
xErr.SetUid(1) //设置用户ID
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
app.use(install)
|
app.use(install)
|
||||||
|
@@ -66,7 +66,7 @@
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="事件类型" prop="EventType" width="100" />
|
<el-table-column label="事件类型" prop="EventType" width="130" />
|
||||||
<el-table-column label="URL地址" prop="Path" min-width="130" />
|
<el-table-column label="URL地址" prop="Path" min-width="130" />
|
||||||
<el-table-column label="错误消息" prop="Message" min-width="130" />
|
<el-table-column label="错误消息" prop="Message" min-width="130" />
|
||||||
|
|
||||||
|
158
admin/src/views/monitor/slow/edit.vue
Normal file
158
admin/src/views/monitor/slow/edit.vue
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
<template>
|
||||||
|
<div class="edit-popup">
|
||||||
|
<popup
|
||||||
|
ref="popupRef"
|
||||||
|
:title="popupTitle"
|
||||||
|
:async="true"
|
||||||
|
width="550px"
|
||||||
|
:clickModalClose="true"
|
||||||
|
@confirm="handleSubmit"
|
||||||
|
@close="handleClose"
|
||||||
|
>
|
||||||
|
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||||
|
<el-form-item label="项目key" prop="ProjectKey">
|
||||||
|
<el-input v-model="formData.ProjectKey" placeholder="请输入项目key" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="sdk生成的客户端id" prop="ClientId">
|
||||||
|
<el-input v-model="formData.ClientId" placeholder="请输入sdk生成的客户端id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户id" prop="UserId">
|
||||||
|
<el-input v-model="formData.UserId" placeholder="请输入用户id" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="URL地址" prop="Path">
|
||||||
|
<el-input
|
||||||
|
v-model="formData.Path"
|
||||||
|
placeholder="请输入URL地址"
|
||||||
|
type="textarea"
|
||||||
|
:autosize="{ minRows: 4, maxRows: 6 }"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="时间" prop="Time">
|
||||||
|
<el-input v-model="formData.Time" type="number" placeholder="请输入时间" />
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
</el-form>
|
||||||
|
</popup>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import type { FormInstance } from 'element-plus'
|
||||||
|
import { monitor_slow_edit, monitor_slow_add, monitor_slow_detail } from '@/api/monitor/slow'
|
||||||
|
import Popup from '@/components/popup/index.vue'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
import { ref, shallowRef, computed, reactive } from 'vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
defineProps({
|
||||||
|
dictData: {
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
},
|
||||||
|
listAllData:{
|
||||||
|
type: Object as PropType<Record<string, any[]>>,
|
||||||
|
default: () => ({})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['success', 'close'])
|
||||||
|
const formRef = shallowRef<FormInstance>()
|
||||||
|
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||||
|
const mode = ref('add')
|
||||||
|
const popupTitle = computed(() => {
|
||||||
|
return mode.value == 'edit' ? '编辑监控-错误列' : '新增监控-错误列'
|
||||||
|
})
|
||||||
|
|
||||||
|
const formData = reactive({
|
||||||
|
Id: null,
|
||||||
|
ProjectKey: null,
|
||||||
|
ClientId: null,
|
||||||
|
UserId: null,
|
||||||
|
Path: null,
|
||||||
|
Time: null,
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRules = {
|
||||||
|
Id: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入错误id',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
ProjectKey: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入项目key',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
ClientId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入sdk生成的客户端id',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
UserId: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入用户id',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Path: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入URL地址',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
Time: [
|
||||||
|
{
|
||||||
|
required: true,
|
||||||
|
message: '请输入时间',
|
||||||
|
trigger: ['blur']
|
||||||
|
}
|
||||||
|
],
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
try {
|
||||||
|
await formRef.value?.validate()
|
||||||
|
const data: any = { ...formData }
|
||||||
|
mode.value == 'edit' ? await monitor_slow_edit(data) : await monitor_slow_add(data)
|
||||||
|
popupRef.value?.close()
|
||||||
|
feedback.msgSuccess('操作成功')
|
||||||
|
emit('success')
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const open = (type = 'add') => {
|
||||||
|
mode.value = type
|
||||||
|
popupRef.value?.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
const setFormData = async (data: Record<string, any>) => {
|
||||||
|
for (const key in formData) {
|
||||||
|
if (data[key] != null && data[key] != undefined) {
|
||||||
|
//@ts-ignore
|
||||||
|
formData[key] = data[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getDetail = async (row: Record<string, any>) => {
|
||||||
|
try {
|
||||||
|
const data = await monitor_slow_detail(row.Id)
|
||||||
|
setFormData(data)
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
emit('close')
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({
|
||||||
|
open,
|
||||||
|
setFormData,
|
||||||
|
getDetail
|
||||||
|
})
|
||||||
|
</script>
|
201
admin/src/views/monitor/slow/index.vue
Normal file
201
admin/src/views/monitor/slow/index.vue
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<div class="index-lists">
|
||||||
|
<el-card class="!border-none" shadow="never">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
class="mb-[-16px]"
|
||||||
|
:model="queryParams"
|
||||||
|
:inline="true"
|
||||||
|
label-width="70px"
|
||||||
|
label-position="left"
|
||||||
|
>
|
||||||
|
<el-form-item label="项目key" prop="ProjectKey" class="w-[280px]">
|
||||||
|
<el-input v-model="queryParams.ProjectKey" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="sdk生成的客户端id" prop="ClientId" class="w-[280px]">
|
||||||
|
<el-input v-model="queryParams.ClientId" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户id" prop="UserId" class="w-[280px]">
|
||||||
|
<el-input v-model="queryParams.UserId" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="CreateTime" class="w-[280px]">
|
||||||
|
<daterange-picker
|
||||||
|
v-model:startTime="queryParams.CreateTimeStart"
|
||||||
|
v-model:endTime="queryParams.CreateTimeEnd"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
|
<el-button @click="resetParams">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
</el-card>
|
||||||
|
<el-card class="!border-none mt-4" shadow="never">
|
||||||
|
<div class="text-right">
|
||||||
|
<el-button v-perms="['admin:monitor_slow:add']" type="primary" @click="handleAdd()">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Plus" />
|
||||||
|
</template>
|
||||||
|
新增
|
||||||
|
</el-button>
|
||||||
|
<upload
|
||||||
|
v-perms="['admin:monitor_slow:ImportFile']"
|
||||||
|
class="ml-3 mr-3"
|
||||||
|
:url="monitor_slow_import_file"
|
||||||
|
:data="{ cid: 0 }"
|
||||||
|
type="file"
|
||||||
|
:show-progress="true"
|
||||||
|
@change="resetPage"
|
||||||
|
>
|
||||||
|
<el-button type="primary">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Upload" />
|
||||||
|
</template>
|
||||||
|
导入
|
||||||
|
</el-button>
|
||||||
|
</upload>
|
||||||
|
<el-button
|
||||||
|
v-perms="['admin:monitor_slow:ExportFile']"
|
||||||
|
type="primary"
|
||||||
|
@click="exportFile"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Download" />
|
||||||
|
</template>
|
||||||
|
导出
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-perms="['admin:monitor_slow:delBatch']"
|
||||||
|
type="danger"
|
||||||
|
:disabled="!multipleSelection.length"
|
||||||
|
@click="deleteBatch"
|
||||||
|
>
|
||||||
|
批量删除
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
<el-table
|
||||||
|
class="mt-4"
|
||||||
|
size="large"
|
||||||
|
v-loading="pager.loading"
|
||||||
|
:data="pager.lists"
|
||||||
|
@selection-change="handleSelectionChange"
|
||||||
|
>
|
||||||
|
<el-table-column type="selection" width="55" />
|
||||||
|
<el-table-column label="项目key" prop="ProjectKey" min-width="130" />
|
||||||
|
<el-table-column label="sdk生成的客户端id" prop="ClientId" min-width="130" />
|
||||||
|
<el-table-column label="用户id" prop="UserId" min-width="130" />
|
||||||
|
<el-table-column label="URL地址" prop="Path" min-width="130" />
|
||||||
|
<el-table-column label="时间" prop="Time" min-width="130" />
|
||||||
|
<el-table-column label="创建时间" prop="CreateTime" min-width="130" />
|
||||||
|
<el-table-column label="操作" width="120" fixed="right">
|
||||||
|
<template #default="{ row }">
|
||||||
|
<el-button
|
||||||
|
v-perms="['admin:monitor_slow:edit']"
|
||||||
|
type="primary"
|
||||||
|
link
|
||||||
|
@click="handleEdit(row)"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
v-perms="['admin:monitor_slow:del']"
|
||||||
|
type="danger"
|
||||||
|
link
|
||||||
|
@click="handleDelete(row.Id)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<div class="flex justify-end mt-4">
|
||||||
|
<pagination v-model="pager" @change="getLists" />
|
||||||
|
</div>
|
||||||
|
</el-card>
|
||||||
|
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive, shallowRef, nextTick } from 'vue'
|
||||||
|
import {
|
||||||
|
monitor_slow_delete,
|
||||||
|
monitor_slow_delete_batch,
|
||||||
|
monitor_slow_list,
|
||||||
|
monitor_slow_import_file,
|
||||||
|
monitor_slow_export_file
|
||||||
|
} from '@/api/monitor/slow'
|
||||||
|
import type { type_monitor_slow, type_monitor_slow_query } from '@/api/monitor/slow'
|
||||||
|
|
||||||
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
import feedback from '@/utils/feedback'
|
||||||
|
import EditPopup from './edit.vue'
|
||||||
|
defineOptions({
|
||||||
|
name: 'monitor_slow'
|
||||||
|
})
|
||||||
|
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||||
|
const showEdit = ref(false)
|
||||||
|
const queryParams = reactive<type_monitor_slow_query>({
|
||||||
|
ProjectKey: null,
|
||||||
|
ClientId: null,
|
||||||
|
UserId: null,
|
||||||
|
Path: null,
|
||||||
|
Time: null,
|
||||||
|
CreateTimeStart: null,
|
||||||
|
CreateTimeEnd: null
|
||||||
|
})
|
||||||
|
|
||||||
|
const { pager, getLists, resetPage, resetParams } = usePaging<type_monitor_slow>({
|
||||||
|
fetchFun: monitor_slow_list,
|
||||||
|
params: queryParams
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleAdd = async () => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('add')
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleEdit = async (data: any) => {
|
||||||
|
showEdit.value = true
|
||||||
|
await nextTick()
|
||||||
|
editRef.value?.open('edit')
|
||||||
|
editRef.value?.getDetail(data)
|
||||||
|
}
|
||||||
|
const multipleSelection = ref<type_monitor_slow[]>([])
|
||||||
|
const handleSelectionChange = (val: type_monitor_slow[]) => {
|
||||||
|
console.log(val)
|
||||||
|
multipleSelection.value = val
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDelete = async (Id: number) => {
|
||||||
|
try {
|
||||||
|
await feedback.confirm('确定要删除?')
|
||||||
|
await monitor_slow_delete(Id)
|
||||||
|
feedback.msgSuccess('删除成功')
|
||||||
|
getLists()
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
// 批量删除
|
||||||
|
const deleteBatch = async () => {
|
||||||
|
if (multipleSelection.value.length === 0) {
|
||||||
|
feedback.msgError('请选择要删除的数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
await feedback.confirm('确定要删除?')
|
||||||
|
await monitor_slow_delete_batch({
|
||||||
|
Ids: multipleSelection.value.map((item) => item.Id).join(',')
|
||||||
|
})
|
||||||
|
feedback.msgSuccess('删除成功')
|
||||||
|
getLists()
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const exportFile = async () => {
|
||||||
|
try {
|
||||||
|
await feedback.confirm('确定要导出?')
|
||||||
|
await monitor_slow_export_file(queryParams)
|
||||||
|
} catch (error) {}
|
||||||
|
}
|
||||||
|
getLists()
|
||||||
|
</script>
|
@@ -8,14 +8,6 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func IndexRoute(rg *gin.RouterGroup) {
|
func IndexRoute(rg *gin.RouterGroup) {
|
||||||
// db := core.GetDB()
|
|
||||||
// permSrv := system.NewSystemAuthPermService(db)
|
|
||||||
// roleSrv := system.NewSystemAuthRoleService(db, permSrv)
|
|
||||||
// adminSrv := system.NewSystemAuthAdminService(db, permSrv, roleSrv)
|
|
||||||
// service := system.NewSystemLoginService(db, adminSrv)
|
|
||||||
|
|
||||||
// authSrv := system.NewSystemAuthMenuService(db, permSrv)
|
|
||||||
// IndexService := NewIndexService()
|
|
||||||
handle := indexHandler{}
|
handle := indexHandler{}
|
||||||
|
|
||||||
rg = rg.Group("/common", middleware.TokenAuth())
|
rg = rg.Group("/common", middleware.TokenAuth())
|
||||||
|
@@ -10,15 +10,10 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IIndexService interface {
|
|
||||||
Console() (res map[string]interface{}, e error)
|
|
||||||
Config() (res map[string]interface{}, e error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var Service = NewIndexService()
|
var Service = NewIndexService()
|
||||||
|
|
||||||
// NewIndexService 初始化
|
// NewIndexService 初始化
|
||||||
func NewIndexService() IIndexService {
|
func NewIndexService() *indexService {
|
||||||
db := core.GetDB()
|
db := core.GetDB()
|
||||||
return &indexService{db: db}
|
return &indexService{db: db}
|
||||||
}
|
}
|
||||||
|
217
server/admin/monitor_slow/monitor_slow_ctl.go
Normal file
217
server/admin/monitor_slow/monitor_slow_ctl.go
Normal file
@@ -0,0 +1,217 @@
|
|||||||
|
package monitor_slow
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
"x_admin/core/request"
|
||||||
|
"x_admin/core/response"
|
||||||
|
"x_admin/util"
|
||||||
|
"x_admin/util/excel2"
|
||||||
|
"golang.org/x/sync/singleflight"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
type MonitorSlowHandler struct {
|
||||||
|
requestGroup singleflight.Group
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary 监控-错误列列表
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param PageNo query int true "页码"
|
||||||
|
// @Param PageSize query int true "每页数量"
|
||||||
|
// @Param ProjectKey query string false "项目key"
|
||||||
|
// @Param ClientId query string false "sdk生成的客户端id"
|
||||||
|
// @Param UserId query string false "用户id"
|
||||||
|
// @Param Path query string false "URL地址"
|
||||||
|
// @Param Time query number false "时间"
|
||||||
|
// @Param CreateTimeStart query string false "创建时间"
|
||||||
|
// @Param CreateTimeEnd query string false "创建时间"
|
||||||
|
//@Success 200 {object} response.Response{ data=response.PageResp{ lists=[]MonitorSlowResp}} "成功"
|
||||||
|
//@Router /api/admin/monitor_slow/list [get]
|
||||||
|
func (hd *MonitorSlowHandler) List(c *gin.Context) {
|
||||||
|
var page request.PageReq
|
||||||
|
var listReq MonitorSlowListReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &page)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := MonitorSlowService.List(page, listReq)
|
||||||
|
response.CheckAndRespWithData(c, res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary 监控-错误列列表-所有
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param ProjectKey query string false "项目key"
|
||||||
|
// @Param ClientId query string false "sdk生成的客户端id"
|
||||||
|
// @Param UserId query string false "用户id"
|
||||||
|
// @Param Path query string false "URL地址"
|
||||||
|
// @Param Time query number false "时间"
|
||||||
|
// @Param CreateTimeStart query string false "创建时间"
|
||||||
|
// @Param CreateTimeEnd query string false "创建时间"
|
||||||
|
// @Success 200 {object} response.Response{ data=[]MonitorSlowResp} "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/listAll [get]
|
||||||
|
func (hd *MonitorSlowHandler) ListAll(c *gin.Context) {
|
||||||
|
var listReq MonitorSlowListReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := MonitorSlowService.ListAll(listReq)
|
||||||
|
response.CheckAndRespWithData(c, res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary 监控-错误列详情
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param Id query number false "错误id"
|
||||||
|
// @Success 200 {object} response.Response{ data=MonitorSlowResp} "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/detail [get]
|
||||||
|
func (hd *MonitorSlowHandler) Detail(c *gin.Context) {
|
||||||
|
var detailReq MonitorSlowDetailReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err, _ := hd.requestGroup.Do("MonitorSlow:Detail:"+strconv.Itoa(detailReq.Id), func() (any, error) {
|
||||||
|
v, err := MonitorSlowService.Detail(detailReq.Id)
|
||||||
|
return v, err
|
||||||
|
})
|
||||||
|
|
||||||
|
response.CheckAndRespWithData(c, res, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// @Summary 监控-错误列新增
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param ProjectKey body string false "项目key"
|
||||||
|
// @Param ClientId body string false "sdk生成的客户端id"
|
||||||
|
// @Param UserId body string false "用户id"
|
||||||
|
// @Param Path body string false "URL地址"
|
||||||
|
// @Param Time body number false "时间"
|
||||||
|
// @Success 200 {object} response.Response "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/add [post]
|
||||||
|
func (hd *MonitorSlowHandler) Add(c *gin.Context) {
|
||||||
|
var addReq MonitorSlowAddReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
createId, e := MonitorSlowService.Add(addReq)
|
||||||
|
response.CheckAndRespWithData(c,createId, e)
|
||||||
|
}
|
||||||
|
// @Summary 监控-错误列编辑
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param Id body number false "错误id"
|
||||||
|
// @Param ProjectKey body string false "项目key"
|
||||||
|
// @Param ClientId body string false "sdk生成的客户端id"
|
||||||
|
// @Param UserId body string false "用户id"
|
||||||
|
// @Param Path body string false "URL地址"
|
||||||
|
// @Param Time body number false "时间"
|
||||||
|
// @Success 200 {object} response.Response "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/edit [post]
|
||||||
|
func (hd *MonitorSlowHandler) Edit(c *gin.Context) {
|
||||||
|
var editReq MonitorSlowEditReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.CheckAndRespWithData(c,editReq.Id, MonitorSlowService.Edit(editReq))
|
||||||
|
}
|
||||||
|
// @Summary 监控-错误列删除
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param Id body number false "错误id"
|
||||||
|
// @Success 200 {object} response.Response "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/del [post]
|
||||||
|
func (hd *MonitorSlowHandler) Del(c *gin.Context) {
|
||||||
|
var delReq MonitorSlowDelReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
response.CheckAndResp(c, MonitorSlowService.Del(delReq.Id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary 监控-错误列删除-批量
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param Ids body string false "逗号分割的id"
|
||||||
|
// @Success 200 {object} response.Response "成功"
|
||||||
|
// @Router /api/admin/monitor_slow/delBatch [post]
|
||||||
|
func (hd *MonitorSlowHandler) DelBatch(c *gin.Context) {
|
||||||
|
var delReq MonitorSlowDelBatchReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if delReq.Ids == "" {
|
||||||
|
response.FailWithMsg(c, response.SystemError, "请选择要删除的数据")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var Ids = strings.Split(delReq.Ids, ",")
|
||||||
|
|
||||||
|
response.CheckAndResp(c, MonitorSlowService.DelBatch(Ids))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// @Summary 监控-错误列导出
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Param Token header string true "token"
|
||||||
|
// @Param ProjectKey query string false "项目key"
|
||||||
|
// @Param ClientId query string false "sdk生成的客户端id"
|
||||||
|
// @Param UserId query string false "用户id"
|
||||||
|
// @Param Path query string false "URL地址"
|
||||||
|
// @Param Time query number false "时间"
|
||||||
|
// @Param CreateTimeStart query string false "创建时间"
|
||||||
|
// @Param CreateTimeEnd query string false "创建时间"
|
||||||
|
// @Router /api/admin/monitor_slow/ExportFile [get]
|
||||||
|
func (hd *MonitorSlowHandler) ExportFile(c *gin.Context) {
|
||||||
|
var listReq MonitorSlowListReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := MonitorSlowService.ExportFile(listReq)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMsg(c, response.SystemError, "查询信息失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, err := excel2.Export(res,MonitorSlowService.GetExcelCol(), "Sheet1", "监控-错误列")
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMsg(c, response.SystemError, "导出失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
excel2.DownLoadExcel("监控-错误列" + time.Now().Format("20060102-150405"), c.Writer, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Summary 监控-错误列导入
|
||||||
|
// @Tags monitor_slow-监控-错误列
|
||||||
|
// @Produce json
|
||||||
|
// @Router /api/admin/monitor_slow/ImportFile [post]
|
||||||
|
func (hd *MonitorSlowHandler) ImportFile(c *gin.Context) {
|
||||||
|
file, _, err := c.Request.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusInternalServerError, "文件不存在")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
importList := []MonitorSlowResp{}
|
||||||
|
err = excel2.GetExcelData(file, &importList,MonitorSlowService.GetExcelCol())
|
||||||
|
if err != nil {
|
||||||
|
c.String(http.StatusInternalServerError, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = MonitorSlowService.ImportFile(importList)
|
||||||
|
response.CheckAndResp(c, err)
|
||||||
|
}
|
63
server/admin/monitor_slow/monitor_slow_schema.go
Normal file
63
server/admin/monitor_slow/monitor_slow_schema.go
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
package monitor_slow
|
||||||
|
import (
|
||||||
|
"x_admin/core"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
//MonitorSlowListReq 监控-错误列列表参数
|
||||||
|
type MonitorSlowListReq struct {
|
||||||
|
ProjectKey *string // 项目key
|
||||||
|
ClientId *string // sdk生成的客户端id
|
||||||
|
UserId *string // 用户id
|
||||||
|
Path *string // URL地址
|
||||||
|
Time *float64 // 时间
|
||||||
|
CreateTimeStart *string // 开始创建时间
|
||||||
|
CreateTimeEnd *string // 结束创建时间
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//MonitorSlowAddReq 监控-错误列新增参数
|
||||||
|
type MonitorSlowAddReq struct {
|
||||||
|
ProjectKey *string // 项目key
|
||||||
|
ClientId *string // sdk生成的客户端id
|
||||||
|
UserId *string // 用户id
|
||||||
|
Path *string // URL地址
|
||||||
|
Time core.NullFloat // 时间
|
||||||
|
}
|
||||||
|
|
||||||
|
//MonitorSlowEditReq 监控-错误列编辑参数
|
||||||
|
type MonitorSlowEditReq struct {
|
||||||
|
Id int // 错误id
|
||||||
|
ProjectKey *string // 项目key
|
||||||
|
ClientId *string // sdk生成的客户端id
|
||||||
|
UserId *string // 用户id
|
||||||
|
Path *string // URL地址
|
||||||
|
Time core.NullFloat // 时间
|
||||||
|
}
|
||||||
|
|
||||||
|
//MonitorSlowDetailReq 监控-错误列详情参数
|
||||||
|
type MonitorSlowDetailReq struct {
|
||||||
|
Id int // 错误id
|
||||||
|
}
|
||||||
|
|
||||||
|
//MonitorSlowDelReq 监控-错误列删除参数
|
||||||
|
type MonitorSlowDelReq struct {
|
||||||
|
Id int // 错误id
|
||||||
|
}
|
||||||
|
|
||||||
|
//MonitorSlowDelReq 监控-错误列批量删除参数
|
||||||
|
type MonitorSlowDelBatchReq struct {
|
||||||
|
Ids string
|
||||||
|
}
|
||||||
|
|
||||||
|
//MonitorSlowResp 监控-错误列返回信息
|
||||||
|
type MonitorSlowResp struct {
|
||||||
|
Id int // 错误id
|
||||||
|
ProjectKey string // 项目key
|
||||||
|
ClientId string // sdk生成的客户端id
|
||||||
|
UserId string // 用户id
|
||||||
|
Path string // URL地址
|
||||||
|
Time core.NullFloat // 时间
|
||||||
|
CreateTime core.NullTime // 创建时间
|
||||||
|
}
|
224
server/admin/monitor_slow/monitor_slow_service.go
Normal file
224
server/admin/monitor_slow/monitor_slow_service.go
Normal file
@@ -0,0 +1,224 @@
|
|||||||
|
package monitor_slow
|
||||||
|
|
||||||
|
import (
|
||||||
|
"x_admin/core"
|
||||||
|
"x_admin/core/request"
|
||||||
|
"x_admin/core/response"
|
||||||
|
"x_admin/model"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"x_admin/util"
|
||||||
|
"x_admin/util/excel2"
|
||||||
|
)
|
||||||
|
|
||||||
|
var MonitorSlowService=NewMonitorSlowService()
|
||||||
|
var cacheUtil = util.CacheUtil{
|
||||||
|
Name: MonitorSlowService.Name,
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMonitorSlowService 初始化
|
||||||
|
func NewMonitorSlowService() *monitorSlowService {
|
||||||
|
return &monitorSlowService{
|
||||||
|
db: core.GetDB(),
|
||||||
|
Name: "monitorSlow",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//monitorSlowService 监控-错误列服务实现类
|
||||||
|
type monitorSlowService struct {
|
||||||
|
db *gorm.DB
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// List 监控-错误列列表
|
||||||
|
func (service monitorSlowService) GetModel(listReq MonitorSlowListReq) *gorm.DB {
|
||||||
|
// 查询
|
||||||
|
dbModel := service.db.Model(&model.MonitorSlow{})
|
||||||
|
if listReq.ProjectKey!= nil {
|
||||||
|
dbModel = dbModel.Where("project_key = ?", *listReq.ProjectKey)
|
||||||
|
}
|
||||||
|
if listReq.ClientId!= nil {
|
||||||
|
dbModel = dbModel.Where("client_id = ?", *listReq.ClientId)
|
||||||
|
}
|
||||||
|
if listReq.UserId!= nil {
|
||||||
|
dbModel = dbModel.Where("user_id = ?", *listReq.UserId)
|
||||||
|
}
|
||||||
|
if listReq.Path!= nil {
|
||||||
|
dbModel = dbModel.Where("path = ?", *listReq.Path)
|
||||||
|
}
|
||||||
|
if listReq.Time!= nil {
|
||||||
|
dbModel = dbModel.Where("time = ?", *listReq.Time)
|
||||||
|
}
|
||||||
|
if listReq.CreateTimeStart!= nil {
|
||||||
|
dbModel = dbModel.Where("create_time >= ?", *listReq.CreateTimeStart)
|
||||||
|
}
|
||||||
|
if listReq.CreateTimeEnd!= nil {
|
||||||
|
dbModel = dbModel.Where("create_time <= ?", *listReq.CreateTimeEnd)
|
||||||
|
}
|
||||||
|
return dbModel
|
||||||
|
}
|
||||||
|
// List 监控-错误列列表
|
||||||
|
func (service monitorSlowService) List(page request.PageReq, listReq MonitorSlowListReq) (res response.PageResp, e error) {
|
||||||
|
// 分页信息
|
||||||
|
limit := page.PageSize
|
||||||
|
offset := page.PageSize * (page.PageNo - 1)
|
||||||
|
dbModel := service.GetModel(listReq)
|
||||||
|
// 总数
|
||||||
|
var count int64
|
||||||
|
err := dbModel.Count(&count).Error
|
||||||
|
if e = response.CheckErr(err, "失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 数据
|
||||||
|
var modelList []model.MonitorSlow
|
||||||
|
err = dbModel.Limit(limit).Offset(offset).Order("id desc").Find(&modelList).Error
|
||||||
|
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result := []MonitorSlowResp{}
|
||||||
|
util.ConvertUtil.Copy(&result, modelList)
|
||||||
|
return response.PageResp{
|
||||||
|
PageNo: page.PageNo,
|
||||||
|
PageSize: page.PageSize,
|
||||||
|
Count: count,
|
||||||
|
Lists: result,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
// ListAll 监控-错误列列表
|
||||||
|
func (service monitorSlowService) ListAll(listReq MonitorSlowListReq) (res []MonitorSlowResp, e error) {
|
||||||
|
dbModel := service.GetModel(listReq)
|
||||||
|
|
||||||
|
var modelList []model.MonitorSlow
|
||||||
|
|
||||||
|
err := dbModel.Find(&modelList).Error
|
||||||
|
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
util.ConvertUtil.Copy(&res, modelList)
|
||||||
|
return res, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detail 监控-错误列详情
|
||||||
|
func (service monitorSlowService) Detail(Id int) (res MonitorSlowResp, e error) {
|
||||||
|
var obj = model.MonitorSlow{}
|
||||||
|
err := cacheUtil.GetCache(Id, &obj)
|
||||||
|
if err != nil {
|
||||||
|
err := service.db.Where("id = ?", Id).Limit(1).First(&obj).Error
|
||||||
|
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 监控-错误列新增
|
||||||
|
func (service monitorSlowService) Add(addReq MonitorSlowAddReq) (createId int,e error) {
|
||||||
|
var obj model.MonitorSlow
|
||||||
|
util.ConvertUtil.StructToStruct(addReq,&obj)
|
||||||
|
err := service.db.Create(&obj).Error
|
||||||
|
e = response.CheckMysqlErr(err)
|
||||||
|
if e != nil {
|
||||||
|
return 0,e
|
||||||
|
}
|
||||||
|
cacheUtil.SetCache(obj.Id, obj)
|
||||||
|
createId = obj.Id
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit 监控-错误列编辑
|
||||||
|
func (service monitorSlowService) Edit(editReq MonitorSlowEditReq) (e error) {
|
||||||
|
var obj model.MonitorSlow
|
||||||
|
err := service.db.Where("id = ?", editReq.Id).Limit(1).First(&obj).Error
|
||||||
|
// 校验
|
||||||
|
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
util.ConvertUtil.Copy(&obj, editReq)
|
||||||
|
|
||||||
|
err = service.db.Model(&obj).Select("*").Updates(obj).Error
|
||||||
|
if e = response.CheckErr(err, "编辑失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cacheUtil.RemoveCache(obj.Id)
|
||||||
|
service.Detail(obj.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Del 监控-错误列删除
|
||||||
|
func (service monitorSlowService) Del(Id int) (e error) {
|
||||||
|
var obj model.MonitorSlow
|
||||||
|
err := service.db.Where("id = ?", Id).Limit(1).First(&obj).Error
|
||||||
|
// 校验
|
||||||
|
if e = response.CheckErrDBNotRecord(err, "数据不存在!"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if e = response.CheckErr(err, "查询数据失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// 删除
|
||||||
|
err = service.db.Delete(&obj).Error
|
||||||
|
e = response.CheckErr(err, "删除失败")
|
||||||
|
cacheUtil.RemoveCache(obj.Id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// DelBatch 用户协议-批量删除
|
||||||
|
func (service monitorSlowService) DelBatch(Ids []string) (e error) {
|
||||||
|
var obj model.MonitorSlow
|
||||||
|
err := service.db.Where("id in (?)", Ids).Delete(&obj).Error
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// 删除缓存
|
||||||
|
cacheUtil.RemoveCache(Ids)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取Excel的列
|
||||||
|
func (service monitorSlowService) GetExcelCol() []excel2.Col {
|
||||||
|
var cols = []excel2.Col{
|
||||||
|
{Name: "项目key", Key: "ProjectKey", Width: 15},
|
||||||
|
{Name: "sdk生成的客户端id", Key: "ClientId", Width: 15},
|
||||||
|
{Name: "用户id", Key: "UserId", Width: 15},
|
||||||
|
{Name: "URL地址", Key: "Path", Width: 15},
|
||||||
|
{Name: "时间", Key: "Time", Width: 15},
|
||||||
|
{Name: "创建时间", Key: "CreateTime", Width: 15, Decode: util.NullTimeUtil.DecodeTime },
|
||||||
|
}
|
||||||
|
// 还可以考虑字典,请求下来加上 Replace 实现替换导出
|
||||||
|
return cols
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExportFile 监控-错误列导出
|
||||||
|
func (service monitorSlowService) ExportFile(listReq MonitorSlowListReq) (res []MonitorSlowResp, e error) {
|
||||||
|
// 查询
|
||||||
|
dbModel := service.GetModel(listReq)
|
||||||
|
|
||||||
|
// 数据
|
||||||
|
var modelList []model.MonitorSlow
|
||||||
|
err := dbModel.Order("id asc").Find(&modelList).Error
|
||||||
|
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
result := []MonitorSlowResp{}
|
||||||
|
util.ConvertUtil.Copy(&result, modelList)
|
||||||
|
return result, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导入
|
||||||
|
func (service monitorSlowService) ImportFile(importReq []MonitorSlowResp) (e error) {
|
||||||
|
var importData []model.MonitorSlow
|
||||||
|
util.ConvertUtil.Copy(&importData, importReq)
|
||||||
|
err := service.db.Create(&importData).Error
|
||||||
|
e = response.CheckErr(err, "添加失败")
|
||||||
|
return e
|
||||||
|
}
|
@@ -4,6 +4,7 @@ import (
|
|||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"x_admin/util/convert"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Float类型别名,支持前端传递null,float64, string类型
|
// Float类型别名,支持前端传递null,float64, string类型
|
||||||
@@ -13,35 +14,14 @@ type NullFloat struct {
|
|||||||
Valid bool
|
Valid bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// func EncodeFloat(value any) any {
|
|
||||||
// switch v := value.(type) {
|
|
||||||
// case map[string]any:
|
|
||||||
// if v["Float"] != nil {
|
|
||||||
// val := v["Float"]
|
|
||||||
// switch f := val.(type) {
|
|
||||||
// case *float32:
|
|
||||||
// return float64(*f)
|
|
||||||
// case *float64:
|
|
||||||
// return *f
|
|
||||||
// case *int:
|
|
||||||
// return float64(*f)
|
|
||||||
// case *int64:
|
|
||||||
// return float64(*f)
|
|
||||||
// case *string:
|
|
||||||
// return *f
|
|
||||||
// default:
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// return nil
|
|
||||||
// }
|
|
||||||
|
|
||||||
func DecodeFloat(value any) (any, error) {
|
func DecodeFloat(value any) (any, error) {
|
||||||
switch v := value.(type) {
|
switch v := value.(type) {
|
||||||
case float64:
|
case float64:
|
||||||
f := v
|
f := v
|
||||||
return NullFloat{Float: &f, Valid: true}, nil
|
return NullFloat{Float: &f, Valid: true}, nil
|
||||||
|
case float32:
|
||||||
|
f := float64(v)
|
||||||
|
return NullFloat{Float: &f, Valid: true}, nil
|
||||||
case int:
|
case int:
|
||||||
f := float64(v)
|
f := float64(v)
|
||||||
return NullFloat{Float: &f, Valid: true}, nil
|
return NullFloat{Float: &f, Valid: true}, nil
|
||||||
@@ -65,12 +45,42 @@ func DecodeFloat(value any) (any, error) {
|
|||||||
// gorm实现Scanner
|
// gorm实现Scanner
|
||||||
func (f *NullFloat) Scan(value interface{}) error {
|
func (f *NullFloat) Scan(value interface{}) error {
|
||||||
f.Valid = false
|
f.Valid = false
|
||||||
if value == nil {
|
|
||||||
return nil
|
result, err := convert.ConvertUtil.ToFloat64(value)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
v := value.(float64)
|
f.Float, f.Valid = &result, true
|
||||||
f.Float, f.Valid = &v, true
|
|
||||||
return nil
|
return nil
|
||||||
|
// switch v := value.(type) {
|
||||||
|
// case float64:
|
||||||
|
// f.Float, f.Valid = &v, true
|
||||||
|
// case float32:
|
||||||
|
// // 直接用float64(float32(v)), 会丢失精度
|
||||||
|
// val, _ := strconv.ParseFloat(fmt.Sprintf("%f", v), 64)
|
||||||
|
// f.Float, f.Valid = &val, true
|
||||||
|
// // 匹配所有int
|
||||||
|
// case uint, uint8, uint16, uint32, uint64, int8, int16, int, int32, int64:
|
||||||
|
// val := float64(v)
|
||||||
|
// f.Float, f.Valid = &val, true
|
||||||
|
// case string:
|
||||||
|
// if v == "" {
|
||||||
|
// f.Float, f.Valid = nil, false
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
// val, err := strconv.ParseFloat(v, 64)
|
||||||
|
// if err != nil {
|
||||||
|
// f.Float, f.Valid = nil, false
|
||||||
|
// return err
|
||||||
|
// }
|
||||||
|
// f.Float, f.Valid = &val, true
|
||||||
|
// return err
|
||||||
|
// case nil:
|
||||||
|
// f.Float, f.Valid = nil, false
|
||||||
|
// return nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// gorm实现 Valuer
|
// gorm实现 Valuer
|
||||||
|
16
server/model/monitor_slow.go
Normal file
16
server/model/monitor_slow.go
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"x_admin/core"
|
||||||
|
)
|
||||||
|
|
||||||
|
// MonitorSlow 监控-错误列实体
|
||||||
|
type MonitorSlow struct {
|
||||||
|
Id int `gorm:"primarykey;comment:'错误id'"` // 错误id
|
||||||
|
ProjectKey string `gorm:"comment:'项目key'"` // 项目key
|
||||||
|
ClientId string `gorm:"comment:'sdk生成的客户端id'"` // sdk生成的客户端id
|
||||||
|
UserId string `gorm:"comment:'用户id'"` // 用户id
|
||||||
|
Path string `gorm:"comment:'URL地址'"` // URL地址
|
||||||
|
Time core.NullFloat `gorm:"comment:'时间'"` // 时间
|
||||||
|
CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间
|
||||||
|
}
|
@@ -60,6 +60,7 @@ func RegisterGroup(rg *gin.RouterGroup) {
|
|||||||
MonitorProjectRoute(rg)
|
MonitorProjectRoute(rg)
|
||||||
MonitorClientRoute(rg)
|
MonitorClientRoute(rg)
|
||||||
MonitorErrorRoute(rg)
|
MonitorErrorRoute(rg)
|
||||||
|
MonitorSlowRoute(rg)
|
||||||
|
|
||||||
UserProtocolRoute(rg)
|
UserProtocolRoute(rg)
|
||||||
}
|
}
|
||||||
|
59
server/router/admin/monitor_slow_route.go
Normal file
59
server/router/admin/monitor_slow_route.go
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"x_admin/admin/monitor_slow"
|
||||||
|
"x_admin/middleware"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
)
|
||||||
|
|
||||||
|
/**
|
||||||
|
集成
|
||||||
|
1. 导入
|
||||||
|
- 请先提交git避免文件覆盖!!!
|
||||||
|
- 下载并解压压缩包后,直接复制server、admin文件夹到项目根目录即可
|
||||||
|
|
||||||
|
2. 注册路由
|
||||||
|
请在 router/admin/entry.go 文件引入 MonitorSlowRoute 注册路由
|
||||||
|
|
||||||
|
3. 后台手动添加菜单和按钮
|
||||||
|
admin:monitor_slow:add
|
||||||
|
admin:monitor_slow:edit
|
||||||
|
admin:monitor_slow:del
|
||||||
|
admin:monitor_slow:delBatch
|
||||||
|
admin:monitor_slow:list
|
||||||
|
admin:monitor_slow:listAll
|
||||||
|
admin:monitor_slow:detail
|
||||||
|
admin:monitor_slow:ExportFile
|
||||||
|
admin:monitor_slow: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', '慢接口', 'monitor/slow/index', 'monitor/slow/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 (834, 'A', '慢接口添加','admin:monitor_slow: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 (834, 'A', '慢接口编辑','admin:monitor_slow: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 (834, 'A', '慢接口删除','admin:monitor_slow: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 (834, 'A', '慢接口删除-批量','admin:monitor_slow:delBatch', 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 (834, 'A', '慢接口列表','admin:monitor_slow: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 (834, 'A', '慢接口全部列表','admin:monitor_slow: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 (834, 'A', '慢接口详情','admin:monitor_slow: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 (834, 'A', '慢接口导出excel','admin:monitor_slow: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 (834, 'A', '慢接口导入excel','admin:monitor_slow:ImportFile', 0, 1, 0, now(), now());
|
||||||
|
*/
|
||||||
|
|
||||||
|
// MonitorSlowRoute(rg)
|
||||||
|
func MonitorSlowRoute(rg *gin.RouterGroup) {
|
||||||
|
handle := monitor_slow.MonitorSlowHandler{}
|
||||||
|
rg.POST("/monitor_slow/add", middleware.RecordLog("慢接口新增"), handle.Add)
|
||||||
|
r := rg.Group("/", middleware.TokenAuth())
|
||||||
|
r.GET("/monitor_slow/list", handle.List)
|
||||||
|
r.GET("/monitor_slow/listAll", handle.ListAll)
|
||||||
|
r.GET("/monitor_slow/detail", handle.Detail)
|
||||||
|
|
||||||
|
r.POST("/monitor_slow/del", middleware.RecordLog("慢接口删除"), handle.Del)
|
||||||
|
r.POST("/monitor_slow/delBatch", middleware.RecordLog("慢接口删除-批量"), handle.DelBatch)
|
||||||
|
|
||||||
|
r.GET("/monitor_slow/ExportFile", middleware.RecordLog("慢接口导出"), handle.ExportFile)
|
||||||
|
// r.POST("/monitor_slow/ImportFile", handle.ImportFile)
|
||||||
|
}
|
@@ -2,7 +2,6 @@ package util
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"x_admin/core"
|
|
||||||
|
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
"github.com/jinzhu/copier"
|
"github.com/jinzhu/copier"
|
||||||
@@ -28,7 +27,7 @@ func (c convertUtil) StructsToMaps(from interface{}) (data []map[string]interfac
|
|||||||
var objList []interface{}
|
var objList []interface{}
|
||||||
err := copier.Copy(&objList, from)
|
err := copier.Copy(&objList, from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, v := range objList {
|
for _, v := range objList {
|
||||||
@@ -57,7 +56,7 @@ func (c convertUtil) ShallowStructsToMaps(from interface{}) (data []map[string]i
|
|||||||
var objList []interface{}
|
var objList []interface{}
|
||||||
err := copier.Copy(&objList, from)
|
err := copier.Copy(&objList, from)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for _, v := range objList {
|
for _, v := range objList {
|
||||||
@@ -82,7 +81,7 @@ func (c convertUtil) StructToStruct(from interface{}, to interface{}) (err error
|
|||||||
|
|
||||||
func (c convertUtil) Copy(toValue interface{}, fromValue interface{}) interface{} {
|
func (c convertUtil) Copy(toValue interface{}, fromValue interface{}) interface{} {
|
||||||
if err := copier.Copy(toValue, fromValue); err != nil {
|
if err := copier.Copy(toValue, fromValue); err != nil {
|
||||||
core.Logger.Errorf("Copy err: err=[%+v]", err)
|
// core.Logger.Errorf("Copy err: err=[%+v]", err)
|
||||||
panic("SystemError")
|
panic("SystemError")
|
||||||
}
|
}
|
||||||
return toValue
|
return toValue
|
||||||
|
104
server/util/convert/convert.go
Normal file
104
server/util/convert/convert.go
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
package convert
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"reflect"
|
||||||
|
|
||||||
|
"github.com/duke-git/lancet/v2/convertor"
|
||||||
|
|
||||||
|
"github.com/fatih/structs"
|
||||||
|
"github.com/jinzhu/copier"
|
||||||
|
"github.com/mitchellh/mapstructure"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ConvertUtil = convertUtil{}
|
||||||
|
|
||||||
|
// convertUtil 转换工具
|
||||||
|
type convertUtil struct{}
|
||||||
|
|
||||||
|
func (c convertUtil) ToFloat64(value interface{}) (float64, error) {
|
||||||
|
switch v := value.(type) {
|
||||||
|
case float64, float32:
|
||||||
|
return strconv.ParseFloat(fmt.Sprintf("%f", v), 64)
|
||||||
|
default:
|
||||||
|
return convertor.ToFloat(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// return 0, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructToMap 结构体转换成map,深度转换
|
||||||
|
func (c convertUtil) StructToMap(from interface{}) map[string]interface{} {
|
||||||
|
// var m = map[string]interface{}{}
|
||||||
|
// mapstructure.Decode(from, &m) //深度转换所有结构体
|
||||||
|
|
||||||
|
m := structs.Map(from) // 需要tag:structs,深度转换
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructsToMaps 将结构体转换成Map列表
|
||||||
|
func (c convertUtil) StructsToMaps(from interface{}) (data []map[string]interface{}) {
|
||||||
|
var objList []interface{}
|
||||||
|
err := copier.Copy(&objList, from)
|
||||||
|
if err != nil {
|
||||||
|
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, v := range objList {
|
||||||
|
data = append(data, c.StructToMap(v))
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShallowStructToMap 将结构体转换成map,浅转换
|
||||||
|
func (c convertUtil) ShallowStructToMap(from interface{}) map[string]interface{} {
|
||||||
|
m := make(map[string]interface{})
|
||||||
|
v := reflect.ValueOf(from)
|
||||||
|
t := v.Type()
|
||||||
|
|
||||||
|
for i := 0; i < t.NumField(); i++ {
|
||||||
|
field := t.Field(i)
|
||||||
|
value := v.Field(i).Interface()
|
||||||
|
m[field.Name] = value
|
||||||
|
}
|
||||||
|
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShallowStructsToMaps 将结构体列表转换成Map列表,浅转换
|
||||||
|
func (c convertUtil) ShallowStructsToMaps(from interface{}) (data []map[string]interface{}) {
|
||||||
|
var objList []interface{}
|
||||||
|
err := copier.Copy(&objList, from)
|
||||||
|
if err != nil {
|
||||||
|
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
for _, v := range objList {
|
||||||
|
data = append(data, c.ShallowStructToMap(v))
|
||||||
|
}
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
// MapToStruct 将map弱类型转换成结构体
|
||||||
|
func (c convertUtil) MapToStruct(from interface{}, to interface{}) (err error) {
|
||||||
|
err = mapstructure.WeakDecode(from, to) // 需要tag:mapstructure
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// StructToStruct 将结构体from弱类型转换成结构体to
|
||||||
|
func (c convertUtil) StructToStruct(from interface{}, to interface{}) (err error) {
|
||||||
|
m := c.StructToMap(from)
|
||||||
|
err = c.MapToStruct(m, to)
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c convertUtil) Copy(toValue interface{}, fromValue interface{}) interface{} {
|
||||||
|
if err := copier.Copy(toValue, fromValue); err != nil {
|
||||||
|
// core.Logger.Errorf("Copy err: err=[%+v]", err)
|
||||||
|
panic("SystemError")
|
||||||
|
}
|
||||||
|
return toValue
|
||||||
|
}
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
"x_admin/core"
|
|
||||||
|
|
||||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||||
)
|
)
|
||||||
@@ -20,7 +19,7 @@ type ipUtil struct {
|
|||||||
func (su ipUtil) GetHostIp() (ip string) {
|
func (su ipUtil) GetHostIp() (ip string) {
|
||||||
conn, err := net.Dial("udp", "114.114.114.114:80")
|
conn, err := net.Dial("udp", "114.114.114.114:80")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.Logger.Errorf("GetHostIp Dial err: err=[%+v]", err)
|
// core.Logger.Errorf("GetHostIp Dial err: err=[%+v]", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer conn.Close()
|
defer conn.Close()
|
||||||
|
@@ -59,8 +59,9 @@ class XLog {
|
|||||||
// 设置用户id
|
// 设置用户id
|
||||||
public SetUid(uid?: Uid) {
|
public SetUid(uid?: Uid) {
|
||||||
if (uid) {
|
if (uid) {
|
||||||
this.platform?.setCache("x_err_uid", uid);
|
|
||||||
this.Uid = uid;
|
this.Uid = uid;
|
||||||
|
this.platform?.setCache("x_err_uid", uid);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
const u_id = this.platform?.getCache("x_err_uid");
|
const u_id = this.platform?.getCache("x_err_uid");
|
||||||
if (u_id) {
|
if (u_id) {
|
||||||
|
@@ -193,6 +193,7 @@ class Logger implements IErrorEvent {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
public listen(callback: ListenCallbackFn): void {
|
public listen(callback: ListenCallbackFn): void {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
|
Reference in New Issue
Block a user