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
|
-
/***/ "
|
|
174
|
-
/***/ (function(module,
|
|
173
|
+
/***/ "3a69":
|
|
174
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
175
175
|
|
|
176
|
-
|
|
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
|
-
/***/ "
|
|
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=
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
720
|
+
console.log('收到用户活动状态消息:', data);
|
|
727
721
|
this.handleActivityStatus(data);
|
|
728
722
|
this.$emit('websocket-message', data);
|
|
729
723
|
} catch (e) {
|
|
730
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
1139
|
-
var
|
|
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
|
-
/***/ "
|
|
183
|
-
/***/ (function(module,
|
|
182
|
+
/***/ "3a69":
|
|
183
|
+
/***/ (function(module, exports, __webpack_require__) {
|
|
184
184
|
|
|
185
|
-
|
|
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
|
-
/***/ "
|
|
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=
|
|
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=
|
|
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
|
-
|
|
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
|
-
|
|
729
|
+
console.log('收到用户活动状态消息:', data);
|
|
736
730
|
this.handleActivityStatus(data);
|
|
737
731
|
this.$emit('websocket-message', data);
|
|
738
732
|
} catch (e) {
|
|
739
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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=
|
|
1148
|
-
var
|
|
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
|
@@ -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
|
-
|
|
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
|
-
|
|
218
|
+
console.log('收到用户活动状态消息:', data);
|
|
214
219
|
this.handleActivityStatus(data);
|
|
215
220
|
this.$emit('websocket-message', data);
|
|
216
221
|
} catch (e) {
|
|
217
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
};
|