From 2d473ac4ed26093ec02f28effe69ce20361c46d2 Mon Sep 17 00:00:00 2001 From: xh <11675084@qq.com> Date: Thu, 26 Jun 2025 00:23:35 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E9=94=99=E8=AF=AF=E6=94=B6?= =?UTF-8?q?=E9=9B=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/public/XErr.umd.js | 6 +- admin/src/api/monitor/client.ts | 9 +-- admin/src/components/pagination/index.vue | 2 +- admin/src/hooks/usePaging.ts | 2 +- admin/src/views/monitor/client/index.vue | 7 +-- .../monitorController/monitor_client_ctl.go | 7 +-- server/model/monitor_client.go | 25 ++++---- server/model/monitor_error_list.go | 2 + .../router/adminRoute/monitor_error_route.go | 2 +- .../monitorSchema/monitor_client_schema.go | 58 +++++++++---------- .../monitor_error_list_schema.go | 14 +++-- .../monitorSchema/monitor_error_schema.go | 29 ++++++---- .../monitorService/monitor_client_service.go | 11 +--- .../monitorService/monitor_error_service.go | 29 +++++----- x_err_sdk/types.ts | 18 +++--- x_err_sdk/web/base.ts | 33 ++++++----- x_err_sdk/web/web.ts | 19 +++--- 17 files changed, 130 insertions(+), 143 deletions(-) diff --git a/admin/public/XErr.umd.js b/admin/public/XErr.umd.js index 73d3d35..655614e 100644 --- a/admin/public/XErr.umd.js +++ b/admin/public/XErr.umd.js @@ -1,3 +1,3 @@ -(function(a,s){typeof exports=="object"&&typeof module<"u"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(a=typeof globalThis<"u"?globalThis:a||self,s(a.XErr={}))})(this,function(a){"use strict";var v=Object.defineProperty;var P=(a,s,d)=>s in a?v(a,s,{enumerable:!0,configurable:!0,writable:!0,value:d}):a[s]=d;var r=(a,s,d)=>P(a,typeof s!="symbol"?s+"":s,d);const s=[];for(let t=0;t<256;++t)s.push((t+256).toString(16).slice(1));function d(t,e=0){return(s[t[e+0]]+s[t[e+1]]+s[t[e+2]]+s[t[e+3]]+"-"+s[t[e+4]]+s[t[e+5]]+"-"+s[t[e+6]]+s[t[e+7]]+"-"+s[t[e+8]]+s[t[e+9]]+"-"+s[t[e+10]]+s[t[e+11]]+s[t[e+12]]+s[t[e+13]]+s[t[e+14]]+s[t[e+15]]).toLowerCase()}let m;const g=new Uint8Array(16);function y(){if(!m){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");m=crypto.getRandomValues.bind(crypto)}return m(g)}const h={};function w(t,e,i){let n;{const l=Date.now(),o=y();_(h,l,o),n=S(o,h.msecs,h.nsecs,h.clockseq,h.node,e,i)}return e?n:d(n)}function _(t,e,i){return t.msecs??(t.msecs=-1/0),t.nsecs??(t.nsecs=0),e===t.msecs?(t.nsecs++,t.nsecs>=1e4&&(t.node=void 0,t.nsecs=0)):e>t.msecs?t.nsecs=0:e>>24&255,o[c++]=u>>>16&255,o[c++]=u>>>8&255,o[c++]=u&255;const p=e/4294967296*1e4&268435455;o[c++]=p>>>8&255,o[c++]=p&255,o[c++]=p>>>24&15|16,o[c++]=p>>>16&255,o[c++]=n>>>8|128,o[c++]=n&255;for(let f=0;f<6;++f)o[c++]=l[f];return o}class x{constructor(e,i){r(this,"Dns","");r(this,"client_id","");r(this,"Pid","");r(this,"Uid","");r(this,"platform",null);r(this,"MessageList",[]);r(this,"timer",0);r(this,"Push",e=>{var i;this.MessageList.push({...e,ProjectKey:this.Pid,ClientId:this.client_id}),this.MessageList.length>5?this.upload():(i=this.platform)==null||i.setCache("x_err_message_list",this.MessageList)});r(this,"uploadInfo",e=>{var i;if(this.Dns)try{(i=this.platform)==null||i.upload(this.Dns+"/admin/monitor_client/add",{ProjectKey:this.Pid,ClientId:this.client_id,UserId:this.Uid,Width:e.ScreenWidth,Height:e.ScreenHeight}).catch(n=>{})}catch{}});r(this,"uploadSlow",e=>{var i;if(this.Dns)try{(i=this.platform)==null||i.upload(this.Dns+"/admin/monitor_slow/add",{ProjectKey:this.Pid,ClientId:this.client_id,UserId:this.Uid,Path:e.Path,Time:e.Time}).catch(n=>{})}catch{}});if(!e){console.error("props is null");return}if(!i){console.error("platform is null");return}if(this.platform=i,e.Dns&&e.Pid)this.Dns=e.Dns,this.Pid=e.Pid;else{console.error("props.Dns and props.Pid cannot be null");return}e.Uid&&(this.Uid=String(e.Uid)),this.setClientID(),this.SetUid(),this.getLocalMessage(),i.listen(n=>{if(console.log("listenCallback",n),n.Type=="onloadTime"){let l=n;this.uploadSlow(l)}else this.Push(n)}),this.timer=setInterval(()=>{this.upload()},1e3*10)}SetUid(e){var i,n;if(e)this.Uid=String(e),(i=this.platform)==null||i.setCache("x_err_uid",this.Uid);else{const l=(n=this.platform)==null?void 0:n.getCache("x_err_uid");l&&(this.Uid=l)}this.initEnv()}initEnv(){var i;let e=(i=this.platform)==null?void 0:i.getEnvInfo();e&&this.uploadInfo(e)}setClientID(){var i,n;const e=(i=this.platform)==null?void 0:i.getCache("x_err_client_id");e?this.client_id=e:(this.client_id=w(),(n=this.platform)==null||n.setCache("x_err_client_id",this.client_id))}getLocalMessage(){var i;let e=(i=this.platform)==null?void 0:i.getCache("x_err_message_list");e?this.MessageList=e:this.MessageList=[]}upload(){var e,i;if(this.Dns&&this.MessageList.length)try{(e=this.platform)==null||e.upload(this.Dns+"/admin/monitor_error/add",this.MessageList).catch(n=>{}),this.MessageList=[],(i=this.platform)==null||i.delCache("x_err_message_list")}catch{}}unListen(){var e;clearInterval(this.timer),(e=this.platform)==null||e.unListen()}}class T{constructor(e){r(this,"props");r(this,"listenError",e=>{var n;console.error([e]);let i=e.target;i!=null&&i.localName?(i==null?void 0:i.localName)==="img"||(i==null?void 0:i.localName)==="script"?this.callback({Type:"resources",EventType:i==null?void 0:i.localName,Path:i.src,Message:"",Stack:""}):(i==null?void 0:i.localName)==="link"&&this.callback({Type:"resources",EventType:i==null?void 0:i.localName,Path:i.href}):this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:e.message,Stack:this.handleStack(((n=e.error)==null?void 0:n.stack)||"")})});r(this,"unhandledrejection",e=>{var i,n;console.error(e),e&&typeof e.reason=="string"?this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:e.reason,Stack:""}):e&&typeof e.reason=="object"&&this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:((i=e.reason)==null?void 0:i.message)||"",Stack:this.handleStack(((n=e.reason)==null?void 0:n.stack)||"")})});r(this,"onLoad",()=>{const e=performance.getEntriesByType("navigation");if(e.length>0){const i=e[0];console.log("performanceData",i);let n=i.loadEventStart-i.startTime;this.props.onloadTimeOut&&n>this.props.onloadTimeOut&&this.callback({Type:"onloadTime",Path:window.location.href,Time:n})}});this.props={onloadTimeOut:5e3,...e}}upload(e,i){return new Promise(n=>{try{let l=new Image;l.onload=function(o){var c=o;c.preventDefault()},l.onerror=function(){},l.src=e+"?data="+encodeURIComponent(JSON.stringify(i)),n()}catch{n()}})}setCache(e,i){localStorage.setItem(e,JSON.stringify(i))}getCache(e){try{let i=localStorage.getItem(e);return i?JSON.parse(i):null}catch{return null}}delCache(e){localStorage.removeItem(e)}getEnvInfo(){const e={Type:"env",ScreenHeight:0,ScreenWidth:0};return window&&(e.ScreenHeight=window.innerHeight||0,e.ScreenWidth=window.innerWidth||0),e}callback(e){}handleStack(e){let i=[];return e&&e.split(` -`).map((n,l)=>{l<4&&i.push(n)}),i.join(` -`)}listen(e){this.callback=e,window.addEventListener("unhandledrejection",this.unhandledrejection),window.addEventListener("error",this.listenError,!0),window.addEventListener("load",this.onLoad)}unListen(){this.callback=()=>{},window.removeEventListener("error",this.listenError),window.removeEventListener("unhandledrejection",this.unhandledrejection)}}a.Base=x,a.Web=T,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}); +(function(a,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(a=typeof globalThis<"u"?globalThis:a||self,n(a.XErr={}))})(this,function(a){"use strict";var k=Object.defineProperty;var I=(a,n,h)=>n in a?k(a,n,{enumerable:!0,configurable:!0,writable:!0,value:h}):a[n]=h;var o=(a,n,h)=>I(a,typeof n!="symbol"?n+"":n,h);const n=[];for(let t=0;t<256;++t)n.push((t+256).toString(16).slice(1));function h(t,e=0){return(n[t[e+0]]+n[t[e+1]]+n[t[e+2]]+n[t[e+3]]+"-"+n[t[e+4]]+n[t[e+5]]+"-"+n[t[e+6]]+n[t[e+7]]+"-"+n[t[e+8]]+n[t[e+9]]+"-"+n[t[e+10]]+n[t[e+11]]+n[t[e+12]]+n[t[e+13]]+n[t[e+14]]+n[t[e+15]]).toLowerCase()}let m;const g=new Uint8Array(16);function y(){if(!m){if(typeof crypto>"u"||!crypto.getRandomValues)throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");m=crypto.getRandomValues.bind(crypto)}return m(g)}const d={};function _(t,e,i){let s;{const r=Date.now(),l=y();w(d,r,l),s=x(l,d.msecs,d.nsecs,d.clockseq,d.node,e,i)}return e?s:h(s)}function w(t,e,i){return t.msecs??(t.msecs=-1/0),t.nsecs??(t.nsecs=0),e===t.msecs?(t.nsecs++,t.nsecs>=1e4&&(t.node=void 0,t.nsecs=0)):e>t.msecs?t.nsecs=0:e>>24&255,l[c++]=u>>>16&255,l[c++]=u>>>8&255,l[c++]=u&255;const p=e/4294967296*1e4&268435455;l[c++]=p>>>8&255,l[c++]=p&255,l[c++]=p>>>24&15|16,l[c++]=p>>>16&255,l[c++]=s>>>8|128,l[c++]=s&255;for(let f=0;f<6;++f)l[c++]=r[f];return l}class S{constructor(e,i){o(this,"Dns","");o(this,"client_id","");o(this,"Pid","");o(this,"Uid","");o(this,"platform",null);o(this,"MessageList",[]);o(this,"timer",0);o(this,"lastTimeStamp",Date.now());o(this,"diffTime",1e3*10);o(this,"Push",e=>{var i;this.MessageList.push({...e,ProjectKey:this.Pid,ClientId:this.client_id}),this.MessageList.length>5?this.upload():(i=this.platform)==null||i.setCache("x_err_message_list",this.MessageList)});o(this,"uploadInfo",()=>{var e;if(this.Dns)try{(e=this.platform)==null||e.upload(this.Dns+"/admin/monitor_client/add",{ProjectKey:this.Pid,ClientId:this.client_id,UserId:this.Uid}).catch(i=>{})}catch{}});if(!e){console.error("props is null");return}if(!i){console.error("platform is null");return}if(this.platform=i,e.Dns&&e.Pid)this.Dns=e.Dns,this.Pid=e.Pid;else{console.error("props.Dns and props.Pid cannot be null");return}e.Uid&&(this.Uid=String(e.Uid)),this.setClientID(),this.SetUid(),this.getLocalMessage(),i.listen(s=>{console.log("listenCallback",s),this.Push(s)}),this.timer=setInterval(()=>{Date.now()-this.lastTimeStamp>=this.diffTime&&this.upload()},2e3)}SetUid(e){var i,s;if(e)this.Uid=String(e),(i=this.platform)==null||i.setCache("x_err_uid",this.Uid);else{const r=(s=this.platform)==null?void 0:s.getCache("x_err_uid");r&&(this.Uid=r)}this.uploadInfo()}setClientID(){var i,s;const e=(i=this.platform)==null?void 0:i.getCache("x_err_client_id");e?this.client_id=e:(this.client_id=_(),(s=this.platform)==null||s.setCache("x_err_client_id",this.client_id))}getLocalMessage(){var i;let e=(i=this.platform)==null?void 0:i.getCache("x_err_message_list");e?this.MessageList=e:this.MessageList=[]}upload(){var e;if(this.Dns&&this.MessageList.length){this.lastTimeStamp=Date.now();try{(e=this.platform)==null||e.upload(this.Dns+"/admin/monitor_error/add",this.MessageList).catch(i=>{}).then(()=>{var i;this.MessageList=[],(i=this.platform)==null||i.delCache("x_err_message_list")})}catch{}}}unListen(){var e;clearInterval(this.timer),(e=this.platform)==null||e.unListen()}}class v{constructor(e){o(this,"props");o(this,"listenError",e=>{var s;console.error([e]);let i=e.target;i!=null&&i.localName?(i==null?void 0:i.localName)==="img"||(i==null?void 0:i.localName)==="script"?this.callback({Type:"resources",EventType:i==null?void 0:i.localName,Path:i.src,Message:"",Stack:"",Height:0}):(i==null?void 0:i.localName)==="link"&&this.callback({Type:"resources",EventType:i==null?void 0:i.localName,Path:i.href}):this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:e.message,Stack:this.handleStack(((s=e.error)==null?void 0:s.stack)||""),...this.getEnvInfo()})});o(this,"unhandledrejection",e=>{var i,s;console.error(e),e&&typeof e.reason=="string"?this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:e.reason,Stack:"",...this.getEnvInfo()}):e&&typeof e.reason=="object"&&this.callback({Type:"error",EventType:e.type,Path:window.location.href,Message:((i=e.reason)==null?void 0:i.message)||"",Stack:this.handleStack(((s=e.reason)==null?void 0:s.stack)||""),...this.getEnvInfo()})});this.props={...e}}upload(e,i){return new Promise(s=>{try{let r=new Image;r.onload=function(l){var c=l;c.preventDefault()},r.onerror=function(){},r.src=e+"?data="+encodeURIComponent(JSON.stringify(i)),s()}catch{s()}})}setCache(e,i){localStorage.setItem(e,JSON.stringify(i))}getCache(e){try{let i=localStorage.getItem(e);return i?JSON.parse(i):null}catch{return null}}delCache(e){localStorage.removeItem(e)}getEnvInfo(){const e={Height:0,Width:0};return window&&(e.Height=window.innerHeight||0,e.Width=window.innerWidth||0),e}callback(e){}handleStack(e){let i=[];return e&&e.split(` +`).map((s,r)=>{r<4&&i.push(s)}),i.join(` +`)}listen(e){this.callback=e,window.addEventListener("unhandledrejection",this.unhandledrejection),window.addEventListener("error",this.listenError,!0)}unListen(){this.callback=()=>{},window.removeEventListener("error",this.listenError),window.removeEventListener("unhandledrejection",this.unhandledrejection)}}a.Base=S,a.Web=v,Object.defineProperty(a,Symbol.toStringTag,{value:"Module"})}); diff --git a/admin/src/api/monitor/client.ts b/admin/src/api/monitor/client.ts index 69aae28..cb4f68e 100644 --- a/admin/src/api/monitor/client.ts +++ b/admin/src/api/monitor/client.ts @@ -18,8 +18,7 @@ export type type_monitor_client = { City?: string Operator?: string Ip?: string - Width?: number - Height?: number + Ua?: string CreateTime?: string } @@ -35,8 +34,7 @@ export type type_monitor_client_query = { City?: string Operator?: string Ip?: string - Width?: number - Height?: number + Ua?: string CreateTimeStart?: string CreateTimeEnd?: string @@ -54,8 +52,7 @@ export type type_monitor_client_edit = { City?: string Operator?: string Ip?: string - Width?: number - Height?: number + Ua?: string } diff --git a/admin/src/components/pagination/index.vue b/admin/src/components/pagination/index.vue index 396fcdf..fb52335 100644 --- a/admin/src/components/pagination/index.vue +++ b/admin/src/components/pagination/index.vue @@ -23,7 +23,7 @@ interface Props { } const props = withDefaults(defineProps(), { modelValue: () => ({}), - pageSizes: () => [15, 20, 30, 40], + pageSizes: () => [10, 15, 20, 30, 40], layout: 'total, sizes, prev, pager, next, jumper' }) diff --git a/admin/src/hooks/usePaging.ts b/admin/src/hooks/usePaging.ts index bb98ac7..d1761d1 100644 --- a/admin/src/hooks/usePaging.ts +++ b/admin/src/hooks/usePaging.ts @@ -21,7 +21,7 @@ interface Options { * */ export function usePaging(options: Options) { - const { page = 1, size = 15, fetchFun, params = {}, firstLoading = false } = options + const { page = 1, size = 10, fetchFun, params = {}, firstLoading = false } = options // 记录分页初始参数 const paramsInit: Record = Object.assign({}, toRaw(params)) // 分页数据 diff --git a/admin/src/views/monitor/client/index.vue b/admin/src/views/monitor/client/index.vue index 5b41928..1e952ec 100644 --- a/admin/src/views/monitor/client/index.vue +++ b/admin/src/views/monitor/client/index.vue @@ -172,10 +172,6 @@ --> - - - - @@ -238,8 +234,7 @@ const queryParams = reactive({ City: null, Operator: null, Ip: null, - Width: null, - Height: null, + Ua: null, CreateTimeStart: null, CreateTimeEnd: null diff --git a/server/controller/admin_ctl/monitorController/monitor_client_ctl.go b/server/controller/admin_ctl/monitorController/monitor_client_ctl.go index 09cf809..51f23e5 100644 --- a/server/controller/admin_ctl/monitorController/monitor_client_ctl.go +++ b/server/controller/admin_ctl/monitorController/monitor_client_ctl.go @@ -154,17 +154,16 @@ func (hd *MonitorClientHandler) Add(c *gin.Context) { 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 + last := lastClient.UserId + "_" + lastClient.Ip + "_" + lastClient.Ua + newStr := *addReq.UserId + "_" + ip + "_" + uaStr if last == newStr { // 前后数据一样,不用创建新的数据 - fmt.Println("前后数据一样,不用创建新的数据") + fmt.Println("前后用户端数据一样,不用创建新的数据") c.Data(200, "image/gif", img_util.EmptyGif()) return } else { // 新建的话,需要清除lastClient对应的缓存 monitorService.MonitorClientService.CacheUtil.RemoveCache("ClientId:" + lastClient.ClientId) - } } diff --git a/server/model/monitor_client.go b/server/model/monitor_client.go index f89d206..5091916 100644 --- a/server/model/monitor_client.go +++ b/server/model/monitor_client.go @@ -6,19 +6,18 @@ import ( // MonitorClient 监控-客户端信息实体 type MonitorClient struct { - Id int `gorm:"primarykey;comment:'uuid'"` // uuid - ProjectKey string `gorm:"comment:'项目key'"` // 项目key - ClientId string `gorm:"comment:'sdk生成的客户端id'"` // sdk生成的客户端id - 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:'屏幕高度'"` // 屏幕高度 + Id int `gorm:"primarykey;comment:'uuid'"` // uuid + ProjectKey string `gorm:"comment:'项目key'"` // 项目key + ClientId string `gorm:"comment:'sdk生成的客户端id'"` // sdk生成的客户端id + 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 + Ua string `gorm:"comment:'ua记录'"` // ua记录 CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间 // ClientTime core.NullTime `gorm:"comment:'更新时间'"` // 更新时间 diff --git a/server/model/monitor_error_list.go b/server/model/monitor_error_list.go index 70852ef..5b18e8b 100644 --- a/server/model/monitor_error_list.go +++ b/server/model/monitor_error_list.go @@ -9,5 +9,7 @@ type MonitorErrorList struct { Id int `gorm:"primarykey;comment:'id'"` Eid string `gorm:"comment:'错误id'"` // 错误表id Cid string `gorm:"comment:'客户端id'"` // 客户端表id + Width core.NullInt `gorm:"comment:'屏幕'"` // 屏幕 + Height core.NullInt `gorm:"comment:'屏幕高度'"` // 屏幕高度 CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间 } diff --git a/server/router/adminRoute/monitor_error_route.go b/server/router/adminRoute/monitor_error_route.go index 11a1b82..c50ff2d 100644 --- a/server/router/adminRoute/monitor_error_route.go +++ b/server/router/adminRoute/monitor_error_route.go @@ -45,7 +45,7 @@ INSERT INTO x_system_auth_menu (pid, menu_type, menu_name, perms,is_cache, is_sh // MonitorErrorRoute(rg) func MonitorErrorRoute(rg *gin.RouterGroup) { handle := monitorController.MonitorErrorHandler{} - rg.GET("/monitor_error/add", middleware.RecordLog("监控-错误列新增"), handle.Add) + rg.GET("/monitor_error/add", handle.Add) r := rg.Group("/", middleware.TokenAuth()) r.GET("/monitor_error/list", handle.List) diff --git a/server/schema/monitorSchema/monitor_client_schema.go b/server/schema/monitorSchema/monitor_client_schema.go index 90a7177..73728a3 100644 --- a/server/schema/monitorSchema/monitor_client_schema.go +++ b/server/schema/monitorSchema/monitor_client_schema.go @@ -18,48 +18,41 @@ type MonitorClientListReq struct { Operator *string // 电信运营商 Ip *string // ip - Width *int // 屏幕 - Height *int // 屏幕高度 Ua *string // ua记录 CreateTimeStart *string // 开始创建时间 CreateTimeEnd *string // 结束创建时间 - } // MonitorClientAddReq 监控-客户端信息新增参数 type MonitorClientAddReq struct { - 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 core.NullInt // 屏幕 - Height core.NullInt // 屏幕高度 - Ua *string // ua记录 + 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 + Ua *string // ua记录 } // MonitorClientEditReq 监控-客户端信息编辑参数 type MonitorClientEditReq struct { - Id int // uuid - 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 core.NullInt // 屏幕 - Height core.NullInt // 屏幕高度 - Ua *string // ua记录 + Id int // uuid + 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 + Ua *string // ua记录 } // MonitorClientDetailReq 监控-客户端信息详情参数 @@ -90,8 +83,9 @@ type MonitorClientResp struct { City string // 城市 Operator string // 电信运营商 Ip string // ip - Width core.NullInt // 屏幕 - Height core.NullInt // 屏幕高度 Ua string // ua记录 CreateTime core.NullTime // 创建时间 + + Width core.NullInt // 屏幕 + Height core.NullInt // 屏幕高度 } diff --git a/server/schema/monitorSchema/monitor_error_list_schema.go b/server/schema/monitorSchema/monitor_error_list_schema.go index 6ed797c..35199bc 100644 --- a/server/schema/monitorSchema/monitor_error_list_schema.go +++ b/server/schema/monitorSchema/monitor_error_list_schema.go @@ -6,16 +6,20 @@ import ( // MonitorErrorListAddReq 错误对应的用户记录新增参数 type MonitorErrorListAddReq struct { - Eid string // 错误id - Cid string // 客户端id + Eid string // 错误id + Cid string // 客户端id + Width core.NullInt // 屏幕 + Height core.NullInt // 屏幕高度 // ProjectKey string // 项目id } // MonitorErrorListResp 错误对应的用户记录返回信息 type MonitorErrorListResp struct { - Id int // 项目id - Eid string // 错误id - Cid string // 客户端id + Id int // 项目id + Eid string // 错误id + Cid string // 客户端id + Width core.NullInt // 屏幕 + Height core.NullInt // 屏幕高度 // ProjectKey string // 项目id CreateTime core.NullTime // 创建时间 } diff --git a/server/schema/monitorSchema/monitor_error_schema.go b/server/schema/monitorSchema/monitor_error_schema.go index d7a2188..47cae87 100644 --- a/server/schema/monitorSchema/monitor_error_schema.go +++ b/server/schema/monitorSchema/monitor_error_schema.go @@ -6,12 +6,13 @@ import ( // MonitorErrorListReq 监控-错误列列表参数 type MonitorErrorListReq struct { - ProjectKey *string // 项目key - EventType *string // 事件类型 - Path *string // URL地址 - Message *string // 错误消息 - Stack *string // 错误堆栈 - Md5 *string // md5 + ProjectKey *string // 项目key + EventType *string // 事件类型 + Path *string // URL地址 + Message *string // 错误消息 + Stack *string // 错误堆栈 + Md5 *string // md5 + CreateTimeStart *string // 开始创建时间 CreateTimeEnd *string // 结束创建时间 @@ -19,12 +20,14 @@ type MonitorErrorListReq struct { // MonitorErrorAddReq 监控-错误列新增参数 type MonitorErrorAddReq struct { - ProjectKey string // 项目key - ClientId string // sdk生成的客户端id - EventType *string // 事件类型 - Path *string // URL地址 - Message *string // 错误消息 - Stack *string // 错误堆栈 + ProjectKey string // 项目key + ClientId string // sdk生成的客户端id + EventType *string // 事件类型 + Path *string // URL地址 + Message *string // 错误消息 + Stack *string // 错误堆栈 + Width core.NullInt // 屏幕 + Height core.NullInt // 屏幕高度 } // MonitorErrorDetailReq 监控-错误列详情参数 @@ -50,6 +53,8 @@ type MonitorErrorResp struct { Path string // URL地址 Message string // 错误消息 Stack string // 错误堆栈 + Width core.NullInt // 屏幕 + Height core.NullInt // 屏幕高度 Md5 string // md5 CreateTime core.NullTime // 创建时间 } diff --git a/server/service/monitorService/monitor_client_service.go b/server/service/monitorService/monitor_client_service.go index c11c53b..bc4198f 100644 --- a/server/service/monitorService/monitor_client_service.go +++ b/server/service/monitorService/monitor_client_service.go @@ -66,12 +66,7 @@ func (service monitorClientService) GetModel(listReq MonitorClientListReq) *gorm if listReq.Ip != nil { dbModel = dbModel.Where("ip = ?", *listReq.Ip) } - if listReq.Width != nil { - dbModel = dbModel.Where("width = ?", *listReq.Width) - } - if listReq.Height != nil { - dbModel = dbModel.Where("height = ?", *listReq.Height) - } + if listReq.Ua != nil { dbModel = dbModel.Where("ua = ?", *listReq.Ua) } @@ -170,8 +165,8 @@ func (service monitorClientService) Detail(Id int) (res MonitorClientResp, e err // ErrorUser 监控-客户端信息详情 func (service monitorClientService) ErrorUsers(error_id int) (res []MonitorClientResp, e error) { - var obj = []model.MonitorClient{} - 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) + var obj = []MonitorClientResp{} + service.db.Raw("SELECT client.*,list.width,list.height,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) convert_util.Copy(&res, obj) return diff --git a/server/service/monitorService/monitor_error_service.go b/server/service/monitorService/monitor_error_service.go index b3976a3..97cedb8 100644 --- a/server/service/monitorService/monitor_error_service.go +++ b/server/service/monitorService/monitor_error_service.go @@ -111,16 +111,13 @@ func (service monitorErrorService) ListAll(listReq MonitorErrorListReq) (res []M // Detail 监控-错误列详情 func (service monitorErrorService) Detail(Id int) (res MonitorErrorResp, e error) { var obj = model.MonitorError{} - err := service.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 - } - service.CacheUtil.SetCache(obj.Id, obj) + + 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 } convert_util.Copy(&res, obj) @@ -165,7 +162,7 @@ func (service monitorErrorService) Add(addReq MonitorErrorAddReq) (createId int, return 0, err } createId = obj.Id - service.CacheUtil.SetCache(createId, obj) + service.CacheUtil.SetCache("md5:"+Md5, obj) } else { createId = errorDetails.Id @@ -176,8 +173,10 @@ func (service monitorErrorService) Add(addReq MonitorErrorAddReq) (createId int, } _, err = MonitorErrorListService.Add(MonitorErrorListAddReq{ - Eid: strconv.Itoa(createId), - Cid: strconv.Itoa(client.Id), + Eid: strconv.Itoa(createId), + Cid: strconv.Itoa(client.Id), + Width: addReq.Width, + Height: addReq.Height, // ClientId: addReq.ClientId, // ProjectKey: addReq.ProjectKey, }) @@ -199,7 +198,7 @@ func (service monitorErrorService) Del(Id int) (e error) { // 删除 err = service.db.Delete(&obj).Error e = response.CheckErr(err, "删除失败") - service.CacheUtil.RemoveCache(obj.Id) + service.CacheUtil.RemoveCache("md5:" + obj.Md5) return } @@ -225,7 +224,7 @@ func (service monitorErrorService) DelBatch(Ids []string) (e error) { md5s = append(md5s, "md5:"+v.Md5) } // 删除缓存 - service.CacheUtil.RemoveCache(Ids) + service.CacheUtil.RemoveCache(md5s) return nil } diff --git a/x_err_sdk/types.ts b/x_err_sdk/types.ts index baed3a1..0e20152 100644 --- a/x_err_sdk/types.ts +++ b/x_err_sdk/types.ts @@ -1,21 +1,17 @@ - export type LogWithEnv = { - Type: "env"; - ScreenHeight?: number; - ScreenWidth?: number; + Height?: number; + Width?: number; }; -export type LogWithError = { - Type: "error"|"event"|"resources"|'click'; +export type LogWithError =LogWithEnv& { + Type: "error" | "event" | "resources" | "click"; EventType: string; - Path:string; + Path: string; Message?: string; - Stack?: string; + Stack?: string; }; - - // 扩展必须实现的接口 -export interface IErrorEvent { +export interface IErrorEvent { upload(url: string, data: object): Promise; setCache(key: string, info: any): void; getCache(key: string): any; diff --git a/x_err_sdk/web/base.ts b/x_err_sdk/web/base.ts index 93008f2..6576d62 100644 --- a/x_err_sdk/web/base.ts +++ b/x_err_sdk/web/base.ts @@ -19,6 +19,8 @@ class Base { private MessageList: any[] = []; private timer: number = 0; + private lastTimeStamp: number = Date.now(); //上次上报时间戳 + private diffTime: number = 1000 * 10; // 上报间隔 constructor(props: Props, platform: IErrorEvent) { if (!props) { @@ -50,10 +52,12 @@ class Base { this.Push(params); }); - + // 定时检查发送一次 this.timer = setInterval(() => { - this.upload(); - }, 1000 * 10); + if (Date.now() - this.lastTimeStamp >= this.diffTime) { + this.upload(); + } + }, 2000); } // 设置用户id @@ -67,15 +71,9 @@ class Base { this.Uid = u_id; } } - this.initEnv(); - } - // 初始化环境信息并上传 - private initEnv() { - let envInfo = this.platform?.getEnvInfo(); - if (envInfo) { - this.uploadInfo(envInfo); - } + this.uploadInfo(); } + // 设置错误ID private setClientID() { const client_id = this.platform?.getCache("x_err_client_id"); @@ -109,7 +107,7 @@ class Base { this.platform?.setCache("x_err_message_list", this.MessageList); } }; - public uploadInfo = (envInfo: LogWithEnv) => { + public uploadInfo = () => { if (!this.Dns) return; //未设置Dns服务器不上传 try { @@ -118,8 +116,8 @@ class Base { ProjectKey: this.Pid, ClientId: this.client_id, UserId: this.Uid, - Width: envInfo.ScreenWidth, - Height: envInfo.ScreenHeight, + // Width: envInfo.ScreenWidth, + // Height: envInfo.ScreenHeight, }) .catch((err: any) => { // 上传失败 @@ -133,14 +131,17 @@ class Base { if (!this.MessageList.length) { return; } + this.lastTimeStamp = Date.now(); try { this.platform ?.upload(this.Dns + `/admin/monitor_error/add`, this.MessageList) .catch((err: any) => { // 上传失败 + }) + .then(() => { + this.MessageList = []; + this.platform?.delCache("x_err_message_list"); }); - this.MessageList = []; - this.platform?.delCache("x_err_message_list"); } catch (error) {} } public unListen() { diff --git a/x_err_sdk/web/web.ts b/x_err_sdk/web/web.ts index 5e7839a..47f6325 100644 --- a/x_err_sdk/web/web.ts +++ b/x_err_sdk/web/web.ts @@ -2,11 +2,10 @@ import type { LogWithError, LogWithEnv, ListenCallbackFn, - IErrorEvent + IErrorEvent, } from "../types"; -interface LoggerProps { -} +interface LoggerProps {} class Web implements IErrorEvent { props: LoggerProps; constructor(props?: LoggerProps) { @@ -54,13 +53,12 @@ class Web implements IErrorEvent { public getEnvInfo(): LogWithEnv { const env: LogWithEnv = { - Type: "env", - ScreenHeight: 0, - ScreenWidth: 0, + Height: 0, + Width: 0, }; if (window) { - env.ScreenHeight = window.innerHeight || 0; // 获取显示屏信息 - env.ScreenWidth = window.innerWidth || 0; + env.Height = window.innerHeight || 0; // 获取显示屏信息 + env.Width = window.innerWidth || 0; } return env; } @@ -76,6 +74,7 @@ class Web implements IErrorEvent { Path: target.src, Message: "", Stack: "", + Height: 0, }); } else if (target?.localName === "link") { this.callback({ @@ -91,6 +90,7 @@ class Web implements IErrorEvent { Path: window.location.href, Message: err.message, Stack: this.handleStack(err.error?.stack || ""), + ...this.getEnvInfo(), }); } }; @@ -103,6 +103,7 @@ class Web implements IErrorEvent { Path: window.location.href, Message: err.reason, Stack: "", + ...this.getEnvInfo(), }); } else if (err && typeof err.reason === "object") { this.callback({ @@ -111,11 +112,11 @@ class Web implements IErrorEvent { Path: window.location.href, Message: err.reason?.message || "", Stack: this.handleStack(err.reason?.stack || ""), + ...this.getEnvInfo(), }); } }; - private handleStack(stack: string): string { let newStack: string[] = []; if (stack) {