mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-09-26 20:21:19 +08:00
Merge branch 'dev'
This commit is contained in:
@@ -13,6 +13,21 @@
|
||||
padding: 0;
|
||||
}
|
||||
</style>
|
||||
<script src="/XErr.umd.js"></script>
|
||||
<script>
|
||||
const xErr = new XErr.Base(
|
||||
{
|
||||
Dns: `${location.origin}/api`,
|
||||
Pid: 'e19e3be20de94f49b68fafb4c30668bc',
|
||||
Uid: ''
|
||||
},
|
||||
new XErr.Web({
|
||||
onloadTimeOut: 5000
|
||||
})
|
||||
)
|
||||
xErr.SetUid(2) //设置用户ID
|
||||
</script>
|
||||
|
||||
<link rel="stylesheet" href="/src/styles/loading.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
3
admin/public/XErr.umd.js
Normal file
3
admin/public/XErr.umd.js
Normal file
File diff suppressed because one or more lines are too long
@@ -13,7 +13,11 @@ export type type_monitor_client = {
|
||||
UserId?: string
|
||||
Os?: string
|
||||
Browser?: string
|
||||
Country?: string
|
||||
Province?: string
|
||||
City?: string
|
||||
Operator?: string
|
||||
Ip?: string
|
||||
Width?: number
|
||||
Height?: number
|
||||
Ua?: string
|
||||
@@ -26,14 +30,16 @@ export type type_monitor_client_query = {
|
||||
UserId?: string
|
||||
Os?: string
|
||||
Browser?: string
|
||||
Country?: string
|
||||
Province?: string
|
||||
City?: string
|
||||
Operator?: string
|
||||
Ip?: string
|
||||
Width?: number
|
||||
Height?: number
|
||||
Ua?: string
|
||||
CreateTimeStart?: string
|
||||
CreateTimeEnd?: string
|
||||
ClientTimeStart?: string
|
||||
ClientTimeEnd?: string
|
||||
}
|
||||
// 添加编辑
|
||||
export type type_monitor_client_edit = {
|
||||
@@ -43,7 +49,11 @@ export type type_monitor_client_edit = {
|
||||
UserId?: string
|
||||
Os?: string
|
||||
Browser?: string
|
||||
Country?: string
|
||||
Province?: string
|
||||
City?: string
|
||||
Operator?: string
|
||||
Ip?: string
|
||||
Width?: number
|
||||
Height?: number
|
||||
Ua?: string
|
||||
|
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)))
|
||||
}
|
@@ -1,14 +1,12 @@
|
||||
<template>
|
||||
<div>
|
||||
<template v-for="(item, index) in getOptions" :key="index">
|
||||
<span :style="{ color: item.color }"
|
||||
>{{ index != 0 ? '、' : '' }}{{ item[props.labelKey] }}</span
|
||||
>
|
||||
</template>
|
||||
</div>
|
||||
<template v-for="(item, index) in getOptions" :key="index">
|
||||
<span :style="{ color: item.color }"
|
||||
>{{ index != 0 ? '、' : '' }}{{ item[props.labelKey] }}</span
|
||||
>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { computed, withDefaults } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
defineOptions({
|
||||
name: 'dict-value'
|
||||
})
|
||||
|
@@ -29,7 +29,7 @@ import type { IEditorConfig, IToolbarConfig } from '@wangeditor/editor'
|
||||
import MaterialPicker from '@/components/material/picker.vue'
|
||||
import { addUnit } from '@/utils/util'
|
||||
|
||||
import { withDefaults, computed, shallowRef, ref, onBeforeUnmount } from 'vue'
|
||||
import { computed, shallowRef, ref, onBeforeUnmount } from 'vue'
|
||||
import type { CSSProperties } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
|
26
admin/src/components/highlight-code/index.vue
Normal file
26
admin/src/components/highlight-code/index.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="ov w-[100%]">
|
||||
<highlightjs autodetect :code="code" :language="lang" />
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import 'highlight.js/styles/monokai.min.css'
|
||||
import hljs from 'highlight.js/lib/common'
|
||||
import javascript from 'highlight.js/lib/languages/javascript'
|
||||
import go from 'highlight.js/lib/languages/go'
|
||||
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
hljs.registerLanguage('go', go)
|
||||
|
||||
import hljsVuePlugin from '@highlightjs/vue-plugin'
|
||||
const highlightjs = hljsVuePlugin.component
|
||||
|
||||
interface Props {
|
||||
code: string
|
||||
lang: 'javascript' | 'go'
|
||||
}
|
||||
withDefaults(defineProps<Props>(), {
|
||||
code: '',
|
||||
lang: 'javascript'
|
||||
})
|
||||
</script>
|
@@ -77,7 +77,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, withDefaults } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { computed, nextTick, onMounted, reactive, shallowRef, watch } from 'vue'
|
||||
import { useEventListener } from '@vueuse/core'
|
||||
import { ElInput } from 'element-plus'
|
||||
|
@@ -11,6 +11,19 @@ import ElementPlus from 'element-plus'
|
||||
|
||||
import VForm3 from 'vform3-builds' //引入VForm3库
|
||||
|
||||
// import { Base, Web } from '../../x_err_sdk/web/index'
|
||||
// const xErr = new Base(
|
||||
// {
|
||||
// Dns: `${location.origin}/api`,
|
||||
// Pid: 'e19e3be20de94f49b68fafb4c30668bc',
|
||||
// Uid: ''
|
||||
// },
|
||||
// new Web({
|
||||
// onloadTimeOut: 300
|
||||
// })
|
||||
// )
|
||||
// xErr.SetUid(1) //设置用户ID
|
||||
|
||||
const app = createApp(App)
|
||||
app.use(install)
|
||||
app.use(ElementPlus)
|
||||
|
@@ -39,13 +39,13 @@
|
||||
</template>
|
||||
删除
|
||||
</el-button>
|
||||
<el-button
|
||||
<!-- <el-button
|
||||
v-perms="['admin:gen:genCode', 'admin:gen:downloadCode']"
|
||||
:disabled="!selectData.length"
|
||||
@click="handleGenerate(selectData)"
|
||||
>
|
||||
生成代码
|
||||
</el-button>
|
||||
</el-button> -->
|
||||
</div>
|
||||
<div class="mt-4">
|
||||
<el-table
|
||||
|
@@ -35,11 +35,15 @@
|
||||
|
||||
<div class="flex-1 overflow-auto">
|
||||
<div style="height: calc(100vh - 200px)">
|
||||
<highlightjs
|
||||
<highlight-code
|
||||
:code="showItem.value"
|
||||
lang="javascript"
|
||||
></highlight-code>
|
||||
<!-- <highlightjs
|
||||
autodetect
|
||||
:code="showItem.value"
|
||||
language="javascript"
|
||||
/>
|
||||
/> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -66,17 +70,17 @@ import { onMounted, ref, computed } from 'vue'
|
||||
import feedback from '@/utils/feedback'
|
||||
import useClipboard from 'vue-clipboard3'
|
||||
|
||||
import 'highlight.js/styles/monokai.min.css'
|
||||
import hljs from 'highlight.js/lib/common'
|
||||
import javascript from 'highlight.js/lib/languages/javascript'
|
||||
import go from 'highlight.js/lib/languages/go'
|
||||
// import 'highlight.js/styles/monokai.min.css'
|
||||
// import hljs from 'highlight.js/lib/common'
|
||||
// import javascript from 'highlight.js/lib/languages/javascript'
|
||||
// import go from 'highlight.js/lib/languages/go'
|
||||
|
||||
// Then register the languages you need
|
||||
hljs.registerLanguage('javascript', javascript)
|
||||
hljs.registerLanguage('go', go)
|
||||
// hljs.registerLanguage('javascript', javascript)
|
||||
// hljs.registerLanguage('go', go)
|
||||
|
||||
import hljsVuePlugin from '@highlightjs/vue-plugin'
|
||||
const highlightjs = hljsVuePlugin.component
|
||||
// import hljsVuePlugin from '@highlightjs/vue-plugin'
|
||||
// const highlightjs = hljsVuePlugin.component
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: boolean
|
||||
|
66
admin/src/views/error/test.vue
Normal file
66
admin/src/views/error/test.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<script setup lang="ts">
|
||||
// import { onUnmounted } from 'vue'
|
||||
// import { XErr, XErrWeb } from '../../../../x_err_sdk/web/index'
|
||||
// // { XErr, XErrWeb }
|
||||
// const xErr = new XErr(
|
||||
// {
|
||||
// Dns: 'http://localhost:5174/api',
|
||||
// Pid: 'e19e3be20de94f49b68fafb4c30668bc',
|
||||
// Uid: '10'
|
||||
// },
|
||||
// new XErrWeb()
|
||||
// )
|
||||
// onUnmounted(() => {
|
||||
// xErr.unListen()
|
||||
// })
|
||||
defineProps<{ msg: string }>()
|
||||
function error() {
|
||||
throw new Error('主动抛error')
|
||||
}
|
||||
function promiseError() {
|
||||
Promise.reject('主动抛promise1')
|
||||
Promise.reject(new Error('主动抛promiseError2'))
|
||||
}
|
||||
function yufaError() {
|
||||
// try {
|
||||
setTimeout(() => {
|
||||
a = 1
|
||||
// a = 2;
|
||||
}, 100)
|
||||
// } catch (error) {
|
||||
// console.log(error);
|
||||
// }
|
||||
}
|
||||
function loadError() {
|
||||
const img = new Image()
|
||||
console.log(img)
|
||||
img.src = 'http://a.cn'
|
||||
document.body.appendChild(img)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<h1>{{ msg }}</h1>
|
||||
|
||||
<div class="card">
|
||||
<button class="a b" type="button" aa="11" @click="error">主动抛error</button>
|
||||
<button class="a b" type="button" aa="11" @click="yufaError">语法错误</button>
|
||||
<button class="a b c" id="abv" type="button" @click="promiseError">promise error</button>
|
||||
<button type="button" @click="loadError">资源加载错误</button>
|
||||
|
||||
<!-- <img src="http://a.cn/a/b" alt="" srcset="" />
|
||||
<link rel="stylesheet" href="http://a.cn/c/c/c" /> -->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
button {
|
||||
color: #fff;
|
||||
background-color: rgb(150, 149, 149);
|
||||
border: 0;
|
||||
padding: 6px 10px;
|
||||
margin: 6px;
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
}
|
||||
</style>
|
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { shallowRef, reactive, defineOptions } from 'vue'
|
||||
import { shallowRef, reactive } from 'vue'
|
||||
import { flow_apply_detail } from '@/api/flow/flow_apply'
|
||||
import { flow_history_list, flow_history_edit } from '@/api/flow/flow_history'
|
||||
import type { type_flow_history } from '@/api/flow/flow_history'
|
||||
|
@@ -58,7 +58,7 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { defineOptions, ref, shallowRef, reactive } from 'vue'
|
||||
import { ref, shallowRef, reactive } from 'vue'
|
||||
import type { FormInstance } from 'element-plus'
|
||||
import feedback from '@/utils/feedback'
|
||||
import { noticeDetail, setNoticeConfig } from '@/api/message'
|
||||
|
@@ -81,7 +81,12 @@ const formData = reactive({
|
||||
UserId: null,
|
||||
Os: null,
|
||||
Browser: null,
|
||||
Country: null,
|
||||
Province: null,
|
||||
City: null,
|
||||
Operator: null,
|
||||
Ip: null,
|
||||
|
||||
Width: null,
|
||||
Height: null,
|
||||
Ua: null,
|
||||
@@ -117,27 +122,7 @@ const formRules = {
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
Os: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入系统',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
Browser: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入浏览器',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
City: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入城市',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
|
||||
Width: [
|
||||
{
|
||||
required: true,
|
||||
@@ -152,13 +137,7 @@ const formRules = {
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
Ua: [
|
||||
{
|
||||
required: true,
|
||||
message: '请输入ua记录',
|
||||
trigger: ['blur']
|
||||
}
|
||||
],
|
||||
|
||||
ClientTime: [
|
||||
{
|
||||
required: true,
|
||||
|
@@ -6,7 +6,7 @@
|
||||
class="mb-[-16px]"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-width="70px"
|
||||
label-width="90px"
|
||||
label-position="left"
|
||||
>
|
||||
<el-form-item label="项目" prop="ProjectKey" class="w-[280px]">
|
||||
@@ -20,9 +20,9 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="客户端id" prop="ClientId" class="w-[280px]">
|
||||
<!-- <el-form-item label="客户端id" prop="ClientId" class="w-[280px]">
|
||||
<el-input v-model="queryParams.ClientId" />
|
||||
</el-form-item>
|
||||
</el-form-item> -->
|
||||
<el-form-item label="用户id" prop="UserId" class="w-[280px]">
|
||||
<el-input v-model="queryParams.UserId" />
|
||||
</el-form-item>
|
||||
@@ -32,13 +32,25 @@
|
||||
<el-form-item label="浏览器" prop="Browser" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Browser" />
|
||||
</el-form-item>
|
||||
<el-form-item label="国家" prop="Country" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Country" />
|
||||
</el-form-item>
|
||||
<el-form-item label="省份" prop="Province" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Province" />
|
||||
</el-form-item>
|
||||
<el-form-item label="城市" prop="City" class="w-[280px]">
|
||||
<el-input v-model="queryParams.City" />
|
||||
</el-form-item>
|
||||
<el-form-item label="ua记录" prop="Ua" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Ua" />
|
||||
<el-form-item label="电信运营商" prop="Operator" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Operator" />
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="CreateTime" class="w-[280px]">
|
||||
<el-form-item label="ip" prop="Ip" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Ip" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="ua记录" prop="Ua" class="w-[280px]">
|
||||
<el-input v-model="queryParams.Ua" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="创建时间" prop="CreateTime" class="w-[425px]">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.CreateTimeStart"
|
||||
v-model:endTime="queryParams.CreateTimeEnd"
|
||||
@@ -116,15 +128,56 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="客户端id" prop="ClientId" min-width="130" />
|
||||
<el-table-column label="用户id" prop="UserId" min-width="130" />
|
||||
<el-table-column label="系统" prop="Os" min-width="130" />
|
||||
<el-table-column label="浏览器" prop="Browser" min-width="130" />
|
||||
<el-table-column label="城市" prop="City" min-width="130" />
|
||||
<el-table-column label="屏幕" prop="Width" min-width="130" />
|
||||
<el-table-column label="屏幕高度" prop="Height" 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="客户端id" prop="ClientId" min-width="130" /> -->
|
||||
<el-table-column label="用户id" prop="UserId">
|
||||
<template #default="{ row }">
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
:width="500"
|
||||
trigger="hover"
|
||||
:content="row.ClientId"
|
||||
>
|
||||
<template #reference>
|
||||
<el-link type="primary">{{ row.UserId }}</el-link>
|
||||
</template>
|
||||
<div>用 户 ID :{{ row.UserId }}</div>
|
||||
<div>客户端ID:{{ row.ClientId }}</div>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="浏览器" prop="Browser" min-width="150">
|
||||
<template #default="{ row }">
|
||||
<el-popover
|
||||
placement="top-start"
|
||||
title="浏览器ua"
|
||||
:width="500"
|
||||
trigger="hover"
|
||||
:content="row.Ua"
|
||||
>
|
||||
<template #reference>
|
||||
<el-link type="primary">{{ row.Os }} / {{ row.Browser }}</el-link>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="IP" prop="Ip" />
|
||||
<el-table-column label="区域">
|
||||
<template #default="{ row }">
|
||||
{{ row.Country }}{{ row.Province }}{{ row.City }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- <el-table-column label="省份" prop="Province" />
|
||||
<el-table-column label="城市" prop="City" /> -->
|
||||
<el-table-column label="运营商" prop="Operator" />
|
||||
|
||||
<el-table-column label="屏幕" prop="Width">
|
||||
<template #default="{ row }"> {{ row.Width }} * {{ row.Height }} </template>
|
||||
</el-table-column>
|
||||
<!-- <el-table-column label="屏幕高度" prop="Height" min-width="130" /> -->
|
||||
<!-- <el-table-column label="ua记录" prop="Ua" min-width="380" /> -->
|
||||
<el-table-column label="创建时间" prop="CreateTime" min-width="140" />
|
||||
|
||||
<el-table-column label="操作" width="80" fixed="right">
|
||||
<template #default="{ row }">
|
||||
@@ -182,14 +235,16 @@ const queryParams = reactive<type_monitor_client_query>({
|
||||
UserId: null,
|
||||
Os: null,
|
||||
Browser: null,
|
||||
Country: null,
|
||||
Province: null,
|
||||
City: null,
|
||||
Operator: null,
|
||||
Ip: null,
|
||||
Width: null,
|
||||
Height: null,
|
||||
Ua: null,
|
||||
CreateTimeStart: null,
|
||||
CreateTimeEnd: null,
|
||||
ClientTimeStart: null,
|
||||
ClientTimeEnd: null
|
||||
CreateTimeEnd: null
|
||||
})
|
||||
|
||||
const { pager, getLists, resetPage, resetParams } = usePaging<type_monitor_client>({
|
||||
|
@@ -4,47 +4,47 @@
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="90%"
|
||||
width="98%"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="12">
|
||||
<el-row :gutter="10">
|
||||
<el-col :xs="24" :md="14">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>错误详情</span>
|
||||
<span
|
||||
>【
|
||||
<dict-value
|
||||
:options="listAllData.monitor_project_listAll"
|
||||
:value="formData.ProjectKey"
|
||||
labelKey="ProjectName"
|
||||
valueKey="ProjectKey"
|
||||
/>】错误详情</span
|
||||
>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form ref="formRef">
|
||||
<el-form-item label="项目key" prop="ProjectKey">
|
||||
<dict-value
|
||||
:options="listAllData.monitor_project_listAll"
|
||||
:value="formData.ProjectKey"
|
||||
labelKey="ProjectName"
|
||||
valueKey="ProjectKey"
|
||||
/>
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="项目key" prop="ProjectKey"> </el-form-item> -->
|
||||
|
||||
<el-form-item label="事件类型" prop="EventType">
|
||||
<el-form-item label="事件类型:" prop="EventType">
|
||||
{{ formData.EventType }}
|
||||
</el-form-item>
|
||||
<el-form-item label="URL地址" prop="Path">
|
||||
<el-form-item label="URL地址:" prop="Path">
|
||||
{{ formData.Path }}
|
||||
</el-form-item>
|
||||
<el-form-item label="错误消息" prop="Message">
|
||||
<el-form-item label="错误消息:" prop="Message">
|
||||
{{ formData.Message }}
|
||||
</el-form-item>
|
||||
<el-form-item label="错误堆栈" prop="Stack">
|
||||
<el-form-item label="" prop="Stack">
|
||||
{{ formData.Stack }}
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<!-- <template #footer>Footer content</template> -->
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :xs="24" :md="10">
|
||||
<el-card>
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
@@ -61,24 +61,31 @@
|
||||
>
|
||||
<template #title>
|
||||
<div class="flex-1 text-left">
|
||||
{{ user.UserId }}
|
||||
{{ user.City }} {{ user.Browser }}:{{ user.Ip }}
|
||||
</div>
|
||||
<span class="">
|
||||
<span>
|
||||
{{ user.CreateTime }}
|
||||
</span>
|
||||
</template>
|
||||
<el-descriptions border>
|
||||
<el-descriptions-item label="城市:">{{
|
||||
user.City
|
||||
<el-descriptions border :column="2">
|
||||
<el-descriptions-item label="省市区">
|
||||
{{ user.Country }}{{ user.Province }}{{ user.City }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="浏览器">
|
||||
{{ user.Os }}/{{ user.Browser }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="网络">{{
|
||||
user.Operator
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="IP">{{
|
||||
user.Ip
|
||||
}}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="OS:">{{
|
||||
user.Os
|
||||
<el-descriptions-item label="业务ID">{{
|
||||
user.UserId
|
||||
}}</el-descriptions-item>
|
||||
<el-descriptions-item label="屏幕尺寸:">
|
||||
<el-tag size="small"
|
||||
>{{ user.Width }}*{{ user.Height }}</el-tag
|
||||
>
|
||||
<el-descriptions-item label="屏幕">
|
||||
{{ user.Width }}*{{ user.Height }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="userAgent">
|
||||
{{ user.Ua }}
|
||||
|
@@ -98,8 +98,7 @@ const formData = reactive({
|
||||
Path: null,
|
||||
Message: null,
|
||||
Stack: null,
|
||||
Md5: null,
|
||||
ClientTime: null
|
||||
Md5: null
|
||||
})
|
||||
|
||||
const formRules = {
|
||||
|
@@ -7,7 +7,7 @@
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-width="70px"
|
||||
label-position="left"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item label="项目" prop="ProjectKey" class="w-[280px]">
|
||||
<el-select v-model="queryParams.ProjectKey" clearable>
|
||||
@@ -38,42 +38,6 @@
|
||||
</el-card>
|
||||
<el-card class="!border-none mt-4" shadow="never">
|
||||
<div class="text-right">
|
||||
<el-button
|
||||
v-perms="['admin:monitor_error:add']"
|
||||
type="primary"
|
||||
@click="handleAdd()"
|
||||
>
|
||||
<template #icon>
|
||||
<icon name="el-icon-Plus" />
|
||||
</template>
|
||||
新增
|
||||
</el-button>
|
||||
<upload
|
||||
v-perms="['admin:monitor_error:ImportFile']"
|
||||
class="ml-3 mr-3"
|
||||
:url="monitor_error_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_error:ExportFile']"
|
||||
type="primary"
|
||||
@click="exportFile"
|
||||
>
|
||||
<template #icon>
|
||||
<icon name="el-icon-Download" />
|
||||
</template>
|
||||
导出
|
||||
</el-button>
|
||||
<el-button
|
||||
v-perms="['admin:monitor_error:delBatch']"
|
||||
type="danger"
|
||||
@@ -92,7 +56,7 @@
|
||||
@selection-change="handleSelectionChange"
|
||||
>
|
||||
<el-table-column type="selection" width="55" />
|
||||
<el-table-column label="项目" prop="ProjectKey" min-width="100">
|
||||
<el-table-column label="项目" prop="ProjectKey" min-width="80">
|
||||
<template #default="{ row }">
|
||||
<dict-value
|
||||
:options="listAllData.monitor_project_listAll"
|
||||
@@ -102,13 +66,13 @@
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="事件类型" prop="EventType" min-width="130" />
|
||||
<el-table-column label="事件类型" prop="EventType" 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="Stack" min-width="130" />
|
||||
<el-table-column label="md5" prop="Md5" min-width="130" />
|
||||
<el-table-column label="创建时间" prop="CreateTime" min-width="130" />
|
||||
<el-table-column label="更新时间" prop="ClientTime" min-width="130" />
|
||||
|
||||
<!-- <el-table-column label="md5" prop="Md5" min-width="130" /> -->
|
||||
<el-table-column label="创建时间" prop="CreateTime" width="170" />
|
||||
|
||||
<el-table-column label="操作" width="120" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button
|
||||
@@ -154,9 +118,7 @@ import { ref, reactive, shallowRef, nextTick } from 'vue'
|
||||
import {
|
||||
monitor_error_delete,
|
||||
monitor_error_delete_batch,
|
||||
monitor_error_list,
|
||||
monitor_error_import_file,
|
||||
monitor_error_export_file
|
||||
monitor_error_list
|
||||
} from '@/api/monitor/error'
|
||||
import type { type_monitor_error, type_monitor_error_query } from '@/api/monitor/error'
|
||||
|
||||
@@ -197,11 +159,6 @@ const { listAllData } = useListAllData<{
|
||||
})
|
||||
|
||||
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
|
||||
const handleAdd = async () => {
|
||||
showEdit.value = true
|
||||
await nextTick()
|
||||
editRef.value?.open('add')
|
||||
}
|
||||
|
||||
const multipleSelection = ref<type_monitor_error[]>([])
|
||||
const handleSelectionChange = (val: type_monitor_error[]) => {
|
||||
@@ -240,11 +197,5 @@ const deleteBatch = async () => {
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
const exportFile = async () => {
|
||||
try {
|
||||
await feedback.confirm('确定要导出?')
|
||||
await monitor_error_export_file(queryParams)
|
||||
} catch (error) {}
|
||||
}
|
||||
getLists()
|
||||
</script>
|
||||
|
@@ -4,14 +4,14 @@
|
||||
ref="popupRef"
|
||||
:title="popupTitle"
|
||||
:async="true"
|
||||
width="550px"
|
||||
width="700px"
|
||||
:clickModalClose="true"
|
||||
@confirm="handleSubmit"
|
||||
@close="handleClose"
|
||||
>
|
||||
<el-form ref="formRef" :model="formData" label-width="84px" :rules="formRules">
|
||||
<el-form-item label="项目uuid" prop="ProjectKey">
|
||||
<el-input v-model="formData.ProjectKey" placeholder="请输入项目uuid" />
|
||||
<el-form-item label="项目uuid" prop="ProjectKey" v-if="mode === 'edit'">
|
||||
{{ formData.ProjectKey }}
|
||||
</el-form-item>
|
||||
<el-form-item label="项目名称" prop="ProjectName">
|
||||
<el-input v-model="formData.ProjectName" placeholder="请输入项目名称" />
|
||||
@@ -48,6 +48,9 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="使用SDK" v-if="mode == 'edit'">
|
||||
<highlight-code :code="code" lang="javascript"></highlight-code>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</popup>
|
||||
</div>
|
||||
@@ -73,6 +76,7 @@ defineProps({
|
||||
default: () => ({})
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['success', 'close'])
|
||||
const formRef = shallowRef<FormInstance>()
|
||||
const popupRef = shallowRef<InstanceType<typeof Popup>>()
|
||||
@@ -88,7 +92,19 @@ const formData = reactive({
|
||||
ProjectType: null,
|
||||
Status: null
|
||||
})
|
||||
|
||||
const code = computed(() => {
|
||||
return `import { XErr, XErrWeb } from '../../x_err_sdk/web/index'
|
||||
new XErr(
|
||||
{
|
||||
Dns: '${location.origin}/api',
|
||||
Pid: '${formData.ProjectKey}',
|
||||
Uid: ''
|
||||
},
|
||||
new XErrWeb({
|
||||
onloadTimeOut: 3000
|
||||
})
|
||||
)`
|
||||
})
|
||||
const formRules = {
|
||||
Id: [
|
||||
{
|
||||
|
@@ -37,13 +37,13 @@
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="创建时间" prop="CreateTime" class="w-[280px]">
|
||||
<el-form-item label="创建时间" prop="CreateTime" class="w-[430px]">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.CreateTimeStart"
|
||||
v-model:endTime="queryParams.CreateTimeEnd"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="更新时间" prop="UpdateTime" class="w-[280px]">
|
||||
<el-form-item label="更新时间" prop="UpdateTime" class="w-[420px]">
|
||||
<daterange-picker
|
||||
v-model:startTime="queryParams.UpdateTimeStart"
|
||||
v-model:endTime="queryParams.UpdateTimeEnd"
|
||||
|
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>
|
202
admin/src/views/monitor/slow/index.vue
Normal file
202
admin/src/views/monitor/slow/index.vue
Normal file
@@ -0,0 +1,202 @@
|
||||
<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="项目" prop="ProjectKey" class="w-[280px]">
|
||||
<el-select v-model="queryParams.ProjectKey" clearable>
|
||||
<el-option label="全部" value="" />
|
||||
<el-option
|
||||
v-for="(item, index) in listAllData.monitor_project_listAll"
|
||||
:key="index"
|
||||
:label="item.ProjectName"
|
||||
:value="item.ProjectKey"
|
||||
/>
|
||||
</el-select>
|
||||
</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-[420px]">
|
||||
<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="项目" prop="ProjectKey" width="150">
|
||||
<template #default="{ row }">
|
||||
<dict-value
|
||||
:options="listAllData.monitor_project_listAll"
|
||||
:value="row.ProjectKey"
|
||||
labelKey="ProjectName"
|
||||
valueKey="ProjectKey"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="用户id" prop="UserId" width="150" />
|
||||
<el-table-column label="URL地址" prop="Path" />
|
||||
<el-table-column label="时间(毫秒)" prop="Time" width="130" />
|
||||
<el-table-column label="创建时间" prop="CreateTime" width="180" />
|
||||
<el-table-column label="操作" width="80" 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 } from 'vue'
|
||||
import {
|
||||
monitor_slow_delete,
|
||||
monitor_slow_delete_batch,
|
||||
monitor_slow_list
|
||||
} from '@/api/monitor/slow'
|
||||
import type { type_monitor_slow, type_monitor_slow_query } from '@/api/monitor/slow'
|
||||
|
||||
import { useListAllData } from '@/hooks/useDictOptions'
|
||||
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 { listAllData } = useListAllData<{
|
||||
monitor_project_listAll: any[]
|
||||
}>({
|
||||
monitor_project_listAll: '/monitor_project/listAll'
|
||||
})
|
||||
|
||||
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) {}
|
||||
}
|
||||
|
||||
getLists()
|
||||
</script>
|
@@ -23,10 +23,12 @@ export default ({ mode }) => {
|
||||
// 依赖预构建,避免开发刷新
|
||||
include: ['@wangeditor/editor-for-vue', 'vuedraggable', 'vue-echarts', 'crypto-js']
|
||||
},
|
||||
|
||||
base: '/',
|
||||
build: {
|
||||
sourcemap: true,
|
||||
rollupOptions: {
|
||||
external: ['XErr'],
|
||||
output: {
|
||||
manualChunks: {
|
||||
vue: ['vue'],
|
||||
|
@@ -4,8 +4,13 @@
|
||||
|
||||
## 前端页面使用history模式需要重定向
|
||||
```nginx
|
||||
|
||||
location / {
|
||||
index /index.html;
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
# 找不到静态文件返回404
|
||||
location ~* \.(?:html|css|js|png|jpg|jpeg|gif|webp|pdf|mp4|mp3|aac|ico|svg|woff|woff2|ttf|eot)$ {
|
||||
try_files $uri =404;
|
||||
}
|
||||
```
|
@@ -17,6 +17,9 @@
|
||||
},
|
||||
{
|
||||
"path": ".workflow"
|
||||
},
|
||||
{
|
||||
"path": "x_err_sdk"
|
||||
}
|
||||
],
|
||||
"settings": {
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -58,7 +58,7 @@ func (service ArticleCollectService) List(page request.PageReq, listReq ArticleC
|
||||
return
|
||||
}
|
||||
result := []ArticleCollectResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/common_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -66,7 +67,7 @@ func (albSrv albumService) AlbumList(page request.PageReq, listReq CommonAlbumLi
|
||||
return
|
||||
}
|
||||
albumResps := []CommonAlbumListResp{}
|
||||
util.ConvertUtil.Copy(&albumResps, albums)
|
||||
convert_util.Copy(&albumResps, albums)
|
||||
// TODO: engine默认local
|
||||
engine := "local"
|
||||
for i := 0; i < len(albumResps); i++ {
|
||||
@@ -134,7 +135,7 @@ func (albSrv albumService) AlbumAdd(addReq CommonAlbumAddReq) (res uint, e error
|
||||
// core.Logger.Errorf("AlbumAdd Decode err: err=[%+v]", err)
|
||||
// return response.SystemError
|
||||
//}
|
||||
util.ConvertUtil.Copy(&alb, addReq)
|
||||
convert_util.Copy(&alb, addReq)
|
||||
err := albSrv.db.Create(&alb).Error
|
||||
if e = response.CheckErr(err, "Album添加失败"); e != nil {
|
||||
return
|
||||
@@ -173,14 +174,14 @@ func (albSrv albumService) CateList(listReq CommonCateListReq) (mapList []Common
|
||||
return
|
||||
}
|
||||
cateResps := []CommonCateListResp{}
|
||||
util.ConvertUtil.Copy(&cateResps, cates)
|
||||
convert_util.Copy(&cateResps, cates)
|
||||
return cateResps, nil
|
||||
}
|
||||
|
||||
// CateAdd 分类新增
|
||||
func (albSrv albumService) CateAdd(addReq CommonCateAddReq) (e error) {
|
||||
var cate common_model.AlbumCate
|
||||
util.ConvertUtil.Copy(&cate, addReq)
|
||||
convert_util.Copy(&cate, addReq)
|
||||
err := albSrv.db.Create(&cate).Error
|
||||
e = response.CheckErr(err, "Cate添加失败")
|
||||
return
|
||||
|
@@ -8,14 +8,6 @@ import (
|
||||
)
|
||||
|
||||
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{}
|
||||
|
||||
rg = rg.Group("/common", middleware.TokenAuth())
|
||||
|
@@ -10,15 +10,10 @@ import (
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type IIndexService interface {
|
||||
Console() (res map[string]interface{}, e error)
|
||||
Config() (res map[string]interface{}, e error)
|
||||
}
|
||||
|
||||
var Service = NewIndexService()
|
||||
|
||||
// NewIndexService 初始化
|
||||
func NewIndexService() IIndexService {
|
||||
func NewIndexService() *indexService {
|
||||
db := core.GetDB()
|
||||
return &indexService{db: db}
|
||||
}
|
||||
@@ -47,7 +42,7 @@ func (iSrv indexService) Console() (res map[string]interface{}, e error) {
|
||||
}
|
||||
// 今日数据
|
||||
today := map[string]interface{}{
|
||||
"time": "2022-08-11 15:08:29",
|
||||
"time": util.NullTimeUtil.Now(),
|
||||
"todayVisits": 10, // 访问量(人)
|
||||
"totalVisits": 100, // 总访问量
|
||||
"todaySales": 30, // 销售额(元)
|
||||
@@ -65,7 +60,7 @@ func (iSrv indexService) Console() (res map[string]interface{}, e error) {
|
||||
}
|
||||
visitor := map[string]interface{}{
|
||||
"date": date,
|
||||
"list": []int{12, 13, 11, 5, 8, 22, 14, 9, 456, 62, 78, 12, 18, 22, 46},
|
||||
"list": []int{12, 13, 11, 5, 100, 22, 14, 9, 456, 62, 78, 12, 18, 22, 46},
|
||||
}
|
||||
return map[string]interface{}{
|
||||
"version": version,
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"mime/multipart"
|
||||
"x_admin/admin/common/album"
|
||||
"x_admin/plugin"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
)
|
||||
|
||||
type IUploadService interface {
|
||||
@@ -39,14 +39,14 @@ func (upSrv uploadService) uploadFile(file *multipart.FileHeader, folder string,
|
||||
return
|
||||
}
|
||||
var addReq album.CommonAlbumAddReq
|
||||
util.ConvertUtil.Copy(&addReq, upRes)
|
||||
convert_util.Copy(&addReq, upRes)
|
||||
addReq.Aid = aid
|
||||
addReq.Cid = cid
|
||||
var albumId uint
|
||||
if albumId, e = album.Service.AlbumAdd(addReq); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, addReq)
|
||||
convert_util.Copy(&res, addReq)
|
||||
res.ID = albumId
|
||||
res.Path = upRes.Path
|
||||
return res, nil
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -81,7 +82,7 @@ func (service flowApplyService) List(page request.PageReq, listReq FlowApplyList
|
||||
return
|
||||
}
|
||||
result := []FlowApplyResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -100,7 +101,7 @@ func (service flowApplyService) Detail(id int) (res FlowApplyResp, e error) {
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -111,7 +112,7 @@ func (service flowApplyService) Add(addReq FlowApplyAddReq) (e error) {
|
||||
if e = response.CheckErrDBNotRecord(err, "模板不存在!"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&obj, addReq)
|
||||
convert_util.Copy(&obj, addReq)
|
||||
// obj.FlowName = flow_template_resp.FlowName
|
||||
obj.FlowGroup = flow_template_resp.FlowGroup
|
||||
obj.FlowRemark = flow_template_resp.FlowRemark
|
||||
@@ -136,7 +137,7 @@ func (service flowApplyService) Edit(editReq FlowApplyEditReq) (e error) {
|
||||
return
|
||||
}
|
||||
// 更新
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
err = service.db.Model(&obj).Updates(obj).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
|
@@ -14,6 +14,7 @@ import (
|
||||
"x_admin/model"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -93,7 +94,7 @@ func (service flowHistoryService) List(page request.PageReq, listReq FlowHistory
|
||||
return
|
||||
}
|
||||
list := []FlowHistoryResp{}
|
||||
util.ConvertUtil.Copy(&list, modelList)
|
||||
convert_util.Copy(&list, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -122,7 +123,7 @@ func (service flowHistoryService) ListAll(listReq FlowHistoryListReq) (res []Flo
|
||||
if e = response.CheckErr(err, "获取列表失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -136,14 +137,14 @@ func (service flowHistoryService) Detail(id int) (res FlowHistoryResp, e error)
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 流程历史新增
|
||||
func (service flowHistoryService) Add(addReq FlowHistoryAddReq) (e error) {
|
||||
var obj model.FlowHistory
|
||||
util.ConvertUtil.Copy(&obj, addReq)
|
||||
convert_util.Copy(&obj, addReq)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -161,7 +162,7 @@ func (service flowHistoryService) Edit(editReq FlowHistoryEditReq) (e error) {
|
||||
return
|
||||
}
|
||||
// 更新
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
err = service.db.Model(&obj).Updates(obj).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
@@ -422,7 +423,7 @@ func (service flowHistoryService) Back(back BackReq) (e error) {
|
||||
}
|
||||
|
||||
var obj model.FlowApply
|
||||
util.ConvertUtil.Copy(&obj, applyDetail)
|
||||
convert_util.Copy(&obj, applyDetail)
|
||||
obj.Status = 4
|
||||
err = tx.Save(&obj).Error
|
||||
if err != nil {
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -67,7 +67,7 @@ func (service flowTemplateService) List(page request.PageReq, listReq FlowTempla
|
||||
return
|
||||
}
|
||||
result := []FlowTemplateResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -83,7 +83,7 @@ func (service flowTemplateService) ListAll() (res []FlowTemplateResp, e error) {
|
||||
if e = response.CheckErr(err, "获取列表失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -97,14 +97,14 @@ func (service flowTemplateService) Detail(id int) (res FlowTemplateResp, e error
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 流程模板新增
|
||||
func (service flowTemplateService) Add(addReq FlowTemplateAddReq) (e error) {
|
||||
var obj model.FlowTemplate
|
||||
util.ConvertUtil.Copy(&obj, addReq)
|
||||
convert_util.Copy(&obj, addReq)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -122,7 +122,7 @@ func (service flowTemplateService) Edit(editReq FlowTemplateEditReq) (e error) {
|
||||
return
|
||||
}
|
||||
// 更新
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
err = service.db.Model(&obj).Updates(obj).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/gen_model"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"strings"
|
||||
|
||||
@@ -123,11 +124,11 @@ func (genSrv generateService) Detail(id uint) (res GenTableDetailResp, e error)
|
||||
return
|
||||
}
|
||||
var base GenTableBaseResp
|
||||
util.ConvertUtil.Copy(&base, genTb)
|
||||
convert_util.Copy(&base, genTb)
|
||||
var gen GenTableGenResp
|
||||
util.ConvertUtil.Copy(&gen, genTb)
|
||||
convert_util.Copy(&gen, genTb)
|
||||
var colResp []GenColumnResp
|
||||
util.ConvertUtil.Copy(&colResp, columns)
|
||||
convert_util.Copy(&colResp, columns)
|
||||
return GenTableDetailResp{
|
||||
Base: base,
|
||||
Gen: gen,
|
||||
@@ -143,7 +144,7 @@ func (genSrv generateService) ImportTable(tableNames []string) (e error) {
|
||||
return
|
||||
}
|
||||
var tables []gen_model.GenTable
|
||||
util.ConvertUtil.Copy(&tables, dbTbs)
|
||||
convert_util.Copy(&tables, dbTbs)
|
||||
if len(tables) == 0 {
|
||||
e = response.AssertArgumentError.SetMessage("表不存在!")
|
||||
return
|
||||
@@ -281,7 +282,7 @@ func (genSrv generateService) EditTable(editReq EditTableReq) (e error) {
|
||||
if e = response.CheckErr(err, "查找数据失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&genTable, editReq)
|
||||
convert_util.Copy(&genTable, editReq)
|
||||
err = genSrv.db.Transaction(func(tx *gorm.DB) error {
|
||||
genTable.SubTableName = strings.Replace(editReq.SubTableName, config.Config.DbTablePrefix, "", 1)
|
||||
txErr := tx.Save(&genTable).Error
|
||||
@@ -290,7 +291,7 @@ func (genSrv generateService) EditTable(editReq EditTableReq) (e error) {
|
||||
}
|
||||
for i := 0; i < len(editReq.Columns); i++ {
|
||||
var col gen_model.GenTableColumn
|
||||
util.ConvertUtil.Copy(&col, editReq.Columns[i])
|
||||
convert_util.Copy(&col, editReq.Columns[i])
|
||||
txErr = tx.Save(&col).Error
|
||||
if te := response.CheckErr(txErr, "更新失败"); te != nil {
|
||||
return te
|
||||
|
@@ -26,19 +26,17 @@ admin:{{{.ModuleName }}}:detail
|
||||
admin:{{{.ModuleName }}}:ExportFile
|
||||
admin:{{{.ModuleName }}}: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', '{{{ .FunctionName }}}', '{{{nameToPath .ModuleName }}}/index', '{{{nameToPath .ModuleName }}}/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', '{{{ .FunctionName }}}添加','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}编辑','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}删除','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}删除-批量','admin:{{{ .ModuleName }}}: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 (0, 'A', '{{{ .FunctionName }}}列表','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}全部列表','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}详情','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}导出excel','admin:{{{ .ModuleName }}}: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', '{{{ .FunctionName }}}导入excel','admin:{{{ .ModuleName }}}: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) SELECT id, 'A', '{{{ .FunctionName }}}添加','admin:{{{ .ModuleName }}}:add', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}编辑','admin:{{{ .ModuleName }}}:edit', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}删除','admin:{{{ .ModuleName }}}:del', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}删除-批量','admin:{{{ .ModuleName }}}:delBatch', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}列表','admin:{{{ .ModuleName }}}:list', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}全部列表','admin:{{{ .ModuleName }}}:listAll', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}详情','admin:{{{ .ModuleName }}}:detail', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}导出excel','admin:{{{ .ModuleName }}}:ExportFile', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_show, is_disable, create_time, update_time) SELECT id, 'A', '{{{ .FunctionName }}}导入excel','admin:{{{ .ModuleName }}}:ImportFile', 0, 1, 0, now(), now() FROM x_system_auth_menu WHERE component='{{{nameToPath .ModuleName }}}/index';
|
||||
*/
|
||||
|
||||
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"x_admin/model"
|
||||
"gorm.io/gorm"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
)
|
||||
|
||||
@@ -82,7 +83,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) List(page request.PageReq,
|
||||
return
|
||||
}
|
||||
result := []{{{ toUpperCamelCase .EntityName }}}Resp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -100,7 +101,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) ListAll(listReq {{{ toUppe
|
||||
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -125,14 +126,14 @@ func (service {{{ toCamelCase .EntityName }}}Service) Detail({{{ toUpperCamelCas
|
||||
cacheUtil.SetCache(obj.{{{ toUpperCamelCase .PrimaryKey }}}, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add {{{ .FunctionName }}}新增
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) Add(addReq {{{ toUpperCamelCase .EntityName }}}AddReq) (createId int,e error) {
|
||||
var obj model.{{{ toUpperCamelCase .EntityName }}}
|
||||
util.ConvertUtil.StructToStruct(addReq,&obj)
|
||||
convert_util.StructToStruct(addReq,&obj)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
@@ -154,7 +155,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) Edit(editReq {{{ toUpperCa
|
||||
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
|
||||
err = service.db.Model(&obj).Select("*").Updates(obj).Error
|
||||
if e = response.CheckErr(err, "编辑失败"); e != nil {
|
||||
@@ -200,9 +201,7 @@ func (service {{{ toCamelCase .EntityName }}}Service) DelBatch(Ids []string) (e
|
||||
return err
|
||||
}
|
||||
// 删除缓存
|
||||
for _, v := range Ids {
|
||||
cacheUtil.RemoveCache(v)
|
||||
}
|
||||
cacheUtil.RemoveCache(Ids)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,14 +236,14 @@ func (service {{{ toCamelCase .EntityName }}}Service) ExportFile(listReq {{{ toU
|
||||
return
|
||||
}
|
||||
result := []{{{ toUpperCamelCase .EntityName }}}Resp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service {{{ toCamelCase .EntityName }}}Service) ImportFile(importReq []{{{ toUpperCamelCase .EntityName }}}Resp) (e error) {
|
||||
var importData []model.{{{ toUpperCamelCase .EntityName }}}
|
||||
util.ConvertUtil.Copy(&importData, importReq)
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
|
@@ -173,7 +173,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
import { ref,reactive,shallowRef } from 'vue'
|
||||
import { ref,reactive,shallowRef,nextTick } from 'vue'
|
||||
import { {{{ .ModuleName }}}_delete,{{{ .ModuleName }}}_delete_batch, {{{ .ModuleName }}}_list,{{{.ModuleName}}}_import_file, {{{.ModuleName}}}_export_file } from '@/api/{{{nameToPath .ModuleName }}}'
|
||||
import type { type_{{{ .ModuleName }}},type_{{{.ModuleName}}}_query } from "@/api/{{{nameToPath .ModuleName }}}";
|
||||
|
||||
|
@@ -1,14 +1,19 @@
|
||||
package monitor_client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"x_admin/core"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/util"
|
||||
"x_admin/util/excel2"
|
||||
"x_admin/util/img_util"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/sync/singleflight"
|
||||
@@ -29,7 +34,11 @@ type MonitorClientHandler struct {
|
||||
// @Param UserId query string false "用户id"
|
||||
// @Param Os query string false "系统"
|
||||
// @Param Browser query string false "浏览器"
|
||||
// @Param Country query string false "国家"
|
||||
// @Param Province query string false "省份"
|
||||
// @Param City query string false "城市"
|
||||
// @Param Operator query string false "电信运营商"
|
||||
// @Param Ip query string false "ip"
|
||||
// @Param Width query number false "屏幕"
|
||||
// @Param Height query number false "屏幕高度"
|
||||
// @Param Ua query string false "ua记录"
|
||||
@@ -59,7 +68,11 @@ func (hd *MonitorClientHandler) List(c *gin.Context) {
|
||||
// @Param UserId query string false "用户id"
|
||||
// @Param Os query string false "系统"
|
||||
// @Param Browser query string false "浏览器"
|
||||
// @Param Country query string false "国家"
|
||||
// @Param Province query string false "省份"
|
||||
// @Param City query string false "城市"
|
||||
// @Param Operator query string false "电信运营商"
|
||||
// @Param Ip query string false "ip"
|
||||
// @Param Width query number false "屏幕"
|
||||
// @Param Height query number false "屏幕高度"
|
||||
// @Param Ua query string false "ua记录"
|
||||
@@ -114,44 +127,67 @@ func (hd *MonitorClientHandler) Detail(c *gin.Context) {
|
||||
// @Param UserId body string false "用户id"
|
||||
// @Param Os body string false "系统"
|
||||
// @Param Browser body string false "浏览器"
|
||||
// @Param City body string false "城市"
|
||||
// @Param Country query string false "国家"
|
||||
// @Param Province query string false "省份"
|
||||
// @Param City query string false "城市"
|
||||
// @Param Operator query string false "电信运营商"
|
||||
// @Param Ip query string false "ip"
|
||||
// @Param Width body number false "屏幕"
|
||||
// @Param Height body number false "屏幕高度"
|
||||
// @Param Ua body string false "ua记录"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_client/add [post]
|
||||
func (hd *MonitorClientHandler) Add(c *gin.Context) {
|
||||
var addReq MonitorClientAddReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
data, err := url.QueryUnescape(c.Query("data"))
|
||||
if err != nil {
|
||||
// response.CheckAndRespWithData(c, 0, err)
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
return
|
||||
}
|
||||
createId, e := MonitorClientService.Add(addReq)
|
||||
response.CheckAndRespWithData(c, createId, e)
|
||||
}
|
||||
var addReq MonitorClientAddReq
|
||||
json.Unmarshal([]byte(data), &addReq)
|
||||
|
||||
// @Summary 监控-客户端信息编辑
|
||||
// @Tags monitor_client-监控-客户端信息
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false "uuid"
|
||||
// @Param ProjectKey body string false "项目key"
|
||||
// @Param ClientId body string false "sdk生成的客户端id"
|
||||
// @Param UserId body string false "用户id"
|
||||
// @Param Os body string false "系统"
|
||||
// @Param Browser body string false "浏览器"
|
||||
// @Param City body string false "城市"
|
||||
// @Param Width body number false "屏幕"
|
||||
// @Param Height body number false "屏幕高度"
|
||||
// @Param Ua body string false "ua记录"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_client/edit [post]
|
||||
// func (hd *MonitorClientHandler) Edit(c *gin.Context) {
|
||||
// var editReq MonitorClientEditReq
|
||||
// if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
|
||||
// return
|
||||
// }
|
||||
// response.CheckAndRespWithData(c, editReq.Id, MonitorClientService.Edit(editReq))
|
||||
// }
|
||||
lastClient, err := MonitorClientService.DetailByClientId(*addReq.ClientId)
|
||||
|
||||
uaStr := c.GetHeader("user-agent")
|
||||
ip := c.ClientIP()
|
||||
|
||||
if err == nil {
|
||||
last := lastClient.UserId + lastClient.Width.String() + lastClient.Height.String() + lastClient.Ip + lastClient.Ua
|
||||
newStr := *addReq.UserId + addReq.Width.String() + addReq.Height.String() + ip + uaStr
|
||||
if last == newStr {
|
||||
// 前后数据一样,不用创建新的数据
|
||||
fmt.Println("前后数据一样,不用创建新的数据")
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
// response.CheckAndRespWithData(c, 0, nil)
|
||||
return
|
||||
} else {
|
||||
// 新建的话,需要清除lastClient对应的缓存
|
||||
cacheUtil.RemoveCache("ClientId:" + lastClient.ClientId)
|
||||
}
|
||||
}
|
||||
|
||||
if uaStr != "" {
|
||||
ua := core.UAParser.Parse(uaStr)
|
||||
addReq.Ua = &uaStr
|
||||
addReq.Os = &ua.Os.Family
|
||||
addReq.Browser = &ua.UserAgent.Family
|
||||
}
|
||||
|
||||
addReq.Ip = &ip
|
||||
if ip != "" && ip != "127.0.0.1" {
|
||||
regionInfo := util.IpUtil.Parse(ip)
|
||||
// regionInfo := util.IpUtil.Parse("118.24.157.190")
|
||||
addReq.City = ®ionInfo.City
|
||||
addReq.Country = ®ionInfo.Country
|
||||
addReq.Operator = ®ionInfo.Operator
|
||||
addReq.Province = ®ionInfo.Province
|
||||
}
|
||||
|
||||
MonitorClientService.Add(addReq)
|
||||
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
}
|
||||
|
||||
// @Summary 监控-客户端信息删除
|
||||
// @Tags monitor_client-监控-客户端信息
|
||||
@@ -199,7 +235,11 @@ func (hd *MonitorClientHandler) DelBatch(c *gin.Context) {
|
||||
// @Param UserId query string false "用户id"
|
||||
// @Param Os query string false "系统"
|
||||
// @Param Browser query string false "浏览器"
|
||||
// @Param Country query string false "国家"
|
||||
// @Param Province query string false "省份"
|
||||
// @Param City query string false "城市"
|
||||
// @Param Operator query string false "电信运营商"
|
||||
// @Param Ip query string false "ip"
|
||||
// @Param Width query number false "屏幕"
|
||||
// @Param Height query number false "屏幕高度"
|
||||
// @Param Ua query string false "ua记录"
|
||||
|
@@ -6,12 +6,18 @@ import (
|
||||
|
||||
// MonitorClientListReq 监控-客户端信息列表参数
|
||||
type MonitorClientListReq struct {
|
||||
ProjectKey *string // 项目key
|
||||
ClientId *string // sdk生成的客户端id
|
||||
UserId *string // 用户id
|
||||
Os *string // 系统
|
||||
Browser *string // 浏览器
|
||||
City *string // 城市
|
||||
ProjectKey *string // 项目key
|
||||
ClientId *string // sdk生成的客户端id
|
||||
UserId *string // 用户id
|
||||
Os *string // 系统
|
||||
Browser *string // 浏览器
|
||||
|
||||
Country *string // 国家
|
||||
Province *string // 省份
|
||||
City *string // 城市
|
||||
Operator *string // 电信运营商
|
||||
Ip *string // ip
|
||||
|
||||
Width *int // 屏幕
|
||||
Height *int // 屏幕高度
|
||||
Ua *string // ua记录
|
||||
@@ -27,7 +33,11 @@ type MonitorClientAddReq struct {
|
||||
UserId *string // 用户id
|
||||
Os *string // 系统
|
||||
Browser *string // 浏览器
|
||||
Country *string // 国家
|
||||
Province *string // 省份
|
||||
City *string // 城市
|
||||
Operator *string // 电信运营商
|
||||
Ip *string // ip
|
||||
Width core.NullInt // 屏幕
|
||||
Height core.NullInt // 屏幕高度
|
||||
Ua *string // ua记录
|
||||
@@ -42,7 +52,11 @@ type MonitorClientEditReq struct {
|
||||
UserId *string // 用户id
|
||||
Os *string // 系统
|
||||
Browser *string // 浏览器
|
||||
Country *string // 国家
|
||||
Province *string // 省份
|
||||
City *string // 城市
|
||||
Operator *string // 电信运营商
|
||||
Ip *string // ip
|
||||
Width core.NullInt // 屏幕
|
||||
Height core.NullInt // 屏幕高度
|
||||
Ua *string // ua记录
|
||||
@@ -71,7 +85,11 @@ type MonitorClientResp struct {
|
||||
UserId string // 用户id
|
||||
Os string // 系统
|
||||
Browser string // 浏览器
|
||||
Country string // 国家
|
||||
Province string // 省份
|
||||
City string // 城市
|
||||
Operator string // 电信运营商
|
||||
Ip string // ip
|
||||
Width core.NullInt // 屏幕
|
||||
Height core.NullInt // 屏幕高度
|
||||
Ua string // ua记录
|
||||
|
@@ -1,11 +1,13 @@
|
||||
package monitor_client
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"x_admin/core"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -49,9 +51,21 @@ func (service monitorClientService) GetModel(listReq MonitorClientListReq) *gorm
|
||||
if listReq.Browser != nil {
|
||||
dbModel = dbModel.Where("browser = ?", *listReq.Browser)
|
||||
}
|
||||
if listReq.Country != nil {
|
||||
dbModel = dbModel.Where("country = ?", *listReq.Country)
|
||||
}
|
||||
if listReq.Province != nil {
|
||||
dbModel = dbModel.Where("province = ?", *listReq.Province)
|
||||
}
|
||||
if listReq.City != nil {
|
||||
dbModel = dbModel.Where("city = ?", *listReq.City)
|
||||
}
|
||||
if listReq.Operator != nil {
|
||||
dbModel = dbModel.Where("operator = ?", *listReq.Operator)
|
||||
}
|
||||
if listReq.Ip != nil {
|
||||
dbModel = dbModel.Where("ip = ?", *listReq.Ip)
|
||||
}
|
||||
if listReq.Width != nil {
|
||||
dbModel = dbModel.Where("width = ?", *listReq.Width)
|
||||
}
|
||||
@@ -90,35 +104,7 @@ func (service monitorClientService) List(page request.PageReq, listReq MonitorCl
|
||||
return
|
||||
}
|
||||
result := []MonitorClientResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
Count: count,
|
||||
Lists: result,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// List 监控-客户端信息列表
|
||||
func (service monitorClientService) ListByErrorId(page request.PageReq, listReq MonitorClientListReq, errorId int) (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.MonitorClient
|
||||
err = dbModel.Limit(limit).Offset(offset).Order("id desc").Find(&modelList).Error
|
||||
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||
return
|
||||
}
|
||||
result := []MonitorClientResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -137,10 +123,32 @@ func (service monitorClientService) ListAll(listReq MonitorClientListReq) (res [
|
||||
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (service monitorClientService) DetailByClientId(ClientId string) (res MonitorClientResp, e error) {
|
||||
if ClientId == "" {
|
||||
return res, errors.New("ClientId不能为空")
|
||||
}
|
||||
var obj = model.MonitorClient{}
|
||||
err := cacheUtil.GetCache("ClientId:"+ClientId, &obj)
|
||||
if err != nil {
|
||||
err := service.db.Where("client_id = ?", ClientId).Order("id DESC").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)
|
||||
cacheUtil.SetCache("ClientId:"+obj.ClientId, obj)
|
||||
}
|
||||
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Detail 监控-客户端信息详情
|
||||
func (service monitorClientService) Detail(Id int) (res MonitorClientResp, e error) {
|
||||
var obj = model.MonitorClient{}
|
||||
@@ -154,65 +162,37 @@ func (service monitorClientService) Detail(Id int) (res MonitorClientResp, e err
|
||||
return
|
||||
}
|
||||
cacheUtil.SetCache(obj.Id, obj)
|
||||
cacheUtil.SetCache("ClientId:"+obj.ClientId, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
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)
|
||||
service.db.Raw("SELECT client.*,list.create_time AS create_time from x_monitor_error_list as list right join x_monitor_client as client on client.id = list.cid where list.eid = ? Order by list.id DESC LIMIT 0,20", 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)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 监控-客户端信息新增
|
||||
func (service monitorClientService) Add(addReq MonitorClientAddReq) (createId int, e error) {
|
||||
var obj model.MonitorClient
|
||||
util.ConvertUtil.StructToStruct(addReq, &obj)
|
||||
convert_util.StructToStruct(addReq, &obj)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
return 0, e
|
||||
}
|
||||
cacheUtil.SetCache(obj.Id, obj)
|
||||
cacheUtil.SetCache("ClientId:"+obj.ClientId, obj)
|
||||
createId = obj.Id
|
||||
return
|
||||
}
|
||||
|
||||
// // Edit 监控-客户端信息编辑
|
||||
// func (service monitorClientService) Edit(editReq MonitorClientEditReq) (e error) {
|
||||
// var obj model.MonitorClient
|
||||
// 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 monitorClientService) Del(Id int) (e error) {
|
||||
var obj model.MonitorClient
|
||||
@@ -228,20 +208,34 @@ func (service monitorClientService) Del(Id int) (e error) {
|
||||
err = service.db.Delete(&obj).Error
|
||||
e = response.CheckErr(err, "删除失败")
|
||||
cacheUtil.RemoveCache(obj.Id)
|
||||
cacheUtil.RemoveCache("ClientId:" + obj.ClientId)
|
||||
return
|
||||
}
|
||||
|
||||
// DelBatch 用户协议-批量删除
|
||||
func (service monitorClientService) DelBatch(Ids []string) (e error) {
|
||||
var obj model.MonitorClient
|
||||
err := service.db.Where("id in (?)", Ids).Delete(&obj).Error
|
||||
var obj []model.MonitorClient
|
||||
// 查询Ids对应的数据
|
||||
err := service.db.Where("id in (?)", Ids).Find(&obj).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除缓存
|
||||
for _, v := range Ids {
|
||||
cacheUtil.RemoveCache(v)
|
||||
if len(obj) == 0 {
|
||||
return errors.New("数据不存在")
|
||||
}
|
||||
err = service.db.Where("id in (?)", Ids).Delete(model.MonitorClient{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// md5集合
|
||||
var Clients []string
|
||||
for _, v := range obj {
|
||||
Clients = append(Clients, "ClientId:"+v.ClientId)
|
||||
}
|
||||
|
||||
// 删除缓存
|
||||
cacheUtil.RemoveCache(Ids)
|
||||
cacheUtil.RemoveCache(Clients)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -275,14 +269,14 @@ func (service monitorClientService) ExportFile(listReq MonitorClientListReq) (re
|
||||
return
|
||||
}
|
||||
result := []MonitorClientResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service monitorClientService) ImportFile(importReq []MonitorClientResp) (e error) {
|
||||
var importData []model.MonitorClient
|
||||
util.ConvertUtil.Copy(&importData, importReq)
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
|
@@ -1,7 +1,9 @@
|
||||
package monitor_error
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -9,6 +11,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/util"
|
||||
"x_admin/util/excel2"
|
||||
"x_admin/util/img_util"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"golang.org/x/sync/singleflight"
|
||||
@@ -18,23 +21,23 @@ type MonitorErrorHandler struct {
|
||||
requestGroup singleflight.Group
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列列表
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @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 EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Summary 监控-错误列列表
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @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 EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
//
|
||||
// @Success 200 {object} response.Response{ data=response.PageResp{ lists=[]MonitorErrorResp}} "成功"
|
||||
// @Router /api/admin/monitor_error/list [get]
|
||||
// @Success 200 {object} response.Response{ data=response.PageResp{ lists=[]MonitorErrorResp}} "成功"
|
||||
// @Router /api/admin/monitor_error/list [get]
|
||||
func (hd *MonitorErrorHandler) List(c *gin.Context) {
|
||||
var page request.PageReq
|
||||
var listReq MonitorErrorListReq
|
||||
@@ -48,19 +51,19 @@ func (hd *MonitorErrorHandler) List(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列列表-所有
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param ProjectKey query string false "项目key"
|
||||
// @Param EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Success 200 {object} response.Response{ data=[]MonitorErrorResp} "成功"
|
||||
// @Router /api/admin/monitor_error/listAll [get]
|
||||
// @Summary 监控-错误列列表-所有
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param ProjectKey query string false "项目key"
|
||||
// @Param EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Success 200 {object} response.Response{ data=[]MonitorErrorResp} "成功"
|
||||
// @Router /api/admin/monitor_error/listAll [get]
|
||||
func (hd *MonitorErrorHandler) ListAll(c *gin.Context) {
|
||||
var listReq MonitorErrorListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
@@ -70,13 +73,13 @@ func (hd *MonitorErrorHandler) ListAll(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列详情
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id query number false "错误id"
|
||||
// @Success 200 {object} response.Response{ data=MonitorErrorResp} "成功"
|
||||
// @Router /api/admin/monitor_error/detail [get]
|
||||
// @Summary 监控-错误列详情
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id query number false "错误id"
|
||||
// @Success 200 {object} response.Response{ data=MonitorErrorResp} "成功"
|
||||
// @Router /api/admin/monitor_error/detail [get]
|
||||
func (hd *MonitorErrorHandler) Detail(c *gin.Context) {
|
||||
var detailReq MonitorErrorDetailReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
|
||||
@@ -90,34 +93,46 @@ func (hd *MonitorErrorHandler) Detail(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列新增
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param ProjectKey body string false "项目key"
|
||||
// @Param EventType body string false "事件类型"
|
||||
// @Param Path body string false "URL地址"
|
||||
// @Param Message body string false "错误消息"
|
||||
// @Param Stack body string false "错误堆栈"
|
||||
// @Param Md5 body string false "md5"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/add [post]
|
||||
// @Summary 监控-错误列新增
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param ProjectKey body string false "项目key"
|
||||
// @Param EventType body string false "事件类型"
|
||||
// @Param Path body string false "URL地址"
|
||||
// @Param Message body string false "错误消息"
|
||||
// @Param Stack body string false "错误堆栈"
|
||||
// @Param Md5 body string false "md5"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/add [post]
|
||||
func (hd *MonitorErrorHandler) Add(c *gin.Context) {
|
||||
var addReq MonitorErrorAddReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
data, err := url.QueryUnescape(c.Query("data"))
|
||||
if err != nil {
|
||||
// response.CheckAndRespWithData(c, 0, err)
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
return
|
||||
}
|
||||
createId, e := MonitorErrorService.Add(addReq)
|
||||
response.CheckAndRespWithData(c, createId, e)
|
||||
|
||||
var addReq []MonitorErrorAddReq
|
||||
json.Unmarshal([]byte(data), &addReq)
|
||||
|
||||
// if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
// return
|
||||
// }
|
||||
for i := 0; i < len(addReq); i++ {
|
||||
MonitorErrorService.Add(addReq[i])
|
||||
}
|
||||
// response.CheckAndRespWithData(c, g, nil)
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列删除
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false "错误id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/del [post]
|
||||
// @Summary 监控-错误列删除
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false "错误id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/del [post]
|
||||
func (hd *MonitorErrorHandler) Del(c *gin.Context) {
|
||||
var delReq MonitorErrorDelReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
@@ -126,14 +141,14 @@ func (hd *MonitorErrorHandler) Del(c *gin.Context) {
|
||||
response.CheckAndResp(c, MonitorErrorService.Del(delReq.Id))
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列删除-批量
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Summary 监控-错误列删除-批量
|
||||
// @Tags monitor_error-监控-错误列
|
||||
//
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Ids body string false "逗号分割的id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/delBatch [post]
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Ids body string false "逗号分割的id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_error/delBatch [post]
|
||||
func (hd *MonitorErrorHandler) DelBatch(c *gin.Context) {
|
||||
var delReq MonitorErrorDelBatchReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
@@ -148,19 +163,19 @@ func (hd *MonitorErrorHandler) DelBatch(c *gin.Context) {
|
||||
response.CheckAndResp(c, MonitorErrorService.DelBatch(Ids))
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列导出
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param ProjectKey query string false "项目key"
|
||||
// @Param EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Router /api/admin/monitor_error/ExportFile [get]
|
||||
// @Summary 监控-错误列导出
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param ProjectKey query string false "项目key"
|
||||
// @Param EventType query string false "事件类型"
|
||||
// @Param Path query string false "URL地址"
|
||||
// @Param Message query string false "错误消息"
|
||||
// @Param Stack query string false "错误堆栈"
|
||||
// @Param Md5 query string false "md5"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Router /api/admin/monitor_error/ExportFile [get]
|
||||
func (hd *MonitorErrorHandler) ExportFile(c *gin.Context) {
|
||||
var listReq MonitorErrorListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
@@ -179,10 +194,10 @@ func (hd *MonitorErrorHandler) ExportFile(c *gin.Context) {
|
||||
excel2.DownLoadExcel("监控-错误列"+time.Now().Format("20060102-150405"), c.Writer, f)
|
||||
}
|
||||
|
||||
// @Summary 监控-错误列导入
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Router /api/admin/monitor_error/ImportFile [post]
|
||||
// @Summary 监控-错误列导入
|
||||
// @Tags monitor_error-监控-错误列
|
||||
// @Produce json
|
||||
// @Router /api/admin/monitor_error/ImportFile [post]
|
||||
func (hd *MonitorErrorHandler) ImportFile(c *gin.Context) {
|
||||
file, _, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
|
@@ -1,13 +1,16 @@
|
||||
package monitor_error
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"x_admin/admin/monitor_client"
|
||||
"x_admin/admin/monitor_error_list"
|
||||
"x_admin/core"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -83,7 +86,7 @@ func (service monitorErrorService) List(page request.PageReq, listReq MonitorErr
|
||||
return
|
||||
}
|
||||
result := []MonitorErrorResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -102,7 +105,7 @@ func (service monitorErrorService) ListAll(listReq MonitorErrorListReq) (res []M
|
||||
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -121,7 +124,7 @@ func (service monitorErrorService) Detail(Id int) (res MonitorErrorResp, e error
|
||||
cacheUtil.SetCache(obj.Id, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -140,41 +143,47 @@ func (service monitorErrorService) DetailByMD5(md5 string) (res MonitorErrorResp
|
||||
cacheUtil.SetCache("md5:"+md5, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 监控-错误列新增
|
||||
func (service monitorErrorService) Add(addReq MonitorErrorAddReq) (createId int, e error) {
|
||||
func (service monitorErrorService) Add(addReq MonitorErrorAddReq) (createId int, err error) {
|
||||
|
||||
var obj model.MonitorError
|
||||
util.ConvertUtil.StructToStruct(addReq, &obj)
|
||||
convert_util.StructToStruct(addReq, &obj)
|
||||
|
||||
Md5 := util.ToolsUtil.MakeMd5(obj.ProjectKey + obj.Path + obj.Stack)
|
||||
Md5 := util.ToolsUtil.MakeMd5(obj.ProjectKey + obj.EventType + obj.Message + obj.Path + obj.Stack)
|
||||
|
||||
errorDetails, e := service.DetailByMD5(Md5)
|
||||
if e != nil {
|
||||
errorDetails, err := service.DetailByMD5(Md5)
|
||||
if err != nil {
|
||||
|
||||
obj.Md5 = Md5
|
||||
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
return 0, e
|
||||
err = response.CheckMysqlErr(err)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
createId = obj.Id
|
||||
cacheUtil.SetCache(createId, obj)
|
||||
cacheUtil.SetCache("md5:"+Md5, obj)
|
||||
} else {
|
||||
createId = errorDetails.Id
|
||||
}
|
||||
client, err := monitor_client.MonitorClientService.DetailByClientId(addReq.ClientId)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
monitor_error_list.MonitorErrorListService.Add(monitor_error_list.MonitorErrorListAddReq{
|
||||
ErrorId: strconv.Itoa(createId),
|
||||
ClientId: addReq.ClientId,
|
||||
ProjectKey: addReq.ProjectKey,
|
||||
_, err = monitor_error_list.MonitorErrorListService.Add(monitor_error_list.MonitorErrorListAddReq{
|
||||
Eid: strconv.Itoa(createId),
|
||||
Cid: strconv.Itoa(client.Id),
|
||||
// ClientId: addReq.ClientId,
|
||||
// ProjectKey: addReq.ProjectKey,
|
||||
})
|
||||
|
||||
return
|
||||
return createId, err
|
||||
}
|
||||
|
||||
// Del 监控-错误列删除
|
||||
@@ -192,20 +201,33 @@ func (service monitorErrorService) Del(Id int) (e error) {
|
||||
err = service.db.Delete(&obj).Error
|
||||
e = response.CheckErr(err, "删除失败")
|
||||
cacheUtil.RemoveCache(obj.Id)
|
||||
cacheUtil.RemoveCache("md5:" + obj.Md5)
|
||||
return
|
||||
}
|
||||
|
||||
// DelBatch 用户协议-批量删除
|
||||
func (service monitorErrorService) DelBatch(Ids []string) (e error) {
|
||||
var obj model.MonitorError
|
||||
err := service.db.Where("id in (?)", Ids).Delete(&obj).Error
|
||||
var obj []model.MonitorError
|
||||
// 查询Ids对应的数据
|
||||
err := service.db.Where("id in (?)", Ids).Find(&obj).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除缓存
|
||||
for _, v := range Ids {
|
||||
cacheUtil.RemoveCache(v)
|
||||
if len(obj) == 0 {
|
||||
return errors.New("数据不存在")
|
||||
}
|
||||
err = service.db.Where("id in (?)", Ids).Delete(model.MonitorError{}).Error
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// md5集合
|
||||
var md5s []string
|
||||
for _, v := range obj {
|
||||
md5s = append(md5s, "md5:"+v.Md5)
|
||||
}
|
||||
// 删除缓存
|
||||
cacheUtil.RemoveCache(Ids)
|
||||
cacheUtil.RemoveCache(md5s)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -237,14 +259,14 @@ func (service monitorErrorService) ExportFile(listReq MonitorErrorListReq) (res
|
||||
return
|
||||
}
|
||||
result := []MonitorErrorResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service monitorErrorService) ImportFile(importReq []MonitorErrorResp) (e error) {
|
||||
var importData []model.MonitorError
|
||||
util.ConvertUtil.Copy(&importData, importReq)
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
|
@@ -6,16 +6,16 @@ import (
|
||||
|
||||
// MonitorErrorListAddReq 错误对应的用户记录新增参数
|
||||
type MonitorErrorListAddReq struct {
|
||||
ErrorId string // 错误id
|
||||
ClientId string // 客户端id
|
||||
ProjectKey string // 项目id
|
||||
Eid string // 错误id
|
||||
Cid string // 客户端id
|
||||
// ProjectKey string // 项目id
|
||||
}
|
||||
|
||||
// MonitorErrorListResp 错误对应的用户记录返回信息
|
||||
type MonitorErrorListResp struct {
|
||||
Id int // 项目id
|
||||
ErrorId string // 错误id
|
||||
ClientId string // 客户端id
|
||||
ProjectKey string // 项目id
|
||||
Id int // 项目id
|
||||
Eid string // 错误id
|
||||
Cid string // 客户端id
|
||||
// ProjectKey string // 项目id
|
||||
CreateTime core.NullTime // 创建时间
|
||||
}
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"x_admin/core"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -28,7 +28,7 @@ type monitorErrorListService struct {
|
||||
// Add 错误对应的用户记录新增
|
||||
func (service monitorErrorListService) Add(addReq MonitorErrorListAddReq) (createId int, e error) {
|
||||
var obj model.MonitorErrorList
|
||||
util.ConvertUtil.StructToStruct(addReq, &obj)
|
||||
convert_util.StructToStruct(addReq, &obj)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -81,7 +82,7 @@ func (service monitorProjectService) List(page request.PageReq, listReq MonitorP
|
||||
return
|
||||
}
|
||||
result := []MonitorProjectResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -100,7 +101,7 @@ func (service monitorProjectService) ListAll(listReq MonitorProjectListReq) (res
|
||||
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -119,14 +120,14 @@ func (service monitorProjectService) Detail(Id int) (res MonitorProjectResp, e e
|
||||
cacheUtil.SetCache(obj.Id, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 监控项目新增
|
||||
func (service monitorProjectService) Add(addReq MonitorProjectAddReq) (createId int, e error) {
|
||||
var obj model.MonitorProject
|
||||
util.ConvertUtil.StructToStruct(addReq, &obj)
|
||||
convert_util.StructToStruct(addReq, &obj)
|
||||
obj.ProjectKey = util.ToolsUtil.MakeUuid()
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
@@ -149,7 +150,7 @@ func (service monitorProjectService) Edit(editReq MonitorProjectEditReq) (e erro
|
||||
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
|
||||
err = service.db.Model(&obj).Select("*").Updates(obj).Error
|
||||
if e = response.CheckErr(err, "编辑失败"); e != nil {
|
||||
@@ -188,9 +189,10 @@ func (service monitorProjectService) DelBatch(Ids []string) (e error) {
|
||||
return err
|
||||
}
|
||||
// 删除缓存
|
||||
for _, v := range Ids {
|
||||
cacheUtil.RemoveCache(v)
|
||||
}
|
||||
// for _, v := range Ids {
|
||||
// cacheUtil.RemoveCache(v)
|
||||
// }
|
||||
cacheUtil.RemoveCache(Ids)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -220,14 +222,14 @@ func (service monitorProjectService) ExportFile(listReq MonitorProjectListReq) (
|
||||
return
|
||||
}
|
||||
result := []MonitorProjectResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service monitorProjectService) ImportFile(importReq []MonitorProjectResp) (e error) {
|
||||
var importData []model.MonitorProject
|
||||
util.ConvertUtil.Copy(&importData, importReq)
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
|
220
server/admin/monitor_slow/monitor_slow_ctl.go
Normal file
220
server/admin/monitor_slow/monitor_slow_ctl.go
Normal file
@@ -0,0 +1,220 @@
|
||||
package monitor_slow
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/util"
|
||||
"x_admin/util/excel2"
|
||||
"x_admin/util/img_util"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"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
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/monitor_slow/add [get]
|
||||
func (hd *MonitorSlowHandler) Add(c *gin.Context) {
|
||||
data, err := url.QueryUnescape(c.Query("data"))
|
||||
if err != nil {
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
return
|
||||
}
|
||||
|
||||
var addReq MonitorSlowAddReq
|
||||
json.Unmarshal([]byte(data), &addReq)
|
||||
|
||||
MonitorSlowService.Add(addReq)
|
||||
c.Data(200, "image/gif", img_util.EmptyGif())
|
||||
}
|
||||
|
||||
// @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)
|
||||
}
|
61
server/admin/monitor_slow/monitor_slow_schema.go
Normal file
61
server/admin/monitor_slow/monitor_slow_schema.go
Normal file
@@ -0,0 +1,61 @@
|
||||
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 // 创建时间
|
||||
}
|
226
server/admin/monitor_slow/monitor_slow_service.go
Normal file
226
server/admin/monitor_slow/monitor_slow_service.go
Normal file
@@ -0,0 +1,226 @@
|
||||
package monitor_slow
|
||||
|
||||
import (
|
||||
"x_admin/core"
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
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{}
|
||||
convert_util.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
|
||||
}
|
||||
convert_util.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)
|
||||
}
|
||||
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 监控-错误列新增
|
||||
func (service monitorSlowService) Add(addReq MonitorSlowAddReq) (createId int, e error) {
|
||||
var obj model.MonitorSlow
|
||||
convert_util.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
|
||||
}
|
||||
convert_util.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{}
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service monitorSlowService) ImportFile(importReq []MonitorSlowResp) (e error) {
|
||||
var importData []model.MonitorSlow
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
}
|
@@ -6,6 +6,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/setting_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -58,7 +59,7 @@ func (ddSrv settingDictDataService) All(allReq SettingDictDataListReq) (res []Se
|
||||
return
|
||||
}
|
||||
res = []SettingDictDataResp{}
|
||||
util.ConvertUtil.Copy(&res, dictDatas)
|
||||
convert_util.Copy(&res, dictDatas)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,7 +96,7 @@ func (ddSrv settingDictDataService) List(page request.PageReq, listReq SettingDi
|
||||
return
|
||||
}
|
||||
dtResp := []SettingDictDataResp{}
|
||||
util.ConvertUtil.Copy(&dtResp, dds)
|
||||
convert_util.Copy(&dtResp, dds)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -114,7 +115,7 @@ func (ddSrv settingDictDataService) Detail(id uint) (res SettingDictDataResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, dd)
|
||||
convert_util.Copy(&res, dd)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -124,7 +125,7 @@ func (ddSrv settingDictDataService) Add(addReq SettingDictDataAddReq) (e error)
|
||||
return response.AssertArgumentError.SetMessage("字典数据已存在!")
|
||||
}
|
||||
var dd setting_model.DictData
|
||||
util.ConvertUtil.Copy(&dd, addReq)
|
||||
convert_util.Copy(&dd, addReq)
|
||||
err := ddSrv.db.Create(&dd).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -144,7 +145,7 @@ func (ddSrv settingDictDataService) Edit(editReq SettingDictDataEditReq) (e erro
|
||||
return response.AssertArgumentError.SetMessage("字典数据已存在!")
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&dd, editReq)
|
||||
convert_util.Copy(&dd, editReq)
|
||||
err = ddSrv.db.Save(&dd).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/setting_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -40,7 +41,7 @@ func (dtSrv settingDictTypeService) All() (res []SettingDictTypeResp, e error) {
|
||||
return
|
||||
}
|
||||
res = []SettingDictTypeResp{}
|
||||
util.ConvertUtil.Copy(&res, dictTypes)
|
||||
convert_util.Copy(&res, dictTypes)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -69,7 +70,7 @@ func (dtSrv settingDictTypeService) List(page request.PageReq, listReq SettingDi
|
||||
return
|
||||
}
|
||||
dtResp := []SettingDictTypeResp{}
|
||||
util.ConvertUtil.Copy(&dtResp, dts)
|
||||
convert_util.Copy(&dtResp, dts)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -88,7 +89,7 @@ func (dtSrv settingDictTypeService) Detail(id uint) (res SettingDictTypeResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, dt)
|
||||
convert_util.Copy(&res, dt)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -101,7 +102,7 @@ func (dtSrv settingDictTypeService) Add(addReq SettingDictTypeAddReq) (e error)
|
||||
return response.AssertArgumentError.SetMessage("字典类型已存在!")
|
||||
}
|
||||
var dt setting_model.DictType
|
||||
util.ConvertUtil.Copy(&dt, addReq)
|
||||
convert_util.Copy(&dt, addReq)
|
||||
err := dtSrv.db.Create(&dt).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -124,7 +125,7 @@ func (dtSrv settingDictTypeService) Edit(editReq SettingDictTypeEditReq) (e erro
|
||||
return response.AssertArgumentError.SetMessage("字典类型已存在!")
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&dt, editReq)
|
||||
convert_util.Copy(&dt, editReq)
|
||||
// err = dtSrv.db.Model(&dt).Updates(&up).Error
|
||||
err = dtSrv.db.Save(&dt).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/gin-gonic/gin"
|
||||
@@ -78,7 +79,7 @@ func (adminSrv systemAuthAdminService) Self(adminId uint) (res SystemAuthAdminSe
|
||||
auths = append(auths, "*")
|
||||
}
|
||||
var admin SystemAuthAdminSelfOneResp
|
||||
util.ConvertUtil.Copy(&admin, sysAdmin)
|
||||
convert_util.Copy(&admin, sysAdmin)
|
||||
admin.Dept = strconv.FormatUint(uint64(sysAdmin.DeptId), 10)
|
||||
admin.Avatar = util.UrlUtil.ToAbsoluteUrl(sysAdmin.Avatar)
|
||||
return SystemAuthAdminSelfResp{User: admin, Permissions: auths}, nil
|
||||
@@ -151,7 +152,7 @@ func (adminSrv systemAuthAdminService) ExportFile(listReq SystemAuthAdminListReq
|
||||
// 导入
|
||||
func (adminSrv systemAuthAdminService) ImportFile(importReq []SystemAuthAdminResp) (e error) {
|
||||
var sysAdmin []system_model.SystemAuthAdmin
|
||||
util.ConvertUtil.Copy(&sysAdmin, importReq)
|
||||
convert_util.Copy(&sysAdmin, importReq)
|
||||
err := adminSrv.db.Create(&sysAdmin).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
@@ -254,7 +255,7 @@ func (adminSrv systemAuthAdminService) Detail(id uint) (res SystemAuthAdminResp,
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, sysAdmin)
|
||||
convert_util.Copy(&res, sysAdmin)
|
||||
res.Avatar = util.UrlUtil.ToAbsoluteUrl(res.Avatar)
|
||||
if res.Dept == "" {
|
||||
res.Dept = strconv.FormatUint(uint64(res.DeptId), 10)
|
||||
@@ -295,7 +296,7 @@ func (adminSrv systemAuthAdminService) Add(addReq SystemAuthAdminAddReq) (e erro
|
||||
return response.Failed.SetMessage("密码格式不正确")
|
||||
}
|
||||
salt := util.ToolsUtil.RandomString(5)
|
||||
util.ConvertUtil.Copy(&sysAdmin, addReq)
|
||||
convert_util.Copy(&sysAdmin, addReq)
|
||||
sysAdmin.Role = strconv.FormatUint(uint64(addReq.Role), 10)
|
||||
sysAdmin.Salt = salt
|
||||
sysAdmin.Password = util.ToolsUtil.MakeMd5(strings.Trim(addReq.Password, " ") + salt)
|
||||
|
@@ -4,7 +4,7 @@ import (
|
||||
"x_admin/core"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -39,7 +39,7 @@ func (service systemAuthDeptService) All() (res []SystemAuthDeptResp, e error) {
|
||||
return
|
||||
}
|
||||
res = []SystemAuthDeptResp{}
|
||||
util.ConvertUtil.Copy(&res, depts)
|
||||
convert_util.Copy(&res, depts)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ func (service systemAuthDeptService) List(listReq SystemAuthDeptListReq) (deptRe
|
||||
if e = response.CheckErr(err, "列表获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&deptResps, depts)
|
||||
convert_util.Copy(&deptResps, depts)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ func (service systemAuthDeptService) Detail(id uint) (res SystemAuthDeptResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, dept)
|
||||
convert_util.Copy(&res, dept)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ func (service systemAuthDeptService) Add(addReq SystemAuthDeptAddReq) (e error)
|
||||
}
|
||||
}
|
||||
var dept system_model.SystemAuthDept
|
||||
util.ConvertUtil.Copy(&dept, addReq)
|
||||
convert_util.Copy(&dept, addReq)
|
||||
err := service.db.Create(&dept).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -111,7 +111,7 @@ func (service systemAuthDeptService) Edit(editReq SystemAuthDeptEditReq) (e erro
|
||||
return response.AssertArgumentError.SetMessage("上级部门不能是自己!")
|
||||
}
|
||||
// 更新
|
||||
util.ConvertUtil.Copy(&dept, editReq)
|
||||
convert_util.Copy(&dept, editReq)
|
||||
err = service.db.Model(&dept).Select("*").Updates(dept).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gorm.io/gorm"
|
||||
@@ -57,9 +58,9 @@ func (menuSrv systemAuthMenuService) SelectMenuByRoleId(c *gin.Context, roleId u
|
||||
return
|
||||
}
|
||||
var menuResps []SystemAuthMenuResp
|
||||
util.ConvertUtil.Copy(&menuResps, menus)
|
||||
convert_util.Copy(&menuResps, menus)
|
||||
mapList = util.ArrayUtil.ListToTree(
|
||||
util.ConvertUtil.StructsToMaps(menuResps), "id", "pid", "children")
|
||||
convert_util.StructsToMaps(menuResps), "id", "pid", "children")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -71,7 +72,7 @@ func (menuSrv systemAuthMenuService) List() (res interface{}, e error) {
|
||||
return
|
||||
}
|
||||
var menuResps []SystemAuthMenuResp
|
||||
util.ConvertUtil.Copy(&menuResps, menus)
|
||||
convert_util.Copy(&menuResps, menus)
|
||||
return menuResps, nil
|
||||
}
|
||||
|
||||
@@ -85,13 +86,13 @@ func (menuSrv systemAuthMenuService) Detail(id uint) (res SystemAuthMenuResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, menu)
|
||||
convert_util.Copy(&res, menu)
|
||||
return
|
||||
}
|
||||
|
||||
func (menuSrv systemAuthMenuService) Add(addReq SystemAuthMenuAddReq) (e error) {
|
||||
var menu system_model.SystemAuthMenu
|
||||
util.ConvertUtil.Copy(&menu, addReq)
|
||||
convert_util.Copy(&menu, addReq)
|
||||
err := menuSrv.db.Create(&menu).Error
|
||||
if e = response.CheckErr(err, "添加失败"); e != nil {
|
||||
return
|
||||
@@ -109,7 +110,7 @@ func (menuSrv systemAuthMenuService) Edit(editReq SystemAuthMenuEditReq) (e erro
|
||||
if e = response.CheckErr(err, "Edit Find err"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&menu, editReq)
|
||||
convert_util.Copy(&menu, editReq)
|
||||
|
||||
err = menuSrv.db.Model(&menu).Select("*").Updates(menu).Error
|
||||
if e = response.CheckErr(err, "编辑失败"); e != nil {
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
"x_admin/core/request"
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -40,7 +40,7 @@ func (service systemAuthPostService) All() (res []SystemAuthPostResp, e error) {
|
||||
return
|
||||
}
|
||||
res = []SystemAuthPostResp{}
|
||||
util.ConvertUtil.Copy(&res, posts)
|
||||
convert_util.Copy(&res, posts)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ func (service systemAuthPostService) List(page request.PageReq, listReq SystemAu
|
||||
return
|
||||
}
|
||||
postResps := []SystemAuthPostResp{}
|
||||
util.ConvertUtil.Copy(&postResps, posts)
|
||||
convert_util.Copy(&postResps, posts)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -92,7 +92,7 @@ func (service systemAuthPostService) Detail(id uint) (res SystemAuthPostResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, post)
|
||||
convert_util.Copy(&res, post)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func (service systemAuthPostService) Add(addReq SystemAuthPostAddReq) (e error)
|
||||
return response.AssertArgumentError.SetMessage("该岗位已存在!")
|
||||
}
|
||||
var post system_model.SystemAuthPost
|
||||
util.ConvertUtil.Copy(&post, addReq)
|
||||
convert_util.Copy(&post, addReq)
|
||||
err := service.db.Create(&post).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return
|
||||
@@ -131,7 +131,7 @@ func (service systemAuthPostService) Edit(editReq SystemAuthPostEditReq) (e erro
|
||||
return response.AssertArgumentError.SetMessage("该岗位已存在!")
|
||||
}
|
||||
// 更新
|
||||
util.ConvertUtil.Copy(&post, editReq)
|
||||
convert_util.Copy(&post, editReq)
|
||||
err = service.db.Model(&post).Select("*").Updates(post).Error
|
||||
e = response.CheckErr(err, "编辑失败")
|
||||
return
|
||||
|
@@ -9,6 +9,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model/system_model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"gorm.io/gorm"
|
||||
@@ -43,7 +44,7 @@ func (roleSrv systemAuthRoleService) All() (res []SystemAuthRoleSimpleResp, e er
|
||||
if e = response.CheckErr(err, "All Find err"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, roles)
|
||||
convert_util.Copy(&res, roles)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -63,7 +64,7 @@ func (roleSrv systemAuthRoleService) List(page request.PageReq) (res response.Pa
|
||||
return
|
||||
}
|
||||
var roleResp []SystemAuthRoleResp
|
||||
util.ConvertUtil.Copy(&roleResp, roles)
|
||||
convert_util.Copy(&roleResp, roles)
|
||||
for i := 0; i < len(roleResp); i++ {
|
||||
roleResp[i].Menus = []uint{}
|
||||
roleResp[i].Member = roleSrv.getMemberCnt(roleResp[i].ID)
|
||||
@@ -86,7 +87,7 @@ func (roleSrv systemAuthRoleService) Detail(id uint) (res SystemAuthRoleResp, e
|
||||
if e = response.CheckErr(err, "详情获取失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, role)
|
||||
convert_util.Copy(&res, role)
|
||||
res.Member = roleSrv.getMemberCnt(role.ID)
|
||||
res.Menus, _ = PermService.SelectMenuIdsByRoleId(role.ID)
|
||||
return
|
||||
@@ -105,7 +106,7 @@ func (roleSrv systemAuthRoleService) Add(addReq SystemAuthRoleAddReq) (e error)
|
||||
if r := roleSrv.db.Where("name = ?", strings.Trim(addReq.Name, " ")).Limit(1).First(&role); r.RowsAffected > 0 {
|
||||
return response.AssertArgumentError.SetMessage("角色名称已存在!")
|
||||
}
|
||||
util.ConvertUtil.Copy(&role, addReq)
|
||||
convert_util.Copy(&role, addReq)
|
||||
role.Name = strings.Trim(addReq.Name, " ")
|
||||
// 事务
|
||||
err := roleSrv.db.Transaction(func(tx *gorm.DB) error {
|
||||
|
@@ -18,22 +18,22 @@ type UserProtocolHandler struct {
|
||||
requestGroup singleflight.Group
|
||||
}
|
||||
|
||||
// @Summary 用户协议列表
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param PageNo query int true "页码"
|
||||
// @Param PageSize query int true "每页数量"
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
// @Summary 用户协议列表
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param PageNo query int true "页码"
|
||||
// @Param PageSize query int true "每页数量"
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
//
|
||||
// @Success 200 {object} response.Response{ data=response.PageResp{ lists=[]UserProtocolResp}} "成功"
|
||||
// @Router /api/admin/user_protocol/list [get]
|
||||
// @Success 200 {object} response.Response{ data=response.PageResp{ lists=[]UserProtocolResp}} "成功"
|
||||
// @Router /api/admin/user_protocol/list [get]
|
||||
func (hd *UserProtocolHandler) List(c *gin.Context) {
|
||||
var page request.PageReq
|
||||
var listReq UserProtocolListReq
|
||||
@@ -47,18 +47,18 @@ func (hd *UserProtocolHandler) List(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 用户协议列表-所有
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
// @Success 200 {object} response.Response{ data=[]UserProtocolResp} "成功"
|
||||
// @Router /api/admin/user_protocol/listAll [get]
|
||||
// @Summary 用户协议列表-所有
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
// @Success 200 {object} response.Response{ data=[]UserProtocolResp} "成功"
|
||||
// @Router /api/admin/user_protocol/listAll [get]
|
||||
func (hd *UserProtocolHandler) ListAll(c *gin.Context) {
|
||||
var listReq UserProtocolListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
@@ -68,13 +68,13 @@ func (hd *UserProtocolHandler) ListAll(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 用户协议详情
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id query number false ""
|
||||
// @Success 200 {object} response.Response{ data=UserProtocolResp} "成功"
|
||||
// @Router /api/admin/user_protocol/detail [get]
|
||||
// @Summary 用户协议详情
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id query number false "Id"
|
||||
// @Success 200 {object} response.Response{ data=UserProtocolResp} "成功"
|
||||
// @Router /api/admin/user_protocol/detail [get]
|
||||
func (hd *UserProtocolHandler) Detail(c *gin.Context) {
|
||||
var detailReq UserProtocolDetailReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &detailReq)) {
|
||||
@@ -88,15 +88,15 @@ func (hd *UserProtocolHandler) Detail(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, res, err)
|
||||
}
|
||||
|
||||
// @Summary 用户协议新增
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Title body string false "标题"
|
||||
// @Param Content body string false "协议内容"
|
||||
// @Param Sort body number false "排序"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/add [post]
|
||||
// @Summary 用户协议新增
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Title body string false "标题"
|
||||
// @Param Content body string false "协议内容"
|
||||
// @Param Sort body number false "排序"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/add [post]
|
||||
func (hd *UserProtocolHandler) Add(c *gin.Context) {
|
||||
var addReq UserProtocolAddReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||
@@ -106,16 +106,16 @@ func (hd *UserProtocolHandler) Add(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, createId, e)
|
||||
}
|
||||
|
||||
// @Summary 用户协议编辑
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false ""
|
||||
// @Param Title body string false "标题"
|
||||
// @Param Content body string false "协议内容"
|
||||
// @Param Sort body number false "排序"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/edit [post]
|
||||
// @Summary 用户协议编辑
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false "Id"
|
||||
// @Param Title body string false "标题"
|
||||
// @Param Content body string false "协议内容"
|
||||
// @Param Sort body number false "排序"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/edit [post]
|
||||
func (hd *UserProtocolHandler) Edit(c *gin.Context) {
|
||||
var editReq UserProtocolEditReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &editReq)) {
|
||||
@@ -124,13 +124,13 @@ func (hd *UserProtocolHandler) Edit(c *gin.Context) {
|
||||
response.CheckAndRespWithData(c, editReq.Id, UserProtocolService.Edit(editReq))
|
||||
}
|
||||
|
||||
// @Summary 用户协议删除
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false ""
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/del [post]
|
||||
// @Summary 用户协议删除
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Id body number false "Id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/del [post]
|
||||
func (hd *UserProtocolHandler) Del(c *gin.Context) {
|
||||
var delReq UserProtocolDelReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
@@ -139,14 +139,14 @@ func (hd *UserProtocolHandler) Del(c *gin.Context) {
|
||||
response.CheckAndResp(c, UserProtocolService.Del(delReq.Id))
|
||||
}
|
||||
|
||||
// @Summary 用户协议删除-批量
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Summary 用户协议删除-批量
|
||||
// @Tags user_protocol-用户协议
|
||||
//
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Ids body string false "逗号分割的id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/delBatch [post]
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Ids body string false "逗号分割的id"
|
||||
// @Success 200 {object} response.Response "成功"
|
||||
// @Router /api/admin/user_protocol/delBatch [post]
|
||||
func (hd *UserProtocolHandler) DelBatch(c *gin.Context) {
|
||||
var delReq UserProtocolDelBatchReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &delReq)) {
|
||||
@@ -161,18 +161,18 @@ func (hd *UserProtocolHandler) DelBatch(c *gin.Context) {
|
||||
response.CheckAndResp(c, UserProtocolService.DelBatch(Ids))
|
||||
}
|
||||
|
||||
// @Summary 用户协议导出
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
// @Router /api/admin/user_protocol/ExportFile [get]
|
||||
// @Summary 用户协议导出
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Param Token header string true "token"
|
||||
// @Param Title query string false "标题"
|
||||
// @Param Content query string false "协议内容"
|
||||
// @Param Sort query number false "排序"
|
||||
// @Param CreateTimeStart query string false "创建时间"
|
||||
// @Param CreateTimeEnd query string false "创建时间"
|
||||
// @Param UpdateTimeStart query string false "更新时间"
|
||||
// @Param UpdateTimeEnd query string false "更新时间"
|
||||
// @Router /api/admin/user_protocol/ExportFile [get]
|
||||
func (hd *UserProtocolHandler) ExportFile(c *gin.Context) {
|
||||
var listReq UserProtocolListReq
|
||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||
@@ -191,10 +191,10 @@ func (hd *UserProtocolHandler) ExportFile(c *gin.Context) {
|
||||
excel2.DownLoadExcel("用户协议"+time.Now().Format("20060102-150405"), c.Writer, f)
|
||||
}
|
||||
|
||||
// @Summary 用户协议导入
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Router /api/admin/user_protocol/ImportFile [post]
|
||||
// @Summary 用户协议导入
|
||||
// @Tags user_protocol-用户协议
|
||||
// @Produce json
|
||||
// @Router /api/admin/user_protocol/ImportFile [post]
|
||||
func (hd *UserProtocolHandler) ImportFile(c *gin.Context) {
|
||||
file, _, err := c.Request.FormFile("file")
|
||||
if err != nil {
|
||||
|
@@ -6,6 +6,7 @@ import (
|
||||
"x_admin/core/response"
|
||||
"x_admin/model"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
"x_admin/util/excel2"
|
||||
|
||||
"gorm.io/gorm"
|
||||
@@ -78,7 +79,7 @@ func (service userProtocolService) List(page request.PageReq, listReq UserProtoc
|
||||
return
|
||||
}
|
||||
result := []UserProtocolResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return response.PageResp{
|
||||
PageNo: page.PageNo,
|
||||
PageSize: page.PageSize,
|
||||
@@ -97,7 +98,7 @@ func (service userProtocolService) ListAll(listReq UserProtocolListReq) (res []U
|
||||
if e = response.CheckErr(err, "查询全部失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&res, modelList)
|
||||
convert_util.Copy(&res, modelList)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
@@ -116,14 +117,14 @@ func (service userProtocolService) Detail(Id int) (res UserProtocolResp, e error
|
||||
cacheUtil.SetCache(obj.Id, obj)
|
||||
}
|
||||
|
||||
util.ConvertUtil.Copy(&res, obj)
|
||||
convert_util.Copy(&res, obj)
|
||||
return
|
||||
}
|
||||
|
||||
// Add 用户协议新增
|
||||
func (service userProtocolService) Add(addReq UserProtocolAddReq) (createId int, e error) {
|
||||
var obj model.UserProtocol
|
||||
util.ConvertUtil.StructToStruct(addReq, &obj)
|
||||
convert_util.StructToStruct(addReq, &obj)
|
||||
err := service.db.Create(&obj).Error
|
||||
e = response.CheckMysqlErr(err)
|
||||
if e != nil {
|
||||
@@ -145,7 +146,7 @@ func (service userProtocolService) Edit(editReq UserProtocolEditReq) (e error) {
|
||||
if e = response.CheckErr(err, "查询失败"); e != nil {
|
||||
return
|
||||
}
|
||||
util.ConvertUtil.Copy(&obj, editReq)
|
||||
convert_util.Copy(&obj, editReq)
|
||||
|
||||
err = service.db.Model(&obj).Select("*").Updates(obj).Error
|
||||
if e = response.CheckErr(err, "编辑失败"); e != nil {
|
||||
@@ -215,14 +216,14 @@ func (service userProtocolService) ExportFile(listReq UserProtocolListReq) (res
|
||||
return
|
||||
}
|
||||
result := []UserProtocolResp{}
|
||||
util.ConvertUtil.Copy(&result, modelList)
|
||||
convert_util.Copy(&result, modelList)
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// 导入
|
||||
func (service userProtocolService) ImportFile(importReq []UserProtocolResp) (e error) {
|
||||
var importData []model.UserProtocol
|
||||
util.ConvertUtil.Copy(&importData, importReq)
|
||||
convert_util.Copy(&importData, importReq)
|
||||
err := service.db.Create(&importData).Error
|
||||
e = response.CheckErr(err, "添加失败")
|
||||
return e
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"x_admin/util/convert_util"
|
||||
)
|
||||
|
||||
// Float类型别名,支持前端传递null,float64, string类型
|
||||
@@ -13,64 +14,78 @@ type NullFloat struct {
|
||||
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) {
|
||||
switch v := value.(type) {
|
||||
case float64:
|
||||
f := v
|
||||
return NullFloat{Float: &f, Valid: true}, nil
|
||||
case int:
|
||||
f := float64(v)
|
||||
return NullFloat{Float: &f, Valid: true}, nil
|
||||
case int64:
|
||||
f := float64(v)
|
||||
return NullFloat{Float: &f, Valid: true}, nil
|
||||
case string:
|
||||
if v == "" {
|
||||
return NullFloat{Float: nil, Valid: false}, nil
|
||||
}
|
||||
f, err := strconv.ParseFloat(v, 64)
|
||||
return NullFloat{Float: &f, Valid: true}, err
|
||||
// case float64:
|
||||
// f := v
|
||||
// return NullFloat{Float: &f, Valid: true}, nil
|
||||
// case float32:
|
||||
// f := float64(v)
|
||||
// return NullFloat{Float: &f, Valid: true}, nil
|
||||
// case int:
|
||||
// f := float64(v)
|
||||
// return NullFloat{Float: &f, Valid: true}, nil
|
||||
// case int64:
|
||||
// f := float64(v)
|
||||
// return NullFloat{Float: &f, Valid: true}, nil
|
||||
// case string:
|
||||
// if v == "" {
|
||||
// return NullFloat{Float: nil, Valid: false}, nil
|
||||
// }
|
||||
// f, err := strconv.ParseFloat(v, 64)
|
||||
// return NullFloat{Float: &f, Valid: true}, err
|
||||
case nil:
|
||||
return NullFloat{Float: nil, Valid: false}, nil
|
||||
case NullFloat:
|
||||
return v, nil
|
||||
default:
|
||||
result, err := convert_util.ToFloat64(value)
|
||||
if err != nil {
|
||||
return NullFloat{Float: nil, Valid: false}, err
|
||||
}
|
||||
return NullFloat{Float: &result, Valid: true}, nil
|
||||
}
|
||||
return NullFloat{Float: nil, Valid: false}, nil
|
||||
}
|
||||
|
||||
// gorm实现Scanner
|
||||
func (f *NullFloat) Scan(value interface{}) error {
|
||||
f.Valid = false
|
||||
if value == nil {
|
||||
return nil
|
||||
|
||||
result, err := convert_util.ToFloat64(value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
v := value.(float64)
|
||||
f.Float, f.Valid = &v, true
|
||||
f.Float, f.Valid = &result, true
|
||||
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
|
||||
|
@@ -4,6 +4,7 @@ import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"x_admin/util/convert_util"
|
||||
)
|
||||
|
||||
// int类型别名,支持前端传递null,int,string类型
|
||||
@@ -41,23 +42,29 @@ type NullInt struct {
|
||||
// }
|
||||
func DecodeInt(value any) (any, error) {
|
||||
switch v := value.(type) {
|
||||
case int:
|
||||
i := int64(v)
|
||||
return NullInt{Int: &i, Valid: true}, nil
|
||||
case int64:
|
||||
return NullInt{Int: &v, Valid: true}, nil
|
||||
case string:
|
||||
if v == "" {
|
||||
return NullInt{Int: nil, Valid: false}, nil
|
||||
}
|
||||
i, err := strconv.ParseInt(v, 10, 64)
|
||||
return NullInt{Int: &i, Valid: true}, err
|
||||
// case int:
|
||||
// i := int64(v)
|
||||
// return NullInt{Int: &i, Valid: true}, nil
|
||||
// case int64:
|
||||
// return NullInt{Int: &v, Valid: true}, nil
|
||||
// case string:
|
||||
// if v == "" {
|
||||
// return NullInt{Int: nil, Valid: false}, nil
|
||||
// }
|
||||
// i, err := strconv.ParseInt(v, 10, 64)
|
||||
// return NullInt{Int: &i, Valid: true}, err
|
||||
case nil:
|
||||
return NullInt{Int: nil, Valid: false}, nil
|
||||
case NullInt:
|
||||
return v, nil
|
||||
default:
|
||||
result, err := convert_util.ToInt64(value)
|
||||
if err != nil {
|
||||
return NullInt{Int: nil, Valid: false}, err
|
||||
}
|
||||
return NullInt{Int: &result, Valid: true}, nil
|
||||
}
|
||||
return NullInt{Int: nil, Valid: false}, nil
|
||||
|
||||
}
|
||||
|
||||
// gorm实现Scanner
|
||||
|
@@ -7,12 +7,3 @@ type PageResp struct {
|
||||
PageSize int `json:"pageSize"` // 每页Size
|
||||
Lists interface{} `json:"lists"` // 数据
|
||||
}
|
||||
|
||||
// Copy 拷贝结构体
|
||||
// func 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
|
||||
// }
|
||||
|
3883
server/docs/docs.go
3883
server/docs/docs.go
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -65,9 +65,11 @@ require (
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
|
@@ -114,6 +114,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6 h1:YeIGErDiB/fhmNsJy0cfjoT8XnRNT9hb19xZ4MvWQDU=
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20240510055607-89e20ab7b6c6/go.mod h1:C5LA5UO2ZXJrLaPLYtE1wUJMiyd/nwWaCO5cw/2pSHs=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@@ -125,6 +127,8 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.3 h1:j7a/xn1U6TKA/PHHxqZuzh64CdtRc7rU9M+AvkOl5bA=
|
||||
github.com/mattn/go-sqlite3 v1.14.3/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
|
@@ -12,7 +12,11 @@ type MonitorClient struct {
|
||||
UserId string `gorm:"comment:'用户id'"` // 用户id
|
||||
Os string `gorm:"comment:'系统'"` // 系统
|
||||
Browser string `gorm:"comment:'浏览器'"` // 浏览器
|
||||
Country string `gorm:"comment:'国家'"` // 国家
|
||||
Province string `gorm:"comment:'省份'"` // 省份
|
||||
City string `gorm:"comment:'城市'"` // 城市
|
||||
Operator string `gorm:"comment:'电信运营商'"` // 电信运营商
|
||||
Ip string `gorm:"comment:'ip'"` // ip
|
||||
Width core.NullInt `gorm:"comment:'屏幕'"` // 屏幕
|
||||
Height core.NullInt `gorm:"comment:'屏幕高度'"` // 屏幕高度
|
||||
Ua string `gorm:"comment:'ua记录'"` // ua记录
|
||||
|
@@ -6,9 +6,8 @@ import (
|
||||
|
||||
// MonitorErrorList 错误对应的用户记录实体
|
||||
type MonitorErrorList struct {
|
||||
Id int `gorm:"primarykey;comment:'项目id'"` // 项目id
|
||||
ErrorId string `gorm:"comment:'错误id'"` // 错误id
|
||||
ClientId string `gorm:"comment:'客户端id'"` // 客户端id
|
||||
ProjectKey string `gorm:"comment:'项目key'"` // 项目id
|
||||
Id int `gorm:"primarykey;comment:'id'"`
|
||||
Eid string `gorm:"comment:'错误id'"` // 错误表id
|
||||
Cid string `gorm:"comment:'客户端id'"` // 客户端表id
|
||||
CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间
|
||||
}
|
||||
|
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:'创建时间'"` // 创建时间
|
||||
}
|
BIN
server/resources/ip/ip2region.xdb
Normal file
BIN
server/resources/ip/ip2region.xdb
Normal file
Binary file not shown.
@@ -60,6 +60,7 @@ func RegisterGroup(rg *gin.RouterGroup) {
|
||||
MonitorProjectRoute(rg)
|
||||
MonitorClientRoute(rg)
|
||||
MonitorErrorRoute(rg)
|
||||
MonitorSlowRoute(rg)
|
||||
|
||||
UserProtocolRoute(rg)
|
||||
}
|
||||
|
@@ -45,6 +45,7 @@ INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_sh
|
||||
// MonitorClientRoute(rg)
|
||||
func MonitorClientRoute(rg *gin.RouterGroup) {
|
||||
handle := monitor_client.MonitorClientHandler{}
|
||||
rg.GET("/monitor_client/add", middleware.RecordLog("监控-客户端信息新增"), handle.Add)
|
||||
|
||||
r := rg.Group("/", middleware.TokenAuth())
|
||||
r.GET("/monitor_client/list", handle.List)
|
||||
@@ -52,7 +53,6 @@ func MonitorClientRoute(rg *gin.RouterGroup) {
|
||||
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/edit",middleware.RecordLog("监控-客户端信息编辑"), handle.Edit)
|
||||
|
||||
r.POST("/monitor_client/del", middleware.RecordLog("监控-客户端信息删除"), handle.Del)
|
||||
|
@@ -45,14 +45,13 @@ INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_sh
|
||||
// MonitorErrorRoute(rg)
|
||||
func MonitorErrorRoute(rg *gin.RouterGroup) {
|
||||
handle := monitor_error.MonitorErrorHandler{}
|
||||
rg.GET("/monitor_error/add", middleware.RecordLog("监控-错误列新增"), handle.Add)
|
||||
|
||||
r := rg.Group("/", middleware.TokenAuth())
|
||||
r.GET("/monitor_error/list", handle.List)
|
||||
r.GET("/monitor_error/listAll", handle.ListAll)
|
||||
r.GET("/monitor_error/detail", handle.Detail)
|
||||
|
||||
r.POST("/monitor_error/add", middleware.RecordLog("监控-错误列新增"), handle.Add)
|
||||
|
||||
r.POST("/monitor_error/del", middleware.RecordLog("监控-错误列删除"), handle.Del)
|
||||
r.POST("/monitor_error/delBatch", middleware.RecordLog("监控-错误列删除-批量"), handle.DelBatch)
|
||||
|
||||
|
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.GET("/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)
|
||||
}
|
@@ -52,16 +52,23 @@ func (c CacheUtil) GetCache(key interface{}, obj interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 删除缓存
|
||||
// 删除缓存-支持批量删除
|
||||
func (c CacheUtil) RemoveCache(key interface{}) bool {
|
||||
var cacheKey string
|
||||
var cacheKey []string
|
||||
switch k := key.(type) {
|
||||
case int:
|
||||
cacheKey = strconv.Itoa(k)
|
||||
cacheKey = append(cacheKey, strconv.Itoa(k))
|
||||
case string:
|
||||
cacheKey = append(cacheKey, k)
|
||||
// 判断是slice
|
||||
case []int:
|
||||
for _, v := range k {
|
||||
cacheKey = append(cacheKey, strconv.Itoa(v))
|
||||
}
|
||||
case []string:
|
||||
cacheKey = k
|
||||
default:
|
||||
return false
|
||||
}
|
||||
return RedisUtil.HDel(c.Name, cacheKey)
|
||||
return RedisUtil.HDel(c.Name, cacheKey...)
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
var ConfigUtil = configUtil{}
|
||||
|
||||
// convertUtil 数据库配置操作工具
|
||||
// 数据库配置操作工具
|
||||
type configUtil struct{}
|
||||
|
||||
// Get 根据类型和名称获取配置字典
|
||||
|
@@ -2,7 +2,6 @@ package util
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"x_admin/core"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/jinzhu/copier"
|
||||
@@ -28,7 +27,7 @@ func (c convertUtil) StructsToMaps(from interface{}) (data []map[string]interfac
|
||||
var objList []interface{}
|
||||
err := copier.Copy(&objList, from)
|
||||
if err != nil {
|
||||
core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||
return nil
|
||||
}
|
||||
for _, v := range objList {
|
||||
@@ -57,7 +56,7 @@ func (c convertUtil) ShallowStructsToMaps(from interface{}) (data []map[string]i
|
||||
var objList []interface{}
|
||||
err := copier.Copy(&objList, from)
|
||||
if err != nil {
|
||||
core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||
// core.Logger.Errorf("convertUtil.StructsToMaps err: err=[%+v]", err)
|
||||
return nil
|
||||
}
|
||||
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{} {
|
||||
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")
|
||||
}
|
||||
return toValue
|
100
server/util/convert_util/convert.go
Normal file
100
server/util/convert_util/convert.go
Normal file
@@ -0,0 +1,100 @@
|
||||
package convert_util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"reflect"
|
||||
|
||||
"github.com/duke-git/lancet/v2/convertor"
|
||||
|
||||
"github.com/fatih/structs"
|
||||
"github.com/jinzhu/copier"
|
||||
"github.com/mitchellh/mapstructure"
|
||||
)
|
||||
|
||||
func ToFloat64(value interface{}) (float64, error) {
|
||||
switch v := value.(type) {
|
||||
case float32:
|
||||
return strconv.ParseFloat(fmt.Sprintf("%f", v), 64)
|
||||
default:
|
||||
return convertor.ToFloat(value)
|
||||
}
|
||||
}
|
||||
func ToInt64(value interface{}) (int64, error) {
|
||||
return convertor.ToInt(value)
|
||||
}
|
||||
|
||||
// StructToMap 结构体转换成map,深度转换
|
||||
func 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 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, StructToMap(v))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// ShallowStructToMap 将结构体转换成map,浅转换
|
||||
func 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 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, ShallowStructToMap(v))
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// MapToStruct 将map弱类型转换成结构体
|
||||
func MapToStruct(from interface{}, to interface{}) (err error) {
|
||||
err = mapstructure.WeakDecode(from, to) // 需要tag:mapstructure
|
||||
return err
|
||||
}
|
||||
|
||||
// StructToStruct 将结构体from弱类型转换成结构体to
|
||||
func StructToStruct(from interface{}, to interface{}) (err error) {
|
||||
m := StructToMap(from)
|
||||
err = MapToStruct(m, to)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func 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
|
||||
}
|
@@ -2,7 +2,7 @@ package excel2
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
@@ -26,7 +26,7 @@ func GetExcelColumnName(columnNumber int) string {
|
||||
func Export(lists any, cols []Col, sheet string, title string) (file *excelize.File, err error) {
|
||||
e := ExcelInit()
|
||||
|
||||
data := util.ConvertUtil.ShallowStructsToMaps(lists)
|
||||
data := convert_util.ShallowStructsToMaps(lists)
|
||||
|
||||
err = ExportExcel(sheet, title, data, cols, e)
|
||||
if err != nil {
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"x_admin/util"
|
||||
"x_admin/util/convert_util"
|
||||
|
||||
"github.com/xuri/excelize/v2"
|
||||
)
|
||||
@@ -99,7 +99,7 @@ func importData(f *excelize.File, dst interface{}, sheetName string, startRow in
|
||||
data = append(data, rowMap)
|
||||
|
||||
}
|
||||
util.ConvertUtil.MapToStruct(data, dst)
|
||||
convert_util.MapToStruct(data, dst)
|
||||
|
||||
// fmt.Println("Type.Name:", field.Type.Name(), field.Type.Kind())
|
||||
// // 根据字段类型设置值
|
||||
|
38
server/util/img_util/img_util.go
Normal file
38
server/util/img_util/img_util.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package img_util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"image"
|
||||
"image/color"
|
||||
"image/gif"
|
||||
)
|
||||
|
||||
func EmptyGif() []byte {
|
||||
img := image.NewRGBA(image.Rect(0, 0, 1, 1))
|
||||
|
||||
// 设置像素颜色为黑色
|
||||
img.Set(0, 0, color.Black)
|
||||
|
||||
// 创建GIF动画
|
||||
g := &gif.GIF{
|
||||
Image: []*image.Paletted{imageToPaletted(img)},
|
||||
Delay: []int{0}, // 延迟时间,单位是10毫秒
|
||||
}
|
||||
var buffer bytes.Buffer
|
||||
|
||||
// 编码GIF到缓冲区
|
||||
gif.EncodeAll(&buffer, g)
|
||||
return buffer.Bytes()
|
||||
}
|
||||
|
||||
// 将image.Image转换为*image.Paletted
|
||||
func imageToPaletted(img image.Image) *image.Paletted {
|
||||
b := img.Bounds()
|
||||
pm := image.NewPaletted(b, color.Palette{color.Black})
|
||||
for y := b.Min.Y; y < b.Max.Y; y++ {
|
||||
for x := b.Min.X; x < b.Max.X; x++ {
|
||||
pm.Set(x, y, img.At(x, y))
|
||||
}
|
||||
}
|
||||
return pm
|
||||
}
|
@@ -1,23 +1,83 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"x_admin/core"
|
||||
"strings"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/binding/golang/xdb"
|
||||
)
|
||||
|
||||
var IpUtil = ipUtil{}
|
||||
var IpUtil = initIpUtil()
|
||||
|
||||
// serverUtil IP工具类
|
||||
type ipUtil struct{}
|
||||
type ipUtil struct {
|
||||
Searcher *xdb.Searcher
|
||||
}
|
||||
|
||||
// GetHostIp 获取本地主机名
|
||||
func (su ipUtil) GetHostIp() (ip string) {
|
||||
conn, err := net.Dial("udp", "114.114.114.114:80")
|
||||
if err != nil {
|
||||
core.Logger.Errorf("GetHostIp Dial err: err=[%+v]", err)
|
||||
// core.Logger.Errorf("GetHostIp Dial err: err=[%+v]", err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
localAddr := conn.LocalAddr().(*net.UDPAddr)
|
||||
return localAddr.IP.String()
|
||||
}
|
||||
|
||||
type Region struct {
|
||||
Country string
|
||||
Province string
|
||||
City string
|
||||
Operator string
|
||||
}
|
||||
|
||||
func (ipUtils *ipUtil) Parse(ip string) Region {
|
||||
|
||||
if ip == "" {
|
||||
fmt.Println("输入ip为空")
|
||||
return Region{}
|
||||
}
|
||||
|
||||
region, err := ipUtils.Searcher.SearchByStr(ip)
|
||||
if err != nil {
|
||||
fmt.Printf("解析ip(%s)错误: %s\n", ip, err)
|
||||
return Region{}
|
||||
}
|
||||
// 中国|0|四川省|成都市|电信
|
||||
parts := strings.Split(region, "|")
|
||||
if len(parts) != 5 {
|
||||
fmt.Println("解析ip返回错误")
|
||||
return Region{}
|
||||
}
|
||||
country := parts[0]
|
||||
province := parts[2]
|
||||
city := parts[3]
|
||||
operator := parts[4]
|
||||
regionInfo := Region{Country: country, Province: province, City: city, Operator: operator}
|
||||
fmt.Println(regionInfo)
|
||||
return regionInfo
|
||||
}
|
||||
func initIpUtil() *ipUtil {
|
||||
ip_util := ipUtil{}
|
||||
|
||||
var dbPath = "resources/ip/ip2region.xdb"
|
||||
// 创建完全基于内存的查询对象。
|
||||
cBuff, err := xdb.LoadContentFromFile(dbPath)
|
||||
if err != nil {
|
||||
fmt.Printf("failed to load content from `%s`: %s\n", dbPath, err)
|
||||
return &ip_util
|
||||
}
|
||||
// 并发使用,用整个 xdb 缓存创建的 searcher 对象可以安全用于并发。
|
||||
searcher, err := xdb.NewWithBuffer(cBuff)
|
||||
|
||||
if err != nil {
|
||||
fmt.Printf("failed to create searcher: %s\n", err.Error())
|
||||
return &ip_util
|
||||
}
|
||||
fmt.Printf("创建完全基于内存的查询对象。")
|
||||
ip_util.Searcher = searcher
|
||||
return &ip_util
|
||||
}
|
||||
|
16
x_err_sdk/.gitignore
vendored
Normal file
16
x_err_sdk/.gitignore
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
pnpm-lock.yaml
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
coverage
|
||||
*.local
|
26
x_err_sdk/package.json
Normal file
26
x_err_sdk/package.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "@adtkcn/x_err_sdk",
|
||||
"version": "1.0.0",
|
||||
"description": "错误监控sdk",
|
||||
"main": "dist/web/XErr.umd.js",
|
||||
"private": false,
|
||||
"file": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "vite build&&npm run build:ts",
|
||||
"build:ts": "tsc --emitDeclarationOnly",
|
||||
"outdated": "pnpm outdated"
|
||||
},
|
||||
"keywords": [
|
||||
"x_err_sdk",
|
||||
"X_admin"
|
||||
],
|
||||
"author": "adtkcn",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"typescript": "^5.6.3",
|
||||
"uuid": "^11.0.2",
|
||||
"vite": "^5.4.10"
|
||||
}
|
||||
}
|
15
x_err_sdk/tsconfig.json
Normal file
15
x_err_sdk/tsconfig.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true, // 生成声明文件,开启后会自动生成声明文件
|
||||
"target": "esnext", // 最新的ES标准
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom"
|
||||
], // TS需要引用的库,即声明文件,es5 默认引用dom、es5、scripthost,如需要使用es的高级版本特性,通常都需要配置,如es8的数组新特性需要引入"ES2019.Array"
|
||||
"strict": true, // 开启所有严格的类型检查
|
||||
"noImplicitAny": true, // 不允许隐式的any类型
|
||||
"esModuleInterop": true, // 允许export=导出,由import from 导入
|
||||
"moduleResolution": "node", // 模块解析策略,ts默认用node的解析策略,即相对的方式导入
|
||||
"outDir": "dist" // 指定输出目录
|
||||
}
|
||||
}
|
33
x_err_sdk/types.ts
Normal file
33
x_err_sdk/types.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
|
||||
export type LogWithEnv = {
|
||||
Type: "env";
|
||||
ScreenHeight?: number;
|
||||
ScreenWidth?: number;
|
||||
};
|
||||
export type LogWithError = {
|
||||
Type: "error"|"event"|"resources"|'click';
|
||||
EventType: string;
|
||||
Path:string;
|
||||
Message?: string;
|
||||
Stack?: string;
|
||||
};
|
||||
|
||||
export type ISlow = {
|
||||
Type: "onloadTime"
|
||||
|
||||
Path:string;
|
||||
Time: number;
|
||||
};
|
||||
|
||||
|
||||
// 扩展必须实现的接口
|
||||
export interface IErrorEvent {
|
||||
upload(url: string, data: object): Promise<void>;
|
||||
setCache(key: string, info: any): void;
|
||||
getCache(key: string): any;
|
||||
delCache(key: string): void;
|
||||
getEnvInfo(): LogWithEnv;
|
||||
listen(callback: ListenCallbackFn): void;
|
||||
unListen(): void;
|
||||
}
|
||||
export type ListenCallbackFn = (params: LogWithError|ISlow) => void;
|
21
x_err_sdk/vite.config.js
Normal file
21
x_err_sdk/vite.config.js
Normal file
@@ -0,0 +1,21 @@
|
||||
import { defineConfig, loadEnv } from 'vite'
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
lib: {
|
||||
entry: 'web/index.ts', // 库的入口文件
|
||||
name: 'XErr', // 库的名称
|
||||
fileName: (format) => `web/XErr.${format}.js`, // 输出文件名
|
||||
},
|
||||
rollupOptions: {
|
||||
// 外部化处理不想打包进库的依赖
|
||||
// external: ['vue'],
|
||||
output: {
|
||||
globals: {
|
||||
// vue: 'Vue'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
175
x_err_sdk/web/base.ts
Normal file
175
x_err_sdk/web/base.ts
Normal file
@@ -0,0 +1,175 @@
|
||||
import { v1 as uuid_v1 } from "uuid";
|
||||
import type { LogWithError, IErrorEvent,ISlow, LogWithEnv } from "../types";
|
||||
|
||||
type Uid = string | number;
|
||||
|
||||
type Props = {
|
||||
Dns: string; // 域名
|
||||
Pid: string; // 项目标识
|
||||
Uid?: Uid; //用户标识
|
||||
};
|
||||
|
||||
class Base {
|
||||
private Dns: string = "";
|
||||
private client_id: string = "";
|
||||
private Pid: string = "";
|
||||
private Uid: Uid = "";
|
||||
|
||||
private platform: IErrorEvent | null = null;
|
||||
|
||||
private MessageList: any[] = [];
|
||||
private timer: number = 0;
|
||||
|
||||
constructor(props: Props, platform: IErrorEvent) {
|
||||
if (!props) {
|
||||
console.error("props is null");
|
||||
return;
|
||||
}
|
||||
if (!platform) {
|
||||
console.error("platform is null");
|
||||
return;
|
||||
}
|
||||
this.platform = platform;
|
||||
if (props.Dns && props.Pid) {
|
||||
this.Dns = props.Dns;
|
||||
this.Pid = props.Pid;
|
||||
} else {
|
||||
console.error("props.Dns and props.Pid cannot be null");
|
||||
return;
|
||||
}
|
||||
if (props.Uid) {
|
||||
this.Uid = String(props.Uid);
|
||||
}
|
||||
this.setClientID();
|
||||
this.SetUid();
|
||||
this.getLocalMessage();
|
||||
|
||||
|
||||
// 监听错误
|
||||
platform.listen((params: LogWithError|ISlow) => {
|
||||
console.log("listenCallback", params);
|
||||
if(params.Type=='onloadTime'){
|
||||
let slow=params as ISlow;
|
||||
this.uploadSlow(slow);
|
||||
}else{
|
||||
this.Push(params);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
this.timer = setInterval(() => {
|
||||
this.upload();
|
||||
}, 1000 * 10);
|
||||
}
|
||||
|
||||
// 设置用户id
|
||||
public SetUid(uid?: Uid) {
|
||||
if (uid) {
|
||||
this.Uid =String(uid) ;
|
||||
this.platform?.setCache("x_err_uid", this.Uid);
|
||||
|
||||
} else {
|
||||
const u_id = this.platform?.getCache("x_err_uid");
|
||||
if (u_id) {
|
||||
this.Uid = u_id;
|
||||
}
|
||||
}
|
||||
this.initEnv();
|
||||
}
|
||||
// 初始化环境信息并上传
|
||||
private initEnv() {
|
||||
let envInfo = this.platform?.getEnvInfo();
|
||||
if (envInfo) {
|
||||
this.uploadInfo(envInfo);
|
||||
}
|
||||
}
|
||||
// 设置错误ID
|
||||
private setClientID() {
|
||||
const client_id = this.platform?.getCache("x_err_client_id");
|
||||
if (client_id) {
|
||||
this.client_id = client_id;
|
||||
} else {
|
||||
this.client_id = uuid_v1();
|
||||
this.platform?.setCache("x_err_client_id", this.client_id);
|
||||
}
|
||||
}
|
||||
// 获取本地缓存消息
|
||||
private getLocalMessage() {
|
||||
let x_err_message_list = this.platform?.getCache("x_err_message_list");
|
||||
if (x_err_message_list) {
|
||||
this.MessageList = x_err_message_list;
|
||||
} else {
|
||||
this.MessageList = [];
|
||||
}
|
||||
}
|
||||
// 记录错误,超出5条时立即上报,否则缓存到本地(等待定时器上报)
|
||||
public Push=(data: LogWithError) =>{
|
||||
this.MessageList.push({
|
||||
...data,
|
||||
ProjectKey: this.Pid,
|
||||
ClientId: this.client_id,
|
||||
});
|
||||
|
||||
if (this.MessageList.length > 5) {
|
||||
this.upload(); //上传
|
||||
} else {
|
||||
this.platform?.setCache("x_err_message_list", this.MessageList);
|
||||
}
|
||||
}
|
||||
public uploadInfo=(envInfo: LogWithEnv) =>{
|
||||
if (!this.Dns) return; //未设置Dns服务器不上传
|
||||
|
||||
try {
|
||||
this.platform
|
||||
?.upload(this.Dns + `/admin/monitor_client/add`, {
|
||||
ProjectKey: this.Pid,
|
||||
ClientId: this.client_id,
|
||||
UserId: this.Uid,
|
||||
Width: envInfo.ScreenWidth,
|
||||
Height: envInfo.ScreenHeight,
|
||||
})
|
||||
.catch((err: any) => {
|
||||
// 上传失败
|
||||
});
|
||||
} catch (error) {}
|
||||
}
|
||||
public uploadSlow=(envInfo: ISlow) =>{
|
||||
if (!this.Dns) return; //未设置Dns服务器不上传
|
||||
|
||||
try {
|
||||
this.platform
|
||||
?.upload(this.Dns + `/admin/monitor_slow/add`, {
|
||||
ProjectKey: this.Pid,
|
||||
ClientId: this.client_id,
|
||||
UserId: this.Uid,
|
||||
Path: envInfo.Path,
|
||||
Time: envInfo.Time,
|
||||
})
|
||||
.catch((err: any) => {
|
||||
// 上传失败
|
||||
});
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
// 上传文件
|
||||
public upload() {
|
||||
if (!this.Dns) return; //未设置Dns服务器不上传
|
||||
if (!this.MessageList.length) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
this.platform
|
||||
?.upload(this.Dns + `/admin/monitor_error/add`, this.MessageList)
|
||||
.catch((err: any) => {
|
||||
// 上传失败
|
||||
});
|
||||
this.MessageList = [];
|
||||
this.platform?.delCache("x_err_message_list");
|
||||
} catch (error) {}
|
||||
}
|
||||
public unListen() {
|
||||
clearInterval(this.timer);
|
||||
this.platform?.unListen();
|
||||
}
|
||||
}
|
||||
export default Base;
|
4
x_err_sdk/web/index.ts
Normal file
4
x_err_sdk/web/index.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import Base from "./base";
|
||||
import Web from "./web";
|
||||
|
||||
export { Base, Web };
|
179
x_err_sdk/web/web.ts
Normal file
179
x_err_sdk/web/web.ts
Normal file
@@ -0,0 +1,179 @@
|
||||
import type {
|
||||
LogWithError,
|
||||
LogWithEnv,
|
||||
ListenCallbackFn,
|
||||
IErrorEvent,ISlow
|
||||
} from "../types";
|
||||
|
||||
interface LoggerProps {
|
||||
// timeout:number
|
||||
onloadTimeOut?: number;
|
||||
}
|
||||
class Web implements IErrorEvent {
|
||||
props: LoggerProps;
|
||||
constructor(props?: LoggerProps) {
|
||||
this.props = {
|
||||
onloadTimeOut: 5000,
|
||||
...props,
|
||||
};
|
||||
}
|
||||
public upload(url: string, data: any): Promise<void> {
|
||||
return new Promise((resolve) => {
|
||||
try {
|
||||
let h = new Image();
|
||||
h.onload = function (event) {
|
||||
var e = event as Event;
|
||||
e.preventDefault();
|
||||
};
|
||||
h.onerror = function () {};
|
||||
h.src = url + "?data=" + encodeURIComponent(JSON.stringify(data));
|
||||
resolve();
|
||||
} catch (error) {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public setCache(key: string, info: any): void {
|
||||
localStorage.setItem(key, JSON.stringify(info));
|
||||
}
|
||||
|
||||
public getCache(key: string): any {
|
||||
try {
|
||||
let list = localStorage.getItem(key);
|
||||
if (list) {
|
||||
return JSON.parse(list);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public delCache(key: string): void {
|
||||
localStorage.removeItem(key);
|
||||
}
|
||||
|
||||
public getEnvInfo(): LogWithEnv {
|
||||
const env: LogWithEnv = {
|
||||
Type: "env",
|
||||
ScreenHeight: 0,
|
||||
ScreenWidth: 0,
|
||||
};
|
||||
if (window) {
|
||||
env.ScreenHeight = window.innerHeight || 0; // 获取显示屏信息
|
||||
env.ScreenWidth = window.innerWidth || 0;
|
||||
}
|
||||
return env;
|
||||
}
|
||||
private callback(err: LogWithError|ISlow): void {}
|
||||
private listenError = (err: any) => {
|
||||
console.error([err]);
|
||||
let target = err.target;
|
||||
if (target?.localName) {
|
||||
if (target?.localName === "img" || target?.localName === "script") {
|
||||
this.callback({
|
||||
Type: "resources",
|
||||
EventType: target?.localName,
|
||||
Path: target.src,
|
||||
Message: "",
|
||||
Stack: "",
|
||||
});
|
||||
} else if (target?.localName === "link") {
|
||||
this.callback({
|
||||
Type: "resources",
|
||||
EventType: target?.localName,
|
||||
Path: target.href,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.callback({
|
||||
Type: "error",
|
||||
EventType: err.type,
|
||||
Path: window.location.href,
|
||||
Message: err.message,
|
||||
Stack: this.handleStack(err.error?.stack || ""),
|
||||
});
|
||||
}
|
||||
};
|
||||
private unhandledrejection = (err: any): void => {
|
||||
console.error(err);
|
||||
if (err && typeof err.reason === "string") {
|
||||
this.callback({
|
||||
Type: "error",
|
||||
EventType: err.type,
|
||||
Path: window.location.href,
|
||||
Message: err.reason,
|
||||
Stack: "",
|
||||
});
|
||||
} else if (err && typeof err.reason === "object") {
|
||||
this.callback({
|
||||
Type: "error",
|
||||
EventType: err.type,
|
||||
Path: window.location.href,
|
||||
Message: err.reason?.message || "",
|
||||
Stack: this.handleStack(err.reason?.stack || ""),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private handleStack(stack: string): string {
|
||||
let newStack: string[] = [];
|
||||
if (stack) {
|
||||
stack.split("\n").map((item, index) => {
|
||||
if (index < 4) {
|
||||
newStack.push(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
return newStack.join("\n");
|
||||
}
|
||||
private onLoad = () => {
|
||||
// 获取性能数据
|
||||
const entries = performance.getEntriesByType("navigation");
|
||||
if (entries.length > 0) {
|
||||
const performanceData = entries[0] as PerformanceNavigationTiming;
|
||||
|
||||
console.log("performanceData", performanceData);
|
||||
|
||||
// 计算页面onload时间
|
||||
let onloadTime =
|
||||
performanceData.loadEventStart - performanceData.startTime;
|
||||
if (
|
||||
this.props.onloadTimeOut &&
|
||||
onloadTime > this.props.onloadTimeOut
|
||||
) {
|
||||
// 页面加载时间5s以上
|
||||
this.callback({
|
||||
Type: "onloadTime",
|
||||
Path: window.location.href,
|
||||
Time:onloadTime
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
public listen(callback: ListenCallbackFn): void {
|
||||
this.callback = callback;
|
||||
window.addEventListener("unhandledrejection", this.unhandledrejection);
|
||||
window.addEventListener("error", this.listenError, true);
|
||||
// window.addEventListener("click", this.listenClick);
|
||||
// window.addEventListener("hashchange", this.listenHashRouterChange);
|
||||
// window.addEventListener("popstate", this.listenHistoryRouterChange);
|
||||
|
||||
window.addEventListener("load", this.onLoad);
|
||||
}
|
||||
|
||||
public unListen(): void {
|
||||
this.callback = () => {};
|
||||
window.removeEventListener("error", this.listenError);
|
||||
window.removeEventListener("unhandledrejection", this.unhandledrejection);
|
||||
// window.removeEventListener("click", this.listenClick);
|
||||
// window.removeEventListener("hashchange", this.listenHashRouterChange);
|
||||
// window.removeEventListener("popstate", this.listenHistoryRouterChange);
|
||||
}
|
||||
}
|
||||
|
||||
export default Web;
|
Reference in New Issue
Block a user