user-behavior-monitor 6.0.0 → 8.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -87,21 +87,6 @@ module.exports =
87
87
  /************************************************************************/
88
88
  /******/ ({
89
89
 
90
- /***/ "0618":
91
- /***/ (function(module, exports, __webpack_require__) {
92
-
93
- exports = module.exports = __webpack_require__("2350")(false);
94
- // imports
95
-
96
-
97
- // module
98
- exports.push([module.i, ".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}", ""]);
99
-
100
- // exports
101
-
102
-
103
- /***/ }),
104
-
105
90
  /***/ "2350":
106
91
  /***/ (function(module, exports) {
107
92
 
@@ -183,17 +168,6 @@ function toComment(sourceMap) {
183
168
  }
184
169
 
185
170
 
186
- /***/ }),
187
-
188
- /***/ "3386":
189
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
190
-
191
- "use strict";
192
- /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("84f3");
193
- /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
194
- /* unused harmony reexport * */
195
-
196
-
197
171
  /***/ }),
198
172
 
199
173
  /***/ "499e":
@@ -462,19 +436,45 @@ function applyToTag (styleElement, obj) {
462
436
 
463
437
  /***/ }),
464
438
 
465
- /***/ "84f3":
439
+ /***/ "84ee":
440
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
441
+
442
+ "use strict";
443
+ /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("ceb5");
444
+ /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
445
+ /* unused harmony reexport * */
446
+
447
+
448
+ /***/ }),
449
+
450
+ /***/ "aa6e":
451
+ /***/ (function(module, exports, __webpack_require__) {
452
+
453
+ exports = module.exports = __webpack_require__("2350")(false);
454
+ // imports
455
+
456
+
457
+ // module
458
+ exports.push([module.i, ".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}", ""]);
459
+
460
+ // exports
461
+
462
+
463
+ /***/ }),
464
+
465
+ /***/ "ceb5":
466
466
  /***/ (function(module, exports, __webpack_require__) {
467
467
 
468
468
  // style-loader: Adds some css to the DOM by adding a <style> tag
469
469
 
470
470
  // load the styles
471
- var content = __webpack_require__("0618");
471
+ var content = __webpack_require__("aa6e");
472
472
  if(content.__esModule) content = content.default;
473
473
  if(typeof content === 'string') content = [[module.i, content, '']];
474
474
  if(content.locals) module.exports = content.locals;
475
475
  // add the styles to the DOM
476
476
  var add = __webpack_require__("499e").default
477
- var update = add("22f24fb0", content, true, {"sourceMap":false,"shadowMode":false});
477
+ var update = add("571b4890", content, true, {"sourceMap":false,"shadowMode":false});
478
478
 
479
479
  /***/ }),
480
480
 
@@ -503,12 +503,12 @@ if (typeof window !== 'undefined') {
503
503
  // Indicate to webpack that this file can be concatenated
504
504
  /* harmony default export */ var setPublicPath = (null);
505
505
 
506
- // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"14550f6a-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=template&id=5fccf94e
506
+ // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"14550f6a-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=template&id=e054cf88
507
507
  var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{ref:"behaviorMonitor",staticClass:"user-behavior-monitor"},[_c('el-dialog',{attrs:{"title":"提示","visible":_vm.showWarning,"show-close":false,"modal":true,"width":"30%","center":"","custom-class":"behavior-warning-dialog"},on:{"update:visible":function($event){_vm.showWarning=$event}}},[_c('span',[_vm._v(_vm._s(_vm.warningMessage))])])],1)}
508
508
  var staticRenderFns = []
509
509
 
510
510
 
511
- // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=5fccf94e
511
+ // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=e054cf88
512
512
 
513
513
  // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
514
514
  //
@@ -564,7 +564,8 @@ var staticRenderFns = []
564
564
  reconnectAttempts: 0,
565
565
  maxReconnectAttempts: 3,
566
566
  reconnectDelay: 3000,
567
- isLocalDevelopment: this.checkIfLocalDevelopment()
567
+ isLocalDevelopment: this.checkIfLocalDevelopment(),
568
+ tokenCheckTimer: null // 新增:用于轮询检查token的定时器
568
569
  };
569
570
  },
570
571
  mounted() {
@@ -670,6 +671,9 @@ var staticRenderFns = []
670
671
 
671
672
  // 绑定事件监听器
672
673
  this.bindEventListeners();
674
+
675
+ // 启动token检查轮询定时器
676
+ this.startTokenCheckPolling();
673
677
  },
674
678
 
675
679
  // 销毁监控
@@ -679,6 +683,7 @@ var staticRenderFns = []
679
683
  // 清除定时器
680
684
  if (this.countdownTimer) clearInterval(this.countdownTimer);
681
685
  if (this.warningTimer) clearTimeout(this.warningTimer);
686
+ if (this.tokenCheckTimer) clearInterval(this.tokenCheckTimer); // 清除token检查定时器
682
687
 
683
688
  // 关闭WebSocket连接
684
689
  if (this.socket) {
@@ -712,7 +717,7 @@ var staticRenderFns = []
712
717
 
713
718
  // 设置连接成功回调
714
719
  this.socket.onopen = () => {
715
- console.log('WebSocket连接已建立');
720
+ // console.log('WebSocket连接已建立');
716
721
  this.sendUserBehavior();
717
722
  this.$emit('websocket-open');
718
723
  // 连接成功时重置重连尝试次数
@@ -723,11 +728,11 @@ var staticRenderFns = []
723
728
  this.socket.onmessage = (event) => {
724
729
  try {
725
730
  const data = JSON.parse(event.data);
726
- console.log('收到用户活动状态消息:', data);
731
+ // console.log('收到用户活动状态消息:', data);
727
732
  this.handleActivityStatus(data);
728
733
  this.$emit('websocket-message', data);
729
734
  } catch (e) {
730
- console.error('解析WebSocket消息失败:', e);
735
+ // console.error('解析WebSocket消息失败:', e);
731
736
  }
732
737
  };
733
738
 
@@ -884,7 +889,7 @@ var staticRenderFns = []
884
889
  "type": "HEARTBEAT",
885
890
  "message": "心跳",
886
891
  };
887
- console.log('用户行为监测:', JSON.stringify(message));
892
+ // console.log('用户行为监测:', JSON.stringify(message));
888
893
  this.socket.send(JSON.stringify(message));
889
894
  }
890
895
  },
@@ -1129,14 +1134,57 @@ var staticRenderFns = []
1129
1134
  this.socket.close();
1130
1135
  }
1131
1136
  this.initWebSocket();
1137
+ },
1138
+
1139
+ // 新增:启动token检查轮询定时器
1140
+ startTokenCheckPolling() {
1141
+ // 清除已存在的定时器
1142
+ if (this.tokenCheckTimer) {
1143
+ clearInterval(this.tokenCheckTimer);
1144
+ }
1145
+
1146
+ // 每30秒检查一次token
1147
+ this.tokenCheckTimer = setInterval(() => {
1148
+ this.checkToken();
1149
+ }, 1000);
1150
+ },
1151
+
1152
+ // 新增:检查token是否存在
1153
+ checkToken() {
1154
+ // 再次确认不在登录页面
1155
+ if (this.isLoginRoute()) {
1156
+ return;
1157
+ }
1158
+
1159
+ // 检查localStorage中的token是否存在
1160
+ const token = localStorage.getItem('api_header');
1161
+
1162
+ // 如果token不存在,刷新页面
1163
+ if (!token) {
1164
+ console.log('Token不存在,即将刷新页面');
1165
+ this.handleTokenMissing();
1166
+ }
1167
+ },
1168
+
1169
+ // 新增:处理token缺失的情况
1170
+ handleTokenMissing() {
1171
+ // 清空缓存
1172
+ localStorage.clear();
1173
+ sessionStorage.clear();
1174
+
1175
+ // 刷新页面
1176
+ location.reload();
1177
+
1178
+ // 触发登出事件
1179
+ this.$emit('logout');
1132
1180
  }
1133
1181
  }
1134
1182
  });
1135
1183
 
1136
1184
  // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
1137
1185
  /* harmony default export */ var components_UserBehaviorMonitorvue_type_script_lang_js = (UserBehaviorMonitorvue_type_script_lang_js);
1138
- // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=5fccf94e&prod&lang=css
1139
- var UserBehaviorMonitorvue_type_style_index_0_id_5fccf94e_prod_lang_css = __webpack_require__("3386");
1186
+ // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=e054cf88&prod&lang=css
1187
+ var UserBehaviorMonitorvue_type_style_index_0_id_e054cf88_prod_lang_css = __webpack_require__("84ee");
1140
1188
 
1141
1189
  // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
1142
1190
  /* globals __VUE_SSR_CONTEXT__ */
@@ -96,21 +96,6 @@ return /******/ (function(modules) { // webpackBootstrap
96
96
  /************************************************************************/
97
97
  /******/ ({
98
98
 
99
- /***/ "0618":
100
- /***/ (function(module, exports, __webpack_require__) {
101
-
102
- exports = module.exports = __webpack_require__("2350")(false);
103
- // imports
104
-
105
-
106
- // module
107
- exports.push([module.i, ".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}", ""]);
108
-
109
- // exports
110
-
111
-
112
- /***/ }),
113
-
114
99
  /***/ "2350":
115
100
  /***/ (function(module, exports) {
116
101
 
@@ -192,17 +177,6 @@ function toComment(sourceMap) {
192
177
  }
193
178
 
194
179
 
195
- /***/ }),
196
-
197
- /***/ "3386":
198
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
199
-
200
- "use strict";
201
- /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("84f3");
202
- /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_5fccf94e_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
203
- /* unused harmony reexport * */
204
-
205
-
206
180
  /***/ }),
207
181
 
208
182
  /***/ "499e":
@@ -471,19 +445,45 @@ function applyToTag (styleElement, obj) {
471
445
 
472
446
  /***/ }),
473
447
 
474
- /***/ "84f3":
448
+ /***/ "84ee":
449
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
450
+
451
+ "use strict";
452
+ /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("ceb5");
453
+ /* harmony import */ var _node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_vue_style_loader_index_js_ref_6_oneOf_1_0_node_modules_css_loader_index_js_ref_6_oneOf_1_1_node_modules_vue_loader_lib_loaders_stylePostLoader_js_node_modules_postcss_loader_src_index_js_ref_6_oneOf_1_2_node_modules_cache_loader_dist_cjs_js_ref_0_0_node_modules_vue_loader_lib_index_js_vue_loader_options_UserBehaviorMonitor_vue_vue_type_style_index_0_id_e054cf88_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
454
+ /* unused harmony reexport * */
455
+
456
+
457
+ /***/ }),
458
+
459
+ /***/ "aa6e":
460
+ /***/ (function(module, exports, __webpack_require__) {
461
+
462
+ exports = module.exports = __webpack_require__("2350")(false);
463
+ // imports
464
+
465
+
466
+ // module
467
+ exports.push([module.i, ".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}", ""]);
468
+
469
+ // exports
470
+
471
+
472
+ /***/ }),
473
+
474
+ /***/ "ceb5":
475
475
  /***/ (function(module, exports, __webpack_require__) {
476
476
 
477
477
  // style-loader: Adds some css to the DOM by adding a <style> tag
478
478
 
479
479
  // load the styles
480
- var content = __webpack_require__("0618");
480
+ var content = __webpack_require__("aa6e");
481
481
  if(content.__esModule) content = content.default;
482
482
  if(typeof content === 'string') content = [[module.i, content, '']];
483
483
  if(content.locals) module.exports = content.locals;
484
484
  // add the styles to the DOM
485
485
  var add = __webpack_require__("499e").default
486
- var update = add("22f24fb0", content, true, {"sourceMap":false,"shadowMode":false});
486
+ var update = add("571b4890", content, true, {"sourceMap":false,"shadowMode":false});
487
487
 
488
488
  /***/ }),
489
489
 
@@ -512,12 +512,12 @@ if (typeof window !== 'undefined') {
512
512
  // Indicate to webpack that this file can be concatenated
513
513
  /* harmony default export */ var setPublicPath = (null);
514
514
 
515
- // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"14550f6a-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=template&id=5fccf94e
515
+ // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js?{"cacheDirectory":"node_modules/.cache/vue-loader","cacheIdentifier":"14550f6a-vue-loader-template"}!./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=template&id=e054cf88
516
516
  var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{ref:"behaviorMonitor",staticClass:"user-behavior-monitor"},[_c('el-dialog',{attrs:{"title":"提示","visible":_vm.showWarning,"show-close":false,"modal":true,"width":"30%","center":"","custom-class":"behavior-warning-dialog"},on:{"update:visible":function($event){_vm.showWarning=$event}}},[_c('span',[_vm._v(_vm._s(_vm.warningMessage))])])],1)}
517
517
  var staticRenderFns = []
518
518
 
519
519
 
520
- // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=5fccf94e
520
+ // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=e054cf88
521
521
 
522
522
  // CONCATENATED MODULE: ./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
523
523
  //
@@ -573,7 +573,8 @@ var staticRenderFns = []
573
573
  reconnectAttempts: 0,
574
574
  maxReconnectAttempts: 3,
575
575
  reconnectDelay: 3000,
576
- isLocalDevelopment: this.checkIfLocalDevelopment()
576
+ isLocalDevelopment: this.checkIfLocalDevelopment(),
577
+ tokenCheckTimer: null // 新增:用于轮询检查token的定时器
577
578
  };
578
579
  },
579
580
  mounted() {
@@ -679,6 +680,9 @@ var staticRenderFns = []
679
680
 
680
681
  // 绑定事件监听器
681
682
  this.bindEventListeners();
683
+
684
+ // 启动token检查轮询定时器
685
+ this.startTokenCheckPolling();
682
686
  },
683
687
 
684
688
  // 销毁监控
@@ -688,6 +692,7 @@ var staticRenderFns = []
688
692
  // 清除定时器
689
693
  if (this.countdownTimer) clearInterval(this.countdownTimer);
690
694
  if (this.warningTimer) clearTimeout(this.warningTimer);
695
+ if (this.tokenCheckTimer) clearInterval(this.tokenCheckTimer); // 清除token检查定时器
691
696
 
692
697
  // 关闭WebSocket连接
693
698
  if (this.socket) {
@@ -721,7 +726,7 @@ var staticRenderFns = []
721
726
 
722
727
  // 设置连接成功回调
723
728
  this.socket.onopen = () => {
724
- console.log('WebSocket连接已建立');
729
+ // console.log('WebSocket连接已建立');
725
730
  this.sendUserBehavior();
726
731
  this.$emit('websocket-open');
727
732
  // 连接成功时重置重连尝试次数
@@ -732,11 +737,11 @@ var staticRenderFns = []
732
737
  this.socket.onmessage = (event) => {
733
738
  try {
734
739
  const data = JSON.parse(event.data);
735
- console.log('收到用户活动状态消息:', data);
740
+ // console.log('收到用户活动状态消息:', data);
736
741
  this.handleActivityStatus(data);
737
742
  this.$emit('websocket-message', data);
738
743
  } catch (e) {
739
- console.error('解析WebSocket消息失败:', e);
744
+ // console.error('解析WebSocket消息失败:', e);
740
745
  }
741
746
  };
742
747
 
@@ -893,7 +898,7 @@ var staticRenderFns = []
893
898
  "type": "HEARTBEAT",
894
899
  "message": "心跳",
895
900
  };
896
- console.log('用户行为监测:', JSON.stringify(message));
901
+ // console.log('用户行为监测:', JSON.stringify(message));
897
902
  this.socket.send(JSON.stringify(message));
898
903
  }
899
904
  },
@@ -1138,14 +1143,57 @@ var staticRenderFns = []
1138
1143
  this.socket.close();
1139
1144
  }
1140
1145
  this.initWebSocket();
1146
+ },
1147
+
1148
+ // 新增:启动token检查轮询定时器
1149
+ startTokenCheckPolling() {
1150
+ // 清除已存在的定时器
1151
+ if (this.tokenCheckTimer) {
1152
+ clearInterval(this.tokenCheckTimer);
1153
+ }
1154
+
1155
+ // 每30秒检查一次token
1156
+ this.tokenCheckTimer = setInterval(() => {
1157
+ this.checkToken();
1158
+ }, 1000);
1159
+ },
1160
+
1161
+ // 新增:检查token是否存在
1162
+ checkToken() {
1163
+ // 再次确认不在登录页面
1164
+ if (this.isLoginRoute()) {
1165
+ return;
1166
+ }
1167
+
1168
+ // 检查localStorage中的token是否存在
1169
+ const token = localStorage.getItem('api_header');
1170
+
1171
+ // 如果token不存在,刷新页面
1172
+ if (!token) {
1173
+ console.log('Token不存在,即将刷新页面');
1174
+ this.handleTokenMissing();
1175
+ }
1176
+ },
1177
+
1178
+ // 新增:处理token缺失的情况
1179
+ handleTokenMissing() {
1180
+ // 清空缓存
1181
+ localStorage.clear();
1182
+ sessionStorage.clear();
1183
+
1184
+ // 刷新页面
1185
+ location.reload();
1186
+
1187
+ // 触发登出事件
1188
+ this.$emit('logout');
1141
1189
  }
1142
1190
  }
1143
1191
  });
1144
1192
 
1145
1193
  // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
1146
1194
  /* harmony default export */ var components_UserBehaviorMonitorvue_type_script_lang_js = (UserBehaviorMonitorvue_type_script_lang_js);
1147
- // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=5fccf94e&prod&lang=css
1148
- var UserBehaviorMonitorvue_type_style_index_0_id_5fccf94e_prod_lang_css = __webpack_require__("3386");
1195
+ // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=e054cf88&prod&lang=css
1196
+ var UserBehaviorMonitorvue_type_style_index_0_id_e054cf88_prod_lang_css = __webpack_require__("84ee");
1149
1197
 
1150
1198
  // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
1151
1199
  /* globals __VUE_SSR_CONTEXT__ */
@@ -1 +1 @@
1
- (function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t():"function"===typeof define&&define.amd?define([],t):"object"===typeof exports?exports["user-behavior-monitor"]=t():e["user-behavior-monitor"]=t()})("undefined"!==typeof self?self:this,(function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="fb15")}({"0618":function(e,t,n){t=e.exports=n("2350")(!1),t.push([e.i,".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}",""])},2350:function(e,t){function n(e,t){var n=e[1]||"",o=e[3];if(!o)return n;if(t&&"function"===typeof btoa){var s=i(o),r=o.sources.map((function(e){return"/*# sourceURL="+o.sourceRoot+e+" */"}));return[n].concat(r).concat([s]).join("\n")}return[n].join("\n")}function i(e){var t=btoa(unescape(encodeURIComponent(JSON.stringify(e)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,"+t;return"/*# "+n+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var i=n(t,e);return t[2]?"@media "+t[2]+"{"+i+"}":i})).join("")},t.i=function(e,n){"string"===typeof e&&(e=[[null,e,""]]);for(var i={},o=0;o<this.length;o++){var s=this[o][0];"number"===typeof s&&(i[s]=!0)}for(o=0;o<e.length;o++){var r=e[o];"number"===typeof r[0]&&i[r[0]]||(n&&!r[2]?r[2]=n:n&&(r[2]="("+r[2]+") and ("+n+")"),t.push(r))}},t}},3386:function(e,t,n){"use strict";n("84f3")},"499e":function(e,t,n){"use strict";function i(e,t){for(var n=[],i={},o=0;o<t.length;o++){var s=t[o],r=s[0],a=s[1],c=s[2],u=s[3],l={id:e+":"+o,css:a,media:c,sourceMap:u};i[r]?i[r].parts.push(l):n.push(i[r]={id:r,parts:[l]})}return n}n.r(t),n.d(t,"default",(function(){return v}));var o="undefined"!==typeof document;if("undefined"!==typeof DEBUG&&DEBUG&&!o)throw new Error("vue-style-loader cannot be used in a non-browser environment. Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.");var s={},r=o&&(document.head||document.getElementsByTagName("head")[0]),a=null,c=0,u=!1,l=function(){},h=null,d="data-vue-ssr-id",m="undefined"!==typeof navigator&&/msie [6-9]\b/.test(navigator.userAgent.toLowerCase());function v(e,t,n,o){u=n,h=o||{};var r=i(e,t);return f(r),function(t){for(var n=[],o=0;o<r.length;o++){var a=r[o],c=s[a.id];c.refs--,n.push(c)}t?(r=i(e,t),f(r)):r=[];for(o=0;o<n.length;o++){c=n[o];if(0===c.refs){for(var u=0;u<c.parts.length;u++)c.parts[u]();delete s[c.id]}}}}function f(e){for(var t=0;t<e.length;t++){var n=e[t],i=s[n.id];if(i){i.refs++;for(var o=0;o<i.parts.length;o++)i.parts[o](n.parts[o]);for(;o<n.parts.length;o++)i.parts.push(g(n.parts[o]));i.parts.length>n.parts.length&&(i.parts.length=n.parts.length)}else{var r=[];for(o=0;o<n.parts.length;o++)r.push(g(n.parts[o]));s[n.id]={id:n.id,refs:1,parts:r}}}}function p(){var e=document.createElement("style");return e.type="text/css",r.appendChild(e),e}function g(e){var t,n,i=document.querySelector("style["+d+'~="'+e.id+'"]');if(i){if(u)return l;i.parentNode.removeChild(i)}if(m){var o=c++;i=a||(a=p()),t=w.bind(null,i,o,!1),n=w.bind(null,i,o,!0)}else i=p(),t=b.bind(null,i),n=function(){i.parentNode.removeChild(i)};return t(e),function(i){if(i){if(i.css===e.css&&i.media===e.media&&i.sourceMap===e.sourceMap)return;t(e=i)}else n()}}var y=function(){var e=[];return function(t,n){return e[t]=n,e.filter(Boolean).join("\n")}}();function w(e,t,n,i){var o=n?"":i.css;if(e.styleSheet)e.styleSheet.cssText=y(t,o);else{var s=document.createTextNode(o),r=e.childNodes;r[t]&&e.removeChild(r[t]),r.length?e.insertBefore(s,r[t]):e.appendChild(s)}}function b(e,t){var n=t.css,i=t.media,o=t.sourceMap;if(i&&e.setAttribute("media",i),h.ssrId&&e.setAttribute(d,t.id),o&&(n+="\n/*# sourceURL="+o.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */"),e.styleSheet)e.styleSheet.cssText=n;else{while(e.firstChild)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}},"84f3":function(e,t,n){var i=n("0618");i.__esModule&&(i=i.default),"string"===typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);var o=n("499e").default;o("22f24fb0",i,!0,{sourceMap:!1,shadowMode:!1})},fb15:function(e,t,n){"use strict";var i;(n.r(t),n.d(t,"UserBehaviorMonitor",(function(){return l})),"undefined"!==typeof window)&&((i=window.document.currentScript)&&(i=i.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))&&(n.p=i[1]));var o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{ref:"behaviorMonitor",staticClass:"user-behavior-monitor"},[n("el-dialog",{attrs:{title:"提示",visible:e.showWarning,"show-close":!1,modal:!0,width:"30%",center:"","custom-class":"behavior-warning-dialog"},on:{"update:visible":function(t){e.showWarning=t}}},[n("span",[e._v(e._s(e.warningMessage))])])],1)},s=[],r={name:"UserBehaviorMonitor",props:{timeoutMinutes:{type:Number,default:10},warningMinutes:{type:Number,default:1}},data(){return{mouseMoveThrottled:!1,socket:null,countdownTimer:null,warningTimer:null,showWarning:!1,warningMessage:`您已${this.timeoutMinutes}分钟未操作,将在1分钟后自动退出`,lastActivityTime:null,isMonitoring:!1,currentTimeoutMinutes:10,currentWarningMinutes:1,reconnectAttempts:0,maxReconnectAttempts:3,reconnectDelay:3e3,isLocalDevelopment:this.checkIfLocalDevelopment()}},mounted(){this.isLoginRoute()||this.initMonitor()},beforeDestroy(){this.destroyMonitor()},watch:{$route(e,t){const n=t.path.includes("/login")||t.href&&t.href.includes("/login"),i=this.isLoginRoute();!n||i||this.isMonitoring?!n&&i&&this.isMonitoring&&this.destroyMonitor():this.initMonitor()}},methods:{isLoginRoute(){return!!(this.$route&&this.$route.path&&this.$route.path.includes("/login"))||"undefined"!==typeof window&&(window.location.pathname.includes("/login")||window.location.href.includes("/login"))},checkIfLocalDevelopment(){if("undefined"!==typeof window){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e||"0.0.0.0"===e||/^192\.168\./.test(e)||/^10\./.test(e)||/^172\.(1[6-9]|2[0-9]|3[01])\./.test(e)}return!1},updateTimeoutSettings(e,t){void 0!==e&&(this.currentTimeoutMinutes=e,localStorage.setItem("userBehavior_timeoutMinutes",e.toString())),void 0!==t&&(this.currentWarningMinutes=t,localStorage.setItem("userBehavior_warningMinutes",t.toString())),this.warningMessage=`您已${this.currentTimeoutMinutes}分钟未操作,将在1分钟后自动退出`,this.resetTimer()},initMonitor(){this.isLoginRoute()?this.destroyMonitor():this.isMonitoring||(this.isMonitoring=!0,this.lastActivityTime=Date.now(),this.reconnectAttempts=0,this.initWebSocket(),this.bindEventListeners())},destroyMonitor(){this.isMonitoring=!1,this.countdownTimer&&clearInterval(this.countdownTimer),this.warningTimer&&clearTimeout(this.warningTimer),this.socket&&(this.socket.close(),this.socket=null),this.unbindEventListeners()},initWebSocket(){try{const t=`wss://${location.host}/xy-api/auth-server/ws/user-activity`;let n="";try{const e=localStorage.getItem("api_header");e&&(n=JSON.parse(e).Authorization||"")}catch(e){n=localStorage.getItem("token")||""}this.socket=new WebSocket(`${t}?token=${encodeURIComponent(n)}`),this.socket.onopen=()=>{console.log("WebSocket连接已建立"),this.sendUserBehavior(),this.$emit("websocket-open"),this.reconnectAttempts=0},this.socket.onmessage=t=>{try{const e=JSON.parse(t.data);console.log("收到用户活动状态消息:",e),this.handleActivityStatus(e),this.$emit("websocket-message",e)}catch(e){console.error("解析WebSocket消息失败:",e)}},this.socket.onclose=e=>{this.$emit("websocket-close"),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())},this.socket.onerror=e=>{this.$emit("websocket-error",e),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())}}catch(t){this.$emit("websocket-error",t),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())}},shouldAttemptReconnect(){return this.isMonitoring&&!this.isLoginRoute()&&this.reconnectAttempts<this.maxReconnectAttempts},attemptReconnect(){this.isLoginRoute()||(this.reconnectAttempts++,console.log(`尝试第${this.reconnectAttempts}次重连...`),this.isLocalDevelopment&&this.reconnectAttempts>=this.maxReconnectAttempts?this.$emit("websocket-reconnect-failed"):!this.isLocalDevelopment&&this.reconnectAttempts>=this.maxReconnectAttempts?this.handleReconnectFailure():setTimeout(()=>{this.initWebSocket()},this.reconnectDelay))},handleReconnectFailure(){localStorage.clear(),sessionStorage.clear(),location.reload(),this.$emit("logout")},handleActivityStatus(e){if("ACTIVITY_STATUS"===e.type&&e.data){const t=e.data;this.currentTimeoutMinutes=t.timeoutMinutes||10,this.currentWarningMinutes=t.reminderMinutes||1,this.warningMessage=`您已${this.currentTimeoutMinutes}分钟未操作,将在${this.currentWarningMinutes}分钟后自动退出`,t.needReminder&&this.showWarningWarning(t.remainingMillis)}},handleInactiveStatus(){localStorage.clear(),sessionStorage.clear(),location.reload(),this.$emit("logout")},sendUserBehavior(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"HEARTBEAT",message:"心跳"};console.log("用户行为监测:",JSON.stringify(e)),this.socket.send(JSON.stringify(e))}},bindEventListeners(){document.addEventListener("click",this.handleUserActivity,!0),document.addEventListener("dblclick",this.handleUserActivity,!0),document.addEventListener("mousedown",this.handleUserActivity,!0),document.addEventListener("mouseup",this.handleUserActivity,!0),document.addEventListener("mousemove",this.handleMouseMove,!0),document.addEventListener("mouseover",this.handleUserActivity,!0),document.addEventListener("mouseout",this.handleUserActivity,!0),document.addEventListener("keydown",this.handleUserActivity,!0),document.addEventListener("keyup",this.handleUserActivity,!0),document.addEventListener("input",this.handleUserActivity,!0),document.addEventListener("change",this.handleUserActivity,!0),document.addEventListener("focus",this.handleUserActivity,!0),document.addEventListener("blur",this.handleUserActivity,!0),document.addEventListener("scroll",this.debounce(this.handleUserActivity,300),!0),window.addEventListener("resize",this.handleUserActivity,!0),window.addEventListener("beforeunload",this.handleBeforeUnload)},unbindEventListeners(){document.removeEventListener("click",this.handleUserActivity,!0),document.removeEventListener("dblclick",this.handleUserActivity,!0),document.removeEventListener("mousedown",this.handleUserActivity,!0),document.removeEventListener("mouseup",this.handleUserActivity,!0),document.removeEventListener("mousemove",this.handleMouseMove,!0),document.removeEventListener("mouseover",this.handleUserActivity,!0),document.removeEventListener("mouseout",this.handleUserActivity,!0),document.removeEventListener("keydown",this.handleUserActivity,!0),document.removeEventListener("keyup",this.handleUserActivity,!0),document.removeEventListener("input",this.handleUserActivity,!0),document.removeEventListener("change",this.handleUserActivity,!0),document.removeEventListener("focus",this.handleUserActivity,!0),document.removeEventListener("blur",this.handleUserActivity,!0),document.removeEventListener("scroll",this.debounce(this.handleUserActivity,300),!0),window.removeEventListener("resize",this.handleUserActivity,!0),window.removeEventListener("beforeunload",this.handleBeforeUnload)},handleUserActivity(e){if(this.isAutomaticEvent(e))return;this.resetTimer();const t={eventType:e.type,target:e.target.tagName,timestamp:Date.now(),url:window.location.href};"click"===e.type?(t.clientX=e.clientX,t.clientY=e.clientY):"keydown"===e.type&&(t.key=e.key,t.ctrlKey=e.ctrlKey,t.altKey=e.altKey,t.shiftKey=e.shiftKey),this.sendUserBehavior(t)},handleMouseMove(e){this.mouseMoveThrottled||(this.handleUserActivity(e),this.mouseMoveThrottled=!0,setTimeout(()=>{this.mouseMoveThrottled=!1},500))},isAutomaticEvent(e){return"scroll"===e.type&&!this.isUserScrolling},debounce(e,t){let n;return function(...i){const o=()=>{clearTimeout(n),e.apply(this,i)};clearTimeout(n),n=setTimeout(o,t)}},resetTimer(){this.lastActivityTime=Date.now(),this.showWarning=!1,this.reconnectAttempts=0,this.warningTimer&&(clearTimeout(this.warningTimer),this.warningTimer=null),this.$emit("user-active")},startCountdown(){this.countdownTimer&&clearInterval(this.countdownTimer),this.countdownTimer=setInterval(()=>{const e=Date.now(),t=(e-this.lastActivityTime)/5e4;t>=this.currentTimeoutMinutes-this.currentWarningMinutes&&!this.warningTimer&&this.showWarningWarning(),t>=this.currentTimeoutMinutes&&this.handleTimeout()},1e3)},showWarningWarning(e){let t=e||5e4;console.log("Setting showWarning to true"),this.showWarning=!0,this.$emit("timeout-warning"),this.warningTimer&&clearTimeout(this.warningTimer),this.warningTimer=setTimeout(()=>{this.handleTimeout()},t)},handleTimeout(){this.showWarning=!1,this.$emit("timeout"),this.logout()},logout(){if(localStorage.clear(),sessionStorage.clear(),location.reload(),this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"logout",timestamp:Date.now()};this.socket.send(JSON.stringify(e))}this.$emit("logout"),this.countdownTimer&&clearInterval(this.countdownTimer),this.warningTimer&&clearTimeout(this.warningTimer)},handleBeforeUnload(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"page_unload",timestamp:Date.now()};this.socket.send(JSON.stringify(e))}},reset(){this.isLoginRoute()?this.destroyMonitor():this.resetTimer()},reconnect(){this.isLoginRoute()?this.destroyMonitor():(this.reconnectAttempts=0,this.socket&&this.socket.close(),this.initWebSocket())}}},a=r;n("3386");function c(e,t,n,i,o,s,r,a){var c,u="function"===typeof e?e.options:e;if(t&&(u.render=t,u.staticRenderFns=n,u._compiled=!0),i&&(u.functional=!0),s&&(u._scopeId="data-v-"+s),r?(c=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),o&&o.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(r)},u._ssrRegister=c):o&&(c=a?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var l=u.render;u.render=function(e,t){return c.call(t),l(e,t)}}else{var h=u.beforeCreate;u.beforeCreate=h?[].concat(h,c):[c]}return{exports:e,options:u}}var u=c(a,o,s,!1,null,null,null),l=u.exports;l.install=function(e){e.component(l.name,l)};var h=l;"undefined"!==typeof window&&window.Vue&&l.install(window.Vue);t["default"]=h}})}));
1
+ (function(e,t){"object"===typeof exports&&"object"===typeof module?module.exports=t():"function"===typeof define&&define.amd?define([],t):"object"===typeof exports?exports["user-behavior-monitor"]=t():e["user-behavior-monitor"]=t()})("undefined"!==typeof self?self:this,(function(){return function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e["default"]}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s="fb15")}({2350:function(e,t){function n(e,t){var n=e[1]||"",o=e[3];if(!o)return n;if(t&&"function"===typeof btoa){var s=i(o),r=o.sources.map((function(e){return"/*# sourceURL="+o.sourceRoot+e+" */"}));return[n].concat(r).concat([s]).join("\n")}return[n].join("\n")}function i(e){var t=btoa(unescape(encodeURIComponent(JSON.stringify(e)))),n="sourceMappingURL=data:application/json;charset=utf-8;base64,"+t;return"/*# "+n+" */"}e.exports=function(e){var t=[];return t.toString=function(){return this.map((function(t){var i=n(t,e);return t[2]?"@media "+t[2]+"{"+i+"}":i})).join("")},t.i=function(e,n){"string"===typeof e&&(e=[[null,e,""]]);for(var i={},o=0;o<this.length;o++){var s=this[o][0];"number"===typeof s&&(i[s]=!0)}for(o=0;o<e.length;o++){var r=e[o];"number"===typeof r[0]&&i[r[0]]||(n&&!r[2]?r[2]=n:n&&(r[2]="("+r[2]+") and ("+n+")"),t.push(r))}},t}},"499e":function(e,t,n){"use strict";function i(e,t){for(var n=[],i={},o=0;o<t.length;o++){var s=t[o],r=s[0],a=s[1],c=s[2],u=s[3],h={id:e+":"+o,css:a,media:c,sourceMap:u};i[r]?i[r].parts.push(h):n.push(i[r]={id:r,parts:[h]})}return n}n.r(t),n.d(t,"default",(function(){return v}));var o="undefined"!==typeof document;if("undefined"!==typeof DEBUG&&DEBUG&&!o)throw new Error("vue-style-loader cannot be used in a non-browser environment. Use { target: 'node' } in your Webpack config to indicate a server-rendering environment.");var s={},r=o&&(document.head||document.getElementsByTagName("head")[0]),a=null,c=0,u=!1,h=function(){},l=null,d="data-vue-ssr-id",m="undefined"!==typeof navigator&&/msie [6-9]\b/.test(navigator.userAgent.toLowerCase());function v(e,t,n,o){u=n,l=o||{};var r=i(e,t);return p(r),function(t){for(var n=[],o=0;o<r.length;o++){var a=r[o],c=s[a.id];c.refs--,n.push(c)}t?(r=i(e,t),p(r)):r=[];for(o=0;o<n.length;o++){c=n[o];if(0===c.refs){for(var u=0;u<c.parts.length;u++)c.parts[u]();delete s[c.id]}}}}function p(e){for(var t=0;t<e.length;t++){var n=e[t],i=s[n.id];if(i){i.refs++;for(var o=0;o<i.parts.length;o++)i.parts[o](n.parts[o]);for(;o<n.parts.length;o++)i.parts.push(g(n.parts[o]));i.parts.length>n.parts.length&&(i.parts.length=n.parts.length)}else{var r=[];for(o=0;o<n.parts.length;o++)r.push(g(n.parts[o]));s[n.id]={id:n.id,refs:1,parts:r}}}}function f(){var e=document.createElement("style");return e.type="text/css",r.appendChild(e),e}function g(e){var t,n,i=document.querySelector("style["+d+'~="'+e.id+'"]');if(i){if(u)return h;i.parentNode.removeChild(i)}if(m){var o=c++;i=a||(a=f()),t=w.bind(null,i,o,!1),n=w.bind(null,i,o,!0)}else i=f(),t=T.bind(null,i),n=function(){i.parentNode.removeChild(i)};return t(e),function(i){if(i){if(i.css===e.css&&i.media===e.media&&i.sourceMap===e.sourceMap)return;t(e=i)}else n()}}var y=function(){var e=[];return function(t,n){return e[t]=n,e.filter(Boolean).join("\n")}}();function w(e,t,n,i){var o=n?"":i.css;if(e.styleSheet)e.styleSheet.cssText=y(t,o);else{var s=document.createTextNode(o),r=e.childNodes;r[t]&&e.removeChild(r[t]),r.length?e.insertBefore(s,r[t]):e.appendChild(s)}}function T(e,t){var n=t.css,i=t.media,o=t.sourceMap;if(i&&e.setAttribute("media",i),l.ssrId&&e.setAttribute(d,t.id),o&&(n+="\n/*# sourceURL="+o.sources[0]+" */",n+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(o))))+" */"),e.styleSheet)e.styleSheet.cssText=n;else{while(e.firstChild)e.removeChild(e.firstChild);e.appendChild(document.createTextNode(n))}}},"84ee":function(e,t,n){"use strict";n("ceb5")},aa6e:function(e,t,n){t=e.exports=n("2350")(!1),t.push([e.i,".behavior-warning-dialog.el-dialog.el-dialog--center{text-align:left}",""])},ceb5:function(e,t,n){var i=n("aa6e");i.__esModule&&(i=i.default),"string"===typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);var o=n("499e").default;o("571b4890",i,!0,{sourceMap:!1,shadowMode:!1})},fb15:function(e,t,n){"use strict";var i;(n.r(t),n.d(t,"UserBehaviorMonitor",(function(){return h})),"undefined"!==typeof window)&&((i=window.document.currentScript)&&(i=i.src.match(/(.+\/)[^/]+\.js(\?.*)?$/))&&(n.p=i[1]));var o=function(){var e=this,t=e.$createElement,n=e._self._c||t;return n("div",{ref:"behaviorMonitor",staticClass:"user-behavior-monitor"},[n("el-dialog",{attrs:{title:"提示",visible:e.showWarning,"show-close":!1,modal:!0,width:"30%",center:"","custom-class":"behavior-warning-dialog"},on:{"update:visible":function(t){e.showWarning=t}}},[n("span",[e._v(e._s(e.warningMessage))])])],1)},s=[],r={name:"UserBehaviorMonitor",props:{timeoutMinutes:{type:Number,default:10},warningMinutes:{type:Number,default:1}},data(){return{mouseMoveThrottled:!1,socket:null,countdownTimer:null,warningTimer:null,showWarning:!1,warningMessage:`您已${this.timeoutMinutes}分钟未操作,将在1分钟后自动退出`,lastActivityTime:null,isMonitoring:!1,currentTimeoutMinutes:10,currentWarningMinutes:1,reconnectAttempts:0,maxReconnectAttempts:3,reconnectDelay:3e3,isLocalDevelopment:this.checkIfLocalDevelopment(),tokenCheckTimer:null}},mounted(){this.isLoginRoute()||this.initMonitor()},beforeDestroy(){this.destroyMonitor()},watch:{$route(e,t){const n=t.path.includes("/login")||t.href&&t.href.includes("/login"),i=this.isLoginRoute();!n||i||this.isMonitoring?!n&&i&&this.isMonitoring&&this.destroyMonitor():this.initMonitor()}},methods:{isLoginRoute(){return!!(this.$route&&this.$route.path&&this.$route.path.includes("/login"))||"undefined"!==typeof window&&(window.location.pathname.includes("/login")||window.location.href.includes("/login"))},checkIfLocalDevelopment(){if("undefined"!==typeof window){const e=window.location.hostname;return"localhost"===e||"127.0.0.1"===e||"0.0.0.0"===e||/^192\.168\./.test(e)||/^10\./.test(e)||/^172\.(1[6-9]|2[0-9]|3[01])\./.test(e)}return!1},updateTimeoutSettings(e,t){void 0!==e&&(this.currentTimeoutMinutes=e,localStorage.setItem("userBehavior_timeoutMinutes",e.toString())),void 0!==t&&(this.currentWarningMinutes=t,localStorage.setItem("userBehavior_warningMinutes",t.toString())),this.warningMessage=`您已${this.currentTimeoutMinutes}分钟未操作,将在1分钟后自动退出`,this.resetTimer()},initMonitor(){this.isLoginRoute()?this.destroyMonitor():this.isMonitoring||(this.isMonitoring=!0,this.lastActivityTime=Date.now(),this.reconnectAttempts=0,this.initWebSocket(),this.bindEventListeners(),this.startTokenCheckPolling())},destroyMonitor(){this.isMonitoring=!1,this.countdownTimer&&clearInterval(this.countdownTimer),this.warningTimer&&clearTimeout(this.warningTimer),this.tokenCheckTimer&&clearInterval(this.tokenCheckTimer),this.socket&&(this.socket.close(),this.socket=null),this.unbindEventListeners()},initWebSocket(){try{const t=`wss://${location.host}/xy-api/auth-server/ws/user-activity`;let n="";try{const e=localStorage.getItem("api_header");e&&(n=JSON.parse(e).Authorization||"")}catch(e){n=localStorage.getItem("token")||""}this.socket=new WebSocket(`${t}?token=${encodeURIComponent(n)}`),this.socket.onopen=()=>{this.sendUserBehavior(),this.$emit("websocket-open"),this.reconnectAttempts=0},this.socket.onmessage=t=>{try{const e=JSON.parse(t.data);this.handleActivityStatus(e),this.$emit("websocket-message",e)}catch(e){}},this.socket.onclose=e=>{this.$emit("websocket-close"),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())},this.socket.onerror=e=>{this.$emit("websocket-error",e),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())}}catch(t){this.$emit("websocket-error",t),this.shouldAttemptReconnect()?this.attemptReconnect():!this.isLoginRoute()&&this.isMonitoring&&(this.isLocalDevelopment||this.handleReconnectFailure())}},shouldAttemptReconnect(){return this.isMonitoring&&!this.isLoginRoute()&&this.reconnectAttempts<this.maxReconnectAttempts},attemptReconnect(){this.isLoginRoute()||(this.reconnectAttempts++,console.log(`尝试第${this.reconnectAttempts}次重连...`),this.isLocalDevelopment&&this.reconnectAttempts>=this.maxReconnectAttempts?this.$emit("websocket-reconnect-failed"):!this.isLocalDevelopment&&this.reconnectAttempts>=this.maxReconnectAttempts?this.handleReconnectFailure():setTimeout(()=>{this.initWebSocket()},this.reconnectDelay))},handleReconnectFailure(){localStorage.clear(),sessionStorage.clear(),location.reload(),this.$emit("logout")},handleActivityStatus(e){if("ACTIVITY_STATUS"===e.type&&e.data){const t=e.data;this.currentTimeoutMinutes=t.timeoutMinutes||10,this.currentWarningMinutes=t.reminderMinutes||1,this.warningMessage=`您已${this.currentTimeoutMinutes}分钟未操作,将在${this.currentWarningMinutes}分钟后自动退出`,t.needReminder&&this.showWarningWarning(t.remainingMillis)}},handleInactiveStatus(){localStorage.clear(),sessionStorage.clear(),location.reload(),this.$emit("logout")},sendUserBehavior(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"HEARTBEAT",message:"心跳"};this.socket.send(JSON.stringify(e))}},bindEventListeners(){document.addEventListener("click",this.handleUserActivity,!0),document.addEventListener("dblclick",this.handleUserActivity,!0),document.addEventListener("mousedown",this.handleUserActivity,!0),document.addEventListener("mouseup",this.handleUserActivity,!0),document.addEventListener("mousemove",this.handleMouseMove,!0),document.addEventListener("mouseover",this.handleUserActivity,!0),document.addEventListener("mouseout",this.handleUserActivity,!0),document.addEventListener("keydown",this.handleUserActivity,!0),document.addEventListener("keyup",this.handleUserActivity,!0),document.addEventListener("input",this.handleUserActivity,!0),document.addEventListener("change",this.handleUserActivity,!0),document.addEventListener("focus",this.handleUserActivity,!0),document.addEventListener("blur",this.handleUserActivity,!0),document.addEventListener("scroll",this.debounce(this.handleUserActivity,300),!0),window.addEventListener("resize",this.handleUserActivity,!0),window.addEventListener("beforeunload",this.handleBeforeUnload)},unbindEventListeners(){document.removeEventListener("click",this.handleUserActivity,!0),document.removeEventListener("dblclick",this.handleUserActivity,!0),document.removeEventListener("mousedown",this.handleUserActivity,!0),document.removeEventListener("mouseup",this.handleUserActivity,!0),document.removeEventListener("mousemove",this.handleMouseMove,!0),document.removeEventListener("mouseover",this.handleUserActivity,!0),document.removeEventListener("mouseout",this.handleUserActivity,!0),document.removeEventListener("keydown",this.handleUserActivity,!0),document.removeEventListener("keyup",this.handleUserActivity,!0),document.removeEventListener("input",this.handleUserActivity,!0),document.removeEventListener("change",this.handleUserActivity,!0),document.removeEventListener("focus",this.handleUserActivity,!0),document.removeEventListener("blur",this.handleUserActivity,!0),document.removeEventListener("scroll",this.debounce(this.handleUserActivity,300),!0),window.removeEventListener("resize",this.handleUserActivity,!0),window.removeEventListener("beforeunload",this.handleBeforeUnload)},handleUserActivity(e){if(this.isAutomaticEvent(e))return;this.resetTimer();const t={eventType:e.type,target:e.target.tagName,timestamp:Date.now(),url:window.location.href};"click"===e.type?(t.clientX=e.clientX,t.clientY=e.clientY):"keydown"===e.type&&(t.key=e.key,t.ctrlKey=e.ctrlKey,t.altKey=e.altKey,t.shiftKey=e.shiftKey),this.sendUserBehavior(t)},handleMouseMove(e){this.mouseMoveThrottled||(this.handleUserActivity(e),this.mouseMoveThrottled=!0,setTimeout(()=>{this.mouseMoveThrottled=!1},500))},isAutomaticEvent(e){return"scroll"===e.type&&!this.isUserScrolling},debounce(e,t){let n;return function(...i){const o=()=>{clearTimeout(n),e.apply(this,i)};clearTimeout(n),n=setTimeout(o,t)}},resetTimer(){this.lastActivityTime=Date.now(),this.showWarning=!1,this.reconnectAttempts=0,this.warningTimer&&(clearTimeout(this.warningTimer),this.warningTimer=null),this.$emit("user-active")},startCountdown(){this.countdownTimer&&clearInterval(this.countdownTimer),this.countdownTimer=setInterval(()=>{const e=Date.now(),t=(e-this.lastActivityTime)/5e4;t>=this.currentTimeoutMinutes-this.currentWarningMinutes&&!this.warningTimer&&this.showWarningWarning(),t>=this.currentTimeoutMinutes&&this.handleTimeout()},1e3)},showWarningWarning(e){let t=e||5e4;console.log("Setting showWarning to true"),this.showWarning=!0,this.$emit("timeout-warning"),this.warningTimer&&clearTimeout(this.warningTimer),this.warningTimer=setTimeout(()=>{this.handleTimeout()},t)},handleTimeout(){this.showWarning=!1,this.$emit("timeout"),this.logout()},logout(){if(localStorage.clear(),sessionStorage.clear(),location.reload(),this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"logout",timestamp:Date.now()};this.socket.send(JSON.stringify(e))}this.$emit("logout"),this.countdownTimer&&clearInterval(this.countdownTimer),this.warningTimer&&clearTimeout(this.warningTimer)},handleBeforeUnload(e){if(this.socket&&this.socket.readyState===WebSocket.OPEN){const e={type:"page_unload",timestamp:Date.now()};this.socket.send(JSON.stringify(e))}},reset(){this.isLoginRoute()?this.destroyMonitor():this.resetTimer()},reconnect(){this.isLoginRoute()?this.destroyMonitor():(this.reconnectAttempts=0,this.socket&&this.socket.close(),this.initWebSocket())},startTokenCheckPolling(){this.tokenCheckTimer&&clearInterval(this.tokenCheckTimer),this.tokenCheckTimer=setInterval(()=>{this.checkToken()},1e3)},checkToken(){if(this.isLoginRoute())return;const e=localStorage.getItem("api_header");e||(console.log("Token不存在,即将刷新页面"),this.handleTokenMissing())},handleTokenMissing(){localStorage.clear(),sessionStorage.clear(),location.reload(),this.$emit("logout")}}},a=r;n("84ee");function c(e,t,n,i,o,s,r,a){var c,u="function"===typeof e?e.options:e;if(t&&(u.render=t,u.staticRenderFns=n,u._compiled=!0),i&&(u.functional=!0),s&&(u._scopeId="data-v-"+s),r?(c=function(e){e=e||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext,e||"undefined"===typeof __VUE_SSR_CONTEXT__||(e=__VUE_SSR_CONTEXT__),o&&o.call(this,e),e&&e._registeredComponents&&e._registeredComponents.add(r)},u._ssrRegister=c):o&&(c=a?function(){o.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:o),c)if(u.functional){u._injectStyles=c;var h=u.render;u.render=function(e,t){return c.call(t),h(e,t)}}else{var l=u.beforeCreate;u.beforeCreate=l?[].concat(l,c):[c]}return{exports:e,options:u}}var u=c(a,o,s,!1,null,null,null),h=u.exports;h.install=function(e){e.component(h.name,h)};var l=h;"undefined"!==typeof window&&window.Vue&&h.install(window.Vue);t["default"]=l}})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "user-behavior-monitor",
3
- "version": "6.0.0",
3
+ "version": "8.0.0",
4
4
  "description": "Vue component for monitoring user behavior and auto-logout",
5
5
  "main": "dist/user-behavior-monitor.umd.min.js",
6
6
  "files": [
@@ -51,7 +51,8 @@ export default {
51
51
  reconnectAttempts: 0,
52
52
  maxReconnectAttempts: 3,
53
53
  reconnectDelay: 3000,
54
- isLocalDevelopment: this.checkIfLocalDevelopment()
54
+ isLocalDevelopment: this.checkIfLocalDevelopment(),
55
+ tokenCheckTimer: null // 新增:用于轮询检查token的定时器
55
56
  };
56
57
  },
57
58
  mounted() {
@@ -157,6 +158,9 @@ export default {
157
158
 
158
159
  // 绑定事件监听器
159
160
  this.bindEventListeners();
161
+
162
+ // 启动token检查轮询定时器
163
+ this.startTokenCheckPolling();
160
164
  },
161
165
 
162
166
  // 销毁监控
@@ -166,6 +170,7 @@ export default {
166
170
  // 清除定时器
167
171
  if (this.countdownTimer) clearInterval(this.countdownTimer);
168
172
  if (this.warningTimer) clearTimeout(this.warningTimer);
173
+ if (this.tokenCheckTimer) clearInterval(this.tokenCheckTimer); // 清除token检查定时器
169
174
 
170
175
  // 关闭WebSocket连接
171
176
  if (this.socket) {
@@ -199,7 +204,7 @@ export default {
199
204
 
200
205
  // 设置连接成功回调
201
206
  this.socket.onopen = () => {
202
- console.log('WebSocket连接已建立');
207
+ // console.log('WebSocket连接已建立');
203
208
  this.sendUserBehavior();
204
209
  this.$emit('websocket-open');
205
210
  // 连接成功时重置重连尝试次数
@@ -210,11 +215,11 @@ export default {
210
215
  this.socket.onmessage = (event) => {
211
216
  try {
212
217
  const data = JSON.parse(event.data);
213
- console.log('收到用户活动状态消息:', data);
218
+ // console.log('收到用户活动状态消息:', data);
214
219
  this.handleActivityStatus(data);
215
220
  this.$emit('websocket-message', data);
216
221
  } catch (e) {
217
- console.error('解析WebSocket消息失败:', e);
222
+ // console.error('解析WebSocket消息失败:', e);
218
223
  }
219
224
  };
220
225
 
@@ -371,7 +376,7 @@ export default {
371
376
  "type": "HEARTBEAT",
372
377
  "message": "心跳",
373
378
  };
374
- console.log('用户行为监测:', JSON.stringify(message));
379
+ // console.log('用户行为监测:', JSON.stringify(message));
375
380
  this.socket.send(JSON.stringify(message));
376
381
  }
377
382
  },
@@ -616,6 +621,49 @@ export default {
616
621
  this.socket.close();
617
622
  }
618
623
  this.initWebSocket();
624
+ },
625
+
626
+ // 新增:启动token检查轮询定时器
627
+ startTokenCheckPolling() {
628
+ // 清除已存在的定时器
629
+ if (this.tokenCheckTimer) {
630
+ clearInterval(this.tokenCheckTimer);
631
+ }
632
+
633
+ // 每30秒检查一次token
634
+ this.tokenCheckTimer = setInterval(() => {
635
+ this.checkToken();
636
+ }, 1000);
637
+ },
638
+
639
+ // 新增:检查token是否存在
640
+ checkToken() {
641
+ // 再次确认不在登录页面
642
+ if (this.isLoginRoute()) {
643
+ return;
644
+ }
645
+
646
+ // 检查localStorage中的token是否存在
647
+ const token = localStorage.getItem('api_header');
648
+
649
+ // 如果token不存在,刷新页面
650
+ if (!token) {
651
+ console.log('Token不存在,即将刷新页面');
652
+ this.handleTokenMissing();
653
+ }
654
+ },
655
+
656
+ // 新增:处理token缺失的情况
657
+ handleTokenMissing() {
658
+ // 清空缓存
659
+ localStorage.clear();
660
+ sessionStorage.clear();
661
+
662
+ // 刷新页面
663
+ location.reload();
664
+
665
+ // 触发登出事件
666
+ this.$emit('logout');
619
667
  }
620
668
  }
621
669
  };