user-behavior-monitor 5.0.0 → 7.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.
@@ -170,14 +170,19 @@ function toComment(sourceMap) {
170
170
 
171
171
  /***/ }),
172
172
 
173
- /***/ "2cd8":
174
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
173
+ /***/ "3a69":
174
+ /***/ (function(module, exports, __webpack_require__) {
175
175
 
176
- "use strict";
177
- /* 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_91790b00_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("89b5");
178
- /* 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_91790b00_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_91790b00_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
179
- /* unused harmony reexport * */
176
+ // style-loader: Adds some css to the DOM by adding a <style> tag
180
177
 
178
+ // load the styles
179
+ var content = __webpack_require__("57b8");
180
+ if(content.__esModule) content = content.default;
181
+ if(typeof content === 'string') content = [[module.i, content, '']];
182
+ if(content.locals) module.exports = content.locals;
183
+ // add the styles to the DOM
184
+ var add = __webpack_require__("499e").default
185
+ var update = add("3621c939", content, true, {"sourceMap":false,"shadowMode":false});
181
186
 
182
187
  /***/ }),
183
188
 
@@ -447,23 +452,7 @@ function applyToTag (styleElement, obj) {
447
452
 
448
453
  /***/ }),
449
454
 
450
- /***/ "89b5":
451
- /***/ (function(module, exports, __webpack_require__) {
452
-
453
- // style-loader: Adds some css to the DOM by adding a <style> tag
454
-
455
- // load the styles
456
- var content = __webpack_require__("9f1b");
457
- if(content.__esModule) content = content.default;
458
- if(typeof content === 'string') content = [[module.i, content, '']];
459
- if(content.locals) module.exports = content.locals;
460
- // add the styles to the DOM
461
- var add = __webpack_require__("499e").default
462
- var update = add("9b2fa8ce", content, true, {"sourceMap":false,"shadowMode":false});
463
-
464
- /***/ }),
465
-
466
- /***/ "9f1b":
455
+ /***/ "57b8":
467
456
  /***/ (function(module, exports, __webpack_require__) {
468
457
 
469
458
  exports = module.exports = __webpack_require__("2350")(false);
@@ -503,12 +492,12 @@ if (typeof window !== 'undefined') {
503
492
  // Indicate to webpack that this file can be concatenated
504
493
  /* harmony default export */ var setPublicPath = (null);
505
494
 
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=91790b00
495
+ // 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=59578a74
507
496
  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
497
  var staticRenderFns = []
509
498
 
510
499
 
511
- // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=91790b00
500
+ // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=59578a74
512
501
 
513
502
  // 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
503
  //
@@ -564,7 +553,8 @@ var staticRenderFns = []
564
553
  reconnectAttempts: 0,
565
554
  maxReconnectAttempts: 3,
566
555
  reconnectDelay: 3000,
567
- isLocalDevelopment: this.checkIfLocalDevelopment()
556
+ isLocalDevelopment: this.checkIfLocalDevelopment(),
557
+ tokenCheckTimer: null // 新增:用于轮询检查token的定时器
568
558
  };
569
559
  },
570
560
  mounted() {
@@ -670,6 +660,9 @@ var staticRenderFns = []
670
660
 
671
661
  // 绑定事件监听器
672
662
  this.bindEventListeners();
663
+
664
+ // 启动token检查轮询定时器
665
+ this.startTokenCheckPolling();
673
666
  },
674
667
 
675
668
  // 销毁监控
@@ -679,6 +672,7 @@ var staticRenderFns = []
679
672
  // 清除定时器
680
673
  if (this.countdownTimer) clearInterval(this.countdownTimer);
681
674
  if (this.warningTimer) clearTimeout(this.warningTimer);
675
+ if (this.tokenCheckTimer) clearInterval(this.tokenCheckTimer); // 清除token检查定时器
682
676
 
683
677
  // 关闭WebSocket连接
684
678
  if (this.socket) {
@@ -712,7 +706,7 @@ var staticRenderFns = []
712
706
 
713
707
  // 设置连接成功回调
714
708
  this.socket.onopen = () => {
715
- // console.log('WebSocket连接已建立');
709
+ console.log('WebSocket连接已建立');
716
710
  this.sendUserBehavior();
717
711
  this.$emit('websocket-open');
718
712
  // 连接成功时重置重连尝试次数
@@ -723,11 +717,11 @@ var staticRenderFns = []
723
717
  this.socket.onmessage = (event) => {
724
718
  try {
725
719
  const data = JSON.parse(event.data);
726
- // console.log('收到用户活动状态消息:', data);
720
+ console.log('收到用户活动状态消息:', data);
727
721
  this.handleActivityStatus(data);
728
722
  this.$emit('websocket-message', data);
729
723
  } catch (e) {
730
- // console.error('解析WebSocket消息失败:', e);
724
+ console.error('解析WebSocket消息失败:', e);
731
725
  }
732
726
  };
733
727
 
@@ -795,7 +789,7 @@ var staticRenderFns = []
795
789
  }
796
790
 
797
791
  this.reconnectAttempts++;
798
- // console.log(`尝试第${this.reconnectAttempts}次重连...`);
792
+ console.log(`尝试第${this.reconnectAttempts}次重连...`);
799
793
 
800
794
  // 如果是本地开发环境且重连次数已达到最大值,则不跳转登录页
801
795
  if (this.isLocalDevelopment && this.reconnectAttempts >= this.maxReconnectAttempts) {
@@ -884,7 +878,7 @@ var staticRenderFns = []
884
878
  "type": "HEARTBEAT",
885
879
  "message": "心跳",
886
880
  };
887
- // console.log('用户行为监测:', JSON.stringify(message));
881
+ console.log('用户行为监测:', JSON.stringify(message));
888
882
  this.socket.send(JSON.stringify(message));
889
883
  }
890
884
  },
@@ -1045,7 +1039,7 @@ var staticRenderFns = []
1045
1039
  // 显示超时警告
1046
1040
  showWarningWarning(timeoutMinutes) {
1047
1041
  let time=timeoutMinutes||50000;
1048
- // console.log('Setting showWarning to true');
1042
+ console.log('Setting showWarning to true');
1049
1043
  this.showWarning = true;
1050
1044
  this.$emit('timeout-warning');
1051
1045
  if (this.warningTimer) clearTimeout(this.warningTimer);
@@ -1129,14 +1123,57 @@ var staticRenderFns = []
1129
1123
  this.socket.close();
1130
1124
  }
1131
1125
  this.initWebSocket();
1126
+ },
1127
+
1128
+ // 新增:启动token检查轮询定时器
1129
+ startTokenCheckPolling() {
1130
+ // 清除已存在的定时器
1131
+ if (this.tokenCheckTimer) {
1132
+ clearInterval(this.tokenCheckTimer);
1133
+ }
1134
+
1135
+ // 每30秒检查一次token
1136
+ this.tokenCheckTimer = setInterval(() => {
1137
+ this.checkToken();
1138
+ }, 1000);
1139
+ },
1140
+
1141
+ // 新增:检查token是否存在
1142
+ checkToken() {
1143
+ // 再次确认不在登录页面
1144
+ if (this.isLoginRoute()) {
1145
+ return;
1146
+ }
1147
+
1148
+ // 检查localStorage中的token是否存在
1149
+ const token = localStorage.getItem('api_header');
1150
+
1151
+ // 如果token不存在,刷新页面
1152
+ if (!token) {
1153
+ console.log('Token不存在,即将刷新页面');
1154
+ this.handleTokenMissing();
1155
+ }
1156
+ },
1157
+
1158
+ // 新增:处理token缺失的情况
1159
+ handleTokenMissing() {
1160
+ // 清空缓存
1161
+ localStorage.clear();
1162
+ sessionStorage.clear();
1163
+
1164
+ // 刷新页面
1165
+ location.reload();
1166
+
1167
+ // 触发登出事件
1168
+ this.$emit('logout');
1132
1169
  }
1133
1170
  }
1134
1171
  });
1135
1172
 
1136
1173
  // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
1137
1174
  /* 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=91790b00&prod&lang=css
1139
- var UserBehaviorMonitorvue_type_style_index_0_id_91790b00_prod_lang_css = __webpack_require__("2cd8");
1175
+ // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=59578a74&prod&lang=css
1176
+ var UserBehaviorMonitorvue_type_style_index_0_id_59578a74_prod_lang_css = __webpack_require__("fc5f");
1140
1177
 
1141
1178
  // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
1142
1179
  /* globals __VUE_SSR_CONTEXT__ */
@@ -1282,6 +1319,17 @@ if (typeof window !== 'undefined' && window.Vue) {
1282
1319
 
1283
1320
 
1284
1321
 
1322
+ /***/ }),
1323
+
1324
+ /***/ "fc5f":
1325
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
1326
+
1327
+ "use strict";
1328
+ /* 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_59578a74_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("3a69");
1329
+ /* 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_59578a74_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_59578a74_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
1330
+ /* unused harmony reexport * */
1331
+
1332
+
1285
1333
  /***/ })
1286
1334
 
1287
1335
  /******/ });
@@ -179,14 +179,19 @@ function toComment(sourceMap) {
179
179
 
180
180
  /***/ }),
181
181
 
182
- /***/ "2cd8":
183
- /***/ (function(module, __webpack_exports__, __webpack_require__) {
182
+ /***/ "3a69":
183
+ /***/ (function(module, exports, __webpack_require__) {
184
184
 
185
- "use strict";
186
- /* 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_91790b00_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("89b5");
187
- /* 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_91790b00_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_91790b00_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
188
- /* unused harmony reexport * */
185
+ // style-loader: Adds some css to the DOM by adding a <style> tag
189
186
 
187
+ // load the styles
188
+ var content = __webpack_require__("57b8");
189
+ if(content.__esModule) content = content.default;
190
+ if(typeof content === 'string') content = [[module.i, content, '']];
191
+ if(content.locals) module.exports = content.locals;
192
+ // add the styles to the DOM
193
+ var add = __webpack_require__("499e").default
194
+ var update = add("3621c939", content, true, {"sourceMap":false,"shadowMode":false});
190
195
 
191
196
  /***/ }),
192
197
 
@@ -456,23 +461,7 @@ function applyToTag (styleElement, obj) {
456
461
 
457
462
  /***/ }),
458
463
 
459
- /***/ "89b5":
460
- /***/ (function(module, exports, __webpack_require__) {
461
-
462
- // style-loader: Adds some css to the DOM by adding a <style> tag
463
-
464
- // load the styles
465
- var content = __webpack_require__("9f1b");
466
- if(content.__esModule) content = content.default;
467
- if(typeof content === 'string') content = [[module.i, content, '']];
468
- if(content.locals) module.exports = content.locals;
469
- // add the styles to the DOM
470
- var add = __webpack_require__("499e").default
471
- var update = add("9b2fa8ce", content, true, {"sourceMap":false,"shadowMode":false});
472
-
473
- /***/ }),
474
-
475
- /***/ "9f1b":
464
+ /***/ "57b8":
476
465
  /***/ (function(module, exports, __webpack_require__) {
477
466
 
478
467
  exports = module.exports = __webpack_require__("2350")(false);
@@ -512,12 +501,12 @@ if (typeof window !== 'undefined') {
512
501
  // Indicate to webpack that this file can be concatenated
513
502
  /* harmony default export */ var setPublicPath = (null);
514
503
 
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=91790b00
504
+ // 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=59578a74
516
505
  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
506
  var staticRenderFns = []
518
507
 
519
508
 
520
- // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=91790b00
509
+ // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=template&id=59578a74
521
510
 
522
511
  // 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
512
  //
@@ -573,7 +562,8 @@ var staticRenderFns = []
573
562
  reconnectAttempts: 0,
574
563
  maxReconnectAttempts: 3,
575
564
  reconnectDelay: 3000,
576
- isLocalDevelopment: this.checkIfLocalDevelopment()
565
+ isLocalDevelopment: this.checkIfLocalDevelopment(),
566
+ tokenCheckTimer: null // 新增:用于轮询检查token的定时器
577
567
  };
578
568
  },
579
569
  mounted() {
@@ -679,6 +669,9 @@ var staticRenderFns = []
679
669
 
680
670
  // 绑定事件监听器
681
671
  this.bindEventListeners();
672
+
673
+ // 启动token检查轮询定时器
674
+ this.startTokenCheckPolling();
682
675
  },
683
676
 
684
677
  // 销毁监控
@@ -688,6 +681,7 @@ var staticRenderFns = []
688
681
  // 清除定时器
689
682
  if (this.countdownTimer) clearInterval(this.countdownTimer);
690
683
  if (this.warningTimer) clearTimeout(this.warningTimer);
684
+ if (this.tokenCheckTimer) clearInterval(this.tokenCheckTimer); // 清除token检查定时器
691
685
 
692
686
  // 关闭WebSocket连接
693
687
  if (this.socket) {
@@ -721,7 +715,7 @@ var staticRenderFns = []
721
715
 
722
716
  // 设置连接成功回调
723
717
  this.socket.onopen = () => {
724
- // console.log('WebSocket连接已建立');
718
+ console.log('WebSocket连接已建立');
725
719
  this.sendUserBehavior();
726
720
  this.$emit('websocket-open');
727
721
  // 连接成功时重置重连尝试次数
@@ -732,11 +726,11 @@ var staticRenderFns = []
732
726
  this.socket.onmessage = (event) => {
733
727
  try {
734
728
  const data = JSON.parse(event.data);
735
- // console.log('收到用户活动状态消息:', data);
729
+ console.log('收到用户活动状态消息:', data);
736
730
  this.handleActivityStatus(data);
737
731
  this.$emit('websocket-message', data);
738
732
  } catch (e) {
739
- // console.error('解析WebSocket消息失败:', e);
733
+ console.error('解析WebSocket消息失败:', e);
740
734
  }
741
735
  };
742
736
 
@@ -804,7 +798,7 @@ var staticRenderFns = []
804
798
  }
805
799
 
806
800
  this.reconnectAttempts++;
807
- // console.log(`尝试第${this.reconnectAttempts}次重连...`);
801
+ console.log(`尝试第${this.reconnectAttempts}次重连...`);
808
802
 
809
803
  // 如果是本地开发环境且重连次数已达到最大值,则不跳转登录页
810
804
  if (this.isLocalDevelopment && this.reconnectAttempts >= this.maxReconnectAttempts) {
@@ -893,7 +887,7 @@ var staticRenderFns = []
893
887
  "type": "HEARTBEAT",
894
888
  "message": "心跳",
895
889
  };
896
- // console.log('用户行为监测:', JSON.stringify(message));
890
+ console.log('用户行为监测:', JSON.stringify(message));
897
891
  this.socket.send(JSON.stringify(message));
898
892
  }
899
893
  },
@@ -1054,7 +1048,7 @@ var staticRenderFns = []
1054
1048
  // 显示超时警告
1055
1049
  showWarningWarning(timeoutMinutes) {
1056
1050
  let time=timeoutMinutes||50000;
1057
- // console.log('Setting showWarning to true');
1051
+ console.log('Setting showWarning to true');
1058
1052
  this.showWarning = true;
1059
1053
  this.$emit('timeout-warning');
1060
1054
  if (this.warningTimer) clearTimeout(this.warningTimer);
@@ -1138,14 +1132,57 @@ var staticRenderFns = []
1138
1132
  this.socket.close();
1139
1133
  }
1140
1134
  this.initWebSocket();
1135
+ },
1136
+
1137
+ // 新增:启动token检查轮询定时器
1138
+ startTokenCheckPolling() {
1139
+ // 清除已存在的定时器
1140
+ if (this.tokenCheckTimer) {
1141
+ clearInterval(this.tokenCheckTimer);
1142
+ }
1143
+
1144
+ // 每30秒检查一次token
1145
+ this.tokenCheckTimer = setInterval(() => {
1146
+ this.checkToken();
1147
+ }, 1000);
1148
+ },
1149
+
1150
+ // 新增:检查token是否存在
1151
+ checkToken() {
1152
+ // 再次确认不在登录页面
1153
+ if (this.isLoginRoute()) {
1154
+ return;
1155
+ }
1156
+
1157
+ // 检查localStorage中的token是否存在
1158
+ const token = localStorage.getItem('api_header');
1159
+
1160
+ // 如果token不存在,刷新页面
1161
+ if (!token) {
1162
+ console.log('Token不存在,即将刷新页面');
1163
+ this.handleTokenMissing();
1164
+ }
1165
+ },
1166
+
1167
+ // 新增:处理token缺失的情况
1168
+ handleTokenMissing() {
1169
+ // 清空缓存
1170
+ localStorage.clear();
1171
+ sessionStorage.clear();
1172
+
1173
+ // 刷新页面
1174
+ location.reload();
1175
+
1176
+ // 触发登出事件
1177
+ this.$emit('logout');
1141
1178
  }
1142
1179
  }
1143
1180
  });
1144
1181
 
1145
1182
  // CONCATENATED MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=script&lang=js
1146
1183
  /* 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=91790b00&prod&lang=css
1148
- var UserBehaviorMonitorvue_type_style_index_0_id_91790b00_prod_lang_css = __webpack_require__("2cd8");
1184
+ // EXTERNAL MODULE: ./src/components/UserBehaviorMonitor.vue?vue&type=style&index=0&id=59578a74&prod&lang=css
1185
+ var UserBehaviorMonitorvue_type_style_index_0_id_59578a74_prod_lang_css = __webpack_require__("fc5f");
1149
1186
 
1150
1187
  // CONCATENATED MODULE: ./node_modules/vue-loader/lib/runtime/componentNormalizer.js
1151
1188
  /* globals __VUE_SSR_CONTEXT__ */
@@ -1291,6 +1328,17 @@ if (typeof window !== 'undefined' && window.Vue) {
1291
1328
 
1292
1329
 
1293
1330
 
1331
+ /***/ }),
1332
+
1333
+ /***/ "fc5f":
1334
+ /***/ (function(module, __webpack_exports__, __webpack_require__) {
1335
+
1336
+ "use strict";
1337
+ /* 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_59578a74_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("3a69");
1338
+ /* 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_59578a74_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_59578a74_prod_lang_css__WEBPACK_IMPORTED_MODULE_0__);
1339
+ /* unused harmony reexport * */
1340
+
1341
+
1294
1342
  /***/ })
1295
1343
 
1296
1344
  /******/ });
@@ -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")}({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}},"2cd8":function(e,t,n){"use strict";n("89b5")},"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 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 h;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),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))}}},"89b5":function(e,t,n){var i=n("9f1b");i.__esModule&&(i=i.default),"string"===typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);var o=n("499e").default;o("9b2fa8ce",i,!0,{sourceMap:!1,shadowMode:!1})},"9f1b":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}",""])},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()}},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=()=>{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++,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;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("2cd8");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}})}));
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}},"3a69":function(e,t,n){var i=n("57b8");i.__esModule&&(i=i.default),"string"===typeof i&&(i=[[e.i,i,""]]),i.locals&&(e.exports=i.locals);var o=n("499e").default;o("3621c939",i,!0,{sourceMap:!1,shadowMode:!1})},"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=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),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))}}},"57b8":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}",""])},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(),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=()=>{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())},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("fc5f");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},fc5f:function(e,t,n){"use strict";n("3a69")}})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "user-behavior-monitor",
3
- "version": "5.0.0",
3
+ "version": "7.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
 
@@ -282,7 +287,7 @@ export default {
282
287
  }
283
288
 
284
289
  this.reconnectAttempts++;
285
- // console.log(`尝试第${this.reconnectAttempts}次重连...`);
290
+ console.log(`尝试第${this.reconnectAttempts}次重连...`);
286
291
 
287
292
  // 如果是本地开发环境且重连次数已达到最大值,则不跳转登录页
288
293
  if (this.isLocalDevelopment && this.reconnectAttempts >= this.maxReconnectAttempts) {
@@ -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
  },
@@ -532,7 +537,7 @@ export default {
532
537
  // 显示超时警告
533
538
  showWarningWarning(timeoutMinutes) {
534
539
  let time=timeoutMinutes||50000;
535
- // console.log('Setting showWarning to true');
540
+ console.log('Setting showWarning to true');
536
541
  this.showWarning = true;
537
542
  this.$emit('timeout-warning');
538
543
  if (this.warningTimer) clearTimeout(this.warningTimer);
@@ -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
  };