diff --git a/gofaster/app/dist/renderer/index.html b/gofaster/app/dist/renderer/index.html
deleted file mode 100644
index 1a45530..0000000
--- a/gofaster/app/dist/renderer/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
-
-
- Vue App
-
-
-
-
-
diff --git a/gofaster/app/dist/renderer/js/index.js b/gofaster/app/dist/renderer/js/index.js
deleted file mode 100644
index 3f213a4..0000000
--- a/gofaster/app/dist/renderer/js/index.js
+++ /dev/null
@@ -1,16782 +0,0 @@
-/******/ (() => { // webpackBootstrap
-/******/ var __webpack_modules__ = ({
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=style&index=0&id=2fa9d48e&lang=css":
-/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=style&index=0&id=2fa9d48e&lang=css ***!
- \*************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-/* 全局样式 */
-#app {
- font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- color: #2c3e50;
- margin: 0;
- padding: 0;
- height: 100vh;
- width: 100vw;
- overflow: hidden;
-}
-
-/* 确保html和body元素也填满窗口 */
-html,
-body {
- margin: 0;
- padding: 0;
- height: 100%;
- width: 100%;
- overflow: hidden;
- /* 添加中文字体支持 */
- font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif;
-}
-
-/* 全局按钮样式 */
-.btn {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- display: inline-flex;
- align-items: center;
- gap: 6px;
- transition: all 0.2s;
- text-decoration: none;
-}
-.btn-primary {
- background: #1976d2;
- color: white;
-}
-.btn-primary:hover {
- background: #1565c0;
-}
-.btn-secondary {
- background: #757575;
- color: white;
-}
-.btn-secondary:hover {
- background: #616161;
-}
-.btn-danger {
- background: #d32f2f;
- color: white;
-}
-.btn-danger:hover {
- background: #c62828;
-}
-.btn-info {
- background: #0288d1;
- color: white;
-}
-.btn-info:hover {
- background: #0277bd;
-}
-
-/* 全局输入框样式 */
-input, select, textarea {
- font-family: inherit;
-}
-
-/* 全局滚动条样式 */
-::-webkit-scrollbar {
- width: 8px;
- height: 8px;
-}
-::-webkit-scrollbar-track {
- background: #f1f1f1;
- border-radius: 4px;
-}
-::-webkit-scrollbar-thumb {
- background: #c1c1c1;
- border-radius: 4px;
-}
-::-webkit-scrollbar-thumb:hover {
- background: #a8a8a8;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=style&index=0&id=768a7af0&scoped=true&lang=css":
-/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=style&index=0&id=768a7af0&scoped=true&lang=css ***!
- \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.speed-test[data-v-768a7af0] {
- padding: 20px;
- max-width: 600px;
- margin: 0 auto;
- text-align: center;
-}
-button[data-v-768a7af0] {
- padding: 10px 20px;
- font-size: 16px;
- background-color: #42b983;
- color: white;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- margin: 20px 0;
-}
-button[data-v-768a7af0]:disabled {
- background-color: #cccccc;
- cursor: not-allowed;
-}
-.results[data-v-768a7af0] {
- margin-top: 20px;
- padding: 15px;
- background-color: #f5f5f5;
- border-radius: 4px;
- text-align: left;
-}
-.result-item[data-v-768a7af0] {
- margin: 10px 0;
- display: flex;
- justify-content: space-between;
-}
-.label[data-v-768a7af0] {
- font-weight: bold;
-}
-.value[data-v-768a7af0] {
- color: #42b983;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=style&index=0&id=7fb85f33&scoped=true&lang=css":
-/*!*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=style&index=0&id=7fb85f33&scoped=true&lang=css ***!
- \*************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.history-view[data-v-7fb85f33] {
- padding: 20px;
- max-width: 800px;
- margin: 0 auto;
-}
-.empty-state[data-v-7fb85f33] {
- text-align: center;
- padding: 40px;
- color: #888;
-}
-.history-list[data-v-7fb85f33] {
- margin-top: 20px;
-}
-.history-item[data-v-7fb85f33] {
- padding: 15px;
- margin-bottom: 10px;
- background-color: #f9f9f9;
- border-radius: 4px;
- display: flex;
- justify-content: space-between;
- align-items: center;
-}
-.history-date[data-v-7fb85f33] {
- color: #666;
-}
-.history-stats[data-v-7fb85f33] {
- display: flex;
- gap: 15px;
-}
-.stat[data-v-7fb85f33] {
- font-weight: bold;
-}
-.download[data-v-7fb85f33] {
- color: #42b983;
-}
-.upload[data-v-7fb85f33] {
- color: #3498db;
-}
-.ping[data-v-7fb85f33] {
- color: #e74c3c;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=style&index=0&id=f48afcd2&scoped=true&lang=css":
-/*!********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=style&index=0&id=f48afcd2&scoped=true&lang=css ***!
- \********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.main-layout[data-v-f48afcd2] {
- height: calc(100vh - 24px); /* 减去状态条高度 */
- display: flex;
- flex-direction: column;
- background: var(--bg-secondary);
- /* 添加中文字体支持 */
- font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif;
- /* 确保不会溢出 */
- overflow: hidden;
-}
-
-/* 顶部导航栏 */
-.header[data-v-f48afcd2] {
- height: 60px;
- background: var(--header-bg);
- border-bottom: 1px solid var(--border-color);
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 20px;
- box-shadow: 0 2px 4px var(--shadow-color);
- z-index: 100;
-}
-.header-left[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- gap: 20px;
-}
-.logo h1[data-v-f48afcd2] {
- margin: 0;
- font-size: 24px;
- color: var(--accent-color);
- font-weight: bold;
-}
-.breadcrumb[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- gap: 8px;
- color: var(--text-secondary);
- font-size: 14px;
-}
-.breadcrumb-item[data-v-f48afcd2] {
- color: var(--text-primary);
-}
-.separator[data-v-f48afcd2] {
- color: var(--text-muted);
- margin: 0 4px;
-}
-.header-right[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- gap: 20px;
-}
-
-/* 消息中心 */
-.message-center[data-v-f48afcd2] {
- position: relative;
-}
-.message-btn[data-v-f48afcd2] {
- background: none;
- border: none;
- font-size: 16px; /* 从20px缩小到16px(缩小一半) */
- cursor: pointer;
- position: relative;
- padding: 8px;
- border-radius: 4px;
- transition: all 0.2s;
- color: var(--text-primary); /* 确保图标颜色与主题一致 */
-}
-.message-btn[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
- color: var(--accent-color);
-}
-.badge[data-v-f48afcd2] {
- position: absolute;
- top: 0;
- right: 0;
- background: #f44336;
- color: white;
- border-radius: 50%;
- width: 18px;
- height: 18px;
- font-size: 11px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-.message-panel[data-v-f48afcd2] {
- position: absolute;
- top: 100%;
- right: 0;
- width: 350px;
- background: var(--card-bg);
- border-radius: 8px;
- box-shadow: 0 4px 12px var(--shadow-color);
- z-index: 1000;
- margin-top: 8px;
- border: 1px solid var(--border-color);
-}
-.message-header[data-v-f48afcd2] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 16px;
- border-bottom: 1px solid var(--border-color);
-}
-.message-header h3[data-v-f48afcd2] {
- margin: 0;
- font-size: 16px;
- color: var(--text-primary);
-}
-.close-btn[data-v-f48afcd2] {
- background: none;
- border: none;
- font-size: 20px;
- cursor: pointer;
- color: var(--text-muted);
-}
-.message-list[data-v-f48afcd2] {
- max-height: 400px;
- overflow-y: auto;
-}
-.message-item[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- padding: 12px 16px;
- border-bottom: 1px solid var(--border-color);
- transition: background-color 0.2s;
-}
-.message-item[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
-}
-.message-icon[data-v-f48afcd2] {
- font-size: 20px;
- margin-right: 12px;
- color: var(--text-primary);
-}
-.message-content[data-v-f48afcd2] {
- flex: 1;
-}
-.message-title[data-v-f48afcd2] {
- font-weight: 500;
- margin-bottom: 4px;
- color: var(--text-primary);
-}
-.message-time[data-v-f48afcd2] {
- font-size: 12px;
- color: var(--text-muted);
-}
-.mark-read-btn[data-v-f48afcd2] {
- background: none;
- border: none;
- color: #4caf50;
- cursor: pointer;
- font-size: 16px;
- padding: 4px;
- border-radius: 4px;
- transition: background-color 0.2s;
-}
-.mark-read-btn[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
-}
-
-/* 用户信息 */
-.user-info[data-v-f48afcd2] {
- position: relative;
-}
-.user-avatar[data-v-f48afcd2] {
- width: 40px;
- height: 40px;
- border-radius: 50%;
- background: #1976d2;
- color: white;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- font-weight: bold;
- transition: background-color 0.2s;
-}
-.user-avatar[data-v-f48afcd2]:hover {
- background: #1565c0;
-}
-.user-avatar img[data-v-f48afcd2] {
- width: 100%;
- height: 100%;
- border-radius: 50%;
- -o-object-fit: cover;
- object-fit: cover;
-}
-.avatar-placeholder[data-v-f48afcd2] {
- font-size: 18px;
-}
-.user-menu[data-v-f48afcd2] {
- position: absolute;
- top: 100%;
- right: 0;
- width: 250px;
- background: var(--card-bg);
- border-radius: 8px;
- box-shadow: 0 4px 12px var(--shadow-color);
- z-index: 1000;
- margin-top: 8px;
-}
-.user-menu-header[data-v-f48afcd2] {
- padding: 16px;
- border-bottom: 1px solid var(--border-color);
-}
-.user-name[data-v-f48afcd2] {
- font-weight: 600;
- margin-bottom: 4px;
- color: var(--text-primary);
-}
-.user-email[data-v-f48afcd2] {
- font-size: 12px;
- color: var(--text-secondary);
-}
-.user-role[data-v-f48afcd2] {
- font-size: 11px;
- color: var(--accent-color);
- background: rgba(25, 118, 210, 0.1);
- padding: 2px 6px;
- border-radius: 10px;
- display: inline-block;
- margin-top: 4px;
-}
-.user-last-login[data-v-f48afcd2] {
- font-size: 10px;
- color: var(--text-muted);
- margin-top: 4px;
- opacity: 0.8;
-}
-.user-menu-items[data-v-f48afcd2] {
- padding: 8px 0;
-}
-.menu-item[data-v-f48afcd2] {
- width: 100%;
- background: none;
- border: none;
- padding: 12px 16px;
- text-align: left;
- cursor: pointer;
- display: flex;
- align-items: center;
- gap: 12px;
- transition: background-color 0.2s;
- font-size: 13px; /* 从默认14px缩小到13px */
- color: var(--text-primary);
-}
-.menu-item[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
-}
-
-/* 主要内容区域 */
-.main-content[data-v-f48afcd2] {
- flex: 1;
- display: flex;
- overflow: hidden;
- /* 高度由flex自动计算 */
-}
-
-/* 左侧菜单 */
-.sidebar[data-v-f48afcd2] {
- width: 250px;
- background: var(--sidebar-bg);
- border-right: 1px solid var(--border-color);
- overflow-y: auto;
-}
-.sidebar-nav[data-v-f48afcd2] {
- padding: 20px 0;
-}
-.nav-section[data-v-f48afcd2] {
- margin-bottom: 20px; /* 从30px减少到20px,因为删除了标题 */
-}
-.nav-section[data-v-f48afcd2]:last-child {
- margin-bottom: 0; /* 最后一个section不需要底部间距 */
-}
-.nav-title[data-v-f48afcd2] {
- padding: 0 20px;
- margin-bottom: 12px;
- font-size: 12px;
- font-weight: 600;
- color: #999;
- text-transform: none; /* 取消大写转换 */
- letter-spacing: normal; /* 取消字母间距 */
-}
-.nav-list[data-v-f48afcd2] {
- list-style: none;
- padding: 0;
- margin: 0;
-}
-.nav-item[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- padding: 10px 20px; /* 从12px减少到10px,因为字体变小了 */
- color: var(--text-primary);
- text-decoration: none;
- transition: all 0.2s;
- position: relative;
- font-size: 13px;
-}
-.nav-item[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
- color: var(--accent-color);
-}
-.nav-item.active[data-v-f48afcd2] {
- background: var(--bg-tertiary);
- color: var(--accent-color);
- border-right: 3px solid var(--accent-color);
-}
-.nav-icon[data-v-f48afcd2] {
- font-size: 12px; /* 从18px缩小到12px(缩小三分之一) */
- margin-right: 12px;
- width: 16px; /* 从20px缩小到16px */
- text-align: center;
-}
-.nav-text[data-v-f48afcd2] {
- flex: 1;
-}
-.favorite-btn[data-v-f48afcd2] {
- background: none;
- border: none;
- font-size: 12px; /* 从14px缩小到12px,与图标保持一致 */
- cursor: pointer;
- opacity: 0.3;
- transition: opacity 0.2s;
- padding: 2px; /* 添加内边距 */
-}
-.favorite-btn[data-v-f48afcd2]:hover,
-.favorite-btn.active[data-v-f48afcd2] {
- opacity: 1;
-}
-
-/* 右侧内容区域 */
-.content-area[data-v-f48afcd2] {
- flex: 1;
- display: flex;
- flex-direction: column;
- overflow: hidden; /* 隐藏所有滚动条 */
- /* 高度由flex自动计算 */
-}
-
-/* 内容选项卡 */
-.content-tabs[data-v-f48afcd2] {
- background: var(--tab-bg);
- border-bottom: 1px solid var(--border-color);
- padding: 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- height: 32px;
- overflow-x: auto;
- overflow-y: hidden; /* 确保垂直方向不滚动 */
-}
-.tab-list[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- flex: 1;
- overflow-x: auto;
- overflow-y: hidden; /* 确保垂直方向不滚动 */
- height: 100%; /* 限制高度 */
-}
-.tab-item[data-v-f48afcd2] {
- padding: 6px 16px;
- background: transparent;
- border: none;
- border-right: 1px solid var(--border-color);
- cursor: pointer;
- font-size: 13px;
- color: var(--text-secondary);
- transition: all 0.2s;
- white-space: nowrap;
- display: flex;
- align-items: center;
- gap: 6px;
- height: 100%; /* 确保高度填满容器 */
- min-width: 120px;
- justify-content: center;
- position: relative;
- box-sizing: border-box; /* 确保padding不会增加总高度 */
-}
-.tab-item[data-v-f48afcd2]:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-.tab-item.active[data-v-f48afcd2] {
- background: var(--tab-active-bg);
- color: var(--tab-active-text);
- border-bottom: 2px solid var(--tab-active-bg);
- font-weight: 500;
-}
-.tab-item .tab-close[data-v-f48afcd2] {
- width: 16px;
- height: 16px;
- border: none;
- background: transparent;
- color: #6c757d;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 12px;
- font-weight: bold;
- transition: all 0.2s;
- margin-left: 4px;
- border-radius: 0;
- line-height: 1;
-}
-.tab-item .tab-close[data-v-f48afcd2]:hover {
- color: #dc3545;
- background: transparent;
- transform: none;
-}
-
-/* 活动状态的选项卡关闭图标使用浅色 */
-.tab-item.active .tab-close[data-v-f48afcd2] {
- color: #ffffff;
-}
-.tab-item.active .tab-close[data-v-f48afcd2]:hover {
- color: #ffcccc;
-}
-.tab-title[data-v-f48afcd2] {
- flex: 1;
- text-align: center;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-.tab-close[data-v-f48afcd2] {
- background: none;
- border: none;
- font-size: 16px;
- cursor: pointer;
- color: #999;
- padding: 2px;
- border-radius: 2px;
- transition: all 0.2s;
-}
-.tab-close[data-v-f48afcd2]:hover {
- background: #f0f0f0;
- color: #666;
-}
-.tab-actions[data-v-f48afcd2] {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- padding-right: 10px;
- flex-shrink: 0;
- height: 100%; /* 确保高度一致 */
-}
-.close-all-btn[data-v-f48afcd2] {
- background: none;
- border: none;
- font-size: 16px;
- cursor: pointer;
- color: #999;
- padding: 4px;
- border-radius: 3px;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- justify-content: center;
- width: 24px;
- height: 24px; /* 确保按钮高度合适 */
- margin-left: 8px;
- box-sizing: border-box; /* 确保padding不会增加总高度 */
-}
-.close-all-btn[data-v-f48afcd2]:hover {
- background: #e9ecef;
- color: #495057;
-}
-.close-all-icon[data-v-f48afcd2] {
- font-size: 14px;
- font-weight: bold;
- line-height: 1;
-}
-
-/* 功能内容区 */
-.content-body[data-v-f48afcd2] {
- flex: 1;
- overflow-y: auto; /* 只有内容区有垂直滚动条 */
- overflow-x: hidden; /* 隐藏水平滚动条 */
- background: var(--header-bg);
- position: relative;
- /* 高度由flex自动计算 */
-}
-
-
-
-/* 确保内容可以滚动 */
-.content-body[data-v-f48afcd2] > * {
- /* 移除强制的最小高度,让内容自然流动 */
- overflow: visible;
-}
-
-/* 登录按钮样式 */
-.login-section[data-v-f48afcd2] {
- display: flex;
- align-items: center;
-}
-.login-btn[data-v-f48afcd2] {
- background: var(--primary-color);
- color: white;
- border: none;
- padding: 8px 16px;
- border-radius: 6px;
- font-size: 14px;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- gap: 6px;
-}
-
-/* 深色主题下的登录按钮样式 */
-.theme-dark .login-btn[data-v-f48afcd2] {
- background: var(--primary-color);
- color: #333333;
- border: 1px solid rgba(255, 255, 255, 0.1);
-}
-.theme-dark .login-btn[data-v-f48afcd2]:hover {
- background: var(--primary-hover);
- color: #222222;
-}
-.login-btn[data-v-f48afcd2]:hover {
- background: var(--primary-hover);
- transform: translateY(-1px);
- box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3);
-}
-.login-btn .icon[data-v-f48afcd2] {
- font-size: 16px;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.sidebar[data-v-f48afcd2] {
- width: 200px;
-}
-.header[data-v-f48afcd2] {
- padding: 0 15px;
-}
-.logo h1[data-v-f48afcd2] {
- font-size: 20px;
-}
-.breadcrumb[data-v-f48afcd2] {
- display: none;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=style&index=0&id=74335f1d&scoped=true&lang=css":
-/*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=style&index=0&id=74335f1d&scoped=true&lang=css ***!
- \*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.status-bar[data-v-74335f1d] {
- position: fixed;
- bottom: 0;
- left: 0;
- right: 0;
- height: 24px;
- background-color: #333;
- color: #fff;
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 0 10px;
- font-size: 11px;
- border-top: 1px solid #444;
- z-index: 1000;
- /* 添加中文字体支持 */
- font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif;
- /* 添加响应式支持 */
- min-width: 800px; /* 设置最小宽度 */
-}
-.status-left[data-v-74335f1d] {
- display: flex;
- align-items: center;
-}
-.status-right[data-v-74335f1d] {
- display: flex;
- align-items: center;
- gap: 10px; /* 使用gap替代margin-right */
- flex-wrap: nowrap; /* 防止换行 */
-}
-.status-item[data-v-74335f1d] {
- margin-right: 15px;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- max-width: none; /* 移除最大宽度限制 */
- flex-shrink: 0; /* 防止收缩 */
-}
-
-/* 为服务地址项添加特殊样式 */
-.status-item[data-v-74335f1d]:contains("服务地址") {
- min-width: 120px; /* 设置最小宽度 */
- max-width: 200px; /* 设置最大宽度 */
-}
-.status-item[data-v-74335f1d]:last-child {
- margin-right: 0;
-}
-
- /* 错误链接样式 */
-.error-link[data-v-74335f1d] {
- cursor: pointer;
- text-decoration: underline;
- color: #ff6b6b;
- transition: color 0.2s ease;
-}
-.error-link[data-v-74335f1d]:hover {
- color: #ff8e8e;
-}
-
-/* 响应式设计 */
-@media (max-width: 1200px) {
-.status-bar[data-v-74335f1d] {
- padding: 0 8px;
- font-size: 10px;
-}
-.status-item[data-v-74335f1d] {
- margin-right: 10px;
-}
-.status-right[data-v-74335f1d] {
- gap: 8px;
-}
-}
-@media (max-width: 1000px) {
-.status-bar[data-v-74335f1d] {
- padding: 0 6px;
- font-size: 9px;
-}
-.status-item[data-v-74335f1d] {
- margin-right: 8px;
-}
-.status-right[data-v-74335f1d] {
- gap: 6px;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=style&index=0&id=4ef284fa&scoped=true&lang=css":
-/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=style&index=0&id=4ef284fa&scoped=true&lang=css ***!
- \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.toast[data-v-4ef284fa] {
- position: fixed;
- top: 20px;
- right: 20px;
- background: var(--bg-primary);
- border: 1px solid var(--border-color);
- border-radius: 8px;
- padding: 16px;
- min-width: 300px;
- max-width: 400px;
- box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
- z-index: 10000;
- display: flex;
- align-items: flex-start;
- gap: 12px;
-}
-.toast.success[data-v-4ef284fa] {
- border-left: 4px solid #4caf50;
-}
-.toast.error[data-v-4ef284fa] {
- border-left: 4px solid #f44336;
-}
-.toast.warning[data-v-4ef284fa] {
- border-left: 4px solid #ff9800;
-}
-.toast.info[data-v-4ef284fa] {
- border-left: 4px solid #2196f3;
-}
-.toast-icon[data-v-4ef284fa] {
- font-size: 20px;
- flex-shrink: 0;
-}
-.toast-content[data-v-4ef284fa] {
- flex: 1;
- min-width: 0;
-}
-.toast-title[data-v-4ef284fa] {
- font-weight: 600;
- color: var(--text-primary);
- margin-bottom: 4px;
- font-size: 14px;
-}
-.toast-message[data-v-4ef284fa] {
- color: var(--text-secondary);
- font-size: 13px;
- line-height: 1.4;
-}
-.toast-close[data-v-4ef284fa] {
- background: none;
- border: none;
- color: var(--text-secondary);
- font-size: 18px;
- cursor: pointer;
- padding: 2px;
- border-radius: 4px;
- transition: all 0.2s;
- flex-shrink: 0;
-}
-.toast-close[data-v-4ef284fa]:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-
-/* 动画 */
-.toast-enter-active[data-v-4ef284fa],
-.toast-leave-active[data-v-4ef284fa] {
- transition: all 0.3s ease;
-}
-.toast-enter-from[data-v-4ef284fa] {
- opacity: 0;
- transform: translateX(100%);
-}
-.toast-leave-to[data-v-4ef284fa] {
- opacity: 0;
- transform: translateX(100%);
-}
-
-/* 响应式 */
-@media (max-width: 480px) {
-.toast[data-v-4ef284fa] {
- left: 20px;
- right: 20px;
- min-width: auto;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=style&index=0&id=1ac2098a&scoped=true&lang=css":
-/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=style&index=0&id=1ac2098a&scoped=true&lang=css ***!
- \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.config-test[data-v-1ac2098a] {
- padding: 20px;
- height: 100%;
- overflow-y: auto;
-}
-.page-header[data-v-1ac2098a] {
- margin-bottom: 30px;
-}
-.page-header h2[data-v-1ac2098a] {
- margin: 0;
- color: var(--text-primary);
- font-size: 24px;
-}
-.config-content[data-v-1ac2098a] {
- max-width: 800px;
-}
-.config-section[data-v-1ac2098a] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 24px;
- margin-bottom: 24px;
- box-shadow: 0 2px 8px var(--shadow-color);
-}
-.config-section h3[data-v-1ac2098a] {
- margin: 0 0 20px 0;
- color: var(--text-primary);
- font-size: 18px;
- border-bottom: 2px solid var(--border-color);
- padding-bottom: 8px;
-}
-.config-item[data-v-1ac2098a] {
- display: flex;
- justify-content: space-between;
- margin-bottom: 16px;
- padding: 12px 0;
- border-bottom: 1px solid var(--border-color);
-}
-.config-item[data-v-1ac2098a]:last-child {
- border-bottom: none;
- margin-bottom: 0;
-}
-.config-item label[data-v-1ac2098a] {
- font-weight: 500;
- color: var(--text-primary);
- min-width: 150px;
-}
-.config-item span[data-v-1ac2098a] {
- color: var(--text-secondary);
- font-family: monospace;
- word-break: break-all;
-}
-.priority-list[data-v-1ac2098a] {
- display: flex;
- flex-direction: column;
- gap: 16px;
-}
-.priority-item[data-v-1ac2098a] {
- display: flex;
- align-items: center;
- gap: 16px;
-}
-.priority-number[data-v-1ac2098a] {
- background: var(--accent-color);
- color: white;
- width: 24px;
- height: 24px;
- border-radius: 50%;
- display: flex;
- align-items: center;
- justify-content: center;
- font-weight: bold;
- font-size: 14px;
-}
-.priority-text[data-v-1ac2098a] {
- color: var(--text-primary);
- font-size: 16px;
-}
-button[data-v-1ac2098a] {
- background: var(--button-bg);
- color: var(--button-text);
- border: none;
- padding: 12px 24px;
- border-radius: 6px;
- cursor: pointer;
- font-size: 16px;
- transition: background-color 0.2s ease;
-}
-button[data-v-1ac2098a]:hover:not(:disabled) {
- background: var(--button-hover);
-}
-button[data-v-1ac2098a]:disabled {
- opacity: 0.6;
- cursor: not-allowed;
-}
-.test-result[data-v-1ac2098a] {
- margin-top: 16px;
- padding: 16px;
- border-radius: 6px;
- background: var(--bg-secondary);
-}
-.test-result .success[data-v-1ac2098a] {
- color: #4caf50;
- margin: 0;
-}
-.test-result .error[data-v-1ac2098a] {
- color: #f44336;
- margin: 0;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=style&index=0&id=15b21c75&scoped=true&lang=css":
-/*!*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=style&index=0&id=15b21c75&scoped=true&lang=css ***!
- \*********************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.home[data-v-15b21c75] {
- background: var(--bg-primary);
- color: var(--text-primary);
- padding: 2rem;
- /* 移除强制的高度设置,让内容自然流动 */
- /* 添加中文字体支持 */
- font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif;
-}
-
-/* 深色主题时使用更暗的渐变背景 */
-.theme-dark .home[data-v-15b21c75] {
- background: linear-gradient(135deg, #1f3a6b 0%, #2d4a8a 100%);
-}
-
-/* 浅色主题时的样式调整 */
-.theme-light .home[data-v-15b21c75] {
- background: var(--bg-primary);
-}
-.theme-light .welcome-card[data-v-15b21c75],
-.theme-light .feature-card[data-v-15b21c75],
-.theme-light .todo-section[data-v-15b21c75],
-.theme-light .recent-section[data-v-15b21c75] {
- box-shadow: 0 4px 12px var(--shadow-color);
-}
-
-/* 主要内容区域 */
-.main-content[data-v-15b21c75] {
- max-width: 1200px;
- margin: 0 auto;
- display: flex;
- flex-direction: column;
- gap: 2rem;
- /* 移除强制的最小高度,让内容自然流动 */
-}
-
-/* 欢迎区域 */
-.welcome-section[data-v-15b21c75] {
- text-align: center;
- margin-bottom: 2rem;
-}
-.welcome-card[data-v-15b21c75] {
- background: var(--card-bg);
- backdrop-filter: blur(10px);
- border-radius: 20px;
- padding: 3rem 2rem;
- border: 1px solid var(--border-color);
-}
-.welcome-card h2[data-v-15b21c75] {
- font-size: 2.5rem;
- margin-bottom: 1rem;
- font-weight: 300;
-}
-.subtitle[data-v-15b21c75] {
- font-size: 1.2rem;
- margin-bottom: 2rem;
- opacity: 0.9;
-}
-.quick-stats[data-v-15b21c75] {
- display: flex;
- justify-content: center;
- gap: 3rem;
- margin-top: 2rem;
-}
-.stat-item[data-v-15b21c75] {
- text-align: center;
-}
-.stat-number[data-v-15b21c75] {
- display: block;
- font-size: 2rem;
- font-weight: bold;
- color: #ffd700;
-}
-.stat-label[data-v-15b21c75] {
- font-size: 0.9rem;
- opacity: 0.8;
-}
-
-/* 功能卡片区域 */
-.features-section[data-v-15b21c75] {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
- gap: 1.5rem;
- margin-bottom: 2rem;
-}
-.feature-card[data-v-15b21c75] {
- background: var(--card-bg);
- backdrop-filter: blur(10px);
- border-radius: 15px;
- padding: 2rem;
- text-align: center;
- cursor: pointer;
- transition: all 0.3s ease;
- border: 1px solid var(--border-color);
-}
-.feature-card[data-v-15b21c75]:hover {
- transform: translateY(-5px);
- background: var(--bg-secondary);
- box-shadow: 0 10px 30px var(--shadow-color);
-}
-.feature-icon[data-v-15b21c75] {
- font-size: 3rem;
- margin-bottom: 1rem;
-}
-.feature-card h3[data-v-15b21c75] {
- font-size: 1.3rem;
- margin-bottom: 0.5rem;
-}
-.feature-card p[data-v-15b21c75] {
- opacity: 0.8;
- line-height: 1.5;
-}
-
-/* 待办事项区域 */
-.todo-section[data-v-15b21c75] {
- background: var(--card-bg);
- backdrop-filter: blur(10px);
- border-radius: 15px;
- padding: 2rem;
- margin-bottom: 2rem;
- border: 1px solid var(--border-color);
-}
-.section-header[data-v-15b21c75] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 1rem;
-}
-.section-header h3[data-v-15b21c75] {
- margin: 0;
-}
-.add-todo-btn[data-v-15b21c75] {
- background: var(--button-bg);
- color: var(--button-text);
- border: none;
- padding: 0.5rem 1rem;
- border-radius: 20px;
- cursor: pointer;
- transition: background 0.3s ease;
-}
-.add-todo-btn[data-v-15b21c75]:hover {
- background: var(--button-hover);
-}
-.todo-list[data-v-15b21c75] {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
-}
-.todo-item[data-v-15b21c75] {
- display: flex;
- align-items: center;
- gap: 1rem;
- padding: 0.75rem;
- background: var(--bg-secondary);
- border-radius: 10px;
- transition: all 0.3s ease;
-}
-.todo-item[data-v-15b21c75]:hover {
- background: var(--bg-tertiary);
-}
-.todo-item.completed .todo-text[data-v-15b21c75] {
- text-decoration: line-through;
- opacity: 0.6;
-}
-.todo-text[data-v-15b21c75] {
- flex: 1;
-}
-.todo-date[data-v-15b21c75] {
- color: var(--text-secondary);
- font-size: 0.9rem;
-}
-.delete-btn[data-v-15b21c75] {
- background: none;
- border: none;
- cursor: pointer;
- font-size: 1rem;
- opacity: 0.7;
- transition: opacity 0.3s ease;
-}
-.delete-btn[data-v-15b21c75]:hover {
- opacity: 1;
-}
-
-/* 最近活动区域 */
-.recent-section[data-v-15b21c75] {
- background: var(--card-bg);
- backdrop-filter: blur(10px);
- border-radius: 15px;
- padding: 2rem;
- border: 1px solid var(--border-color);
-}
-.recent-section h3[data-v-15b21c75] {
- margin-bottom: 1.5rem;
-}
-.activity-list[data-v-15b21c75] {
- display: flex;
- flex-direction: column;
- gap: 1rem;
-}
-.activity-item[data-v-15b21c75] {
- display: flex;
- align-items: center;
- gap: 1rem;
- padding: 0.75rem;
- background: var(--bg-secondary);
- border-radius: 10px;
-}
-.activity-icon[data-v-15b21c75] {
- font-size: 1.5rem;
-}
-.activity-content[data-v-15b21c75] {
- flex: 1;
-}
-.activity-title[data-v-15b21c75] {
- font-weight: 500;
-}
-.activity-time[data-v-15b21c75] {
- color: var(--text-secondary);
- font-size: 0.9rem;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.home[data-v-15b21c75] {
- padding: 1rem;
-}
-.main-content[data-v-15b21c75] {
- gap: 1.5rem;
-}
-.welcome-card[data-v-15b21c75] {
- padding: 2rem 1rem;
-}
-.welcome-card h2[data-v-15b21c75] {
- font-size: 2rem;
-}
-.quick-stats[data-v-15b21c75] {
- flex-direction: column;
- gap: 1rem;
-}
-.features-section[data-v-15b21c75] {
- grid-template-columns: 1fr;
-}
-.todo-section[data-v-15b21c75],
- .recent-section[data-v-15b21c75] {
- padding: 1.5rem;
-}
-}
-
- /* 欢迎页面登录相关样式 */
-.welcome-header[data-v-15b21c75] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- gap: 2rem;
-}
-.welcome-text[data-v-15b21c75] {
- flex: 1;
-}
-.login-section[data-v-15b21c75] {
- flex-shrink: 0;
-}
-.login-btn[data-v-15b21c75] {
- background: var(--accent-color);
- color: white;
- border: none;
- padding: 1rem 2rem;
- border-radius: 25px;
- font-size: 1.1rem;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.3s ease;
- display: flex;
- align-items: center;
- gap: 0.5rem;
-}
-.login-btn[data-v-15b21c75]:hover {
- background: var(--accent-hover);
- transform: translateY(-2px);
- box-shadow: 0 8px 25px var(--shadow-color);
-}
-.login-prompt-section[data-v-15b21c75] {
- text-align: center;
- margin-bottom: 2rem;
-}
-.login-prompt-card[data-v-15b21c75] {
- background: var(--card-bg);
- backdrop-filter: blur(10px);
- border-radius: 20px;
- padding: 3rem 2rem;
- border: 1px solid var(--border-color);
- max-width: 500px;
- margin: 0 auto;
-}
-.prompt-icon[data-v-15b21c75] {
- font-size: 4rem;
- margin-bottom: 1rem;
- opacity: 0.8;
-}
-.login-prompt-card h3[data-v-15b21c75] {
- font-size: 1.5rem;
- margin-bottom: 1rem;
- color: var(--text-primary);
-}
-.login-prompt-card p[data-v-15b21c75] {
- font-size: 1.1rem;
- margin-bottom: 2rem;
- opacity: 0.8;
- color: var(--text-secondary);
-}
-.prompt-login-btn[data-v-15b21c75] {
- background: var(--accent-color);
- color: white;
- border: none;
- padding: 1rem 2rem;
- border-radius: 25px;
- font-size: 1.1rem;
- font-weight: 500;
- cursor: pointer;
- transition: all 0.3s ease;
- display: flex;
- align-items: center;
- gap: 0.5rem;
- margin: 0 auto;
-}
-.prompt-login-btn[data-v-15b21c75]:hover {
- background: var(--accent-hover);
- transform: translateY(-2px);
- box-shadow: 0 8px 25px var(--shadow-color);
-}
-
-/* 深色主题下登录按钮的字体颜色 */
-.theme-dark .login-btn[data-v-15b21c75],
-.theme-dark .prompt-login-btn[data-v-15b21c75] {
- color: #000000 !important;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=style&index=0&id=de6ba976&scoped=true&lang=css":
-/*!**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=style&index=0&id=de6ba976&scoped=true&lang=css ***!
- \**************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.permission-manager[data-v-de6ba976] {
- /* 组件样式 */
-}
-.permission-content[data-v-de6ba976] {
- max-height: 500px;
- overflow-y: auto;
-}
-.role-info[data-v-de6ba976] {
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 1px solid var(--border-color);
-}
-.role-info h4[data-v-de6ba976] {
- margin: 0 0 8px 0;
- color: var(--text-primary);
-}
-.role-description[data-v-de6ba976] {
- margin: 0;
- color: var(--text-secondary);
- font-size: 14px;
-}
-.permission-tree-container[data-v-de6ba976] {
- max-height: 400px;
- overflow-y: auto;
- border: 1px solid var(--border-color);
- border-radius: 4px;
- padding: 10px;
-}
-.permission-tree[data-v-de6ba976] {
- display: flex;
- flex-direction: column;
- gap: 15px;
-}
-.resource-group[data-v-de6ba976] {
- border: 1px solid var(--border-color);
- border-radius: 4px;
- overflow: hidden;
-}
-.resource-header[data-v-de6ba976] {
- background: var(--bg-secondary);
- padding: 10px;
- border-bottom: 1px solid var(--border-color);
-}
-.resource-label[data-v-de6ba976] {
- display: flex;
- align-items: center;
- gap: 8px;
- cursor: pointer;
- font-weight: 600;
- color: var(--text-primary);
-}
-.resource-name[data-v-de6ba976] {
- font-size: 14px;
-}
-.permission-list[data-v-de6ba976] {
- padding: 10px;
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-.permission-item[data-v-de6ba976] {
- display: flex;
- align-items: center;
- gap: 8px;
- cursor: pointer;
- padding: 4px 0;
-}
-.permission-item[data-v-de6ba976]:hover {
- background: var(--bg-secondary);
- border-radius: 4px;
- padding: 4px 8px;
- margin: 0 -8px;
-}
-.permission-name[data-v-de6ba976] {
- font-size: 13px;
- color: var(--text-primary);
-}
-input[type="checkbox"][data-v-de6ba976] {
- width: 16px;
- height: 16px;
- cursor: pointer;
-}
-.modal-overlay[data-v-de6ba976] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
-}
-.modal[data-v-de6ba976] {
- background: var(--card-bg);
- border-radius: 8px;
- width: 90%;
- max-width: 700px;
- max-height: 90vh;
- overflow: hidden;
- display: flex;
- flex-direction: column;
-}
-.modal-header[data-v-de6ba976] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px;
- border-bottom: 1px solid var(--border-color);
-}
-.modal-header h3[data-v-de6ba976] {
- margin: 0;
- color: var(--text-primary);
-}
-.close-btn[data-v-de6ba976] {
- background: none;
- border: none;
- font-size: 24px;
- cursor: pointer;
- color: var(--text-muted);
-}
-.modal-body[data-v-de6ba976] {
- padding: 20px;
- flex: 1;
- overflow-y: auto;
-}
-.modal-footer[data-v-de6ba976] {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
- padding: 20px;
- border-top: 1px solid var(--border-color);
-}
-.btn[data-v-de6ba976] {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- transition: all 0.2s;
-}
-.btn-primary[data-v-de6ba976] {
- background: var(--accent-color);
- color: white;
-}
-.btn-primary[data-v-de6ba976]:hover:not(:disabled) {
- background: var(--accent-hover);
-}
-.btn-secondary[data-v-de6ba976] {
- background: #757575;
- color: white;
-}
-.btn-secondary[data-v-de6ba976]:hover {
- background: #616161;
-}
-.btn[data-v-de6ba976]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=style&index=0&id=7f7c6d92&scoped=true&lang=css":
-/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=style&index=0&id=7f7c6d92&scoped=true&lang=css ***!
- \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.user-role-assignment[data-v-7f7c6d92] {
- /* 组件样式 */
-}
-.assignment-content[data-v-7f7c6d92] {
- max-height: 500px;
- overflow-y: auto;
-}
-.user-info[data-v-7f7c6d92] {
- margin-bottom: 20px;
- padding-bottom: 15px;
- border-bottom: 1px solid var(--border-color);
-}
-.user-info h4[data-v-7f7c6d92] {
- margin: 0 0 8px 0;
- color: var(--text-primary);
-}
-.user-email[data-v-7f7c6d92] {
- margin: 0;
- color: var(--text-secondary);
- font-size: 14px;
-}
-.role-assignment[data-v-7f7c6d92] {
- margin-top: 20px;
-}
-.available-roles h5[data-v-7f7c6d92] {
- margin: 0 0 15px 0;
- color: var(--text-primary);
-}
-.transfer-container[data-v-7f7c6d92] {
- display: flex;
- align-items: stretch;
- gap: 20px;
- height: 400px;
-}
-.transfer-panel[data-v-7f7c6d92] {
- flex: 1;
- border: 1px solid var(--border-color);
- border-radius: 4px;
- display: flex;
- flex-direction: column;
-}
-.panel-header[data-v-7f7c6d92] {
- background: var(--bg-secondary);
- padding: 10px;
- border-bottom: 1px solid var(--border-color);
- font-weight: 600;
- color: var(--text-primary);
-}
-.panel-body[data-v-7f7c6d92] {
- flex: 1;
- overflow-y: auto;
- padding: 10px;
-}
-.role-list[data-v-7f7c6d92] {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-.role-item[data-v-7f7c6d92] {
- padding: 8px;
- border: 1px solid var(--border-color);
- border-radius: 4px;
- cursor: pointer;
- transition: all 0.2s;
-}
-.role-item[data-v-7f7c6d92]:hover {
- background: var(--bg-secondary);
- border-color: var(--accent-color);
-}
-.role-name[data-v-7f7c6d92] {
- display: block;
- font-weight: 500;
- color: var(--text-primary);
- margin-bottom: 4px;
-}
-.role-description[data-v-7f7c6d92] {
- display: block;
- font-size: 12px;
- color: var(--text-secondary);
-}
-.transfer-actions[data-v-7f7c6d92] {
- display: flex;
- flex-direction: column;
- justify-content: center;
- gap: 10px;
-}
-.transfer-actions .btn[data-v-7f7c6d92] {
- width: 40px;
- height: 40px;
- display: flex;
- align-items: center;
- justify-content: center;
- font-size: 18px;
-}
-.modal-overlay[data-v-7f7c6d92] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
-}
-.modal[data-v-7f7c6d92] {
- background: var(--card-bg);
- border-radius: 8px;
- width: 90%;
- max-width: 800px;
- max-height: 90vh;
- overflow: hidden;
- display: flex;
- flex-direction: column;
-}
-.modal-header[data-v-7f7c6d92] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px;
- border-bottom: 1px solid var(--border-color);
-}
-.modal-header h3[data-v-7f7c6d92] {
- margin: 0;
- color: var(--text-primary);
-}
-.close-btn[data-v-7f7c6d92] {
- background: none;
- border: none;
- font-size: 24px;
- cursor: pointer;
- color: var(--text-muted);
-}
-.modal-body[data-v-7f7c6d92] {
- padding: 20px;
- flex: 1;
- overflow-y: auto;
-}
-.modal-footer[data-v-7f7c6d92] {
- display: flex;
- justify-content: flex-end;
- gap: 10px;
- padding: 20px;
- border-top: 1px solid var(--border-color);
-}
-.btn[data-v-7f7c6d92] {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- transition: all 0.2s;
-}
-.btn-primary[data-v-7f7c6d92] {
- background: var(--accent-color);
- color: white;
-}
-.btn-primary[data-v-7f7c6d92]:hover:not(:disabled) {
- background: var(--accent-hover);
-}
-.btn-secondary[data-v-7f7c6d92] {
- background: #757575;
- color: white;
-}
-.btn-secondary[data-v-7f7c6d92]:hover {
- background: #616161;
-}
-.btn-sm[data-v-7f7c6d92] {
- padding: 6px 12px;
- font-size: 12px;
-}
-.btn[data-v-7f7c6d92]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=style&index=0&id=77b697b6&scoped=true&lang=css":
-/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=style&index=0&id=77b697b6&scoped=true&lang=css ***!
- \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.role-api-test[data-v-77b697b6] {
- padding: 20px;
- height: 100%;
- overflow-y: auto;
-}
-.page-header[data-v-77b697b6] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-.page-header h2[data-v-77b697b6] {
- margin: 0;
- color: var(--text-primary);
-}
-.header-actions[data-v-77b697b6] {
- display: flex;
- gap: 12px;
- align-items: center;
-}
-.test-content[data-v-77b697b6] {
- max-width: 1200px;
-}
-.test-section[data-v-77b697b6] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 24px;
- margin-bottom: 24px;
- box-shadow: 0 2px 8px var(--shadow-color);
-}
-.test-section h3[data-v-77b697b6] {
- margin: 0 0 20px 0;
- color: var(--text-primary);
- font-size: 18px;
- border-bottom: 2px solid var(--border-color);
- padding-bottom: 8px;
-}
-.config-info[data-v-77b697b6] {
- display: grid;
- gap: 12px;
-}
-.config-item[data-v-77b697b6] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 12px;
- background: var(--bg-secondary);
- border-radius: 4px;
-}
-.config-item label[data-v-77b697b6] {
- font-weight: 500;
- color: var(--text-primary);
-}
-.config-item span[data-v-77b697b6] {
- color: var(--text-secondary);
- font-family: monospace;
-}
-.test-mode[data-v-77b697b6] {
- color: #ff9800 !important;
- font-weight: bold;
-}
-.prod-mode[data-v-77b697b6] {
- color: #4caf50 !important;
- font-weight: bold;
-}
-.test-results[data-v-77b697b6] {
- max-height: 400px;
- overflow-y: auto;
-}
-.test-result-item[data-v-77b697b6] {
- margin-bottom: 16px;
- padding: 16px;
- border-radius: 6px;
- border-left: 4px solid;
-}
-.test-result-item.success[data-v-77b697b6] {
- background: rgba(76, 175, 80, 0.1);
- border-left-color: #4caf50;
-}
-.test-result-item.error[data-v-77b697b6] {
- background: rgba(244, 67, 54, 0.1);
- border-left-color: #f44336;
-}
-.test-result-item.warning[data-v-77b697b6] {
- background: rgba(255, 152, 0, 0.1);
- border-left-color: #ff9800;
-}
-.test-header[data-v-77b697b6] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 8px;
-}
-.test-name[data-v-77b697b6] {
- font-weight: 500;
- color: var(--text-primary);
-}
-.test-status[data-v-77b697b6] {
- font-size: 12px;
- padding: 4px 8px;
- border-radius: 4px;
- font-weight: 500;
-}
-.test-result-item.success .test-status[data-v-77b697b6] {
- background: #4caf50;
- color: white;
-}
-.test-result-item.error .test-status[data-v-77b697b6] {
- background: #f44336;
- color: white;
-}
-.test-result-item.warning .test-status[data-v-77b697b6] {
- background: #ff9800;
- color: white;
-}
-.test-message[data-v-77b697b6] {
- color: var(--text-secondary);
- margin-bottom: 8px;
-}
-.test-data[data-v-77b697b6] {
- background: var(--bg-secondary);
- padding: 12px;
- border-radius: 4px;
- overflow-x: auto;
-}
-.test-data pre[data-v-77b697b6] {
- margin: 0;
- font-size: 12px;
- color: var(--text-secondary);
-}
-.manual-tests[data-v-77b697b6] {
- display: grid;
- gap: 24px;
-}
-.test-group[data-v-77b697b6] {
- padding: 16px;
- background: var(--bg-secondary);
- border-radius: 6px;
-}
-.test-group h4[data-v-77b697b6] {
- margin: 0 0 16px 0;
- color: var(--text-primary);
-}
-.form-group[data-v-77b697b6] {
- margin-bottom: 12px;
-}
-.form-group label[data-v-77b697b6] {
- display: block;
- margin-bottom: 4px;
- font-weight: 500;
- color: var(--text-primary);
-}
-.form-group input[data-v-77b697b6] {
- width: 100%;
- padding: 8px 12px;
- border: 1px solid var(--border-color);
- border-radius: 4px;
- background: var(--input-bg);
- color: var(--input-text);
- box-sizing: border-box;
-}
-.btn[data-v-77b697b6] {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- display: inline-flex;
- align-items: center;
- gap: 6px;
- transition: all 0.2s;
-}
-.btn-primary[data-v-77b697b6] {
- background: var(--accent-color);
- color: white;
-}
-.btn-primary[data-v-77b697b6]:hover {
- background: var(--accent-hover);
-}
-.btn-secondary[data-v-77b697b6] {
- background: #757575;
- color: white;
-}
-.btn-secondary[data-v-77b697b6]:hover {
- background: #616161;
-}
-.btn[data-v-77b697b6]:hover {
- opacity: 0.9;
-}
-.btn[data-v-77b697b6]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-button[data-v-77b697b6] {
- background: var(--accent-color);
- color: white;
- border: none;
- padding: 8px 16px;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- transition: all 0.2s;
-}
-button[data-v-77b697b6]:hover:not(:disabled) {
- background: var(--accent-hover);
-}
-button[data-v-77b697b6]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=style&index=0&id=03643bfa&scoped=true&lang=css":
-/*!******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=style&index=0&id=03643bfa&scoped=true&lang=css ***!
- \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.role-management[data-v-03643bfa] {
- padding: 20px;
-}
-.page-header[data-v-03643bfa] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-.page-header h2[data-v-03643bfa] {
- margin: 0;
- color: var(--text-primary);
-}
-.header-actions[data-v-03643bfa] {
- display: flex;
- gap: 12px;
- align-items: center;
-}
-.role-list[data-v-03643bfa] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 20px;
- box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
-}
-.loading[data-v-03643bfa] {
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- padding: 40px;
- color: var(--text-secondary);
- gap: 10px;
-}
-.loading i[data-v-03643bfa] {
- font-size: 24px;
- color: var(--accent-color);
-}
-.empty-state[data-v-03643bfa] {
- text-align: center;
- padding: 40px;
- color: var(--text-secondary);
-}
-.empty-state p[data-v-03643bfa] {
- margin-bottom: 20px;
- font-size: 16px;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
-}
-.empty-state i[data-v-03643bfa] {
- font-size: 18px;
- color: var(--text-muted);
-}
-table[data-v-03643bfa] {
- width: 100%;
- border-collapse: collapse;
- margin-bottom: 20px;
-}
-th[data-v-03643bfa], td[data-v-03643bfa] {
- padding: 12px;
- text-align: left;
- border-bottom: 1px solid var(--border-color);
-}
-th[data-v-03643bfa] {
- background: var(--bg-secondary);
- font-weight: 600;
- color: var(--text-primary);
-}
-.actions[data-v-03643bfa] {
- display: flex;
- gap: 8px;
-}
-.btn[data-v-03643bfa] {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- display: inline-flex;
- align-items: center;
- gap: 6px;
- transition: all 0.2s;
-}
-.btn-primary[data-v-03643bfa] {
- background: var(--accent-color);
- color: white;
-}
-.btn-primary[data-v-03643bfa]:hover {
- background: var(--accent-hover);
-}
-.btn-secondary[data-v-03643bfa] {
- background: #757575;
- color: white;
-}
-.btn-secondary[data-v-03643bfa]:hover {
- background: #616161;
-}
-.btn-info[data-v-03643bfa] {
- background: #0288d1;
- color: white;
-}
-.btn-danger[data-v-03643bfa] {
- background: #d32f2f;
- color: white;
-}
-.btn-sm[data-v-03643bfa] {
- padding: 6px 12px;
- font-size: 12px;
-}
-
-/* 表格操作按钮样式优化 */
-.actions .btn-sm[data-v-03643bfa] {
- background: none;
- border: none;
- padding: 4px 8px;
- margin: 0 2px;
- color: var(--text-primary);
- transition: all 0.2s;
-}
-.actions .btn-sm[data-v-03643bfa]:hover {
- background: var(--bg-secondary);
- color: var(--accent-color);
- transform: scale(1.1);
-}
-.actions .btn-sm.btn-info[data-v-03643bfa]:hover {
- color: #2196f3;
-}
-.actions .btn-sm.btn-danger[data-v-03643bfa]:hover {
- color: #d32f2f;
-}
-.btn[data-v-03643bfa]:hover {
- opacity: 0.9;
-}
-.btn[data-v-03643bfa]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-.pagination[data-v-03643bfa] {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 20px;
-}
-.page-info[data-v-03643bfa] {
- color: var(--text-secondary);
- font-size: 14px;
-}
-.modal-overlay[data-v-03643bfa] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
-}
-.modal[data-v-03643bfa] {
- background: var(--card-bg);
- border-radius: 8px;
- width: 90%;
- max-width: 500px;
- max-height: 90vh;
- overflow-y: auto;
- box-sizing: border-box;
-}
-.modal-header[data-v-03643bfa] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px;
- border-bottom: 1px solid var(--border-color);
-}
-.modal-header h3[data-v-03643bfa] {
- margin: 0;
- color: var(--text-primary);
-}
-.close-btn[data-v-03643bfa] {
- background: none;
- border: none;
- font-size: 18px;
- cursor: pointer;
- color: var(--text-muted);
- display: flex;
- align-items: center;
- justify-content: center;
- width: 32px;
- height: 32px;
- border-radius: 4px;
- transition: all 0.2s;
-}
-.close-btn[data-v-03643bfa]:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-.modal-body[data-v-03643bfa] {
- padding: 20px;
- box-sizing: border-box;
-}
-.form-group[data-v-03643bfa] {
- margin-bottom: 20px;
-}
-.form-group label[data-v-03643bfa] {
- display: block;
- margin-bottom: 8px;
- font-weight: 500;
- color: var(--text-primary);
-}
-.form-group input[data-v-03643bfa],
-.form-group textarea[data-v-03643bfa] {
- width: 100%;
- padding: 10px;
- border: 1px solid var(--border-color);
- border-radius: 4px;
- font-size: 14px;
- box-sizing: border-box;
- background: var(--input-bg);
- color: var(--input-text);
-}
-.form-group textarea[data-v-03643bfa] {
- resize: vertical;
- min-height: 80px;
-}
-.form-actions[data-v-03643bfa] {
- display: flex;
- gap: 12px;
- justify-content: flex-end;
- margin-top: 30px;
-}
-.icon[data-v-03643bfa] {
- font-size: 14px;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=style&index=0&id=69b5cd1d&scoped=true&lang=css":
-/*!************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=style&index=0&id=69b5cd1d&scoped=true&lang=css ***!
- \************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.settings[data-v-69b5cd1d] {
- padding: 20px;
- /* 移除强制高度和滚动条设置,让内容自然流动 */
-}
-.page-header[data-v-69b5cd1d] {
- margin-bottom: 30px;
-}
-.page-header h2[data-v-69b5cd1d] {
- margin: 0;
- color: var(--text-primary);
- font-size: 24px;
-}
-.settings-content[data-v-69b5cd1d] {
- max-width: 800px;
-}
-.settings-section[data-v-69b5cd1d] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 24px;
- margin-bottom: 24px;
- box-shadow: 0 2px 8px var(--shadow-color);
-}
-.settings-section h3[data-v-69b5cd1d] {
- margin: 0 0 20px 0;
- color: var(--text-primary);
- font-size: 18px;
- border-bottom: 2px solid var(--border-color);
- padding-bottom: 8px;
-}
-.setting-item[data-v-69b5cd1d] {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 20px;
- padding: 16px 0;
- border-bottom: 1px solid #f5f5f5;
-}
-.setting-item[data-v-69b5cd1d]:last-child {
- border-bottom: none;
- margin-bottom: 0;
-}
-.setting-item label[data-v-69b5cd1d] {
- font-weight: 500;
- color: var(--text-primary);
- min-width: 200px;
-}
-.setting-item input[type="text"][data-v-69b5cd1d],
-.setting-item input[type="number"][data-v-69b5cd1d],
-.setting-item select[data-v-69b5cd1d] {
- padding: 8px 12px;
- border: 1px solid var(--input-border);
- border-radius: 4px;
- font-size: 14px;
- min-width: 200px;
- background-color: var(--input-bg);
- color: var(--input-text);
-}
-.setting-item input[type="text"][data-v-69b5cd1d]:focus,
-.setting-item input[type="number"][data-v-69b5cd1d]:focus,
-.setting-item select[data-v-69b5cd1d]:focus {
- outline: none;
- border-color: var(--accent-color);
- box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2);
-}
-
-/* 开关样式 */
-.toggle-switch[data-v-69b5cd1d] {
- position: relative;
- display: inline-block;
-}
-.toggle-switch input[type="checkbox"][data-v-69b5cd1d] {
- opacity: 0;
- width: 0;
- height: 0;
-}
-.toggle-label[data-v-69b5cd1d] {
- display: block;
- width: 50px;
- height: 24px;
- background: #ccc;
- border-radius: 12px;
- cursor: pointer;
- position: relative;
- transition: background-color 0.3s;
-}
-.toggle-label[data-v-69b5cd1d]:before {
- content: '';
- position: absolute;
- width: 20px;
- height: 20px;
- border-radius: 50%;
- background: white;
- top: 2px;
- left: 2px;
- transition: transform 0.3s;
-}
-.toggle-switch input[type="checkbox"]:checked + .toggle-label[data-v-69b5cd1d] {
- background: #1976d2;
-}
-.toggle-switch input[type="checkbox"]:checked + .toggle-label[data-v-69b5cd1d]:before {
- transform: translateX(26px);
-}
-
-/* 设置描述文字 */
-.setting-description[data-v-69b5cd1d] {
- font-size: 12px;
- color: var(--text-secondary);
- margin-top: 8px;
- line-height: 1.4;
- opacity: 0.8;
-}
-
-/* 操作按钮 */
-.settings-actions[data-v-69b5cd1d] {
- display: flex;
- gap: 16px;
- justify-content: flex-end;
- margin-top: 30px;
-}
-.btn[data-v-69b5cd1d] {
- padding: 12px 24px;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- transition: all 0.2s;
-}
-.btn-primary[data-v-69b5cd1d] {
- background: #1976d2;
- color: white;
-}
-.btn-primary[data-v-69b5cd1d]:hover {
- background: #1565c0;
-}
-.btn-secondary[data-v-69b5cd1d] {
- background: #757575;
- color: white;
-}
-.btn-secondary[data-v-69b5cd1d]:hover {
- background: #616161;
-}
-
-/* 响应式保存按钮样式 */
-.btn-disabled[data-v-69b5cd1d] {
- background: #e0e0e0;
- color: #9e9e9e;
- cursor: not-allowed;
-}
-.btn-disabled[data-v-69b5cd1d]:hover {
- background: #e0e0e0;
-}
-.btn-saving[data-v-69b5cd1d] {
- background: #ff9800;
- color: white;
- cursor: not-allowed;
-}
-.btn-saving[data-v-69b5cd1d]:hover {
- background: #ff9800;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.setting-item[data-v-69b5cd1d] {
- flex-direction: column;
- align-items: flex-start;
- gap: 12px;
-}
-.setting-item label[data-v-69b5cd1d] {
- min-width: auto;
-}
-.setting-item input[type="text"][data-v-69b5cd1d],
- .setting-item input[type="number"][data-v-69b5cd1d],
- .setting-item select[data-v-69b5cd1d] {
- min-width: 100%;
-}
-.settings-actions[data-v-69b5cd1d] {
- flex-direction: column;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=style&index=0&id=2de9ad90&scoped=true&lang=css":
-/*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=style&index=0&id=2de9ad90&scoped=true&lang=css ***!
- \*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.login-modal-overlay[data-v-2de9ad90] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
- backdrop-filter: blur(4px);
-}
-.login-modal[data-v-2de9ad90] {
- background: var(--bg-primary);
- border-radius: 12px;
- box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
- width: 90%;
- max-width: 400px;
- max-height: 90vh;
- overflow: hidden;
- animation: modalSlideIn-2de9ad90 0.3s ease-out;
-}
-@keyframes modalSlideIn-2de9ad90 {
-from {
- opacity: 0;
- transform: translateY(-20px) scale(0.95);
-}
-to {
- opacity: 1;
- transform: translateY(0) scale(1);
-}
-}
-.login-modal-header[data-v-2de9ad90] {
- display: flex;
- align-items: center;
- justify-content: space-between;
- padding: 20px 24px;
- border-bottom: 1px solid var(--border-color);
- background: var(--header-bg);
-}
-.login-modal-header h2[data-v-2de9ad90] {
- margin: 0;
- font-size: 20px;
- font-weight: 600;
- color: var(--text-primary);
-}
-.close-btn[data-v-2de9ad90] {
- background: none;
- border: none;
- font-size: 24px;
- color: var(--text-secondary);
- cursor: pointer;
- padding: 4px;
- border-radius: 4px;
- transition: all 0.2s;
-}
-.close-btn[data-v-2de9ad90]:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-.login-modal-body[data-v-2de9ad90] {
- padding: 24px;
-}
-.login-form[data-v-2de9ad90] {
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-.form-group[data-v-2de9ad90] {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-.form-group label[data-v-2de9ad90] {
- font-weight: 500;
- color: var(--text-primary);
- font-size: 14px;
-}
-.form-group input[data-v-2de9ad90] {
- width: 100%;
- padding: 12px 16px;
- border: 2px solid var(--border-color);
- border-radius: 8px;
- font-size: 14px;
- background: var(--bg-secondary);
- color: var(--text-primary);
- transition: all 0.2s;
- box-sizing: border-box;
-}
-.form-group input[data-v-2de9ad90]:focus {
- outline: none;
- border-color: var(--primary-color);
- box-shadow: 0 0 0 3px rgba(25, 118, 210, 0.1);
-}
-.form-group input[data-v-2de9ad90]:disabled {
- opacity: 0.6;
- cursor: not-allowed;
-}
-
-/* 密码输入框容器 */
-.password-input-container[data-v-2de9ad90] {
- position: relative;
- display: flex;
- align-items: center;
-}
-.password-input-container input[data-v-2de9ad90] {
- padding-right: 50px; /* 为密码切换按钮留出空间 */
-}
-.password-toggle-btn[data-v-2de9ad90] {
- position: absolute;
- right: 8px;
- top: 50%;
- transform: translateY(-50%);
- background: none;
- border: none;
- cursor: pointer;
- padding: 4px;
- border-radius: 4px;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-.password-toggle-btn[data-v-2de9ad90]:hover {
- background: var(--bg-secondary);
-}
-.password-toggle-btn[data-v-2de9ad90]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-.password-icon[data-v-2de9ad90] {
- font-size: 16px;
- line-height: 1;
-}
-.captcha-container[data-v-2de9ad90] {
- display: flex;
- gap: 12px;
- align-items: stretch;
-}
-.captcha-container input[data-v-2de9ad90] {
- flex: 1;
-}
-.captcha-image-container[data-v-2de9ad90] {
- width: 100px;
- height: 44px;
- border-radius: 8px;
- overflow: hidden;
- cursor: pointer;
- border: 2px solid var(--border-color);
- transition: all 0.2s;
-}
-.captcha-image-container[data-v-2de9ad90]:hover {
- border-color: var(--primary-color);
-}
-.captcha-image[data-v-2de9ad90] {
- width: 100%;
- height: 100%;
- -o-object-fit: cover;
- object-fit: cover;
-}
-.captcha-placeholder[data-v-2de9ad90] {
- width: 100%;
- height: 100%;
- background: var(--bg-secondary);
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- color: var(--text-secondary);
- font-size: 12px;
- text-align: center;
- padding: 8px;
- cursor: pointer;
- transition: all 0.2s;
-}
-.captcha-placeholder[data-v-2de9ad90]:hover {
- background: var(--bg-tertiary);
- color: var(--text-primary);
-}
-.captcha-hint[data-v-2de9ad90] {
- font-size: 10px;
- opacity: 0.7;
- margin-top: 2px;
-}
-.captcha-loading-spinner[data-v-2de9ad90] {
- width: 12px;
- height: 12px;
- border: 2px solid transparent;
- border-top: 2px solid currentColor;
- border-radius: 50%;
- animation: spin-2de9ad90 1s linear infinite;
- margin-top: 4px;
-}
-.form-actions[data-v-2de9ad90] {
- margin-top: 8px;
-}
-.login-btn[data-v-2de9ad90] {
- width: 100%;
- padding: 14px 24px;
- background: var(--primary-color);
- color: white;
- border: none;
- border-radius: 8px;
- font-size: 16px;
- font-weight: 600;
- cursor: pointer;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
-}
-
-/* 深色主题下的登录按钮样式 */
-.theme-dark .login-btn[data-v-2de9ad90] {
- background: var(--primary-color);
- color: #333333;
- border: 1px solid rgba(255, 255, 255, 0.1);
-}
-.theme-dark .login-btn[data-v-2de9ad90]:hover:not(:disabled) {
- background: var(--primary-hover);
- color: #222222;
-}
-.login-btn[data-v-2de9ad90]:hover:not(:disabled) {
- background: var(--primary-hover);
- transform: translateY(-1px);
- box-shadow: 0 4px 12px rgba(25, 118, 210, 0.3);
-}
-.login-btn[data-v-2de9ad90]:disabled {
- opacity: 0.6;
- cursor: not-allowed;
- transform: none;
- box-shadow: none;
-}
-.loading-spinner[data-v-2de9ad90] {
- width: 16px;
- height: 16px;
- border: 2px solid transparent;
- border-top: 2px solid currentColor;
- border-radius: 50%;
- animation: spin-2de9ad90 1s linear infinite;
-}
-@keyframes spin-2de9ad90 {
-to {
- transform: rotate(360deg);
-}
-}
-.error-message[data-v-2de9ad90] {
- background: var(--error-bg);
- color: var(--error-text);
- padding: 12px 16px;
- border-radius: 8px;
- font-size: 14px;
- text-align: center;
- border: 1px solid var(--error-border);
- display: flex;
- align-items: center;
- justify-content: center;
- gap: 8px;
- margin-top: 16px;
- animation: errorShake-2de9ad90 0.5s ease-in-out;
-}
-.error-icon[data-v-2de9ad90] {
- font-size: 16px;
- flex-shrink: 0;
-}
-@keyframes errorShake-2de9ad90 {
-0%, 100% { transform: translateX(0);
-}
-25% { transform: translateX(-5px);
-}
-75% { transform: translateX(5px);
-}
-}
-
-/* 深色主题下的错误提示样式优化 */
-.theme-dark .error-message[data-v-2de9ad90] {
- background: rgba(244, 67, 54, 0.2);
- color: #ffab91;
- border: 1px solid rgba(244, 67, 54, 0.5);
- font-weight: 500;
-}
-.login-modal-footer[data-v-2de9ad90] {
- padding: 16px 24px;
- border-top: 1px solid var(--border-color);
- background: var(--bg-secondary);
-}
-.login-tips[data-v-2de9ad90] {
- margin: 0;
- font-size: 12px;
- color: var(--text-secondary);
- text-align: center;
- line-height: 1.5;
-}
-.login-tips span[data-v-2de9ad90] {
- display: block;
- margin-bottom: 4px;
-}
-.login-tips span[data-v-2de9ad90]:first-child {
- font-weight: 600;
- color: var(--text-primary);
-}
-
-/* 响应式设计 */
-@media (max-width: 480px) {
-.login-modal[data-v-2de9ad90] {
- width: 95%;
- margin: 20px;
-}
-.login-modal-header[data-v-2de9ad90],
- .login-modal-body[data-v-2de9ad90],
- .login-modal-footer[data-v-2de9ad90] {
- padding: 16px 20px;
-}
-.captcha-container[data-v-2de9ad90] {
- flex-direction: column;
- gap: 8px;
-}
-.captcha-image-container[data-v-2de9ad90] {
- width: 100%;
- height: 40px;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=style&index=0&id=0b66487e&scoped=true&lang=css":
-/*!****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=style&index=0&id=0b66487e&scoped=true&lang=css ***!
- \****************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.password-modal-overlay[data-v-0b66487e] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0, 0, 0, 0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
-}
-.password-modal[data-v-0b66487e] {
- background: var(--card-bg);
- border-radius: 12px;
- width: 90%;
- max-width: 500px;
- max-height: 90vh;
- overflow-y: auto;
- box-shadow: 0 8px 32px var(--shadow-color);
-}
-.modal-header[data-v-0b66487e] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px 24px;
- border-bottom: 1px solid var(--border-color);
-}
-.modal-header h3[data-v-0b66487e] {
- margin: 0;
- color: var(--text-primary);
- font-size: 18px;
-}
-.close-btn[data-v-0b66487e] {
- background: none;
- border: none;
- font-size: 24px;
- cursor: pointer;
- color: var(--text-muted);
- padding: 4px;
- border-radius: 4px;
- transition: all 0.2s;
-}
-.close-btn[data-v-0b66487e]:hover {
- background: var(--bg-secondary);
- color: var(--text-primary);
-}
-.modal-body[data-v-0b66487e] {
- padding: 24px;
-}
-.form-group[data-v-0b66487e] {
- margin-bottom: 20px;
-}
-.form-group label[data-v-0b66487e] {
- display: block;
- margin-bottom: 8px;
- font-weight: 500;
- color: var(--text-primary);
-}
-.form-group input[data-v-0b66487e] {
- width: 100%;
- padding: 12px;
- border: 1px solid var(--border-color);
- border-radius: 6px;
- font-size: 14px;
- background: var(--input-bg);
- color: var(--text-primary);
- transition: all 0.2s;
- box-sizing: border-box;
-}
-.form-group input[data-v-0b66487e]:focus {
- outline: none;
- border-color: var(--accent-color);
- box-shadow: 0 0 0 2px rgba(25, 118, 210, 0.2);
-}
-.form-group input.error[data-v-0b66487e] {
- border-color: #f44336;
-}
-
-/* 确保禁用状态下的输入框仍然可见 */
-.form-group input[data-v-0b66487e]:disabled {
- opacity: 0.7;
- background: var(--bg-secondary);
- cursor: not-allowed;
-}
-
-/* 测试焦点样式 */
-.form-group input[data-v-0b66487e]:focus {
- outline: 2px solid #ff9800;
- outline-offset: 2px;
-}
-.error-message[data-v-0b66487e] {
- color: #f44336;
- font-size: 12px;
- margin-top: 4px;
-}
-
-/* 密码强度指示器 */
-.password-strength[data-v-0b66487e] {
- margin-top: 12px;
-}
-.strength-bar[data-v-0b66487e] {
- width: 100%;
- height: 6px;
- background: #e0e0e0;
- border-radius: 3px;
- overflow: hidden;
- margin-bottom: 8px;
-}
-.strength-fill[data-v-0b66487e] {
- height: 100%;
- transition: width 0.3s ease;
-}
-.strength-fill.very-weak[data-v-0b66487e] {
- background: #f44336;
-}
-.strength-fill.weak[data-v-0b66487e] {
- background: #ff9800;
-}
-.strength-fill.medium[data-v-0b66487e] {
- background: #ffc107;
-}
-.strength-fill.strong[data-v-0b66487e] {
- background: #4caf50;
-}
-.strength-text[data-v-0b66487e] {
- font-size: 12px;
- color: var(--text-secondary);
- text-align: center;
-}
-
-/* 密码要求提示 */
-.password-requirements[data-v-0b66487e] {
- margin-top: 12px;
- padding: 12px;
- background: var(--bg-secondary);
- border-radius: 6px;
- font-size: 12px;
-}
-.requirement[data-v-0b66487e] {
- color: var(--text-muted);
- margin-bottom: 4px;
- transition: color 0.2s;
-}
-.requirement.met[data-v-0b66487e] {
- color: #4caf50;
-}
-.requirement[data-v-0b66487e]:last-child {
- margin-bottom: 0;
-}
-
-/* 操作按钮 */
-.form-actions[data-v-0b66487e] {
- display: flex;
- gap: 12px;
- justify-content: flex-end;
- margin-top: 30px;
-}
-
-/* 强制修改密码提示 */
-.force-change-notice[data-v-0b66487e] {
- margin-top: 20px;
- padding: 16px;
- background: #fff3cd;
- border: 1px solid #ffeaa7;
- border-radius: 8px;
- display: flex;
- align-items: flex-start;
- gap: 12px;
-}
-.notice-icon[data-v-0b66487e] {
- font-size: 20px;
- flex-shrink: 0;
-}
-.notice-text[data-v-0b66487e] {
- color: #856404;
- font-size: 14px;
- line-height: 1.5;
-}
-.notice-text strong[data-v-0b66487e] {
- color: #856404;
-}
-.btn[data-v-0b66487e] {
- padding: 12px 24px;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- transition: all 0.2s;
- display: flex;
- align-items: center;
- gap: 8px;
-}
-.btn[data-v-0b66487e]:disabled {
- opacity: 0.6;
- cursor: not-allowed;
-}
-.btn-primary[data-v-0b66487e] {
- background: var(--accent-color);
- color: white;
-}
-.btn-primary[data-v-0b66487e]:hover:not(:disabled) {
- background: var(--accent-hover);
-}
-.btn-secondary[data-v-0b66487e] {
- background: var(--bg-secondary);
- color: var(--text-primary);
- border: 1px solid var(--border-color);
-}
-.btn-secondary[data-v-0b66487e]:hover:not(:disabled) {
- background: var(--bg-tertiary);
-}
-
-/* 加载动画 */
-.loading-spinner[data-v-0b66487e] {
- width: 16px;
- height: 16px;
- border: 2px solid transparent;
- border-top: 2px solid currentColor;
- border-radius: 50%;
- animation: spin-0b66487e 1s linear infinite;
-}
-@keyframes spin-0b66487e {
-0% { transform: rotate(0deg);
-}
-100% { transform: rotate(360deg);
-}
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.password-modal[data-v-0b66487e] {
- width: 95%;
- margin: 20px;
-}
-.modal-header[data-v-0b66487e],
- .modal-body[data-v-0b66487e] {
- padding: 16px;
-}
-.form-actions[data-v-0b66487e] {
- flex-direction: column;
-}
-.btn[data-v-0b66487e] {
- width: 100%;
- justify-content: center;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=style&index=0&id=1a74186c&scoped=true&lang=css":
-/*!************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=style&index=0&id=1a74186c&scoped=true&lang=css ***!
- \************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.password-profile[data-v-1a74186c] {
- padding: 20px;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=style&index=0&id=7889d364&scoped=true&lang=css":
-/*!******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=style&index=0&id=7889d364&scoped=true&lang=css ***!
- \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.user-management[data-v-7889d364] {
- padding: 20px;
- /* 移除强制高度和滚动条设置,让内容自然流动 */
-}
-.page-header[data-v-7889d364] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- margin-bottom: 20px;
-}
-.page-header h2[data-v-7889d364] {
- margin: 0;
- color: var(--text-primary);
-}
-.search-bar[data-v-7889d364] {
- display: flex;
- gap: 20px;
- margin-bottom: 20px;
- align-items: center;
- flex-wrap: wrap;
- justify-content: space-between;
-}
-.search-input[data-v-7889d364] {
- position: relative;
- flex: 0 0 280px;
- min-width: 200px;
- max-width: 350px;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.search-bar[data-v-7889d364] {
- flex-direction: column;
- align-items: stretch;
- gap: 15px;
- justify-content: flex-start;
-}
-.search-input[data-v-7889d364] {
- flex: 1;
- min-width: auto;
- max-width: none;
-}
-.filters[data-v-7889d364] {
- justify-content: space-between;
- flex: none;
-}
-.filters select[data-v-7889d364] {
- flex: 1;
- min-width: auto;
- max-width: none;
-}
-}
-
-/* 中等屏幕优化 */
-@media (max-width: 1024px) and (min-width: 769px) {
-.search-input[data-v-7889d364] {
- flex: 0 0 250px;
- min-width: 200px;
- max-width: 300px;
-}
-.filters select[data-v-7889d364] {
- min-width: 90px;
- max-width: 130px;
-}
-}
-.search-input i[data-v-7889d364] {
- position: absolute;
- left: 12px;
- top: 50%;
- transform: translateY(-50%);
- color: var(--text-muted);
-}
-.search-input input[data-v-7889d364] {
- width: 100%;
- padding: 10px 10px 10px 35px;
- border: 1px solid var(--input-border);
- border-radius: 6px;
- font-size: 14px;
- background-color: var(--input-bg);
- color: var(--input-text);
-}
-.filters[data-v-7889d364] {
- display: flex;
- gap: 15px;
- flex-wrap: wrap;
- flex: 1;
- justify-content: flex-end;
- min-width: 0;
-}
-.filters select[data-v-7889d364] {
- padding: 8px 12px;
- border: 1px solid var(--input-border);
- border-radius: 4px;
- font-size: 14px;
- background-color: var(--input-bg);
- color: var(--input-text);
- min-width: 100px;
- max-width: 150px;
- flex: 0 0 auto;
-}
-.user-table[data-v-7889d364] {
- background: var(--card-bg);
- border-radius: 8px;
- box-shadow: 0 2px 8px var(--shadow-color);
- overflow: hidden;
- margin-bottom: 20px;
-}
-table[data-v-7889d364] {
- width: 100%;
- border-collapse: collapse;
-}
-th[data-v-7889d364], td[data-v-7889d364] {
- padding: 12px;
- text-align: left;
- border-bottom: 1px solid var(--border-color);
-}
-th[data-v-7889d364] {
- background: var(--bg-secondary);
- font-weight: 600;
- color: var(--text-primary);
-}
-.status-badge[data-v-7889d364] {
- padding: 4px 8px;
- border-radius: 12px;
- font-size: 12px;
- font-weight: 500;
-}
-.status-badge.active[data-v-7889d364] {
- background: #e8f5e8;
- color: #2e7d32;
-}
-.status-badge.inactive[data-v-7889d364] {
- background: #ffebee;
- color: #c62828;
-}
-.role-tags[data-v-7889d364] {
- display: flex;
- gap: 4px;
- flex-wrap: wrap;
-}
-.role-tag[data-v-7889d364] {
- background: #e3f2fd;
- color: #1976d2;
- padding: 2px 6px;
- border-radius: 4px;
- font-size: 11px;
-}
-.actions[data-v-7889d364] {
- display: flex;
- gap: 8px;
-}
-.btn[data-v-7889d364] {
- padding: 8px 16px;
- border: none;
- border-radius: 4px;
- cursor: pointer;
- font-size: 14px;
- display: inline-flex;
- align-items: center;
- gap: 6px;
- transition: all 0.2s;
-}
-.btn-primary[data-v-7889d364] {
- background: #1976d2;
- color: white;
-}
-.btn-primary[data-v-7889d364]:hover {
- background: #1565c0;
-}
-.btn-info[data-v-7889d364] {
- background: #0288d1;
- color: white;
-}
-.btn-danger[data-v-7889d364] {
- background: #d32f2f;
- color: white;
-}
-.btn-secondary[data-v-7889d364] {
- background: #757575;
- color: white;
-}
-.btn-sm[data-v-7889d364] {
- padding: 6px 12px;
- font-size: 12px;
-}
-
-/* 表格操作按钮样式优化 */
-.actions .btn-sm[data-v-7889d364] {
- background: none;
- border: none;
- padding: 4px 8px;
- margin: 0 2px;
- color: var(--text-primary);
- transition: all 0.2s;
-}
-.actions .btn-sm[data-v-7889d364]:hover {
- background: var(--bg-secondary);
- color: var(--accent-color);
- transform: scale(1.1);
-}
-.actions .btn-sm.btn-info[data-v-7889d364]:hover {
- color: #2196f3;
-}
-.actions .btn-sm.btn-primary[data-v-7889d364]:hover {
- color: #1976d2;
-}
-.actions .btn-sm.btn-danger[data-v-7889d364]:hover {
- color: #d32f2f;
-}
-.btn[data-v-7889d364]:hover {
- opacity: 0.9;
-}
-.btn[data-v-7889d364]:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-.pagination[data-v-7889d364] {
- display: flex;
- justify-content: center;
- align-items: center;
- gap: 20px;
-}
-.page-info[data-v-7889d364] {
- color: #666;
- font-size: 14px;
-}
-.modal-overlay[data-v-7889d364] {
- position: fixed;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- background: rgba(0,0,0,0.5);
- display: flex;
- align-items: center;
- justify-content: center;
- z-index: 1000;
-}
-.modal[data-v-7889d364] {
- background: white;
- border-radius: 8px;
- width: 90%;
- max-width: 500px;
- max-height: 90vh;
- overflow-y: auto;
- box-sizing: border-box;
-}
-.modal-header[data-v-7889d364] {
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 20px;
- border-bottom: 1px solid #eee;
-}
-.modal-header h3[data-v-7889d364] {
- margin: 0;
-}
-.close-btn[data-v-7889d364] {
- background: none;
- border: none;
- font-size: 24px;
- cursor: pointer;
- color: #999;
-}
-.modal-body[data-v-7889d364] {
- padding: 20px;
- box-sizing: border-box;
-}
-.form-group[data-v-7889d364] {
- margin-bottom: 20px;
-}
-.form-group label[data-v-7889d364] {
- display: block;
- margin-bottom: 8px;
- font-weight: 500;
- color: #333;
-}
-.form-group input[data-v-7889d364],
-.form-group select[data-v-7889d364] {
- width: 100%;
- padding: 10px;
- border: 1px solid #ddd;
- border-radius: 4px;
- font-size: 14px;
- box-sizing: border-box;
-}
-.role-checkboxes[data-v-7889d364] {
- display: flex;
- flex-direction: column;
- gap: 8px;
-}
-.checkbox-item[data-v-7889d364] {
- display: flex;
- align-items: center;
- gap: 8px;
- cursor: pointer;
-}
-.checkbox-item input[type="checkbox"][data-v-7889d364] {
- width: auto;
-}
-.form-actions[data-v-7889d364] {
- display: flex;
- gap: 12px;
- justify-content: flex-end;
- margin-top: 30px;
-}
-.icon[data-v-7889d364] {
- font-size: 14px;
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=style&index=0&id=8301bb50&scoped=true&lang=css":
-/*!***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=style&index=0&id=8301bb50&scoped=true&lang=css ***!
- \***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `
-.user-profile[data-v-8301bb50] {
- padding: 20px;
- /* 移除强制高度和滚动条设置,让内容自然流动 */
-}
-.profile-header[data-v-8301bb50] {
- text-align: center;
- margin-bottom: 30px;
-}
-.profile-header h1[data-v-8301bb50] {
- font-size: 2.5rem;
- color: var(--text-primary);
- margin-bottom: 10px;
-}
-.profile-subtitle[data-v-8301bb50] {
- font-size: 1.1rem;
- color: var(--text-secondary);
- margin: 0;
-}
-.loading-container[data-v-8301bb50] {
- text-align: center;
- padding: 60px 20px;
-}
-.loading-spinner[data-v-8301bb50] {
- width: 50px;
- height: 50px;
- border: 4px solid #f3f3f3;
- border-top: 4px solid #3498db;
- border-radius: 50%;
- animation: spin-8301bb50 1s linear infinite;
- margin: 0 auto 20px;
-}
-@keyframes spin-8301bb50 {
-0% { transform: rotate(0deg);
-}
-100% { transform: rotate(360deg);
-}
-}
-.error-container[data-v-8301bb50] {
- text-align: center;
- padding: 60px 20px;
- background: #fff5f5;
- border-radius: 12px;
- border: 1px solid #fed7d7;
-}
-.error-icon[data-v-8301bb50] {
- font-size: 3rem;
- margin-bottom: 20px;
-}
-.retry-btn[data-v-8301bb50] {
- background: #e53e3e;
- color: white;
- border: none;
- padding: 12px 24px;
- border-radius: 8px;
- cursor: pointer;
- font-size: 1rem;
- margin-top: 20px;
-}
-.retry-btn[data-v-8301bb50]:hover {
- background: #c53030;
-}
-.profile-content[data-v-8301bb50] {
- max-width: 800px;
- margin: 0 auto;
-}
-.profile-card[data-v-8301bb50] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 24px;
- margin-bottom: 24px;
- box-shadow: 0 2px 8px var(--shadow-color);
-}
-.card-header[data-v-8301bb50] {
- margin: 0 0 20px 0;
- color: var(--text-primary);
- font-size: 18px;
- border-bottom: 2px solid var(--border-color);
- padding-bottom: 8px;
-}
-.card-header h2[data-v-8301bb50] {
- margin: 0;
- font-size: 18px;
- color: var(--text-primary);
-}
-.info-grid[data-v-8301bb50] {
- display: flex;
- flex-direction: column;
- gap: 0;
-}
-.info-item[data-v-8301bb50] {
- display: flex;
- align-items: center;
- justify-content: space-between;
- margin-bottom: 20px;
- padding: 16px 0;
- border-bottom: 1px solid #f5f5f5;
-}
-.info-item[data-v-8301bb50]:last-child {
- border-bottom: none;
- margin-bottom: 0;
-}
-.info-item label[data-v-8301bb50] {
- font-weight: 500;
- color: var(--text-primary);
- min-width: 200px;
-}
-.info-item span[data-v-8301bb50] {
- color: var(--text-primary);
- font-size: 14px;
- text-align: right;
- flex: 1;
-}
-.status-badge[data-v-8301bb50] {
- display: inline-block;
- padding: 6px 12px;
- border-radius: 20px;
- font-size: 0.85rem;
- font-weight: 600;
- text-align: center;
- min-width: 80px;
-}
-.status-active[data-v-8301bb50] {
- background: #d4edda;
- color: #155724;
-}
-.status-inactive[data-v-8301bb50] {
- background: #f8d7da;
- color: #721c24;
-}
-.status-pending[data-v-8301bb50] {
- background: #fff3cd;
- color: #856404;
-}
-.status-unknown[data-v-8301bb50] {
- background: #e2e3e5;
- color: #383d41;
-}
-.roles-list[data-v-8301bb50] {
- display: flex;
- flex-direction: column;
- gap: 20px;
-}
-.role-item[data-v-8301bb50] {
- background: var(--card-bg);
- border-radius: 8px;
- padding: 20px;
- border: 1px solid var(--border-color);
- margin-bottom: 16px;
-}
-.role-header[data-v-8301bb50] {
- margin-bottom: 16px;
-}
-.role-name[data-v-8301bb50] {
- display: block;
- font-size: 1.1rem;
- font-weight: 600;
- color: var(--text-primary);
- margin-bottom: 8px;
-}
-.role-description[data-v-8301bb50] {
- color: var(--text-secondary);
- font-size: 0.9rem;
-}
-.role-permissions h4[data-v-8301bb50] {
- margin: 0 0 12px 0;
- color: var(--text-primary);
- font-size: 1rem;
-}
-.permissions-grid[data-v-8301bb50] {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
-}
-.permission-tag[data-v-8301bb50] {
- background: var(--accent-color);
- color: white;
- padding: 4px 12px;
- border-radius: 16px;
- font-size: 0.85rem;
- border: none;
-}
-.no-roles[data-v-8301bb50] {
- text-align: center;
- color: var(--text-secondary);
- padding: 40px 20px;
-}
-.profile-actions[data-v-8301bb50] {
- display: flex;
- gap: 16px;
- justify-content: flex-end;
- margin-top: 30px;
-}
-.action-btn[data-v-8301bb50] {
- padding: 12px 24px;
- border: none;
- border-radius: 6px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
- transition: all 0.2s;
-}
-.refresh-btn[data-v-8301bb50] {
- background: #1976d2;
- color: white;
-}
-.refresh-btn[data-v-8301bb50]:hover {
- background: #1565c0;
-}
-.edit-btn[data-v-8301bb50] {
- background: #f39c12;
- color: white;
-}
-.edit-btn[data-v-8301bb50]:hover {
- background: #e67e22;
-}
-.password-btn[data-v-8301bb50] {
- background: #e74c3c;
- color: white;
-}
-.password-btn[data-v-8301bb50]:hover {
- background: #c0392b;
-}
-.empty-state[data-v-8301bb50] {
- text-align: center;
- padding: 80px 20px;
-}
-.empty-icon[data-v-8301bb50] {
- font-size: 4rem;
- margin-bottom: 20px;
-}
-.empty-state h3[data-v-8301bb50] {
- color: var(--text-primary);
- margin-bottom: 10px;
-}
-.empty-state p[data-v-8301bb50] {
- color: var(--text-secondary);
- margin-bottom: 30px;
-}
-.login-btn[data-v-8301bb50] {
- background: #1976d2;
- color: white;
- border: none;
- padding: 12px 32px;
- border-radius: 6px;
- cursor: pointer;
- font-size: 14px;
- font-weight: 500;
-}
-.login-btn[data-v-8301bb50]:hover {
- background: #1565c0;
-}
-
-/* 响应式设计 */
-@media (max-width: 768px) {
-.user-profile[data-v-8301bb50] {
- padding: 15px;
-}
-.profile-header h1[data-v-8301bb50] {
- font-size: 2rem;
-}
-.info-item[data-v-8301bb50] {
- flex-direction: column;
- align-items: flex-start;
- gap: 12px;
-}
-.info-item label[data-v-8301bb50] {
- min-width: auto;
-}
-.info-item span[data-v-8301bb50] {
- text-align: left;
-}
-.profile-actions[data-v-8301bb50] {
- flex-direction: column;
- align-items: center;
-}
-.action-btn[data-v-8301bb50] {
- width: 100%;
- max-width: 300px;
-}
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/renderer/assets/fonts.css":
-/*!*************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/renderer/assets/fonts.css ***!
- \*************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `/* 中文字体配置文件 */
-
-/* 定义字体族变量 */
-:root {
- --font-family-chinese: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', 'SimHei', 'SimSun', Avenir, Helvetica, Arial, sans-serif;
- --font-family-english: 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
-}
-
-/* 全局字体设置 */
-* {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 确保所有文本元素都使用中文字体 */
-body, html, #app {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 特定组件的字体设置 */
-.main-layout,
-.status-bar,
-.home,
-.user-management,
-.settings {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 标题和重要文本的字体设置 */
-h1, h2, h3, h4, h5, h6 {
- font-family: var(--font-family-chinese), var(--font-family-english);
- font-weight: 500;
-}
-
-/* 按钮和输入框的字体设置 */
-button, input, select, textarea {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 表格内容的字体设置 */
-table, th, td {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 状态栏文本的字体设置 */
-.status-item {
- font-family: var(--font-family-chinese), var(--font-family-english);
-}
-
-/* 响应式字体大小 */
-@media (max-width: 768px) {
- :root {
- --font-size-base: 14px;
- --font-size-small: 12px;
- }
-}
-
-@media (min-width: 769px) {
- :root {
- --font-size-base: 16px;
- --font-size-small: 14px;
- }
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/renderer/assets/themes.css":
-/*!**************************************************************************************************************************************************************************!*\
- !*** ./node_modules/css-loader/dist/cjs.js??clonedRuleSet-14.use[1]!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-14.use[2]!./src/renderer/assets/themes.css ***!
- \**************************************************************************************************************************************************************************/
-/***/ ((module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__);
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js");
-/* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__);
-// Imports
-
-
-var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default()));
-// Module
-___CSS_LOADER_EXPORT___.push([module.id, `/* 全局主题样式 */
-
-/* 浅色主题(默认) */
-:root {
- --bg-primary: #ffffff;
- --bg-secondary: #f5f5f5;
- --bg-tertiary: #e0e0e0;
- --text-primary: #333333;
- --text-secondary: #666666;
- --text-muted: #999999;
- --border-color: #e0e0e0;
- --accent-color: #1976d2;
- --accent-hover: #1565c0;
- --primary-color: #1976d2;
- --primary-hover: #1565c0;
- --success-color: #4caf50;
- --warning-color: #ff9800;
- --error-color: #f44336;
- --shadow-color: rgba(0, 0, 0, 0.1);
- --card-bg: #ffffff;
- --input-bg: #ffffff;
- --input-border: #ddd;
- --input-text: #333333;
- --button-bg: #1976d2;
- --button-text: #ffffff;
- --button-hover: #1565c0;
- --sidebar-bg: #ffffff;
- --header-bg: #ffffff;
- --tab-bg: #f8f9fa;
- --tab-active-bg: #007bff;
- --tab-active-text: #ffffff;
- --error-bg: #ffebee;
- --error-text: #c62828;
- --error-border: #ffcdd2;
-}
-
-/* 深色主题 */
-.theme-dark {
- --bg-primary: #2d4a8a;
- --bg-secondary: #1f3a6b;
- --bg-tertiary: #1a2a4a;
- --text-primary: #ffffff;
- --text-secondary: #e0e0e0;
- --text-muted: #b0b0b0;
- --border-color: rgba(255, 255, 255, 0.2);
- --accent-color: #ffffff;
- --accent-hover: #e0e0e0;
- --primary-color: #ffffff;
- --primary-hover: #e0e0e0;
- --success-color: #4caf50;
- --warning-color: #ff9800;
- --error-color: #f44336;
- --shadow-color: rgba(0, 0, 0, 0.2);
- --card-bg: rgba(255, 255, 255, 0.08);
- --input-bg: #1a2a4a;
- --input-border: rgba(255, 255, 255, 0.2);
- --input-text: #ffffff;
- --button-bg: #2d4a8a;
- --button-text: #ffffff;
- --button-hover: #1f3a6b;
- --sidebar-bg: #1a2a4a;
- --header-bg: #1f3a6b;
- --tab-bg: #1a2a4a;
- --tab-active-bg: #2d4a8a;
- --tab-active-text: #ffffff;
- --error-bg: rgba(244, 67, 54, 0.15);
- --error-text: #ff8a80;
- --error-border: rgba(244, 67, 54, 0.4);
-}
-
-/* 主题切换过渡动画 */
-* {
- transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease;
-}
-
-/* 全局背景和文字颜色 */
-body {
- background-color: var(--bg-primary);
- color: var(--text-primary);
-}
-
-/* 卡片样式 */
-.card, .settings-section, .feature-card, .todo-section, .recent-section {
- background-color: var(--card-bg);
- border: 1px solid var(--border-color);
- box-shadow: 0 2px 8px var(--shadow-color);
-}
-
-/* 输入框样式 */
-input, select, textarea {
- background-color: var(--input-bg);
- border: 1px solid var(--input-border);
- color: var(--input-text);
-}
-
-input:focus, select:focus, textarea:focus {
- border-color: var(--accent-color);
- box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2);
-}
-
-/* 按钮样式 */
-.btn, button {
- background-color: var(--button-bg);
- color: var(--button-text);
- border: 1px solid var(--button-bg);
-}
-
-.btn:hover, button:hover {
- background-color: var(--button-hover);
-}
-
-/* 深色主题下的按钮特殊样式 */
-.theme-dark .btn, .theme-dark button {
- border-color: var(--border-color);
-}
-
-/* 深色主题下的消息样式 */
-.theme-dark .message-title {
- color: var(--text-primary) !important;
-}
-
-.theme-dark .message-icon {
- color: var(--text-primary) !important;
-}
-
-.theme-dark .message-content {
- color: var(--text-primary);
-}
-
-/* 链接样式 */
-a {
- color: var(--accent-color);
-}
-
-a:hover {
- color: var(--button-hover);
-}
-
-/* 表格样式 */
-table {
- background-color: var(--card-bg);
- color: var(--text-primary);
-}
-
-th, td {
- border-color: var(--border-color);
-}
-
-/* 滚动条样式 */
-::-webkit-scrollbar {
- width: 8px;
- height: 8px;
-}
-
-::-webkit-scrollbar-track {
- background: var(--bg-secondary);
-}
-
-::-webkit-scrollbar-thumb {
- background: var(--border-color);
- border-radius: 4px;
-}
-
-::-webkit-scrollbar-thumb:hover {
- background: var(--text-muted);
-}
-
-/* 选择框样式 */
-select {
- background-color: var(--input-bg);
- color: var(--input-text);
- border: 1px solid var(--input-border);
-}
-
-/* 深色主题下的选择框选项样式 */
-.theme-dark select option {
- background-color: #1a2a4a !important;
- color: #ffffff !important;
-}
-
-.theme-dark select option:hover {
- background-color: #2d4a8a !important;
- color: #ffffff !important;
-}
-
-/* 确保选择框本身在深色主题下有正确的样式 */
-.theme-dark select {
- background-color: #1a2a4a !important;
- color: #ffffff !important;
- border-color: rgba(255, 255, 255, 0.3) !important;
-}
-
-/* 复选框和单选框样式 */
-input[type="checkbox"], input[type="radio"] {
- accent-color: var(--accent-color);
-}
-
-/* 占位符文本样式 */
-::-moz-placeholder {
- color: var(--text-muted);
- opacity: 1;
-}
-::placeholder {
- color: var(--text-muted);
- opacity: 1;
-}
-
-/* 代码块样式 */
-code, pre {
- background-color: var(--bg-secondary);
- color: var(--text-primary);
- border: 1px solid var(--border-color);
-}
-
-/* 引用样式 */
-blockquote {
- border-left: 4px solid var(--accent-color);
- background-color: var(--bg-secondary);
- color: var(--text-secondary);
-}
-
-/* 分割线样式 */
-hr {
- border-color: var(--border-color);
-}
-
-/* 工具提示样式 */
-[title]:hover::after {
- background-color: var(--bg-secondary);
- color: var(--text-primary);
- border: 1px solid var(--border-color);
-}
-`, ""]);
-// Exports
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___);
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=script&lang=js":
-/*!*****************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=script&lang=js ***!
- \*****************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _modules_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./modules/core */ "./src/renderer/modules/core/index.js");
-/* harmony import */ var _assets_fonts_css__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./assets/fonts.css */ "./src/renderer/assets/fonts.css");
-/* harmony import */ var _assets_fonts_css__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_assets_fonts_css__WEBPACK_IMPORTED_MODULE_1__);
-/* harmony import */ var _assets_themes_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./assets/themes.css */ "./src/renderer/assets/themes.css");
-/* harmony import */ var _assets_themes_css__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(_assets_themes_css__WEBPACK_IMPORTED_MODULE_2__);
-
-
-
- // 引入主题配置文件
- // 引入主题管理器
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'App',
- components: {
- StatusBar: _modules_core__WEBPACK_IMPORTED_MODULE_0__.StatusBar
- },
- mounted() {
- // 确保主题管理器在应用启动时初始化
- if (_modules_core__WEBPACK_IMPORTED_MODULE_0__.themeManager) {
- console.log('主题管理器已初始化')
- }
- },
- mounted() {
- // 请求初始状态
- window.electronAPI?.sendStatusRequest();
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=script&lang=js":
-/*!************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=script&lang=js ***!
- \************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm-bundler.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'SpeedTest',
- setup() {
- const store = (0,vuex__WEBPACK_IMPORTED_MODULE_1__.useStore)()
- const testing = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const result = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
-
- const startTest = async () => {
- testing.value = true
- result.value = null
-
- // 模拟网络测试 (替换为真实测试逻辑)
- await new Promise(resolve => setTimeout(resolve, 2000))
-
- const testResult = {
- download: (Math.random() * 100).toFixed(2),
- upload: (Math.random() * 50).toFixed(2),
- ping: (Math.random() * 100).toFixed(2),
- timestamp: new Date().toISOString()
- }
-
- // 保存结果
- await store.dispatch('saveTestResult', testResult)
- result.value = testResult
- testing.value = false
- }
-
- return { testing, result, startTest }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=script&lang=js":
-/*!*****************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=script&lang=js ***!
- \*****************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm-bundler.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'HistoryView',
- setup() {
- const store = (0,vuex__WEBPACK_IMPORTED_MODULE_1__.useStore)()
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- store.dispatch('loadTestResults')
- })
-
- const testResults = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => store.state.testResults)
-
- const formatDate = (timestamp) => {
- return new Date(timestamp).toLocaleString()
- }
-
- return { testResults, formatDate }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=script&lang=js":
-/*!************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=script&lang=js ***!
- \************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _user_management_components_PasswordChangeModal_vue__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../user-management/components/PasswordChangeModal.vue */ "./src/renderer/modules/user-management/components/PasswordChangeModal.vue");
-/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! vue-router */ "./node_modules/vue-router/dist/vue-router.mjs");
-/* harmony import */ var _modules_user_management__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/modules/user-management */ "./src/renderer/modules/user-management/index.js");
-/* harmony import */ var _modules_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/modules/core */ "./src/renderer/modules/core/index.js");
-/* harmony import */ var _user_management_components_LoginModal_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../user-management/components/LoginModal.vue */ "./src/renderer/modules/user-management/components/LoginModal.vue");
-/* harmony import */ var _Toast_vue__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./Toast.vue */ "./src/renderer/modules/core/components/Toast.vue");
-
-
-
-
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'MainLayout',
- components: {
- LoginModal: _user_management_components_LoginModal_vue__WEBPACK_IMPORTED_MODULE_5__["default"],
- Toast: _Toast_vue__WEBPACK_IMPORTED_MODULE_6__["default"],
- PasswordChangeModal: _user_management_components_PasswordChangeModal_vue__WEBPACK_IMPORTED_MODULE_1__["default"]
- },
- setup() {
- const router = (0,vue_router__WEBPACK_IMPORTED_MODULE_2__.useRouter)()
- const route = (0,vue_router__WEBPACK_IMPORTED_MODULE_2__.useRoute)()
-
- // 响应式数据
- const showMessagePanel = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showUserMenu = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showLoginModalFlag = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showToast = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
-
- // 密码修改弹窗状态
- const showPasswordModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const isForceChange = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const currentTab = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('home')
- const openTabs = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([
- { id: 'home', title: '欢迎', path: '/', closable: false }
- ])
-
- const currentUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- id: null,
- name: '',
- email: '',
- avatar: null,
- role: '',
- lastLogin: null,
- lastLoginIP: '',
- status: 1,
- roles: []
- })
-
- // 创建一个安全的用户对象,确保所有属性都有安全的值
- const safeCurrentUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- return {
- id: currentUser.id || null,
- name: currentUser.name || '',
- email: currentUser.email || '',
- avatar: currentUser.avatar || null,
- role: currentUser.role || '',
- lastLogin: currentUser.lastLogin || null,
- lastLoginIP: currentUser.lastLoginIP || '',
- status: currentUser.status || 1,
- roles: Array.isArray(currentUser.roles) ? currentUser.roles : []
- }
- })
-
- // 登录状态
- const isLoggedIn = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
-
- // 应用设置
- const appSettings = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- appName: 'GoFaster'
- })
-
- // Toast 配置
- const toastConfig = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- type: 'info',
- title: '',
- content: '',
- duration: 3000
- })
-
- // 会话超时相关
- let sessionTimeoutTimer = null
- let lastActivityTime = Date.now()
- const sessionTimeoutMinutes = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(30) // 默认30分钟
-
- const messages = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([
- {
- id: 1,
- title: '系统更新完成',
- icon: '🔄',
- time: new Date(Date.now() - 1000 * 60 * 30),
- read: false
- },
- {
- id: 2,
- title: '新用户注册',
- icon: '👤',
- time: new Date(Date.now() - 1000 * 60 * 60),
- read: false
- }
- ])
-
- const allMenuItems = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([
- { id: 'home', name: '欢迎', path: '/', icon: 'home', favorite: false, requireAuth: false },
- { id: 'speed-test', name: '速度测试', path: '/speed-test', icon: 'bolt', favorite: false, requireAuth: true },
- { id: 'user-management', name: '用户管理', path: '/user-management', icon: 'users', favorite: false, requireAuth: true },
- { id: 'role-management', name: '角色管理', path: '/role-management', icon: 'user-shield', favorite: false, requireAuth: true },
- { id: 'history', name: '历史记录', path: '/history', icon: 'chart-bar', favorite: false, requireAuth: true },
- { id: 'user-profile', name: '个人资料', path: '/user-profile', icon: 'user', favorite: false, requireAuth: true },
- { id: 'settings', name: '用户设置', path: '/settings', icon: 'cog', favorite: false, requireAuth: false }
- ])
-
- // 根据登录状态过滤菜单项
- const mainMenuItems = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- if (isLoggedIn.value) {
- return allMenuItems.value
- } else {
- return allMenuItems.value.filter(item => !item.requireAuth)
- }
- })
-
- const favoriteMenuItems = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
-
- // 计算属性
- const unreadCount = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => messages.value.filter(m => !m.read).length)
- const currentRoute = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => route.path)
-
-
- const breadcrumbs = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- const path = route.path
- if (path === '/') return ['欢迎']
- if (path === '/user-management') return ['欢迎', '用户管理']
- if (path === '/role-management') return ['欢迎', '角色管理']
- if (path === '/speed-test') return ['欢迎', '速度测试']
- if (path === '/history') return ['欢迎', '历史记录']
- if (path === '/settings') return ['欢迎', '用户设置']
- if (path === '/user-profile') return ['欢迎', '个人资料']
- return ['欢迎']
- })
-
- // 方法
- const toggleMessagePanel = () => {
- showMessagePanel.value = !showMessagePanel.value
- showUserMenu.value = false
- }
-
- const toggleUserMenu = () => {
- showUserMenu.value = !showUserMenu.value
- showMessagePanel.value = false
- }
-
- // 关闭所有悬浮菜单
- const closeAllMenus = () => {
- showMessagePanel.value = false
- showUserMenu.value = false
- }
-
- // 处理全局点击事件
- const handleGlobalClick = (event) => {
- // 检查点击是否在消息面板内
- const messagePanel = document.querySelector('.message-panel')
- const messageBtn = document.querySelector('.message-btn')
-
- // 检查点击是否在用户菜单内
- const userMenu = document.querySelector('.user-menu')
- const userAvatar = document.querySelector('.user-avatar')
-
- // 如果点击在消息面板或消息按钮外,且消息面板是打开的,则关闭
- if (showMessagePanel.value &&
- messagePanel &&
- !messagePanel.contains(event.target) &&
- messageBtn &&
- !messageBtn.contains(event.target)) {
- showMessagePanel.value = false
- }
-
- // 如果点击在用户菜单或用户头像外,且用户菜单是打开的,则关闭
- if (showUserMenu.value &&
- userMenu &&
- !userMenu.contains(event.target) &&
- userAvatar &&
- !userAvatar.contains(event.target)) {
- showUserMenu.value = false
- }
- }
-
-
-
- const handleMenuClick = (item) => {
- // 添加标签页
- addTabIfNotExists({
- id: item.id,
- title: item.name,
- path: item.path,
- closable: true
- })
- }
-
- const switchTab = (tabId) => {
- currentTab.value = tabId
- const tab = openTabs.value.find(t => t.id === tabId)
- if (tab) {
- router.push(tab.path)
- }
- }
-
- const closeTab = (tabId) => {
- const index = openTabs.value.findIndex(tab => tab.id === tabId)
- if (index > -1) {
- openTabs.value.splice(index, 1)
- // 如果关闭的是当前标签页,切换到前一个标签页
- if (currentTab.value === tabId) {
- const newTab = openTabs.value[index - 1] || openTabs.value[0]
- if (newTab) {
- currentTab.value = newTab.id
- router.push(newTab.path)
- }
- }
- }
- }
-
- const closeAllTabs = () => {
- openTabs.value = openTabs.value.filter(tab => !tab.closable)
- currentTab.value = 'home'
- router.push('/')
- }
-
- const toggleFavorite = (itemId) => {
- const item = allMenuItems.value.find(i => i.id === itemId)
- if (item) {
- item.favorite = !item.favorite
- updateFavoriteMenu()
- }
- }
-
- const updateFavoriteMenu = () => {
- favoriteMenuItems.value = allMenuItems.value.filter(item => item.favorite)
- }
-
- const markAsRead = (messageId) => {
- const message = messages.value.find(m => m.id === messageId)
- if (message) {
- message.read = true
- }
- }
-
- const formatTime = (time) => {
- const now = new Date()
- const diff = now - time
- const minutes = Math.floor(diff / (1000 * 60))
- const hours = Math.floor(diff / (1000 * 60 * 60))
- const days = Math.floor(diff / (1000 * 60 * 60 * 24))
-
- if (minutes < 60) return `${minutes}分钟前`
- if (hours < 24) return `${hours}小时前`
- return `${days}天前`
- }
-
- const formatLastLogin = (lastLogin) => {
- if (!lastLogin) return '未知'
-
- try {
- const loginTime = new Date(lastLogin)
- const now = new Date()
- const diff = now - loginTime
- const minutes = Math.floor(diff / (1000 * 60))
- const hours = Math.floor(diff / (1000 * 60 * 60))
- const days = Math.floor(diff / (1000 * 60 * 60 * 24))
-
- if (minutes < 60) return `${minutes}分钟前`
- if (hours < 24) return `${hours}小时前`
- if (days < 7) return `${days}天前`
-
- // 超过7天显示具体日期
- return loginTime.toLocaleDateString('zh-CN', {
- month: 'short',
- day: 'numeric',
- hour: '2-digit',
- minute: '2-digit'
- })
- } catch (error) {
- return '未知'
- }
- }
-
- const openProfile = () => {
- showUserMenu.value = false
-
- // 添加标签页
- addTabIfNotExists({
- id: 'user-profile',
- title: '个人资料',
- path: '/user-profile',
- closable: true
- })
-
- router.push('/user-profile')
- }
-
- const openSettings = () => {
- showUserMenu.value = false
-
- // 添加标签页
- addTabIfNotExists({
- id: 'settings',
- title: '用户设置',
- path: '/settings',
- closable: true
- })
-
- router.push('/settings')
- }
-
- // 统一的添加标签页方法
- const addTabIfNotExists = (tabInfo) => {
- const existingTab = openTabs.value.find(tab => tab.id === tabInfo.id)
- if (!existingTab) {
- openTabs.value.push(tabInfo)
- }
- currentTab.value = tabInfo.id
- }
-
- // 处理从子组件添加标签页的请求
- const handleAddTab = (tabInfo) => {
- addTabIfNotExists(tabInfo)
- }
-
- const showLoginModal = () => {
- showLoginModalFlag.value = true
- showUserMenu.value = false
- }
-
- // 处理密码修改成功
- const handlePasswordChangeSuccess = () => {
- // 关闭密码修改弹窗
- showPasswordModal.value = false
- isForceChange.value = false
-
- // 显示成功消息
- showToastMessage('success', '密码修改成功', '您的密码已成功修改')
-
- // 跳转到首页
- router.push('/')
- }
-
- const handleLoginSuccess = async (response) => {
- // 检查响应数据结构 - 后端返回的是 { code: 200, message: "登录成功", data: { token: "...", user: {...} } }
- const responseData = response.data || response
- const token = responseData.token
- const user = responseData.user
-
- if (!token) {
- console.error('登录响应中没有token:', response)
- return
- }
-
- // 更新登录状态
- isLoggedIn.value = true
-
- // 保存token到本地存储
- localStorage.setItem('isLoggedIn', 'true')
- localStorage.setItem('token', token)
-
- // 关闭登录弹窗
- showLoginModalFlag.value = false
-
- try {
- // 登录成功后,调用后端接口获取完整的用户信息
- const userResponse = await _modules_user_management__WEBPACK_IMPORTED_MODULE_3__.userService.getCurrentUser(token)
-
-
- if (userResponse.data) {
- const userData = userResponse.data
-
- // 更新用户信息 - 使用后端返回的完整信息,确保字段名一致
- currentUser.id = userData.id || null
- currentUser.name = userData.username || '用户'
- currentUser.email = userData.email || ''
- currentUser.phone = userData.phone || '' // 添加电话字段
- currentUser.avatar = null
- // 从roles数组中获取第一个角色名称
- currentUser.role = userData.roles && userData.roles.length > 0 ? userData.roles[0].name : ''
- currentUser.lastLogin = userData.last_login_at || null
- currentUser.lastLoginAt = userData.last_login_at || null // 添加兼容字段
- currentUser.lastLoginIP = userData.last_login_ip || ''
- currentUser.status = userData.status || 1
- currentUser.roles = userData.roles || []
-
- // 保存完整的用户信息到本地存储,使用一致的字段名
- const userForStorage = {
- id: currentUser.id,
- username: currentUser.name, // 保持与后端一致
- name: currentUser.name,
- email: currentUser.email,
- phone: currentUser.phone,
- status: currentUser.status,
- roles: currentUser.roles,
- last_login_at: userData.last_login_at || null,
- last_login_ip: userData.last_login_ip || ''
- }
- localStorage.setItem('user', JSON.stringify(userForStorage))
-
-
-
- // 检查是否需要强制修改密码
- if (userData.force_change_password) {
- isForceChange.value = true
- showPasswordModal.value = true
- showToastMessage('warning', '密码重置提醒', '您的密码已被重置,请立即修改密码')
- } else {
- // 触发全局事件,通知其他组件用户已登录
- window.dispatchEvent(new CustomEvent('user-login-success', {
- detail: { user: currentUser, token: token }
- }))
-
- // 显示欢迎消息 - 确保用户名称存在
- const userName = currentUser.name || userData.username || '用户'
- showToastMessage('success', '登录成功', `欢迎回来,${userName}!`)
-
- // 启动会话超时检测
- startSessionTimeoutCheck()
-
- // 更新用户活动时间
- updateUserActivity()
-
- // 跳转到首页
- router.push('/')
- }
- }
- } catch (error) {
- console.error('获取用户信息失败:', error)
-
- // 如果获取用户信息失败,使用登录响应中的基本信息
- if (user) {
- currentUser.id = user.id || null
- currentUser.name = user.username || '用户'
- currentUser.email = user.email || ''
- currentUser.phone = user.phone || ''
- currentUser.avatar = null
- currentUser.role = ''
- currentUser.lastLogin = null
- currentUser.lastLoginIP = ''
- currentUser.status = 1
- currentUser.roles = []
-
- // 保存基本信息到本地存储
- const userForStorage = {
- id: currentUser.id,
- username: currentUser.name,
- name: currentUser.name,
- email: currentUser.email,
- phone: currentUser.phone,
- status: currentUser.status,
- roles: currentUser.roles,
- last_login_at: null,
- last_login_ip: ''
- }
- localStorage.setItem('user', JSON.stringify(userForStorage))
-
- // 显示欢迎消息 - 使用基本信息
- const userName = currentUser.name || user.username || '用户'
- showToastMessage('success', '登录成功', `欢迎回来,${userName}!`)
-
- // 跳转到首页
- router.push('/')
- } else {
- // 如果连基本信息都没有,显示通用消息
- showToastMessage('success', '登录成功', '欢迎回来!')
-
- // 跳转到首页
- router.push('/')
- }
- }
-
- // 强制触发响应式更新
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.nextTick)()
- }
-
- const handleShowMessage = (message) => {
- // 配置 Toast 消息
- toastConfig.type = message.type || 'info'
- toastConfig.title = message.title || '消息'
- toastConfig.content = message.content || ''
- toastConfig.duration = message.duration || 3000
-
- // 显示 Toast
- showToast.value = true
- }
-
- // 显示Toast消息的便捷函数
- const showToastMessage = (type, title, content, duration = 3000) => {
- toastConfig.type = type
- toastConfig.title = title
- toastConfig.content = content
- toastConfig.duration = duration
- showToast.value = true
- }
-
- // 更新用户活动时间
- const updateUserActivity = () => {
- lastActivityTime = Date.now()
- }
-
- // 启动会话超时检测
- const startSessionTimeoutCheck = () => {
- // 清除之前的定时器
- if (sessionTimeoutTimer) {
- clearInterval(sessionTimeoutTimer)
- }
-
- // 获取用户设置的会话超时时间
- try {
- const userSettings = localStorage.getItem('gofaster-settings')
- if (userSettings) {
- const settings = JSON.parse(userSettings)
- if (settings.sessionTimeout) {
- sessionTimeoutMinutes.value = settings.sessionTimeout
- }
- }
- } catch (error) {
- console.error('获取会话超时设置失败:', error)
- }
-
- // 每分钟检查一次会话状态
- sessionTimeoutTimer = setInterval(() => {
- const currentTime = Date.now()
- const inactiveTime = (currentTime - lastActivityTime) / 1000 / 60 // 转换为分钟
-
- if (inactiveTime >= sessionTimeoutMinutes.value) {
- showToastMessage('warning', '会话超时', '您的会话已超时,将自动退出登录')
-
- // 延迟2秒后执行退出登录,让用户看到提示
- setTimeout(() => {
- logout()
- }, 2000)
- }
- }, 60000) // 每分钟检查一次
- }
-
- // 停止会话超时检测
- const stopSessionTimeoutCheck = () => {
- if (sessionTimeoutTimer) {
- clearInterval(sessionTimeoutTimer)
- sessionTimeoutTimer = null
- }
- }
-
- // 统一的退出登录函数
- const performLogout = () => {
- if (!isLoggedIn.value) return
-
- try {
-
- // 获取token并尝试调用后端接口
- const token = localStorage.getItem('token')
- if (token) {
- // 异步调用登出接口,不等待结果
- _modules_user_management__WEBPACK_IMPORTED_MODULE_3__.userService.logout(token).catch(error => {
- console.error('调用登出接口失败:', error)
- })
- }
-
- // 清除本地状态
- localStorage.removeItem('user')
- localStorage.removeItem('isLoggedIn')
- localStorage.removeItem('token')
-
- // 清除用户对象状态
- Object.assign(currentUser, {
- id: null,
- name: '',
- email: '',
- avatar: null,
- role: '',
- lastLogin: null,
- lastLoginIP: '',
- status: 1,
- roles: []
- })
-
- // 更新登录状态
- isLoggedIn.value = false
-
- // 停止会话超时检测
- stopSessionTimeoutCheck()
-
- } catch (error) {
- console.error('退出登录失败:', error)
- }
- }
-
- // 处理应用关闭事件(主进程事件)
- const handleAppWillClose = () => {
-
- // 检查用户设置,如果选择"关闭窗口不登出",则不执行退出登录
- try {
- const userSettings = localStorage.getItem('gofaster-settings')
- if (userSettings) {
- const settings = JSON.parse(userSettings)
- if (settings.keepLoginOnClose) {
- return
- }
- }
- } catch (error) {
- console.error('读取用户设置失败:', error)
- }
-
- // 执行退出登录
- performLogout()
- }
-
- // 处理页面卸载事件
- const handleBeforeUnload = () => {
- if (isLoggedIn.value) {
-
- // 检查用户设置,如果选择"关闭窗口不登出",则不执行退出登录
- try {
- const userSettings = localStorage.getItem('gofaster-settings')
- if (userSettings) {
- const settings = JSON.parse(userSettings)
- if (settings.keepLoginOnClose) {
- return
- }
- }
- } catch (error) {
- console.error('读取用户设置失败:', error)
- }
-
- // 执行退出登录
- performLogout()
- }
- }
-
- // 处理页面隐藏事件
- const handleVisibilityChange = () => {
- if (document.visibilityState === 'hidden' && isLoggedIn.value) {
-
- // 检查用户设置,如果选择"关闭窗口不登出",则不执行退出登录
- try {
- const userSettings = localStorage.getItem('gofaster-settings')
- if (userSettings) {
- const settings = JSON.parse(userSettings)
- if (settings.keepLoginOnClose) {
- return
- }
- }
- } catch (error) {
- console.error('读取用户设置失败:', error)
- }
-
- // 执行退出登录
- performLogout()
- }
- }
-
- // 处理窗口焦点丢失事件
- const handleWindowBlur = () => {
- // 可以在这里添加额外的检查逻辑
- // 暂时不执行退出登录,因为用户可能只是切换到其他窗口
- }
-
- // 自动退出登录(不显示提示)
- const autoLogout = async () => {
- try {
- // 获取当前token
- const token = localStorage.getItem('token')
- if (token) {
- // 调用后端登出接口
- await _modules_user_management__WEBPACK_IMPORTED_MODULE_3__.userService.logout(token)
- }
- } catch (error) {
- console.error('调用登出接口失败:', error)
- } finally {
- // 清除用户信息
- currentUser.id = null
- currentUser.name = ''
- currentUser.email = ''
- currentUser.avatar = null
- currentUser.role = ''
- currentUser.lastLogin = null
- currentUser.lastLoginIP = ''
- currentUser.status = 1
- currentUser.roles = []
- isLoggedIn.value = false
-
- // 清除本地存储
- localStorage.removeItem('user')
- localStorage.removeItem('isLoggedIn')
- localStorage.removeItem('token')
-
- // 关闭用户菜单
- showUserMenu.value = false
-
- // 触发全局事件,通知其他组件用户已登出
- window.dispatchEvent(new CustomEvent('user-logout', {
- detail: { user: currentUser }
- }))
-
- // 跳转到首页
- router.push('/')
- }
- }
-
- const logout = async () => {
- try {
- // 获取当前token
- const token = localStorage.getItem('token')
- if (token) {
- // 调用后端登出接口
- await _modules_user_management__WEBPACK_IMPORTED_MODULE_3__.userService.logout(token)
- }
- } catch (error) {
- console.error('调用登出接口失败:', error)
- // 即使后端调用失败,也要清除本地状态
- } finally {
- // 停止会话超时检测
- stopSessionTimeoutCheck()
-
- // 清除用户信息
- currentUser.id = null
- currentUser.name = ''
- currentUser.email = ''
- currentUser.avatar = null
- currentUser.role = ''
- currentUser.lastLogin = null
- currentUser.lastLoginIP = ''
- currentUser.status = 1
- currentUser.roles = []
- isLoggedIn.value = false
-
- // 清除本地存储
- localStorage.removeItem('user')
- localStorage.removeItem('isLoggedIn')
- localStorage.removeItem('token')
-
- // 关闭用户菜单
- showUserMenu.value = false
-
- // 触发全局事件,通知其他组件用户已登出
- window.dispatchEvent(new CustomEvent('user-logout', {
- detail: { user: currentUser }
- }))
-
- // 跳转到首页
- router.push('/')
-
- // 显示登出成功消息
- handleShowMessage({
- type: 'info',
- title: '已退出登录',
- content: '您已成功退出登录'
- })
- }
- }
-
- // 监听路由变化
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => route.path, (newPath) => {
- const tab = openTabs.value.find(t => t.path === newPath)
- if (tab) {
- currentTab.value = tab.id
- }
- })
-
- // 监听应用设置变化
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => localStorage.getItem('gofaster-settings'), (newSettings) => {
- if (newSettings) {
- try {
- const parsedSettings = JSON.parse(newSettings)
- if (parsedSettings.appName && parsedSettings.appName !== appSettings.appName) {
- appSettings.appName = parsedSettings.appName
- // 更新窗口标题
- if (window.electronAPI && window.electronAPI.updateWindowTitle) {
- window.electronAPI.updateWindowTitle(parsedSettings.appName)
- }
- }
-
- // 监听主题变化
- if (parsedSettings.theme && parsedSettings.theme !== _modules_core__WEBPACK_IMPORTED_MODULE_4__.themeManager.getCurrentTheme()) {
- _modules_core__WEBPACK_IMPORTED_MODULE_4__.themeManager.setTheme(parsedSettings.theme)
- }
- } catch (error) {
- console.error('解析用户应用设置失败:', error)
- }
- }
- }, { immediate: false })
-
- const loadAppSettings = () => {
- try {
- const savedSettings = localStorage.getItem('gofaster-settings')
- if (savedSettings) {
- const parsedSettings = JSON.parse(savedSettings)
- if (parsedSettings.appName) {
- appSettings.appName = parsedSettings.appName
- // 初始加载时也更新窗口标题
- if (window.electronAPI && window.electronAPI.updateWindowTitle) {
- window.electronAPI.updateWindowTitle(parsedSettings.appName)
- }
- }
- }
- } catch (error) {
- console.error('加载用户应用设置失败:', error)
- }
- }
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- // 初始化收藏菜单
- updateFavoriteMenu()
-
- // 添加用户活动监听器
- const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
- userActivityEvents.forEach(event => {
- document.addEventListener(event, updateUserActivity, { passive: true })
- })
-
- // 1. 监听主进程应用关闭事件(主要方案)
- if (window.electronAPI && window.electronAPI.onAppWillClose) {
- window.electronAPI.onAppWillClose(handleAppWillClose)
- } else {
- console.warn('electronAPI不可用,无法注册主进程应用关闭事件监听器')
- }
-
- // 2. 监听页面卸载事件(备用方案)
- window.addEventListener('beforeunload', handleBeforeUnload)
-
- // 3. 监听页面隐藏事件(额外备用方案)
- document.addEventListener('visibilitychange', handleVisibilityChange)
-
- // 4. 监听窗口焦点丢失事件(Windows 特有,暂时只记录不执行退出)
- window.addEventListener('blur', handleWindowBlur)
-
- // 检查登录状态
- const savedIsLoggedIn = localStorage.getItem('isLoggedIn')
- const savedUser = localStorage.getItem('user')
-
- if (savedIsLoggedIn === 'true' && savedUser) {
- try {
- const userData = JSON.parse(savedUser)
-
- // 先设置默认值,然后用localStorage的数据覆盖
- const defaultUser = {
- id: null,
- name: '',
- email: '',
- avatar: null,
- role: '',
- lastLogin: null,
- lastLoginIP: '',
- status: 1,
- roles: []
- }
-
- // 确保字段名映射正确
- const mappedUserData = {
- id: userData.id || null,
- name: userData.username || userData.name || '',
- email: userData.email || '',
- avatar: userData.avatar || null,
- role: userData.role || '',
- lastLogin: userData.last_login_at || userData.lastLogin || null,
- lastLoginIP: userData.last_login_ip || userData.lastLoginIP || '',
- status: userData.status || 1,
- roles: userData.roles || []
- }
-
- Object.assign(currentUser, defaultUser, mappedUserData)
-
- isLoggedIn.value = true
- } catch (error) {
- console.warn('解析用户信息失败:', error)
- // 清除无效的用户信息
- localStorage.removeItem('user')
- localStorage.removeItem('isLoggedIn')
- }
- }
-
- // 加载应用设置
- loadAppSettings()
-
- // 初始化主题
- const savedSettings = localStorage.getItem('gofaster-settings')
- if (savedSettings) {
- try {
- const settings = JSON.parse(savedSettings)
- if (settings.theme) {
- _modules_core__WEBPACK_IMPORTED_MODULE_4__.themeManager.setTheme(settings.theme)
- }
- } catch (error) {
- console.warn('加载用户主题设置失败:', error)
- }
- }
-
- // 监听全局登录弹窗事件
- window.addEventListener('show-login-modal', () => {
- showLoginModalFlag.value = true
- })
-
- // 添加全局点击事件监听器
- document.addEventListener('click', handleGlobalClick)
-
-
- })
-
- // 组件卸载时清理事件监听器
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(() => {
- document.removeEventListener('click', handleGlobalClick)
-
- // 移除用户活动监听器
- const userActivityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click']
- userActivityEvents.forEach(event => {
- document.removeEventListener(event, updateUserActivity)
- })
-
- // 移除应用关闭相关的事件监听器
- window.removeEventListener('beforeunload', handleBeforeUnload)
- document.removeEventListener('visibilitychange', handleVisibilityChange)
- window.removeEventListener('blur', handleWindowBlur)
-
- // 停止会话超时检测
- stopSessionTimeoutCheck()
- })
-
- // 提供响应式数据给子组件
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)('isLoggedIn', isLoggedIn)
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)('currentUser', safeCurrentUser)
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.provide)('showLoginModal', showLoginModal)
-
- // 获取导航图标类名的方法
- const getNavIconClass = (iconName) => {
- return `fas fa-${iconName}`
- }
-
-
- return {
- showMessagePanel,
- showUserMenu,
- showLoginModalFlag,
- showToast,
- currentTab,
- openTabs,
- currentUser: safeCurrentUser,
- isLoggedIn,
- appSettings,
- toastConfig,
- messages,
- mainMenuItems,
- favoriteMenuItems,
- unreadCount,
- currentRoute,
- breadcrumbs,
- toggleMessagePanel,
- toggleUserMenu,
- closeAllMenus,
- handleGlobalClick,
- showLoginModal,
- handleMenuClick,
- switchTab,
- closeTab,
- closeAllTabs,
- toggleFavorite,
- markAsRead,
- formatTime,
- formatLastLogin,
- openProfile,
- openSettings,
- logout,
- handleLoginSuccess,
- handlePasswordChangeSuccess,
- handleShowMessage,
- loadAppSettings,
- handleAddTab,
- addTabIfNotExists,
- showPasswordModal,
- isForceChange,
- showToastMessage,
- getNavIconClass
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=script&lang=js":
-/*!***********************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=script&lang=js ***!
- \***********************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _config_app_config_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../../config/app.config.js */ "./src/config/app.config.js");
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'StatusBar',
- data() {
- return {
- serverUrl: (0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_0__.getFinalConfig)().serverUrl,
- userInfo: '未登录',
- errorCount: 0,
- appVersion: ({"NODE_ENV":"development","BASE_URL":""}).VUE_APP_VERSION || '1.0.0',
- memoryUsage: 0,
- systemMemoryUsage: 'N/A',
- intervalId: null
- };
- },
- mounted() {
- // 获取初始错误日志计数
- this.getInitialErrorCount();
-
- this.intervalId = setInterval(() => {
- this.updateMemoryUsage();
- }, 3000); // 每3秒更新一次
-
- // 监听用户登录状态变化
- this.listenToUserChanges();
-
- // 设置主进程监听器
- this.setupMainProcessListeners();
-
- // 监听localStorage变化
- window.addEventListener('storage', this.updateServerUrl);
-
- // 监听自定义事件(当设置页面保存配置时触发)
- window.addEventListener('gofaster-settings-changed', this.updateServerUrl);
-
- // 监听用户登录成功事件
- window.addEventListener('user-login-success', this.handleUserLogin);
-
- // 监听用户登出事件
- window.addEventListener('user-logout', this.handleUserLogout);
- },
- beforeDestroy() {
- if (this.intervalId) {
- clearInterval(this.intervalId);
- }
-
- window.removeEventListener('storage', this.updateServerUrl);
- window.removeEventListener('gofaster-settings-changed', this.updateServerUrl);
- window.removeEventListener('user-login-success', this.handleUserLogin);
- window.removeEventListener('user-logout', this.handleUserLogout);
- },
-
- methods: {
- // 更新内存使用情况
- async updateMemoryUsage() {
- try {
- // 使用 Electron 的 IPC 获取进程内存信息
- if (window.electronAPI && window.electronAPI.getProcessMemoryInfo) {
- const memoryInfo = await window.electronAPI.getProcessMemoryInfo();
- if (memoryInfo && memoryInfo.privateBytes) {
- // privateBytes 是进程的私有内存使用量(字节)
- this.memoryUsage = (memoryInfo.privateBytes / (1024 * 1024)).toFixed(1);
- }
-
- // 显示系统内存使用情况
- if (memoryInfo.systemTotal && memoryInfo.systemUsed) {
- const totalGB = (memoryInfo.systemTotal / (1024 * 1024 * 1024)).toFixed(1);
- const usedGB = (memoryInfo.systemUsed / (1024 * 1024 * 1024)).toFixed(1);
- const usedPercent = ((memoryInfo.systemUsed / memoryInfo.systemTotal) * 100).toFixed(1);
- this.systemMemoryUsage = `${usedGB}/${totalGB} GB (${usedPercent}%)`;
- }
- } else {
- // 回退到浏览器API
- this.fallbackMemoryUsage();
- }
- } catch (error) {
- console.warn('无法获取内存使用情况:', error);
- this.fallbackMemoryUsage();
- }
- },
-
- // 回退的内存获取方法
- fallbackMemoryUsage() {
- if (window.performance && window.performance.memory) {
- const memory = window.performance.memory;
- // 使用 usedJSHeapSize 作为JavaScript堆内存使用量
- this.memoryUsage = (memory.usedJSHeapSize / (1024 * 1024)).toFixed(1);
- this.systemMemoryUsage = 'N/A (浏览器模式)';
- } else {
- this.memoryUsage = 'N/A';
- this.systemMemoryUsage = 'N/A';
- }
- },
-
- // 获取初始错误日志计数
- async getInitialErrorCount() {
- try {
- if (window.electronAPI && window.electronAPI.getErrorLogCount) {
- const result = await window.electronAPI.getErrorLogCount();
- this.errorCount = result.count || 0;
- }
- } catch (error) {
- console.warn('无法获取初始错误日志计数:', error);
- }
- },
-
- // 监听用户登录状态变化
- listenToUserChanges() {
- // 检查localStorage中的用户信息
- const savedUser = localStorage.getItem('user');
- const isLoggedIn = localStorage.getItem('isLoggedIn') === 'true';
-
- if (isLoggedIn && savedUser) {
- try {
- const user = JSON.parse(savedUser);
- // 优先使用username字段,保持与后端一致
- this.userInfo = user.username || user.name || '已登录';
- } catch (error) {
- console.warn('解析用户信息失败:', error);
- this.userInfo = '已登录';
- }
- } else {
- this.userInfo = '未登录';
- }
- },
-
- // 处理用户登录成功
- handleUserLogin(event) {
- if (event.detail && event.detail.user) {
- const user = event.detail.user;
- this.userInfo = user.username || user.name || '已登录';
- }
- },
-
- // 处理用户登出
- handleUserLogout() {
- this.userInfo = '未登录';
- },
-
- // 监听主进程消息
- setupMainProcessListeners() {
- if (window.electronAPI) {
- window.electronAPI.onStatusUpdate((event, data) => {
- if (data.userInfo) this.userInfo = data.userInfo;
- if (data.errorCount !== undefined) this.errorCount = data.errorCount;
- });
-
- window.electronAPI.onErrorLogUpdated((event, data) => {
- if (data.count !== undefined) {
- this.errorCount = data.count;
- }
- });
- }
- },
-
- // 监听设置变化,更新服务地址
- updateServerUrl() {
- const config = (0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_0__.getFinalConfig)();
- this.serverUrl = config.serverUrl;
- },
-
- // 打开日志文件夹
- async openLogFolder() {
- try {
- if (window.electronAPI && window.electronAPI.openLogFolder) {
- const result = await window.electronAPI.openLogFolder();
- if (!result.success) {
- console.warn('打开日志文件夹失败:', result.message);
- }
- }
- } catch (error) {
- console.warn('打开日志文件夹失败:', error);
- }
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=script&lang=js":
-/*!*******************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=script&lang=js ***!
- \*******************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'Toast',
- props: {
- visible: {
- type: Boolean,
- default: false
- },
- type: {
- type: String,
- default: 'info',
- validator: value => ['success', 'error', 'warning', 'info'].includes(value)
- },
- title: {
- type: String,
- required: true
- },
- content: {
- type: String,
- default: ''
- },
- duration: {
- type: Number,
- default: 3000
- }
- },
- computed: {
- iconClass() {
- const icons = {
- success: 'fas fa-check-circle',
- error: 'fas fa-times-circle',
- warning: 'fas fa-exclamation-triangle',
- info: 'fas fa-info-circle'
- }
- return icons[this.type] || icons.info
- }
- },
- watch: {
- visible(newVal) {
- if (newVal && this.duration > 0) {
- setTimeout(() => {
- this.close()
- }, this.duration)
- }
- }
- },
- methods: {
- close() {
- this.$emit('update:visible', false)
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=script&lang=js":
-/*!*******************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=script&lang=js ***!
- \*******************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _config_app_config_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../../config/app.config.js */ "./src/config/app.config.js");
-/* harmony import */ var _config_env_config_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../config/env.config.js */ "./src/config/env.config.js");
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'ConfigTest',
- setup() {
- const currentConfig = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({});
- const envConfigInfo = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('');
- const testing = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false);
- const testResult = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null);
-
- const loadConfig = () => {
- currentConfig.value = (0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_1__.getFinalConfig)();
- envConfigInfo.value = (0,_config_env_config_js__WEBPACK_IMPORTED_MODULE_2__.getEnvConfigInfo)();
- };
-
- const testApiConnection = async () => {
- testing.value = true;
- testResult.value = null;
-
- try {
- const response = await fetch(currentConfig.value.apiBaseUrl);
- if (response.ok) {
- testResult.value = {
- success: true,
- message: 'API连接成功!'
- };
- } else {
- testResult.value = {
- success: false,
- message: `API连接失败: HTTP ${response.status}`
- };
- }
- } catch (error) {
- testResult.value = {
- success: false,
- message: `API连接失败: ${error.message}`
- };
- } finally {
- testing.value = false;
- }
- };
-
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- loadConfig();
- });
-
- return {
- currentConfig,
- envConfigInfo,
- testing,
- testResult,
- testApiConnection
- };
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=script&lang=js":
-/*!*************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=script&lang=js ***!
- \*************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'HomeView',
- inject: ['isLoggedIn', 'currentUser', 'showLoginModal'],
- data() {
- return {
- userInfo: {
- name: '用户',
- email: 'user@example.com',
- avatar: 'fas fa-user'
- },
- currentDate: '',
- stats: {
- totalTests: 0,
- avgSpeed: '0 Mbps',
- bestSpeed: '0 Mbps'
- },
- todoList: [
- { id: 1, text: '完成网络速度测试', completed: false, date: '今天' },
- { id: 2, text: '查看历史测试记录', completed: true, date: '昨天' },
- { id: 3, text: '配置测试参数', completed: false, date: '明天' }
- ],
- recentActivities: [
- { id: 1, icon: 'fas fa-bolt', title: '完成速度测试', time: '2小时前' },
- { id: 2, icon: 'fas fa-chart-bar', title: '查看测试报告', time: '昨天' },
- { id: 3, icon: 'fas fa-cog', title: '更新设置', time: '3天前' }
- ],
- db: null // 新增:用于存储数据库实例
- }
- },
- computed: {
- // 计算属性,确保响应式更新
- computedIsLoggedIn() {
- return this.isLoggedIn
- },
- computedCurrentUser() {
- return this.currentUser
- }
- },
- methods: {
- updateCurrentDate() {
- const now = new Date();
- const options = {
- year: 'numeric',
- month: 'long',
- day: 'numeric',
- weekday: 'long'
- };
- this.currentDate = now.toLocaleDateString('zh-CN', options);
- },
- async loadUserData() {
- try {
- // 从数据库加载用户数据
- if (this.db && this.db.data && this.db.data.userInfo) {
- this.userInfo = this.db.data.userInfo;
- }
- } catch (error) {
- console.error('加载用户数据失败:', error);
- }
- },
- async loadStats() {
- try {
- // 从数据库加载统计数据
- if (this.db && this.db.data && this.db.data.stats) {
- this.stats = this.db.data.stats;
- }
- } catch (error) {
- console.error('加载统计数据失败:', error);
- }
- },
- async loadTodoList() {
- try {
- // 从数据库加载待办事项
- if (this.db && this.db.data && this.db.data.todoList) {
- this.todoList = this.db.data.todoList;
- }
- } catch (error) {
- console.error('加载待办事项失败:', error);
- }
- },
- async loadRecentActivities() {
- try {
- // 从数据库加载最近活动
- if (this.db && this.db.data && this.db.data.recentActivities) {
- this.recentActivities = this.db.data.recentActivities;
- }
- } catch (error) {
- console.error('加载最近活动失败:', error);
- }
- },
- startSpeedTest() {
- this.$router.push('/speed-test');
- },
- viewHistory() {
- this.$router.push('/history');
- },
- openSettings() {
-
- // 通过事件通知父组件添加标签页
- this.$emit('add-tab', {
- id: 'settings',
- title: '用户设置',
- path: '/settings',
- closable: true
- });
-
- this.$router.push('/settings');
- },
- exportData() {
- console.log('导出数据');
- },
- showLoginModalHandler() {
- // 调用注入的登录弹窗方法
- if (this.showLoginModal) {
- this.showLoginModal();
- }
- },
- async addTodo() {
- const newTodo = {
- id: Date.now(),
- text: '新的待办事项',
- completed: false,
- date: '今天'
- };
- this.todoList.unshift(newTodo);
-
- // 保存到数据库
- try {
- if (this.db && this.db.data) {
- this.db.data.todoList = this.todoList;
- await this.db.write();
- }
- } catch (error) {
- console.error('保存待办事项失败:', error);
- }
- },
- async toggleTodo(id) {
- const todo = this.todoList.find(t => t.id === id);
- if (todo) {
- todo.completed = !todo.completed;
-
- // 保存到数据库
- try {
- if (this.db && this.db.data) {
- this.db.data.todoList = this.todoList;
- await this.db.write();
- }
- } catch (error) {
- console.error('更新待办事项失败:', error);
- }
- }
- },
- async deleteTodo(id) {
- this.todoList = this.todoList.filter(t => t.id !== id);
-
- // 保存到数据库
- try {
- if (this.db && this.db.data) {
- this.db.data.todoList = this.todoList;
- await this.db.write();
- }
- } catch (error) {
- console.error('删除待办事项失败:', error);
- }
- }
- },
- async mounted() {
- this.updateCurrentDate();
-
- // 等待数据库初始化完成
- try {
- const { db } = await Promise.resolve(/*! import() */).then(__webpack_require__.bind(__webpack_require__, /*! ../services/db */ "./src/renderer/modules/core/services/db.js"));
- this.db = db;
-
- // 加载所有数据
- await this.loadUserData();
- await this.loadStats();
- await this.loadTodoList();
- await this.loadRecentActivities();
- } catch (error) {
- console.error('数据库初始化失败:', error);
- }
-
- // 监听登录状态变化 - 使用计算属性确保响应式
- this.$watch('computedIsLoggedIn', (newVal) => {
- if (newVal && this.computedCurrentUser) {
- this.userInfo.name = this.computedCurrentUser.name || this.userInfo.name;
- this.userInfo.email = this.computedCurrentUser.email || this.userInfo.email;
- }
- }, { immediate: true });
-
- // 监听用户信息变化 - 使用计算属性确保响应式
- this.$watch('computedCurrentUser', (newUser) => {
- if (newUser && newUser.name) {
- this.userInfo.name = newUser.name;
- this.userInfo.email = newUser.email || this.userInfo.email;
- }
- }, { immediate: true, deep: true });
-
- // 监听全局登录成功事件
- window.addEventListener('user-login-success', (event) => {
- const { user } = event.detail;
- if (user) {
- this.userInfo.name = user.name || this.userInfo.name;
- this.userInfo.email = user.email || this.userInfo.email;
- }
- });
-
- // 监听全局登出事件
- window.addEventListener('user-logout', () => {
- this.userInfo.name = '用户';
- this.userInfo.email = 'user@example.com';
- });
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=script&lang=js":
-/*!******************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=script&lang=js ***!
- \******************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/roleService.js */ "./src/renderer/modules/role-management/services/roleService.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'PermissionManager',
- props: {
- modelValue: {
- type: Boolean,
- default: false
- },
- role: {
- type: Object,
- default: null
- }
- },
- emits: ['update:modelValue', 'saved'],
- setup(props, { emit }) {
- const visible = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const saving = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const currentRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
- const permissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const permissionTree = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const selectedPermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
-
- // 监听visible变化
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => props.modelValue, (newVal) => {
- visible.value = newVal
- if (newVal && props.role) {
- currentRole.value = props.role
- loadPermissions()
- loadRolePermissions()
- }
- })
-
- // 监听visible变化,同步到父组件
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(visible, (newVal) => {
- emit('update:modelValue', newVal)
- })
-
- // 获取权限列表
- const loadPermissions = async () => {
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getPermissions()
- permissions.value = response.data || []
- buildPermissionTree()
- } catch (error) {
- console.error('获取权限列表失败:', error)
- alert('获取权限列表失败')
- }
- }
-
- // 获取角色当前权限
- const loadRolePermissions = async () => {
- if (!currentRole.value) return
-
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getRole(currentRole.value.id)
- const roleData = response.data
- selectedPermissions.value = roleData.permissions?.map(p => p.id) || []
- } catch (error) {
- console.error('获取角色权限失败:', error)
- alert('获取角色权限失败')
- }
- }
-
- // 构建权限树
- const buildPermissionTree = () => {
- const resourceMap = {}
-
- permissions.value.forEach(permission => {
- if (!resourceMap[permission.resource]) {
- resourceMap[permission.resource] = {
- id: `resource_${permission.resource}`,
- name: permission.resource,
- children: []
- }
- }
- resourceMap[permission.resource].children.push({
- id: permission.id,
- name: `${permission.name} (${permission.action})`,
- permission: permission
- })
- })
-
- permissionTree.value = Object.values(resourceMap)
- }
-
- // 检查资源是否全选
- const isResourceChecked = (resource) => {
- const permissionIds = resource.children.map(p => p.id)
- return permissionIds.every(id => selectedPermissions.value.includes(id))
- }
-
- // 切换资源选择
- const toggleResource = (resource) => {
- const permissionIds = resource.children.map(p => p.id)
- const isChecked = isResourceChecked(resource)
-
- if (isChecked) {
- // 取消选择所有权限
- selectedPermissions.value = selectedPermissions.value.filter(id => !permissionIds.includes(id))
- } else {
- // 选择所有权限
- permissionIds.forEach(id => {
- if (!selectedPermissions.value.includes(id)) {
- selectedPermissions.value.push(id)
- }
- })
- }
- }
-
- // 切换权限选择
- const togglePermission = (permissionId) => {
- const index = selectedPermissions.value.indexOf(permissionId)
- if (index > -1) {
- selectedPermissions.value.splice(index, 1)
- } else {
- selectedPermissions.value.push(permissionId)
- }
- }
-
- // 保存权限
- const savePermissions = async () => {
- if (!currentRole.value) return
-
- saving.value = true
- try {
- // 更新角色权限
- await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].updateRole(currentRole.value.id, {
- ...currentRole.value,
- permissions: selectedPermissions.value
- })
-
- alert('权限保存成功')
- emit('saved')
- handleClose()
- } catch (error) {
- console.error('权限保存失败:', error)
- alert('权限保存失败')
- } finally {
- saving.value = false
- }
- }
-
- // 关闭对话框
- const handleClose = () => {
- visible.value = false
- currentRole.value = null
- selectedPermissions.value = []
- }
-
- return {
- visible,
- saving,
- currentRole,
- permissions,
- permissionTree,
- selectedPermissions,
- isResourceChecked,
- toggleResource,
- togglePermission,
- savePermissions,
- handleClose
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=script&lang=js":
-/*!*******************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=script&lang=js ***!
- \*******************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/roleService.js */ "./src/renderer/modules/role-management/services/roleService.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'UserRoleAssignment',
- props: {
- modelValue: {
- type: Boolean,
- default: false
- },
- user: {
- type: Object,
- default: null
- }
- },
- emits: ['update:modelValue', 'saved'],
- setup(props, { emit }) {
- const visible = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const saving = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const currentUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
- const allRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const userRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const selectedRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const selectedUnassigned = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const selectedAssigned = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
-
- // 计算属性
- const unassignedRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- return allRoles.value.filter(role => !selectedRoles.value.includes(role.key))
- })
-
- const assignedRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- return allRoles.value.filter(role => selectedRoles.value.includes(role.key))
- })
-
- // 监听visible变化
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => props.modelValue, (newVal) => {
- visible.value = newVal
- if (newVal && props.user) {
- currentUser.value = props.user
- loadRoles()
- loadUserRoles()
- }
- })
-
- // 监听visible变化,同步到父组件
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(visible, (newVal) => {
- emit('update:modelValue', newVal)
- })
-
- // 获取所有角色
- const loadRoles = async () => {
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getRoles(1, 1000) // 获取所有角色
- allRoles.value = (response.data || []).map(role => ({
- key: role.id,
- label: `${role.name} (${role.code})`,
- description: role.description,
- disabled: false
- }))
- } catch (error) {
- console.error('获取角色列表失败:', error)
- alert('获取角色列表失败')
- }
- }
-
- // 获取用户当前角色
- const loadUserRoles = async () => {
- if (!currentUser.value) return
-
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getUserRoles(currentUser.value.id)
- userRoles.value = response.data || []
- selectedRoles.value = userRoles.value.map(role => role.id)
- } catch (error) {
- console.error('获取用户角色失败:', error)
- alert('获取用户角色失败')
- }
- }
-
- // 分配角色
- const assignRole = (roleId) => {
- if (!selectedRoles.value.includes(roleId)) {
- selectedRoles.value.push(roleId)
- }
- }
-
- // 移除角色
- const removeRole = (roleId) => {
- const index = selectedRoles.value.indexOf(roleId)
- if (index > -1) {
- selectedRoles.value.splice(index, 1)
- }
- }
-
- // 分配选中的角色
- const assignSelected = () => {
- selectedUnassigned.value.forEach(roleId => {
- assignRole(roleId)
- })
- selectedUnassigned.value = []
- }
-
- // 移除选中的角色
- const removeSelected = () => {
- selectedAssigned.value.forEach(roleId => {
- removeRole(roleId)
- })
- selectedAssigned.value = []
- }
-
- // 保存角色分配
- const saveRoleAssignment = async () => {
- if (!currentUser.value) return
-
- saving.value = true
- try {
- // 计算需要分配和移除的角色
- const currentRoleIds = userRoles.value.map(role => role.id)
- const newRoleIds = selectedRoles.value
-
- const rolesToAssign = newRoleIds.filter(id => !currentRoleIds.includes(id))
- const rolesToRemove = currentRoleIds.filter(id => !newRoleIds.includes(id))
-
- // 分配新角色
- if (rolesToAssign.length > 0) {
- await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].assignRolesToUser(currentUser.value.id, rolesToAssign)
- }
-
- // 移除角色
- if (rolesToRemove.length > 0) {
- await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].removeRolesFromUser(currentUser.value.id, rolesToRemove)
- }
-
- alert('角色分配保存成功')
- emit('saved')
- handleClose()
- } catch (error) {
- console.error('角色分配保存失败:', error)
- alert('角色分配保存失败')
- } finally {
- saving.value = false
- }
- }
-
- // 关闭对话框
- const handleClose = () => {
- visible.value = false
- currentUser.value = null
- selectedRoles.value = []
- userRoles.value = []
- selectedUnassigned.value = []
- selectedAssigned.value = []
- }
-
- return {
- visible,
- saving,
- currentUser,
- allRoles,
- userRoles,
- selectedRoles,
- selectedUnassigned,
- selectedAssigned,
- unassignedRoles,
- assignedRoles,
- assignRole,
- removeRole,
- assignSelected,
- removeSelected,
- saveRoleAssignment,
- handleClose
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=script&lang=js":
-/*!*******************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=script&lang=js ***!
- \*******************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/roleService.js */ "./src/renderer/modules/role-management/services/roleService.js");
-/* harmony import */ var _config_app_config_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../../config/app.config.js */ "./src/config/app.config.js");
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'RoleApiTest',
- setup() {
- const testing = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const testMode = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const testResults = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
-
- const updateRoleId = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('')
- const deleteRoleId = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('')
-
- const testRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- name: '测试角色',
- code: 'TEST_ROLE',
- description: '这是一个测试角色'
- })
-
- const apiBaseUrl = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => (0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_2__.getFinalConfig)().apiBaseUrl)
- const currentApiPath = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => testMode.value ? '/auth/roles/test' : '/auth/roles')
-
- // 切换测试模式
- const toggleTestMode = () => {
- testMode.value = _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.toggleTestMode()
- addTestResult('模式切换', 'success', `已切换到${testMode.value ? '测试' : '正式'}模式`)
- }
-
- // 添加测试结果
- const addTestResult = (name, status, message, data = null) => {
- testResults.value.unshift({
- name,
- status,
- message,
- data,
- timestamp: new Date().toLocaleString()
- })
- }
-
- // 获取状态文本
- const getStatusText = (status) => {
- const statusMap = {
- 'success': '成功',
- 'error': '失败',
- 'warning': '警告'
- }
- return statusMap[status] || status
- }
-
- // 测试获取角色列表
- const testGetRoles = async () => {
- testing.value = true
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.getRoles(1, 10)
- if (response.code === 200) {
- addTestResult('获取角色列表', 'success', '获取角色列表成功', response.data)
- } else {
- addTestResult('获取角色列表', 'error', `获取失败: ${response.message}`, response)
- }
- } catch (error) {
- addTestResult('获取角色列表', 'error', `请求失败: ${error.message || error.error}`, error)
- } finally {
- testing.value = false
- }
- }
-
- // 测试创建角色
- const testCreateRole = async () => {
- testing.value = true
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.createRole(testRole)
- if (response.code === 200) {
- addTestResult('创建角色', 'success', '创建角色成功', response.data)
- } else {
- addTestResult('创建角色', 'error', `创建失败: ${response.message}`, response)
- }
- } catch (error) {
- addTestResult('创建角色', 'error', `请求失败: ${error.message || error.error}`, error)
- } finally {
- testing.value = false
- }
- }
-
- // 测试更新角色
- const testUpdateRole = async () => {
- if (!updateRoleId.value) {
- addTestResult('更新角色', 'warning', '请输入角色ID')
- return
- }
-
- testing.value = true
- try {
- const updateData = {
- name: `${testRole.name}_更新`,
- code: `${testRole.code}_UPDATED`,
- description: `${testRole.description}_更新`
- }
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.updateRole(updateRoleId.value, updateData)
- if (response.code === 200) {
- addTestResult('更新角色', 'success', '更新角色成功', response.data)
- } else {
- addTestResult('更新角色', 'error', `更新失败: ${response.message}`, response)
- }
- } catch (error) {
- addTestResult('更新角色', 'error', `请求失败: ${error.message || error.error}`, error)
- } finally {
- testing.value = false
- }
- }
-
- // 测试删除角色
- const testDeleteRole = async () => {
- if (!deleteRoleId.value) {
- addTestResult('删除角色', 'warning', '请输入角色ID')
- return
- }
-
- testing.value = true
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.deleteRole(deleteRoleId.value)
- if (response.code === 200) {
- addTestResult('删除角色', 'success', '删除角色成功', response.data)
- } else {
- addTestResult('删除角色', 'error', `删除失败: ${response.message}`, response)
- }
- } catch (error) {
- addTestResult('删除角色', 'error', `请求失败: ${error.message || error.error}`, error)
- } finally {
- testing.value = false
- }
- }
-
- // 运行所有测试
- const runAllTests = async () => {
- addTestResult('测试开始', 'success', '开始运行所有API测试')
-
- await testGetRoles()
- await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
- await testCreateRole()
- await new Promise(resolve => setTimeout(resolve, 1000)) // 等待1秒
-
- addTestResult('测试完成', 'success', '所有API测试已完成')
- }
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- testMode.value = _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.getTestModeStatus()
- addTestResult('页面加载', 'success', '角色管理API测试页面已加载')
- })
-
- return {
- testing,
- testMode,
- testResults,
- updateRoleId,
- deleteRoleId,
- testRole,
- apiBaseUrl,
- currentApiPath,
- toggleTestMode,
- testGetRoles,
- testCreateRole,
- testUpdateRole,
- testDeleteRole,
- runAllTests,
- getStatusText
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=script&lang=js":
-/*!**********************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=script&lang=js ***!
- \**********************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/roleService.js */ "./src/renderer/modules/role-management/services/roleService.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'RoleManagement',
- setup() {
- const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const saving = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showCreateDialog = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const editingRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
- const testMode = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
-
- const roles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const currentPage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(1)
- const pageSize = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(10)
- const total = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0)
-
- const roleForm = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- name: '',
- code: '',
- description: ''
- })
-
- // 切换测试模式
- const toggleTestMode = () => {
- testMode.value = _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.toggleTestMode()
- // 重新加载数据
- loadRoles()
- }
-
- // 获取角色列表
- const loadRoles = async () => {
- loading.value = true
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.getRoles(currentPage.value, pageSize.value)
-
- // 处理API响应格式
- if (response.code === 200 && response.data) {
- roles.value = response.data.data || []
- total.value = response.data.total || 0
- } else {
- console.error('获取角色列表失败:', response.message)
- alert('获取角色列表失败: ' + response.message)
- }
- } catch (error) {
- console.error('获取角色列表失败:', error)
- alert('获取角色列表失败: ' + (error.message || error.error || '未知错误'))
- } finally {
- loading.value = false
- }
- }
-
- // 创建新角色
- const createNewRole = () => {
- editingRole.value = null
- resetForm()
- showCreateDialog.value = true
- }
-
- // 编辑角色
- const editRole = (role) => {
- editingRole.value = role
- roleForm.name = role.name
- roleForm.code = role.code
- roleForm.description = role.description || ''
- showCreateDialog.value = true
- }
-
- // 保存角色
- const saveRole = async () => {
- if (!roleForm.name || !roleForm.code) {
- alert('请填写必填字段')
- return
- }
-
- saving.value = true
- try {
- if (editingRole.value) {
- // 更新角色
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.updateRole(editingRole.value.id, roleForm)
- if (response.code === 200) {
- alert('角色更新成功')
- showCreateDialog.value = false
- resetForm()
- loadRoles() // 重新加载列表
- } else {
- alert('角色更新失败: ' + response.message)
- }
- } else {
- // 创建角色
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.createRole(roleForm)
- if (response.code === 200) {
- alert('角色创建成功')
- showCreateDialog.value = false
- resetForm()
- loadRoles() // 重新加载列表
- } else {
- alert('角色创建失败: ' + response.message)
- }
- }
- } catch (error) {
- console.error('保存角色失败:', error)
- alert('操作失败: ' + (error.message || error.error || '未知错误'))
- } finally {
- saving.value = false
- }
- }
-
- // 删除角色
- const deleteRole = async (role) => {
- if (confirm(`确定要删除角色 "${role.name}" 吗?`)) {
- try {
- const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.deleteRole(role.id)
- if (response.code === 200) {
- alert('角色删除成功')
- loadRoles() // 重新加载列表
- } else {
- alert('角色删除失败: ' + response.message)
- }
- } catch (error) {
- console.error('删除角色失败:', error)
- alert('删除失败: ' + (error.message || error.error || '未知错误'))
- }
- }
- }
-
- // 重置表单
- const resetForm = () => {
- editingRole.value = null
- roleForm.name = ''
- roleForm.code = ''
- roleForm.description = ''
- }
-
- // 分页处理
- const handleCurrentChange = (val) => {
- currentPage.value = val
- loadRoles()
- }
-
- // 格式化日期
- const formatDate = (dateStr) => {
- if (!dateStr) return ''
- return new Date(dateStr).toLocaleString('zh-CN')
- }
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- // 初始化测试模式状态
- testMode.value = _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.getTestModeStatus()
- loadRoles()
- })
-
- return {
- loading,
- saving,
- showCreateDialog,
- editingRole,
- testMode,
- roles,
- currentPage,
- pageSize,
- total,
- roleForm,
- toggleTestMode,
- createNewRole,
- editRole,
- saveRole,
- deleteRole,
- handleCurrentChange,
- formatDate
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=script&lang=js":
-/*!****************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=script&lang=js ***!
- \****************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _modules_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/modules/core */ "./src/renderer/modules/core/index.js");
-/* harmony import */ var _modules_core_components_Toast_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/modules/core/components/Toast.vue */ "./src/renderer/modules/core/components/Toast.vue");
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'Settings',
- components: {
- Toast: _modules_core_components_Toast_vue__WEBPACK_IMPORTED_MODULE_2__["default"]
- },
- setup() {
- const settings = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- // 基本设置
- appName: 'GoFaster',
- language: 'zh-CN',
- theme: 'light',
-
- // 网络设置
- apiUrl: 'http://localhost:8080',
- timeout: 10,
- retryCount: 3,
-
- // 用户设置
- keepLoginOnClose: false,
- rememberPassword: false,
- sessionTimeout: 30,
-
- // 通知设置
- desktopNotifications: true,
- soundNotifications: true,
- notificationInterval: 10,
-
- // 数据设置
- cacheSize: 100,
- autoCleanCache: true,
- backupFrequency: 'weekly'
- })
-
- // 保存原始设置用于比较
- const originalSettings = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({})
- const hasChanges = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const isSaving = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
-
- // Toast 相关状态
- const showToast = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const toastConfig = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- type: 'success',
- title: '保存成功',
- content: '用户设置已成功保存',
- duration: 3000
- })
-
- // 计算保存按钮的样式类
- const saveButtonClass = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- if (isSaving.value) {
- return 'btn-saving'
- } else if (hasChanges.value) {
- return 'btn-primary'
- } else {
- return 'btn-disabled'
- }
- })
-
- // 检查设置是否有变化
- const checkChanges = () => {
- hasChanges.value = JSON.stringify(settings) !== JSON.stringify(originalSettings.value)
- }
-
- // 显示Toast提示
- const showToastMessage = (type, title, content, duration = 3000) => {
- toastConfig.type = type
- toastConfig.title = title
- toastConfig.content = content
- toastConfig.duration = duration
- showToast.value = true
- }
-
- const loadSettings = () => {
- const savedSettings = localStorage.getItem('gofaster-settings')
- if (savedSettings) {
- Object.assign(settings, JSON.parse(savedSettings))
- }
-
- // 保存原始设置
- originalSettings.value = JSON.parse(JSON.stringify(settings))
-
- // 同步主题管理器
- if (settings.theme) {
- _modules_core__WEBPACK_IMPORTED_MODULE_1__.themeManager.setTheme(settings.theme)
- }
- }
-
- const saveSettings = async () => {
- if (!hasChanges.value || isSaving.value) return
-
- isSaving.value = true
-
- try {
- // 模拟保存延迟
- await new Promise(resolve => setTimeout(resolve, 1000))
-
- localStorage.setItem('gofaster-settings', JSON.stringify(settings))
-
- // 应用主题设置
- if (settings.theme) {
- _modules_core__WEBPACK_IMPORTED_MODULE_1__.themeManager.setTheme(settings.theme)
- }
-
- // 触发自定义事件,通知其他组件设置已更新
- window.dispatchEvent(new CustomEvent('gofaster-settings-changed', {
- detail: { settings: settings }
- }));
-
- // 更新原始设置
- originalSettings.value = JSON.parse(JSON.stringify(settings))
- hasChanges.value = false
-
- // 显示保存成功提示
- showToastMessage('success', '保存成功', '用户设置已成功保存')
-
-
- } catch (error) {
- console.error('保存用户设置失败:', error)
- // 显示保存失败提示
- showToastMessage('error', '保存失败', '保存用户设置时发生错误,请重试')
- } finally {
- isSaving.value = false
- }
- }
-
- // 主题切换处理
- const handleThemeChange = (newTheme) => {
- settings.theme = newTheme
- _modules_core__WEBPACK_IMPORTED_MODULE_1__.themeManager.setTheme(newTheme)
- }
-
- const resetSettings = () => {
- if (confirm('确定要重置所有用户设置吗?此操作不可撤销。')) {
- localStorage.removeItem('gofaster-settings')
- location.reload()
- }
- }
-
- // 监听设置变化
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(settings, () => {
- checkChanges()
- }, { deep: true })
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- loadSettings()
- })
-
- return {
- settings,
- hasChanges,
- isSaving,
- saveButtonClass,
- showToast,
- toastConfig,
- saveSettings,
- resetSettings,
- handleThemeChange
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=script&lang=js":
-/*!***********************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=script&lang=js ***!
- \***********************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var _services_userService_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../services/userService.js */ "./src/renderer/modules/user-management/services/userService.js");
-/* harmony import */ var _modules_core_utils_ipUtils__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/modules/core/utils/ipUtils */ "./src/renderer/modules/core/utils/ipUtils.js");
-
-
-
-
-const { getClientIP } = _modules_core_utils_ipUtils__WEBPACK_IMPORTED_MODULE_1__
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'LoginModal',
- props: {
- visible: {
- type: Boolean,
- default: false
- }
- },
- data() {
- return {
- loading: false,
- captchaLoading: false,
- showPassword: false,
- errorMessage: '',
- captchaImage: '',
- captchaId: '',
- clientIP: '',
- loginForm: {
- username: '',
- password: '',
- captcha: ''
- }
- }
- },
- computed: {
- isFormValid() {
- return this.loginForm.username.trim() &&
- this.loginForm.password.trim() &&
- this.loginForm.captcha.trim() &&
- this.captchaImage // 确保验证码图片已加载
- },
-
-
- },
- watch: {
- visible(newVal) {
- if (newVal) {
- this.resetForm()
- this.getClientIP() // 获取客户端IP
- this.refreshCaptcha()
- this.loadSavedLoginInfo() // 加载保存的登录信息
- }
- }
- },
- methods: {
- // 加载保存的登录信息
- loadSavedLoginInfo() {
- try {
- const savedLoginInfo = localStorage.getItem('gofaster-login-info')
- if (savedLoginInfo) {
- const loginInfo = JSON.parse(savedLoginInfo)
- if (loginInfo.username && loginInfo.password) {
- this.loginForm.username = loginInfo.username
- this.loginForm.password = loginInfo.password
- console.log('已自动填充保存的登录信息')
- }
- }
- } catch (error) {
- console.error('加载保存的登录信息失败:', error)
- }
- },
-
- // 保存登录信息到本地存储
- saveLoginInfo() {
- try {
- // 检查用户设置中的"记住密码"选项
- const userSettings = localStorage.getItem('gofaster-settings')
- if (userSettings) {
- const settings = JSON.parse(userSettings)
- if (settings.rememberPassword) {
- const loginInfo = {
- username: this.loginForm.username,
- password: this.loginForm.password,
- timestamp: Date.now()
- }
- localStorage.setItem('gofaster-login-info', JSON.stringify(loginInfo))
- console.log('已保存登录信息到本地存储')
- } else {
- // 如果用户选择不记住密码,清除保存的登录信息
- localStorage.removeItem('gofaster-login-info')
- console.log('用户选择不记住密码,已清除保存的登录信息')
- }
- }
- } catch (error) {
- console.error('保存登录信息失败:', error)
- }
- },
-
- async handleLogin() {
- if (!this.isFormValid) {
- this.errorMessage = '请填写完整的登录信息'
- return
- }
-
- this.loading = true
- this.errorMessage = ''
-
- try {
- // 调用登录接口
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_0__.userService.login({
- username: this.loginForm.username,
- password: this.loginForm.password,
- captcha: this.loginForm.captcha,
- captcha_id: this.captchaId, // 修复字段名:后端期望 snake_case
- client_ip: this.clientIP // 传入客户端IP
- })
-
- // 登录成功后保存登录信息
- this.saveLoginInfo()
-
- // 登录成功
- this.$emit('login-success', response)
- this.closeModal()
-
- // 显示成功提示
- this.$emit('show-message', {
- type: 'success',
- title: '登录成功',
- content: `欢迎回来,${response.data?.user?.username || response.user?.username || this.loginForm.username || '用户'}!`
- })
-
- } catch (error) {
- // 增强错误提示,显示具体的错误原因
- console.log('登录错误详情:', error)
- console.log('错误响应状态:', error.response?.status)
- console.log('错误响应数据:', error.response?.data)
-
- let errorMsg = '登录失败,请重试'
-
- if (error.response) {
- // 服务器返回错误响应
- const status = error.response.status
- const data = error.response.data
-
- // 优先检查错误消息内容,判断是否为验证码错误
- if (data.message && data.message.includes('验证码')) {
- errorMsg = '验证码错误,请重新输入'
- } else if (data.error && data.error.includes('验证码')) {
- errorMsg = '验证码错误,请重新输入'
- } else if (status === 400) {
- // 400 状态码,可能是验证码错误或其他参数错误
- if (data.message) {
- errorMsg = data.message
- } else if (data.error) {
- errorMsg = data.error
- } else {
- errorMsg = '请求参数错误,请检查输入信息'
- }
- } else if (status === 401) {
- // 401 是用户名或密码错误,显示模糊信息
- errorMsg = '用户名或密码错误'
- } else if (status === 422) {
- // 422 通常是验证失败
- if (data.message) {
- errorMsg = data.message
- } else {
- errorMsg = '验证失败,请检查输入信息'
- }
- } else if (status === 423) {
- // 账户被锁定
- if (data.error) {
- errorMsg = data.error
- } else if (data.message) {
- errorMsg = data.message
- } else {
- errorMsg = '账户被锁定,请稍后重试'
- }
- } else if (status === 500) {
- errorMsg = '服务器内部错误,请稍后重试'
- }
- } else if (error.message) {
- // 网络错误或其他错误
- if (error.message.includes('验证码')) {
- errorMsg = '验证码错误,请重新输入'
- } else if (error.message.includes('用户名') || error.message.includes('密码')) {
- // 账户密码相关错误显示模糊信息
- errorMsg = '用户名或密码错误'
- } else {
- errorMsg = error.message
- }
- }
-
- console.log('最终显示的错误信息:', errorMsg)
- this.errorMessage = errorMsg
-
- // 强制触发视图更新
- this.$nextTick(() => {
- console.log('错误信息已设置到界面:', this.errorMessage)
- })
-
- // 登录失败时刷新验证码,但不清空错误信息
- this.refreshCaptchaWithoutClearError()
- } finally {
- this.loading = false
- }
- },
-
- async refreshCaptcha() {
- try {
- this.captchaLoading = true
- this.errorMessage = ''
- // 调用获取验证码接口
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_0__.userService.getCaptcha()
- // 修复字段映射:后端返回的是 snake_case,前端使用 camelCase
- this.captchaImage = response.data.captcha_image
- this.captchaId = response.data.captcha_id
- this.loginForm.captcha = ''
- console.log('验证码获取成功:', response)
- } catch (error) {
- console.error('获取验证码失败:', error)
- this.errorMessage = '获取验证码失败,请重试'
- this.captchaImage = ''
- this.captchaId = ''
- } finally {
- this.captchaLoading = false
- }
- },
-
- async refreshCaptchaWithoutClearError() {
- try {
- this.captchaLoading = true
- // 不清空错误信息
- // 调用获取验证码接口
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_0__.userService.getCaptcha()
- // 修复字段映射:后端返回的是 snake_case,前端使用 camelCase
- this.captchaImage = response.data.captcha_image
- this.captchaId = response.data.captcha_id
- this.loginForm.captcha = ''
- console.log('验证码获取成功(不清空错误):', response)
- } catch (error) {
- console.error('获取验证码失败:', error)
- // 不清空错误信息,只设置验证码相关的错误
- this.captchaImage = ''
- this.captchaId = ''
- } finally {
- this.captchaLoading = false
- }
- },
-
- // 获取客户端IP地址
- async getClientIP() {
- try {
- this.clientIP = await getClientIP()
- console.log('获取到客户端IP:', this.clientIP)
- } catch (error) {
- console.error('获取客户端IP失败:', error)
- this.clientIP = '127.0.0.1'
- }
- },
-
- resetForm() {
- this.loginForm = {
- username: '',
- password: '',
- captcha: ''
- }
- this.showPassword = false
- this.errorMessage = ''
- this.captchaImage = ''
- this.captchaId = ''
- },
-
- togglePassword() {
- this.showPassword = !this.showPassword
- },
-
- closeModal() {
- this.$emit('update:visible', false)
- this.resetForm()
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=script&lang=js":
-/*!********************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=script&lang=js ***!
- \********************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_userService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/userService.js */ "./src/renderer/modules/user-management/services/userService.js");
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'PasswordChangeModal',
- props: {
- visible: {
- type: Boolean,
- default: false
- },
- isForceChange: {
- type: Boolean,
- default: false
- }
- },
- emits: ['close', 'success'],
- setup(props, { emit }) {
- const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const policy = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)({
- minLength: 6,
- minCharTypes: 1,
- preventReuse: 3,
- level: 1,
- minRequiredLevel: 1,
- requireUppercase: false,
- requireLowercase: false,
- requireNumbers: false,
- requireSpecial: false
- })
-
- const form = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- currentPassword: '',
- newPassword: '',
- confirmPassword: ''
- })
-
- const errors = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- currentPassword: '',
- newPassword: '',
- confirmPassword: ''
- })
-
- const requirements = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- length: false,
- uppercase: false,
- lowercase: false,
- numbers: false,
- special: false
- })
-
- const passwordStrength = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0)
- const passwordLevel = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0)
-
- // 计算属性
- const title = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- return props.isForceChange ? '强制修改密码' : '修改密码'
- })
-
- const submitText = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- return props.isForceChange ? '确认修改' : '修改密码'
- })
-
- const strengthClass = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- if (passwordStrength.value >= 4) return 'strong'
- if (passwordStrength.value >= 3) return 'medium'
- if (passwordStrength.value >= 2) return 'weak'
- return 'very-weak'
- })
-
- const strengthText = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- if (passwordStrength.value >= 4) return '强'
- if (passwordStrength.value >= 3) return '中'
- if (passwordStrength.value >= 2) return '弱'
- return '很弱'
- })
-
- const strengthPercentage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- // 将0-5的等级转换为0-100的百分比显示
- return (passwordStrength.value / 5) * 100
- })
-
- const isFormValid = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- if (props.isForceChange) {
- return form.newPassword && form.confirmPassword &&
- form.newPassword === form.confirmPassword &&
- !errors.newPassword && !errors.confirmPassword
- }
- return form.currentPassword && form.newPassword && form.confirmPassword &&
- form.newPassword === form.confirmPassword &&
- !errors.currentPassword && !errors.newPassword && !errors.confirmPassword
- })
-
- // 方法
- const loadPasswordPolicy = async () => {
- try {
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.getPasswordPolicy()
-
- // 修复:直接检查response.data的结构
- if (response.data && response.data.code === 200 && response.data.data) {
- policy.value = response.data.data
- } else if (response && response.code === 200 && response.data) {
- // 备用检查:如果response.data不存在,直接检查response
- policy.value = response.data
- } else {
- console.warn('密码策略响应格式不正确:', response)
- console.warn('尝试解析响应结构...')
- if (response.data) {
- console.warn('response.data.code:', response.data.code)
- console.warn('response.data.data:', response.data.data)
- }
- if (response) {
- console.warn('response.code:', response.code)
- console.warn('response.data:', response.data)
- }
- // 使用默认策略作为后备
- policy.value = {
- minLength: 6,
- minCharTypes: 1,
- preventReuse: 3,
- level: 1,
- minRequiredLevel: 1,
- requireUppercase: false,
- requireLowercase: false,
- requireNumbers: false,
- requireSpecial: false
- }
- }
- } catch (error) {
- console.error('加载密码策略失败:', error)
- // 使用默认策略作为后备
- policy.value = {
- minLength: 6,
- minCharTypes: 1,
- preventReuse: 3,
- level: 1,
- minRequiredLevel: 1,
- requireUppercase: false,
- requireLowercase: false,
- requireNumbers: false,
- requireSpecial: false
- }
- }
- }
-
- const validatePassword = async () => {
- errors.newPassword = ''
-
- if (!form.newPassword) {
- // 如果密码为空,重置所有要求状态
- updateRequirements('')
- return
- }
-
- try {
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.validatePassword(form.newPassword)
-
- // 修复:检查多种可能的响应结构
- let result = null
- if (response.data && response.data.code === 200 && response.data.data) {
- result = response.data.data
- } else if (response && response.code === 200 && response.data) {
- result = response.data
- }
-
- if (result) {
-
- if (!result.is_valid) {
- // 确保错误信息是数组格式
- if (Array.isArray(result.errors)) {
- errors.newPassword = result.errors.join('; ')
- } else if (typeof result.errors === 'string') {
- errors.newPassword = result.errors
- } else {
- errors.newPassword = '密码验证失败'
- }
- }
-
- passwordStrength.value = result.strength || 0
- passwordLevel.value = result.level || 0
-
- // 更新要求满足状态
- updateRequirements(form.newPassword)
- } else {
- console.warn('密码验证响应格式不正确:', response)
- // 即使验证失败,也要更新要求状态
- updateRequirements(form.newPassword)
- }
- } catch (error) {
- console.error('密码验证失败:', error)
- // 即使验证失败,也要更新要求状态
- updateRequirements(form.newPassword)
- }
- }
-
- const updateRequirements = (password) => {
-
- // 重置所有状态
- requirements.length = false
- requirements.uppercase = false
- requirements.lowercase = false
- requirements.numbers = false
- requirements.special = false
-
- // 如果密码为空,直接返回
- if (!password || password.length === 0) {
- return
- }
-
- let hasUppercase = false
- let hasLowercase = false
- let hasNumbers = false
- let hasSpecial = false
-
- for (const char of password) {
- // 使用更准确的字符类型检测
- const charCode = char.charCodeAt(0)
-
- if (charCode >= 65 && charCode <= 90) { // A-Z
- hasUppercase = true
- } else if (charCode >= 97 && charCode <= 122) { // a-z
- hasLowercase = true
- } else if (charCode >= 48 && charCode <= 57) { // 0-9
- hasNumbers = true
- } else {
- // 特殊字符:包括标点符号、符号、空格等
- hasSpecial = true
- }
- }
-
- // 更新要求状态
- requirements.length = password.length >= 6 // 要求至少6位
- requirements.uppercase = hasUppercase
- requirements.lowercase = hasLowercase
- requirements.numbers = hasNumbers
- requirements.special = hasSpecial
-
- // 计算字符类型数量
- let charTypes = 0
- if (hasUppercase) charTypes++
- if (hasLowercase) charTypes++
- if (hasNumbers) charTypes++
- if (hasSpecial) charTypes++
-
- // 计算密码强度
- const strength = calculatePasswordStrength(password, charTypes)
- passwordStrength.value = strength
- passwordLevel.value = strength
- }
-
- // 前端密码强度计算方法
- const calculatePasswordStrength = (password, charTypes) => {
- // 从最高等级开始判断,一旦满足条件就返回对应等级
-
- // 5级:长度>=8,字符类型>=4
- if (password.length >= 8 && charTypes >= 4) {
- return 5
- }
-
- // 4级:长度>=8,字符类型>=3
- if (password.length >= 8 && charTypes >= 3) {
- return 4
- }
-
- // 3级:长度>=6,字符类型>=3
- if (password.length >= 6 && charTypes >= 3) {
- return 3
- }
-
- // 2级:长度>=6,字符类型>=2
- if (password.length >= 6 && charTypes >= 2) {
- return 2
- }
-
- // 1级:长度>=6,字符类型>=1
- if (password.length >= 6 && charTypes >= 1) {
- return 1
- }
-
- // 0级:长度>=1,字符类型>=1(任何密码都至少有一种字符类型)
- if (password.length >= 1) {
- return 0
- }
-
- // 如果连0级都不满足,返回0
- return 0
- }
-
- const validateConfirmPassword = () => {
- errors.confirmPassword = ''
-
- if (form.newPassword !== form.confirmPassword) {
- errors.confirmPassword = '两次输入的密码不一致'
- }
- }
-
- const handleSubmit = async () => {
- if (!isFormValid.value) return
-
- loading.value = true
-
- // 清除之前的错误信息
- Object.keys(errors).forEach(key => {
- errors[key] = ''
- })
-
- try {
- const requestData = {
- current_password: form.currentPassword,
- new_password: form.newPassword,
- confirm_password: form.confirmPassword
- }
-
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.changePassword(requestData)
-
- // 成功处理
- // 显示成功消息
- if (window.showToast) {
- window.showToast({
- type: 'success',
- title: '密码修改成功',
- content: '您的密码已成功修改'
- })
- } else {
- // 如果没有全局toast,使用alert作为后备
- alert('密码修改成功!')
- }
-
- // 延迟关闭弹窗,让用户看到成功提示
- setTimeout(() => {
- emit('success')
- handleClose()
- }, 1500)
-
- } catch (error) {
-
- // 改进错误信息处理
- let errorMessage = '修改密码失败,请重试'
- let targetField = 'newPassword'
-
- if (error.response?.data) {
- const responseData = error.response.data
-
- // 处理不同的错误情况
- if (responseData.error) {
- // 优先使用error字段,这通常包含具体的错误信息
- errorMessage = responseData.error
-
- // 根据错误信息内容判断应该显示在哪个字段
- if (errorMessage.includes('当前密码') || errorMessage.includes('current password')) {
- targetField = 'currentPassword'
- } else if (errorMessage.includes('新密码') || errorMessage.includes('new password')) {
- targetField = 'newPassword'
- } else if (errorMessage.includes('确认密码') || errorMessage.includes('confirm password')) {
- targetField = 'confirmPassword'
- }
- } else if (responseData.message) {
- // 如果没有error字段,使用message字段
- errorMessage = responseData.message
-
- // 根据错误信息内容判断应该显示在哪个字段
- if (errorMessage.includes('当前密码') || errorMessage.includes('current password')) {
- targetField = 'currentPassword'
- } else if (errorMessage.includes('新密码') || errorMessage.includes('new password')) {
- targetField = 'newPassword'
- } else if (errorMessage.includes('确认密码') || errorMessage.includes('confirm password')) {
- targetField = 'confirmPassword'
- }
- }
- } else if (error.message) {
- errorMessage = error.message
- }
-
- // 显示错误信息
- errors[targetField] = errorMessage
-
- // 如果是强制修改密码模式,错误信息也显示在newPassword字段
- if (props.isForceChange && targetField === 'currentPassword') {
- errors.newPassword = errorMessage
- }
- } finally {
- loading.value = false
- }
- }
-
- const handleClose = () => {
- if (loading.value) return
-
- // 使用统一的重置函数
- resetFormState()
-
- emit('close')
- }
-
- const handleOverlayClick = () => {
- // 密码修改模态窗不应该在点击外部区域时关闭
- // 避免用户意外丢失已输入的密码内容
- // 只有通过明确的取消按钮或关闭按钮才能关闭
- return false
- }
-
- const clearCurrentPasswordError = () => {
- errors.currentPassword = ''
- }
-
- const clearNewPasswordError = () => {
- errors.newPassword = ''
- }
-
- const clearConfirmPasswordError = () => {
- errors.confirmPassword = ''
- }
-
- const handleNewPasswordInput = () => {
- clearNewPasswordError()
- validatePassword()
- }
-
- const handleConfirmPasswordInput = () => {
- clearConfirmPasswordError()
- validateConfirmPassword()
- }
-
- // 监听器
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => props.visible, (newVal) => {
- if (newVal) {
-
- // 每次打开弹窗时,确保完全重置所有状态
- resetFormState()
-
- loadPasswordPolicy()
-
- // 延迟测试输入框焦点和强制聚焦
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.nextTick)(() => {
- if (!props.isForceChange && form.currentPassword === '') {
- // 尝试强制聚焦到第一个输入框
- try {
- const currentPasswordInput = document.querySelector('input[type="password"]')
- if (currentPasswordInput) {
- currentPasswordInput.focus()
- }
- } catch (error) {
- console.error('聚焦失败:', error)
- }
- } else {
- // 尝试强制聚焦到新密码输入框
- try {
- const newPasswordInput = document.querySelectorAll('input[type="password"]')[1]
- if (newPasswordInput) {
- newPasswordInput.focus()
- }
- } catch (error) {
- console.error('聚焦失败:', error)
- }
- }
- })
- }
- })
-
- // 重置表单状态的函数
- const resetFormState = () => {
-
- // 重置表单数据
- form.currentPassword = ''
- form.newPassword = ''
- form.confirmPassword = ''
-
- // 清除所有错误信息
- Object.keys(errors).forEach(key => {
- errors[key] = ''
- })
-
- // 重置密码要求状态
- Object.keys(requirements).forEach(key => {
- requirements[key] = false
- })
-
- // 重置密码强度和等级
- passwordStrength.value = 0
- passwordLevel.value = 0
-
- // 重置加载状态 - 这是关键!
- loading.value = false
-
- // 强制触发响应式更新
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.nextTick)(() => {
- })
- }
-
- // 监听密码变化,实时更新要求状态
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => form.newPassword, (newPassword) => {
- if (newPassword) {
- updateRequirements(newPassword)
- } else {
- // 密码为空时重置所有状态
- Object.keys(requirements).forEach(key => {
- requirements[key] = false
- })
- // 重置密码强度
- passwordStrength.value = 0
- passwordLevel.value = 0
- }
- })
-
- // 生命周期
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- if (props.visible) {
- loadPasswordPolicy()
- }
- // 如果有初始密码内容,计算强度
- if (form.newPassword) {
- updateRequirements(form.newPassword)
- }
- })
-
- return {
- loading,
- policy,
- form,
- errors,
- requirements,
- passwordStrength,
- passwordLevel,
- title,
- submitText,
- strengthClass,
- strengthText,
- strengthPercentage,
- isFormValid,
- validatePassword,
- validateConfirmPassword,
- updateRequirements,
- handleSubmit,
- handleClose,
- handleOverlayClick,
- clearCurrentPasswordError,
- clearNewPasswordError,
- clearConfirmPasswordError,
- handleNewPasswordInput,
- handleConfirmPasswordInput,
- resetFormState // 暴露重置函数
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=script&lang=js":
-/*!****************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=script&lang=js ***!
- \****************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'PasswordProfile',
- setup() {
- return {}
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=script&lang=js":
-/*!**********************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=script&lang=js ***!
- \**********************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var _services_userService_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../services/userService.js */ "./src/renderer/modules/user-management/services/userService.js");
-/* harmony import */ var _modules_role_management__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/modules/role-management */ "./src/renderer/modules/role-management/index.js");
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'UserManagement',
- components: {
- UserRoleAssignment: _modules_role_management__WEBPACK_IMPORTED_MODULE_2__.UserRoleAssignment
- },
- setup() {
- const users = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const roles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([])
- const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const currentPage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(1)
- const pageSize = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(10)
- const total = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0)
- const searchQuery = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('')
- const statusFilter = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('')
- const roleFilter = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('')
-
- const showAddUserModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showEditUserModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const showRoleAssignmentModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const editingUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
- const selectedUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
-
- const userForm = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({
- username: '',
- password: '',
- email: '',
- phone: '',
- status: 1,
- roleIds: []
- })
-
- const totalPages = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => Math.ceil(total.value / pageSize.value))
-
- const filteredUsers = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => {
- let filtered = users.value
-
- if (searchQuery.value) {
- const query = searchQuery.value.toLowerCase()
- filtered = filtered.filter(user =>
- user.username.toLowerCase().includes(query) ||
- user.email.toLowerCase().includes(query) ||
- user.phone?.toLowerCase().includes(query)
- )
- }
-
- if (statusFilter.value) {
- filtered = filtered.filter(user => user.status === parseInt(statusFilter.value))
- }
-
- // 暂时注释掉角色过滤,避免API调用错误
- // if (roleFilter.value) {
- // filtered = filtered.filter(user =>
- // user.roles.some(role => role.id === parseInt(roleFilter.value))
- // )
- // }
-
- return filtered
- })
-
- const loadUsers = async () => {
- try {
- loading.value = true
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.getUsers(currentPage.value, pageSize.value)
- // 修复数据结构访问
- users.value = response.data.data
- total.value = response.data.total
- console.log('🔍 [前台] 加载用户数据:', {
- users: users.value,
- total: total.value,
- response: response.data
- })
- } catch (error) {
- console.error('加载用户失败:', error)
- } finally {
- loading.value = false
- }
- }
-
- const loadRoles = async () => {
- try {
- // 暂时注释掉角色加载,避免API调用错误
- // const response = await userService.getRoles()
- // roles.value = response.data
- console.log('角色功能暂时禁用')
- } catch (error) {
- console.error('加载角色失败:', error)
- }
- }
-
- const handleSearch = () => {
- currentPage.value = 1
- }
-
- const handleFilter = () => {
- currentPage.value = 1
- }
-
- const changePage = (page) => {
- currentPage.value = page
- loadUsers()
- }
-
- const editUser = (user) => {
- editingUser.value = user
- Object.assign(userForm, {
- username: user.username,
- password: '',
- email: user.email,
- phone: user.phone,
- status: user.status,
- roleIds: [] // 暂时注释掉角色处理,避免API调用错误
- })
- showEditUserModal.value = true
- }
-
- const submitUser = async () => {
- try {
- if (showEditUserModal.value) {
- await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.updateUser(editingUser.value.id, userForm)
- } else {
- await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.createUser(userForm)
- }
- closeModal()
- loadUsers()
- } catch (error) {
- console.error('保存用户失败:', error)
- }
- }
-
- const deleteUser = async (userId) => {
- if (confirm('确定要删除这个用户吗?')) {
- try {
- await _services_userService_js__WEBPACK_IMPORTED_MODULE_1__.userService.deleteUser(userId)
- loadUsers()
- } catch (error) {
- console.error('删除用户失败:', error)
- }
- }
- }
-
- const assignRoles = (user) => {
- selectedUser.value = user
- showRoleAssignmentModal.value = true
- }
-
- const closeModal = () => {
- showAddUserModal.value = false
- showEditUserModal.value = false
- editingUser.value = null
- Object.assign(userForm, {
- username: '',
- password: '',
- email: '',
- phone: '',
- status: 1,
- roleIds: []
- })
- }
-
- const formatDate = (dateString) => {
- if (!dateString) return ''
- return new Date(dateString).toLocaleDateString('zh-CN')
- }
-
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- loadUsers()
- loadRoles()
- })
-
- return {
- users,
- roles,
- loading,
- currentPage,
- pageSize,
- total,
- searchQuery,
- statusFilter,
- roleFilter,
- showAddUserModal,
- showEditUserModal,
- showRoleAssignmentModal,
- editingUser,
- selectedUser,
- userForm,
- totalPages,
- filteredUsers,
- loadUsers,
- loadRoles,
- handleSearch,
- handleFilter,
- changePage,
- editUser,
- submitUser,
- deleteUser,
- assignRoles,
- closeModal,
- formatDate
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=script&lang=js":
-/*!*******************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=script&lang=js ***!
- \*******************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-/* harmony import */ var vue_router__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue-router */ "./node_modules/vue-router/dist/vue-router.mjs");
-/* harmony import */ var _services_userService_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../services/userService.js */ "./src/renderer/modules/user-management/services/userService.js");
-/* harmony import */ var _components_PasswordChangeModal_vue__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../components/PasswordChangeModal.vue */ "./src/renderer/modules/user-management/components/PasswordChangeModal.vue");
-
-
-
-
-
-
-/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({
- name: 'UserProfile',
- components: {
- PasswordChangeModal: _components_PasswordChangeModal_vue__WEBPACK_IMPORTED_MODULE_3__["default"]
- },
- setup() {
- const router = (0,vue_router__WEBPACK_IMPORTED_MODULE_1__.useRouter)()
-
- // 注入依赖
- const currentUser = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)('currentUser', null)
- const isLoggedIn = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)('isLoggedIn', false)
- const showLoginModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.inject)('showLoginModal', null)
-
- // 响应式数据
- const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const error = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
- const userInfo = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null)
-
- // 密码修改弹窗状态
- const showPasswordModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
- const isForceChange = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false)
-
- // 加载用户资料
- const loadUserProfile = async () => {
- if (!isLoggedIn.value) {
- error.value = '请先登录'
- return
- }
-
- loading.value = true
- error.value = null
-
- try {
- const token = localStorage.getItem('token')
- if (!token) {
- throw new Error('未找到认证token')
- }
-
- const response = await _services_userService_js__WEBPACK_IMPORTED_MODULE_2__.userService.getCurrentUser(token)
- userInfo.value = response.data || response
-
- console.log('加载的用户信息:', userInfo.value)
- } catch (err) {
- console.error('加载用户资料失败:', err)
- error.value = err.response?.data?.message || err.message || '加载用户资料失败'
- } finally {
- loading.value = false
- }
- }
-
- // 刷新资料
- const refreshProfile = () => {
- loadUserProfile()
- }
-
-
-
- // 修改密码
- const changePassword = () => {
- isForceChange.value = false
- showPasswordModal.value = true
- }
-
- // 强制修改密码
- const forceChangePassword = () => {
- isForceChange.value = true
- showPasswordModal.value = true
- }
-
- // 密码修改成功回调
- const onPasswordChangeSuccess = () => {
- // 刷新用户信息
- loadUserProfile()
- }
-
- // 去登录
- const goToLogin = () => {
- if (showLoginModal) {
- showLoginModal()
- } else {
- router.push('/')
- }
- }
-
- // 格式化日期
- const formatDate = (dateString) => {
- if (!dateString) return null
- try {
- const date = new Date(dateString)
- return date.toLocaleString('zh-CN', {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: '2-digit',
- minute: '2-digit',
- second: '2-digit'
- })
- } catch (err) {
- return dateString
- }
- }
-
- // 获取状态文本
- const getStatusText = (status) => {
- const statusMap = {
- 1: '正常',
- 0: '禁用',
- 2: '待验证'
- }
- return statusMap[status] || '未知'
- }
-
- // 获取状态样式类
- const getStatusClass = (status) => {
- const classMap = {
- 1: 'status-active',
- 0: 'status-inactive',
- 2: 'status-pending'
- }
- return classMap[status] || 'status-unknown'
- }
-
- // 组件挂载时加载数据
- ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => {
- if (isLoggedIn.value) {
- loadUserProfile()
- }
- })
-
- return {
- loading,
- error,
- userInfo,
- currentUser,
- isLoggedIn,
- showPasswordModal,
- isForceChange,
- loadUserProfile,
- refreshProfile,
- changePassword,
- forceChangePassword,
- onPasswordChangeSuccess,
- goToLogin,
- formatDate,
- getStatusText,
- getStatusClass
- }
- }
-});
-
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=template&id=2fa9d48e":
-/*!*********************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=template&id=2fa9d48e ***!
- \*********************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { id: "app" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- const _component_router_view = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("router-view")
- const _component_StatusBar = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("StatusBar")
-
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_router_view),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_StatusBar)
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=template&id=768a7af0&scoped=true":
-/*!****************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/components/SpeedTest.vue?vue&type=template&id=768a7af0&scoped=true ***!
- \****************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "speed-test" }
-const _hoisted_2 = ["disabled"]
-const _hoisted_3 = {
- key: 0,
- class: "results"
-}
-const _hoisted_4 = { class: "result-item" }
-const _hoisted_5 = { class: "value" }
-const _hoisted_6 = { class: "result-item" }
-const _hoisted_7 = { class: "value" }
-const _hoisted_8 = { class: "result-item" }
-const _hoisted_9 = { class: "value" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h1", null, "GoFaster Speed Test", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.startTest && $setup.startTest(...args))),
- disabled: $setup.testing
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? 'Testing...' : 'Start Test'), 9 /* TEXT, PROPS */, _hoisted_2),
- ($setup.result)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_3, [
- _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "Test Results:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", { class: "label" }, "Download:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.result.download) + " Mbps", 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", { class: "label" }, "Upload:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.result.upload) + " Mbps", 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", { class: "label" }, "Ping:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_9, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.result.ping) + " ms", 1 /* TEXT */)
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=template&id=7fb85f33&scoped=true":
-/*!*********************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/business-features/views/History.vue?vue&type=template&id=7fb85f33&scoped=true ***!
- \*********************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "history-view" }
-const _hoisted_2 = {
- key: 0,
- class: "empty-state"
-}
-const _hoisted_3 = {
- key: 1,
- class: "history-list"
-}
-const _hoisted_4 = { class: "history-date" }
-const _hoisted_5 = { class: "history-stats" }
-const _hoisted_6 = { class: "stat download" }
-const _hoisted_7 = { class: "stat upload" }
-const _hoisted_8 = { class: "stat ping" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h1", null, "Test History", -1 /* CACHED */)),
- ($setup.testResults.length === 0)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_2, " No speed tests recorded yet. "))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_3, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.testResults, (result, index) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: index,
- class: "history-item"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate(result.timestamp)), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_6, "↓ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.download) + " Mbps", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_7, "↑ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.upload) + " Mbps", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_8, "↔ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.ping) + " ms", 1 /* TEXT */)
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ]))
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=template&id=f48afcd2&scoped=true":
-/*!****************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/MainLayout.vue?vue&type=template&id=f48afcd2&scoped=true ***!
- \****************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "main-layout" }
-const _hoisted_2 = { class: "header" }
-const _hoisted_3 = { class: "header-left" }
-const _hoisted_4 = { class: "logo" }
-const _hoisted_5 = { class: "breadcrumb" }
-const _hoisted_6 = {
- key: 0,
- class: "separator"
-}
-const _hoisted_7 = { class: "breadcrumb-item" }
-const _hoisted_8 = { class: "header-right" }
-const _hoisted_9 = { class: "message-center" }
-const _hoisted_10 = {
- key: 0,
- class: "badge"
-}
-const _hoisted_11 = {
- key: 0,
- class: "message-panel"
-}
-const _hoisted_12 = { class: "message-header" }
-const _hoisted_13 = { class: "message-list" }
-const _hoisted_14 = { class: "message-icon" }
-const _hoisted_15 = { class: "message-content" }
-const _hoisted_16 = { class: "message-title" }
-const _hoisted_17 = { class: "message-time" }
-const _hoisted_18 = ["onClick"]
-const _hoisted_19 = { class: "user-info" }
-const _hoisted_20 = ["src", "alt"]
-const _hoisted_21 = {
- key: 1,
- class: "avatar-placeholder"
-}
-const _hoisted_22 = { class: "login-section" }
-const _hoisted_23 = {
- key: 2,
- class: "user-menu"
-}
-const _hoisted_24 = { class: "user-menu-header" }
-const _hoisted_25 = { class: "user-details" }
-const _hoisted_26 = { class: "user-name" }
-const _hoisted_27 = { class: "user-email" }
-const _hoisted_28 = {
- key: 0,
- class: "user-role"
-}
-const _hoisted_29 = {
- key: 1,
- class: "user-last-login"
-}
-const _hoisted_30 = { class: "user-menu-items" }
-const _hoisted_31 = { class: "main-content" }
-const _hoisted_32 = { class: "sidebar" }
-const _hoisted_33 = { class: "sidebar-nav" }
-const _hoisted_34 = { class: "nav-section" }
-const _hoisted_35 = { class: "nav-list" }
-const _hoisted_36 = { class: "nav-text" }
-const _hoisted_37 = ["onClick"]
-const _hoisted_38 = { class: "nav-section" }
-const _hoisted_39 = { class: "nav-list" }
-const _hoisted_40 = { class: "nav-text" }
-const _hoisted_41 = ["onClick"]
-const _hoisted_42 = { class: "content-area" }
-const _hoisted_43 = { class: "content-tabs" }
-const _hoisted_44 = { class: "tab-list" }
-const _hoisted_45 = ["onClick"]
-const _hoisted_46 = { class: "tab-title" }
-const _hoisted_47 = ["onClick"]
-const _hoisted_48 = { class: "tab-actions" }
-const _hoisted_49 = { class: "content-body" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- const _component_router_link = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("router-link")
- const _component_router_view = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("router-view")
- const _component_LoginModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("LoginModal")
- const _component_PasswordChangeModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("PasswordChangeModal")
- const _component_Toast = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("Toast")
-
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 顶部导航栏 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("header", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h1", null, [
- _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-rocket" }, null, -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.appSettings.appName), 1 /* TEXT */)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.breadcrumbs, (item, index) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", { key: index }, [
- (index > 0)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_6, "/"))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_7, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item), 1 /* TEXT */)
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 消息通知 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "message-btn",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.toggleMessagePanel && $setup.toggleMessagePanel(...args)))
- }, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-bell" }, null, -1 /* CACHED */)),
- ($setup.unreadCount > 0)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_10, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.unreadCount), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 消息面板 "),
- ($setup.showMessagePanel)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_11, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-envelope" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 消息")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[1] || (_cache[1] = $event => ($setup.showMessagePanel = false))
- }, _cache[14] || (_cache[14] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.messages, (message) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: message.id,
- class: "message-item"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_14, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(message.icon), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(message.title), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatTime(message.time)), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "mark-read-btn",
- onClick: $event => ($setup.markAsRead(message.id))
- }, [...(_cache[16] || (_cache[16] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-check" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_18)
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户信息 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- ($setup.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "user-avatar",
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.toggleUserMenu && $setup.toggleUserMenu(...args)))
- }, [
- ($setup.currentUser.avatar)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("img", {
- key: 0,
- src: $setup.currentUser.avatar,
- alt: $setup.currentUser.name
- }, null, 8 /* PROPS */, _hoisted_20))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(($setup.currentUser.name || '').charAt(0) || 'U'), 1 /* TEXT */))
- ]))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: 1 }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 未登录状态显示登录按钮 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "login-btn",
- onClick: _cache[3] || (_cache[3] = (...args) => ($setup.showLoginModal && $setup.showLoginModal(...args)))
- }, _cache[17] || (_cache[17] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-sign-in-alt" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 登录 ", -1 /* CACHED */)
- ]))
- ])
- ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户菜单 "),
- ($setup.showUserMenu && $setup.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_23, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentUser.name || '用户'), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_27, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentUser.email || 'user@example.com'), 1 /* TEXT */),
- ($setup.currentUser.role)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentUser.role), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- ($setup.currentUser.lastLogin)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_29, "上次登录: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatLastLogin($setup.currentUser.lastLogin)), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_30, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "menu-item",
- onClick: _cache[4] || (_cache[4] = (...args) => ($setup.openProfile && $setup.openProfile(...args)))
- }, _cache[18] || (_cache[18] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 个人资料 ", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "menu-item",
- onClick: _cache[5] || (_cache[5] = (...args) => ($setup.openSettings && $setup.openSettings(...args)))
- }, _cache[19] || (_cache[19] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-cog" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 用户设置 ", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "menu-item",
- onClick: _cache[6] || (_cache[6] = (...args) => ($setup.logout && $setup.logout(...args)))
- }, _cache[20] || (_cache[20] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-sign-out-alt" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 退出登录 ", -1 /* CACHED */)
- ]))
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 主要内容区域 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_31, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 左侧菜单 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("aside", _hoisted_32, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("nav", _hoisted_33, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_34, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("ul", _hoisted_35, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.mainMenuItems, (item) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("li", {
- key: item.id
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_router_link, {
- to: item.path,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["nav-item", { active: $setup.currentRoute === item.path }]),
- onClick: $event => ($setup.handleMenuClick(item))
- }, {
- default: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(() => [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["nav-icon", $setup.getNavIconClass(item.icon)])
- }, null, 2 /* CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_36, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.name), 1 /* TEXT */),
- (item.favorite)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("button", {
- key: 0,
- class: "favorite-btn",
- onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => ($setup.toggleFavorite(item.id)), ["stop"])
- }, [...(_cache[21] || (_cache[21] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-star" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_37))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- _: 2 /* DYNAMIC */
- }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["to", "class", "onClick"])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_38, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("ul", _hoisted_39, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.favoriteMenuItems, (item) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("li", {
- key: item.id
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_router_link, {
- to: item.path,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["nav-item", { active: $setup.currentRoute === item.path }])
- }, {
- default: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(() => [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["nav-icon", $setup.getNavIconClass(item.icon)])
- }, null, 2 /* CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_40, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.name), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "favorite-btn active",
- onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => ($setup.toggleFavorite(item.id)), ["stop"])
- }, [...(_cache[22] || (_cache[22] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-star" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_41)
- ]),
- _: 2 /* DYNAMIC */
- }, 1032 /* PROPS, DYNAMIC_SLOTS */, ["to", "class"])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 右侧内容区域 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_42, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 内容选项卡 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_43, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_44, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.openTabs, (tab) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: tab.id,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['tab-item', { active: tab.id === $setup.currentTab }]),
- onClick: $event => ($setup.switchTab(tab.id))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_46, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(tab.title), 1 /* TEXT */),
- ($setup.openTabs.length > 1)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("button", {
- key: 0,
- class: "tab-close",
- onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => ($setup.closeTab(tab.id)), ["stop"]),
- title: "关闭标签页"
- }, [...(_cache[23] || (_cache[23] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_47))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ], 10 /* CLASS, PROPS */, _hoisted_45))
- }), 128 /* KEYED_FRAGMENT */))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_48, [
- ($setup.openTabs.length > 1)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("button", {
- key: 0,
- class: "close-all-btn",
- onClick: _cache[7] || (_cache[7] = (...args) => ($setup.closeAllTabs && $setup.closeAllTabs(...args))),
- title: "关闭所有标签页"
- }, _cache[24] || (_cache[24] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times-circle" }, null, -1 /* CACHED */)
- ])))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 功能内容区 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_49, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_router_view, { onAddTab: $setup.handleAddTab }, null, 8 /* PROPS */, ["onAddTab"])
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 登录弹窗 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_LoginModal, {
- visible: $setup.showLoginModalFlag,
- "onUpdate:visible": _cache[8] || (_cache[8] = $event => (($setup.showLoginModalFlag) = $event)),
- onLoginSuccess: $setup.handleLoginSuccess,
- onShowMessage: $setup.handleShowMessage
- }, null, 8 /* PROPS */, ["visible", "onLoginSuccess", "onShowMessage"]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 密码修改弹窗 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_PasswordChangeModal, {
- visible: $setup.showPasswordModal,
- "onUpdate:visible": _cache[9] || (_cache[9] = $event => (($setup.showPasswordModal) = $event)),
- "is-force-change": $setup.isForceChange,
- onClose: _cache[10] || (_cache[10] = $event => ($setup.showPasswordModal = false)),
- onSuccess: $setup.handlePasswordChangeSuccess
- }, null, 8 /* PROPS */, ["visible", "is-force-change", "onSuccess"]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" Toast 消息提示 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Toast, {
- visible: $setup.showToast,
- "onUpdate:visible": _cache[11] || (_cache[11] = $event => (($setup.showToast) = $event)),
- type: $setup.toastConfig.type,
- title: $setup.toastConfig.title,
- content: $setup.toastConfig.content,
- duration: $setup.toastConfig.duration
- }, null, 8 /* PROPS */, ["visible", "type", "title", "content", "duration"])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=template&id=74335f1d&scoped=true":
-/*!***************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/StatusBar.vue?vue&type=template&id=74335f1d&scoped=true ***!
- \***************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "status-bar" }
-const _hoisted_2 = { class: "status-left" }
-const _hoisted_3 = { class: "status-item" }
-const _hoisted_4 = { class: "status-item" }
-const _hoisted_5 = { class: "status-right" }
-const _hoisted_6 = { class: "status-item" }
-const _hoisted_7 = { class: "status-item" }
-const _hoisted_8 = { class: "status-item" }
-const _hoisted_9 = { class: "status-item" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 左侧:用户和版本信息 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, "用户: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.userInfo), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, "版本: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.appVersion), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 右侧:其他状态信息 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, "服务地址: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.serverUrl), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", {
- class: "error-link",
- onClick: _cache[0] || (_cache[0] = (...args) => ($options.openLogFolder && $options.openLogFolder(...args))),
- title: "点击打开日志文件夹"
- }, " 最近错误: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.errorCount), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, "内存: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.memoryUsage) + " MB", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, "系统内存: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.systemMemoryUsage), 1 /* TEXT */)
- ])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=template&id=4ef284fa&scoped=true":
-/*!***********************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/components/Toast.vue?vue&type=template&id=4ef284fa&scoped=true ***!
- \***********************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "toast-icon" }
-const _hoisted_2 = { class: "toast-content" }
-const _hoisted_3 = { class: "toast-title" }
-const _hoisted_4 = {
- key: 0,
- class: "toast-message"
-}
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Transition, { name: "toast" }, {
- default: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withCtx)(() => [
- ($props.visible)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["toast", $props.type])
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($options.iconClass)
- }, null, 2 /* CLASS */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.title), 1 /* TEXT */),
- ($props.content)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_4, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($props.content), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "toast-close",
- onClick: _cache[0] || (_cache[0] = (...args) => ($options.close && $options.close(...args)))
- }, _cache[1] || (_cache[1] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ], 2 /* CLASS */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- _: 1 /* STABLE */
- }))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=template&id=1ac2098a&scoped=true":
-/*!***********************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/ConfigTest.vue?vue&type=template&id=1ac2098a&scoped=true ***!
- \***********************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "config-test" }
-const _hoisted_2 = { class: "config-content" }
-const _hoisted_3 = { class: "config-section" }
-const _hoisted_4 = { class: "config-item" }
-const _hoisted_5 = { class: "config-item" }
-const _hoisted_6 = { class: "config-item" }
-const _hoisted_7 = { class: "config-item" }
-const _hoisted_8 = { class: "config-section" }
-const _hoisted_9 = ["disabled"]
-const _hoisted_10 = {
- key: 0,
- class: "test-result"
-}
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "page-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "配置测试页面")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "当前配置信息", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- _cache[1] || (_cache[1] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "API基础地址:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentConfig.apiBaseUrl), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- _cache[2] || (_cache[2] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "服务器地址:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentConfig.serverUrl), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "WebSocket地址:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentConfig.wsUrl), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "环境变量配置:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.envConfigInfo), 1 /* TEXT */)
- ])
- ]),
- _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("配置优先级说明
1用户设置(最高优先级)
2环境变量配置
3默认配置(最低优先级)
", 1)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "测试API连接", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.testApiConnection && $setup.testApiConnection(...args))),
- disabled: $setup.testing
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? '测试中...' : '测试连接'), 9 /* TEXT, PROPS */, _hoisted_9),
- ($setup.testResult)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_10, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($setup.testResult.success ? 'success' : 'error')
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testResult.message), 3 /* TEXT, CLASS */)
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ])
- ])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=template&id=15b21c75&scoped=true":
-/*!*****************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/core/views/Home.vue?vue&type=template&id=15b21c75&scoped=true ***!
- \*****************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "home" }
-const _hoisted_2 = { class: "main-content" }
-const _hoisted_3 = { class: "welcome-section" }
-const _hoisted_4 = { class: "welcome-card" }
-const _hoisted_5 = { class: "welcome-header" }
-const _hoisted_6 = { class: "welcome-text" }
-const _hoisted_7 = { key: 0 }
-const _hoisted_8 = { key: 1 }
-const _hoisted_9 = {
- key: 2,
- class: "subtitle"
-}
-const _hoisted_10 = {
- key: 3,
- class: "subtitle"
-}
-const _hoisted_11 = {
- key: 0,
- class: "features-section"
-}
-const _hoisted_12 = { class: "login-prompt-section" }
-const _hoisted_13 = { class: "login-prompt-card" }
-const _hoisted_14 = {
- key: 2,
- class: "todo-section"
-}
-const _hoisted_15 = { class: "section-header" }
-const _hoisted_16 = { class: "todo-list" }
-const _hoisted_17 = ["checked", "onChange"]
-const _hoisted_18 = { class: "todo-text" }
-const _hoisted_19 = { class: "todo-date" }
-const _hoisted_20 = ["onClick"]
-const _hoisted_21 = {
- key: 3,
- class: "recent-section"
-}
-const _hoisted_22 = { class: "activity-list" }
-const _hoisted_23 = { class: "activity-icon" }
-const _hoisted_24 = { class: "activity-content" }
-const _hoisted_25 = { class: "activity-title" }
-const _hoisted_26 = { class: "activity-time" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 主要内容区域 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("main", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 欢迎区域 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("section", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- ($options.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("h2", _hoisted_7, "欢迎回来," + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($options.currentUser?.name || $data.userInfo.name) + "!", 1 /* TEXT */))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("h2", _hoisted_8, "欢迎光临,请登录!")),
- ($options.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("p", _hoisted_9, "今天是 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.currentDate) + ",您有 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.todoList.length) + " 个待办事项", 1 /* TEXT */))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("p", _hoisted_10, "登录后享受更多功能"))
- ])
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 功能卡片区域 "),
- ($options.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_11, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "feature-card",
- onClick: _cache[0] || (_cache[0] = (...args) => ($options.startSpeedTest && $options.startSpeedTest(...args)))
- }, _cache[6] || (_cache[6] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-bolt" })
- ], -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "开始速度测试", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "测试您的网络连接速度", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "feature-card",
- onClick: _cache[1] || (_cache[1] = (...args) => ($options.viewHistory && $options.viewHistory(...args)))
- }, _cache[7] || (_cache[7] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chart-bar" })
- ], -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "查看历史", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "查看历史测试记录", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "feature-card",
- onClick: _cache[2] || (_cache[2] = (...args) => ($options.openSettings && $options.openSettings(...args)))
- }, _cache[8] || (_cache[8] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-cog" })
- ], -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "用户设置", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "配置个人偏好", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "feature-card",
- onClick: _cache[3] || (_cache[3] = (...args) => ($options.exportData && $options.exportData(...args)))
- }, _cache[9] || (_cache[9] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-download" })
- ], -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "导出数据", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "导出测试数据", -1 /* CACHED */)
- ]))
- ]))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: 1 }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 登录提示区域 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("section", _hoisted_12, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "prompt-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-lock" })
- ], -1 /* CACHED */)),
- _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "需要登录", -1 /* CACHED */)),
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "登录后即可使用所有功能", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "prompt-login-btn",
- onClick: _cache[4] || (_cache[4] = (...args) => ($options.showLoginModalHandler && $options.showLoginModalHandler(...args)))
- }, _cache[10] || (_cache[10] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-sign-in-alt" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 立即登录 ", -1 /* CACHED */)
- ]))
- ])
- ])
- ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 待办事项区域 "),
- ($options.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_14, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-tasks" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 待办事项")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "add-todo-btn",
- onClick: _cache[5] || (_cache[5] = (...args) => ($options.addTodo && $options.addTodo(...args)))
- }, _cache[14] || (_cache[14] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 添加 ", -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($data.todoList, (todo) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: todo.id,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["todo-item", { completed: todo.completed }])
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- type: "checkbox",
- checked: todo.completed,
- onChange: $event => ($options.toggleTodo(todo.id))
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_17),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_18, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(todo.text), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(todo.date), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "delete-btn",
- onClick: $event => ($options.deleteTodo(todo.id))
- }, [...(_cache[16] || (_cache[16] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-trash" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_20)
- ], 2 /* CLASS */))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 最近活动区域 "),
- ($options.isLoggedIn)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_21, [
- _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-clock" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 最近活动")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($data.recentActivities, (activity) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: activity.id,
- class: "activity-item"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(activity.icon)
- }, null, 2 /* CLASS */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(activity.title), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(activity.time), 1 /* TEXT */)
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=template&id=de6ba976&scoped=true":
-/*!**********************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/PermissionManager.vue?vue&type=template&id=de6ba976&scoped=true ***!
- \**********************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "permission-manager" }
-const _hoisted_2 = { class: "modal-header" }
-const _hoisted_3 = { class: "modal-body" }
-const _hoisted_4 = {
- key: 0,
- class: "permission-content"
-}
-const _hoisted_5 = { class: "role-info" }
-const _hoisted_6 = { class: "role-description" }
-const _hoisted_7 = { class: "permission-tree-container" }
-const _hoisted_8 = { class: "permission-tree" }
-const _hoisted_9 = { class: "resource-header" }
-const _hoisted_10 = { class: "resource-label" }
-const _hoisted_11 = ["checked", "onChange"]
-const _hoisted_12 = { class: "resource-name" }
-const _hoisted_13 = { class: "permission-list" }
-const _hoisted_14 = ["checked", "onChange"]
-const _hoisted_15 = { class: "permission-name" }
-const _hoisted_16 = { class: "modal-footer" }
-const _hoisted_17 = ["disabled"]
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- ($setup.visible)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "modal-overlay",
- onClick: _cache[4] || (_cache[4] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "modal",
- onClick: _cache[3] || (_cache[3] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "权限管理", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, _cache[5] || (_cache[5] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- ($setup.currentRole)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_4, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentRole.name) + " - 权限分配", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", _hoisted_6, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentRole.description), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.permissionTree, (resource) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: resource.id,
- class: "resource-group"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", _hoisted_10, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- type: "checkbox",
- checked: $setup.isResourceChecked(resource),
- onChange: $event => ($setup.toggleResource(resource))
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_11),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_12, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(resource.name), 1 /* TEXT */)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)(resource.children, (permission) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("label", {
- key: permission.id,
- class: "permission-item"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- type: "checkbox",
- checked: $setup.selectedPermissions.includes(permission.id),
- onChange: $event => ($setup.togglePermission(permission.id))
- }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_14),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.name), 1 /* TEXT */)
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-secondary",
- onClick: _cache[1] || (_cache[1] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, "取消"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.savePermissions && $setup.savePermissions(...args))),
- disabled: $setup.saving
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.saving ? '保存中...' : '保存权限'), 9 /* TEXT, PROPS */, _hoisted_17)
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=template&id=7f7c6d92&scoped=true":
-/*!***********************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/UserRoleAssignment.vue?vue&type=template&id=7f7c6d92&scoped=true ***!
- \***********************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "user-role-assignment" }
-const _hoisted_2 = { class: "modal-header" }
-const _hoisted_3 = { class: "modal-body" }
-const _hoisted_4 = {
- key: 0,
- class: "assignment-content"
-}
-const _hoisted_5 = { class: "user-info" }
-const _hoisted_6 = { class: "user-email" }
-const _hoisted_7 = { class: "role-assignment" }
-const _hoisted_8 = { class: "available-roles" }
-const _hoisted_9 = { class: "transfer-container" }
-const _hoisted_10 = { class: "transfer-panel" }
-const _hoisted_11 = { class: "panel-header" }
-const _hoisted_12 = { class: "panel-body" }
-const _hoisted_13 = { class: "role-list" }
-const _hoisted_14 = ["onClick"]
-const _hoisted_15 = { class: "role-name" }
-const _hoisted_16 = { class: "role-description" }
-const _hoisted_17 = { class: "transfer-actions" }
-const _hoisted_18 = ["disabled"]
-const _hoisted_19 = ["disabled"]
-const _hoisted_20 = { class: "transfer-panel" }
-const _hoisted_21 = { class: "panel-header" }
-const _hoisted_22 = { class: "panel-body" }
-const _hoisted_23 = { class: "role-list" }
-const _hoisted_24 = ["onClick"]
-const _hoisted_25 = { class: "role-name" }
-const _hoisted_26 = { class: "role-description" }
-const _hoisted_27 = { class: "modal-footer" }
-const _hoisted_28 = ["disabled"]
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- ($setup.visible)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "modal-overlay",
- onClick: _cache[6] || (_cache[6] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "modal",
- onClick: _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "用户角色分配", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, _cache[7] || (_cache[7] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- ($setup.currentUser)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_4, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentUser.name || $setup.currentUser.username) + " - 角色分配", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", _hoisted_6, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentUser.email), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h5", null, "可用角色", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "未分配角色 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.unassignedRoles.length) + ")", 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.unassignedRoles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: role.key,
- class: "role-item",
- onClick: $event => ($setup.assignRole(role.key))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.label), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.description), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_14))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-primary",
- onClick: _cache[1] || (_cache[1] = (...args) => ($setup.assignSelected && $setup.assignSelected(...args))),
- disabled: !$setup.selectedUnassigned.length
- }, _cache[9] || (_cache[9] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-right" }, null, -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_18),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-primary",
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.removeSelected && $setup.removeSelected(...args))),
- disabled: !$setup.selectedAssigned.length
- }, _cache[10] || (_cache[10] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-left" }, null, -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_19)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "已分配角色 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.assignedRoles.length) + ")", 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.assignedRoles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: role.key,
- class: "role-item",
- onClick: $event => ($setup.removeRole(role.key))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_25, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.label), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.description), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_24))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ])
- ])
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_27, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-secondary",
- onClick: _cache[3] || (_cache[3] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, "取消"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[4] || (_cache[4] = (...args) => ($setup.saveRoleAssignment && $setup.saveRoleAssignment(...args))),
- disabled: $setup.saving
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.saving ? '保存中...' : '保存分配'), 9 /* TEXT, PROPS */, _hoisted_28)
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=template&id=77b697b6&scoped=true":
-/*!***********************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleApiTest.vue?vue&type=template&id=77b697b6&scoped=true ***!
- \***********************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "role-api-test" }
-const _hoisted_2 = { class: "page-header" }
-const _hoisted_3 = { class: "header-actions" }
-const _hoisted_4 = ["title"]
-const _hoisted_5 = { class: "test-content" }
-const _hoisted_6 = { class: "test-section" }
-const _hoisted_7 = { class: "config-info" }
-const _hoisted_8 = { class: "config-item" }
-const _hoisted_9 = { class: "config-item" }
-const _hoisted_10 = { class: "config-item" }
-const _hoisted_11 = { class: "test-section" }
-const _hoisted_12 = { class: "test-results" }
-const _hoisted_13 = { class: "test-header" }
-const _hoisted_14 = { class: "test-name" }
-const _hoisted_15 = { class: "test-status" }
-const _hoisted_16 = {
- key: 0,
- class: "test-message"
-}
-const _hoisted_17 = {
- key: 1,
- class: "test-data"
-}
-const _hoisted_18 = { class: "test-section" }
-const _hoisted_19 = { class: "manual-tests" }
-const _hoisted_20 = { class: "test-group" }
-const _hoisted_21 = ["disabled"]
-const _hoisted_22 = { class: "test-group" }
-const _hoisted_23 = { class: "form-group" }
-const _hoisted_24 = { class: "form-group" }
-const _hoisted_25 = { class: "form-group" }
-const _hoisted_26 = ["disabled"]
-const _hoisted_27 = { class: "test-group" }
-const _hoisted_28 = { class: "form-group" }
-const _hoisted_29 = ["disabled"]
-const _hoisted_30 = { class: "test-group" }
-const _hoisted_31 = { class: "form-group" }
-const _hoisted_32 = ["disabled"]
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "角色管理API测试", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-secondary",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.toggleTestMode && $setup.toggleTestMode(...args))),
- title: $setup.testMode ? '当前为测试模式(无需认证)' : '当前为正式模式(需要认证)'
- }, [
- _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-flask" }, null, -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testMode ? '测试模式' : '正式模式'), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_4),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[1] || (_cache[1] = (...args) => ($setup.runAllTests && $setup.runAllTests(...args)))
- }, _cache[12] || (_cache[12] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-play" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 运行所有测试 ", -1 /* CACHED */)
- ]))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" API配置信息 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "API配置信息", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "API基础地址:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.apiBaseUrl), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "当前模式:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)($setup.testMode ? 'test-mode' : 'prod-mode')
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testMode ? '测试模式' : '正式模式'), 3 /* TEXT, CLASS */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- _cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "API路径:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentApiPath), 1 /* TEXT */)
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 测试结果 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [
- _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "测试结果", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.testResults, (result, index) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: index,
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["test-result-item", result.status])
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_14, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.name), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.getStatusText(result.status)), 1 /* TEXT */)
- ]),
- (result.message)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_16, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.message), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (result.data)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_17, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("pre", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(JSON.stringify(result.data, null, 2)), 1 /* TEXT */)
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ], 2 /* CLASS */))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 手动测试 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "手动测试", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [
- _cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "获取角色列表", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.testGetRoles && $setup.testGetRoles(...args))),
- disabled: $setup.testing
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? '测试中...' : '测试获取角色列表'), 9 /* TEXT, PROPS */, _hoisted_21)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- _cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "创建角色", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [
- _cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色名称:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($setup.testRole.name) = $event)),
- type: "text",
- placeholder: "测试角色"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.testRole.name]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, [
- _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色代码:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => (($setup.testRole.code) = $event)),
- type: "text",
- placeholder: "TEST_ROLE"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.testRole.code]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [
- _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "描述:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[5] || (_cache[5] = $event => (($setup.testRole.description) = $event)),
- type: "text",
- placeholder: "测试角色描述"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.testRole.description]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[6] || (_cache[6] = (...args) => ($setup.testCreateRole && $setup.testCreateRole(...args))),
- disabled: $setup.testing
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? '测试中...' : '测试创建角色'), 9 /* TEXT, PROPS */, _hoisted_26)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_27, [
- _cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "更新角色", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_28, [
- _cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色ID:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[7] || (_cache[7] = $event => (($setup.updateRoleId) = $event)),
- type: "number",
- placeholder: "输入角色ID"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.updateRoleId]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[8] || (_cache[8] = (...args) => ($setup.testUpdateRole && $setup.testUpdateRole(...args))),
- disabled: $setup.testing || !$setup.updateRoleId
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? '测试中...' : '测试更新角色'), 9 /* TEXT, PROPS */, _hoisted_29)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_30, [
- _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "删除角色", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_31, [
- _cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色ID:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[9] || (_cache[9] = $event => (($setup.deleteRoleId) = $event)),
- type: "number",
- placeholder: "输入角色ID"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.deleteRoleId]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[10] || (_cache[10] = (...args) => ($setup.testDeleteRole && $setup.testDeleteRole(...args))),
- disabled: $setup.testing || !$setup.deleteRoleId
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testing ? '测试中...' : '测试删除角色'), 9 /* TEXT, PROPS */, _hoisted_32)
- ])
- ])
- ])
- ])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=template&id=03643bfa&scoped=true":
-/*!**************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/views/RoleManagement.vue?vue&type=template&id=03643bfa&scoped=true ***!
- \**************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "role-management" }
-const _hoisted_2 = { class: "page-header" }
-const _hoisted_3 = { class: "header-actions" }
-const _hoisted_4 = ["title"]
-const _hoisted_5 = { class: "role-list" }
-const _hoisted_6 = {
- key: 0,
- class: "loading"
-}
-const _hoisted_7 = {
- key: 1,
- class: "empty-state"
-}
-const _hoisted_8 = { key: 2 }
-const _hoisted_9 = { class: "actions" }
-const _hoisted_10 = ["onClick"]
-const _hoisted_11 = ["onClick"]
-const _hoisted_12 = {
- key: 3,
- class: "pagination"
-}
-const _hoisted_13 = ["disabled"]
-const _hoisted_14 = { class: "page-info" }
-const _hoisted_15 = ["disabled"]
-const _hoisted_16 = { class: "modal-header" }
-const _hoisted_17 = { class: "modal-body" }
-const _hoisted_18 = { class: "form-group" }
-const _hoisted_19 = { class: "form-group" }
-const _hoisted_20 = { class: "form-group" }
-const _hoisted_21 = { class: "form-actions" }
-const _hoisted_22 = ["disabled"]
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "角色管理", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-secondary",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.toggleTestMode && $setup.toggleTestMode(...args))),
- title: $setup.testMode ? '当前为测试模式(无需认证)' : '当前为正式模式(需要认证)'
- }, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-flask" }, null, -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.testMode ? '测试模式' : '正式模式'), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_4),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[1] || (_cache[1] = (...args) => ($setup.createNewRole && $setup.createNewRole(...args)))
- }, _cache[14] || (_cache[14] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 新建角色 ", -1 /* CACHED */)
- ]))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 角色列表 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- ($setup.loading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_6, _cache[16] || (_cache[16] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-spinner fa-spin" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "加载中...", -1 /* CACHED */)
- ])))
- : ($setup.roles.length === 0)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_7, [
- _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-inbox" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 暂无角色数据")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.createNewRole && $setup.createNewRole(...args)))
- }, _cache[17] || (_cache[17] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 创建第一个角色 ", -1 /* CACHED */)
- ]))
- ]))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("table", _hoisted_8, [
- _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("thead", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tr", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "ID"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "角色名称"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "角色代码"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "描述"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "创建时间"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "操作")
- ])
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tbody", null, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.roles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("tr", {
- key: role.id
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.id), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.code), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.description), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate(role.created_at)), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-info",
- onClick: $event => ($setup.editRole(role))
- }, [...(_cache[19] || (_cache[19] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-edit" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_10),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-danger",
- onClick: $event => ($setup.deleteRole(role))
- }, [...(_cache[20] || (_cache[20] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-trash" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_11)
- ])
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 分页 "),
- ($setup.total > $setup.pageSize)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_12, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- disabled: $setup.currentPage === 1,
- onClick: _cache[3] || (_cache[3] = $event => ($setup.handleCurrentChange($setup.currentPage - 1))),
- class: "btn btn-sm"
- }, _cache[22] || (_cache[22] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-left" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 上一页 ", -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_13),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_14, " 第 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentPage) + " 页,共 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(Math.ceil($setup.total / $setup.pageSize)) + " 页 ", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- disabled: $setup.currentPage >= Math.ceil($setup.total / $setup.pageSize),
- onClick: _cache[4] || (_cache[4] = $event => ($setup.handleCurrentChange($setup.currentPage + 1))),
- class: "btn btn-sm"
- }, _cache[23] || (_cache[23] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 下一页 ", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-right" }, null, -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_15)
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 创建/编辑角色对话框 "),
- ($setup.showCreateDialog)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "modal-overlay",
- onClick: _cache[12] || (_cache[12] = $event => ($setup.showCreateDialog = false))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "modal",
- onClick: _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.editingRole ? '编辑角色' : '新建角色'), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[5] || (_cache[5] = $event => ($setup.showCreateDialog = false))
- }, _cache[24] || (_cache[24] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", {
- onSubmit: _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.saveRole && $setup.saveRole(...args)), ["prevent"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- _cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色名称 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[6] || (_cache[6] = $event => (($setup.roleForm.name) = $event)),
- type: "text",
- required: "",
- placeholder: "请输入角色名称"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.roleForm.name]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- _cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色代码 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[7] || (_cache[7] = $event => (($setup.roleForm.code) = $event)),
- type: "text",
- required: "",
- placeholder: "请输入角色代码"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.roleForm.code]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [
- _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "描述", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("textarea", {
- "onUpdate:modelValue": _cache[8] || (_cache[8] = $event => (($setup.roleForm.description) = $event)),
- rows: "3",
- placeholder: "请输入角色描述"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.roleForm.description]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "button",
- class: "btn btn-secondary",
- onClick: _cache[9] || (_cache[9] = $event => ($setup.showCreateDialog = false))
- }, " 取消 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "submit",
- class: "btn btn-primary",
- disabled: $setup.saving
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.saving ? '保存中...' : ($setup.editingRole ? '更新' : '创建')), 9 /* TEXT, PROPS */, _hoisted_22)
- ])
- ], 32 /* NEED_HYDRATION */)
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=template&id=69b5cd1d&scoped=true":
-/*!********************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/system-settings/views/Settings.vue?vue&type=template&id=69b5cd1d&scoped=true ***!
- \********************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "settings" }
-const _hoisted_2 = { class: "settings-content" }
-const _hoisted_3 = { class: "settings-section" }
-const _hoisted_4 = { class: "setting-item" }
-const _hoisted_5 = { class: "setting-item" }
-const _hoisted_6 = { class: "setting-item" }
-const _hoisted_7 = { class: "settings-section" }
-const _hoisted_8 = { class: "setting-item" }
-const _hoisted_9 = { class: "setting-item" }
-const _hoisted_10 = { class: "settings-section" }
-const _hoisted_11 = { class: "setting-item" }
-const _hoisted_12 = { class: "toggle-switch" }
-const _hoisted_13 = { class: "setting-item" }
-const _hoisted_14 = { class: "toggle-switch" }
-const _hoisted_15 = { class: "settings-section" }
-const _hoisted_16 = { class: "setting-item" }
-const _hoisted_17 = { class: "toggle-switch" }
-const _hoisted_18 = { class: "setting-item" }
-const _hoisted_19 = { class: "toggle-switch" }
-const _hoisted_20 = { class: "setting-item" }
-const _hoisted_21 = { class: "settings-section" }
-const _hoisted_22 = { class: "setting-item" }
-const _hoisted_23 = { class: "setting-item" }
-const _hoisted_24 = { class: "toggle-switch" }
-const _hoisted_25 = { class: "setting-item" }
-const _hoisted_26 = { class: "settings-actions" }
-const _hoisted_27 = ["disabled"]
-const _hoisted_28 = { key: 0 }
-const _hoisted_29 = { key: 1 }
-const _hoisted_30 = { key: 2 }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- const _component_Toast = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("Toast")
-
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- _cache[43] || (_cache[43] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "page-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "用户设置")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 个人偏好 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "个人偏好", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "应用名称", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($setup.settings.appName) = $event)),
- type: "text",
- placeholder: "GoFaster"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.settings.appName]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- _cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "语言", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($setup.settings.language) = $event))
- }, _cache[18] || (_cache[18] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "zh-CN" }, "简体中文", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "en-US" }, "English", -1 /* CACHED */)
- ]), 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.settings.language]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "主题", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => (($setup.settings.theme) = $event)),
- onChange: _cache[3] || (_cache[3] = $event => ($setup.handleThemeChange($setup.settings.theme)))
- }, _cache[20] || (_cache[20] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "light" }, "浅色主题", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "dark" }, "深色主题", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "auto" }, "跟随系统", -1 /* CACHED */)
- ]), 544 /* NEED_HYDRATION, NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.settings.theme]
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 应用设置 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- _cache[25] || (_cache[25] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "应用设置", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "请求超时时间 (秒)", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => (($setup.settings.timeout) = $event)),
- type: "number",
- min: "5",
- max: "60"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.settings.timeout]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- _cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "自动重试次数", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[5] || (_cache[5] = $event => (($setup.settings.retryCount) = $event)),
- type: "number",
- min: "0",
- max: "5"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.settings.retryCount]
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户设置 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- _cache[30] || (_cache[30] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "用户设置", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [
- _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "关闭窗口不登出", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[6] || (_cache[6] = $event => (($setup.settings.keepLoginOnClose) = $event)),
- type: "checkbox",
- id: "keepLoginOnClose"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.settings.keepLoginOnClose]
- ]),
- _cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", {
- for: "keepLoginOnClose",
- class: "toggle-label"
- }, null, -1 /* CACHED */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- _cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "记住密码", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_14, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[7] || (_cache[7] = $event => (($setup.settings.rememberPassword) = $event)),
- type: "checkbox",
- id: "rememberPassword"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.settings.rememberPassword]
- ]),
- _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", {
- for: "rememberPassword",
- class: "toggle-label"
- }, null, -1 /* CACHED */))
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 通知偏好 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [
- _cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "通知偏好", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- _cache[32] || (_cache[32] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "桌面通知", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[8] || (_cache[8] = $event => (($setup.settings.desktopNotifications) = $event)),
- type: "checkbox",
- id: "desktopNotifications"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.settings.desktopNotifications]
- ]),
- _cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", {
- for: "desktopNotifications",
- class: "toggle-label"
- }, null, -1 /* CACHED */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- _cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "声音提醒", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[9] || (_cache[9] = $event => (($setup.settings.soundNotifications) = $event)),
- type: "checkbox",
- id: "soundNotifications"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.settings.soundNotifications]
- ]),
- _cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", {
- for: "soundNotifications",
- class: "toggle-label"
- }, null, -1 /* CACHED */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [
- _cache[35] || (_cache[35] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "消息提醒间隔 (秒)", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[10] || (_cache[10] = $event => (($setup.settings.notificationInterval) = $event)),
- type: "number",
- min: "5",
- max: "300"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.settings.notificationInterval]
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 数据管理 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [
- _cache[42] || (_cache[42] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "数据管理", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- _cache[37] || (_cache[37] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "数据缓存大小 (MB)", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[11] || (_cache[11] = $event => (($setup.settings.cacheSize) = $event)),
- type: "number",
- min: "50",
- max: "1000"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.settings.cacheSize]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [
- _cache[39] || (_cache[39] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "自动清理缓存", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[12] || (_cache[12] = $event => (($setup.settings.autoCleanCache) = $event)),
- type: "checkbox",
- id: "autoCleanCache"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.settings.autoCleanCache]
- ]),
- _cache[38] || (_cache[38] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", {
- for: "autoCleanCache",
- class: "toggle-label"
- }, null, -1 /* CACHED */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [
- _cache[41] || (_cache[41] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "数据备份频率", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[13] || (_cache[13] = $event => (($setup.settings.backupFrequency) = $event))
- }, _cache[40] || (_cache[40] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "daily" }, "每日", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "weekly" }, "每周", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "monthly" }, "每月", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "never" }, "从不", -1 /* CACHED */)
- ]), 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.settings.backupFrequency]
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 操作按钮 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_26, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-secondary",
- onClick: _cache[14] || (_cache[14] = (...args) => ($setup.resetSettings && $setup.resetSettings(...args)))
- }, " 重置所有设置 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["btn", $setup.saveButtonClass]),
- onClick: _cache[15] || (_cache[15] = (...args) => ($setup.saveSettings && $setup.saveSettings(...args))),
- disabled: !$setup.hasChanges || $setup.isSaving
- }, [
- ($setup.isSaving)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_28, "保存中..."))
- : ($setup.hasChanges)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_29, "保存更改"))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_30, "已保存"))
- ], 10 /* CLASS, PROPS */, _hoisted_27)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" Toast 消息提示 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Toast, {
- visible: $setup.showToast,
- "onUpdate:visible": _cache[16] || (_cache[16] = $event => (($setup.showToast) = $event)),
- type: $setup.toastConfig.type,
- title: $setup.toastConfig.title,
- content: $setup.toastConfig.content,
- duration: $setup.toastConfig.duration
- }, null, 8 /* PROPS */, ["visible", "type", "title", "content", "duration"])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=template&id=2de9ad90&scoped=true":
-/*!***************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/LoginModal.vue?vue&type=template&id=2de9ad90&scoped=true ***!
- \***************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = {
- key: 0,
- class: "login-modal-overlay"
-}
-const _hoisted_2 = { class: "login-modal-header" }
-const _hoisted_3 = { class: "login-modal-body" }
-const _hoisted_4 = { class: "form-group" }
-const _hoisted_5 = ["disabled"]
-const _hoisted_6 = { class: "form-group" }
-const _hoisted_7 = { class: "password-input-container" }
-const _hoisted_8 = ["type", "disabled"]
-const _hoisted_9 = ["disabled", "title"]
-const _hoisted_10 = { class: "form-group" }
-const _hoisted_11 = { class: "captcha-container" }
-const _hoisted_12 = ["disabled"]
-const _hoisted_13 = { class: "captcha-image-container" }
-const _hoisted_14 = ["src"]
-const _hoisted_15 = { key: 0 }
-const _hoisted_16 = { key: 1 }
-const _hoisted_17 = {
- key: 2,
- class: "captcha-loading-spinner"
-}
-const _hoisted_18 = { class: "form-actions" }
-const _hoisted_19 = ["disabled"]
-const _hoisted_20 = {
- key: 0,
- class: "loading-spinner"
-}
-const _hoisted_21 = {
- key: 0,
- class: "error-message",
- role: "alert"
-}
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ($props.visible)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "login-modal",
- onClick: _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "用户登录", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[0] || (_cache[0] = (...args) => ($options.closeModal && $options.closeModal(...args)))
- }, _cache[9] || (_cache[9] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", {
- onSubmit: _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($options.handleLogin && $options.handleLogin(...args)), ["prevent"])),
- class: "login-form"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户名 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", { for: "username" }, "用户名", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- id: "username",
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($data.loginForm.username) = $event)),
- type: "text",
- placeholder: "请输入用户名",
- required: "",
- disabled: $data.loading
- }, null, 8 /* PROPS */, _hoisted_5), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.loginForm.username]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 密码 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", { for: "password" }, "密码", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- id: "password",
- "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => (($data.loginForm.password) = $event)),
- type: $data.showPassword ? 'text' : 'password',
- placeholder: "请输入密码",
- required: "",
- disabled: $data.loading
- }, null, 8 /* PROPS */, _hoisted_8), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelDynamic, $data.loginForm.password]
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "button",
- class: "password-toggle-btn",
- onClick: _cache[3] || (_cache[3] = (...args) => ($options.togglePassword && $options.togglePassword(...args))),
- disabled: $data.loading,
- title: $data.showPassword ? '隐藏密码' : '显示密码'
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["password-icon", $data.showPassword ? 'fas fa-eye-slash' : 'fas fa-eye'])
- }, null, 2 /* CLASS */)
- ], 8 /* PROPS */, _hoisted_9)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 验证码 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", { for: "captcha" }, "验证码", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- id: "captcha",
- "onUpdate:modelValue": _cache[4] || (_cache[4] = $event => (($data.loginForm.captcha) = $event)),
- type: "text",
- placeholder: "请输入验证码",
- required: "",
- disabled: $data.loading,
- maxlength: "4"
- }, null, 8 /* PROPS */, _hoisted_12), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.loginForm.captcha]
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- ($data.captchaImage)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("img", {
- key: 0,
- src: $data.captchaImage,
- alt: "验证码",
- onClick: _cache[5] || (_cache[5] = (...args) => ($options.refreshCaptcha && $options.refreshCaptcha(...args))),
- class: "captcha-image"
- }, null, 8 /* PROPS */, _hoisted_14))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 1,
- class: "captcha-placeholder",
- onClick: _cache[6] || (_cache[6] = (...args) => ($options.refreshCaptcha && $options.refreshCaptcha(...args)))
- }, [
- ($data.captchaLoading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_15, "验证码加载中..."))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_16, "点击获取验证码")),
- ($data.captchaLoading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_17))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 登录按钮 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "submit",
- class: "login-btn",
- disabled: $data.loading || !$options.isFormValid
- }, [
- ($data.loading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_20))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.loading ? '登录中...' : '登录'), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_19)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 错误提示 "),
- ($data.errorMessage)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_21, [
- _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "error-icon fas fa-exclamation-triangle" }, null, -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($data.errorMessage), 1 /* TEXT */)
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ], 32 /* NEED_HYDRATION */)
- ]),
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "login-modal-footer" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", { class: "login-tips" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "提示:"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "默认管理员账号:admin"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "默认密码:password")
- ])
- ], -1 /* CACHED */))
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=template&id=0b66487e&scoped=true":
-/*!************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordChangeModal.vue?vue&type=template&id=0b66487e&scoped=true ***!
- \************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "modal-header" }
-const _hoisted_2 = { class: "modal-body" }
-const _hoisted_3 = {
- key: 0,
- class: "form-group"
-}
-const _hoisted_4 = ["disabled"]
-const _hoisted_5 = {
- key: 0,
- class: "error-message"
-}
-const _hoisted_6 = { class: "form-group" }
-const _hoisted_7 = ["disabled"]
-const _hoisted_8 = {
- key: 0,
- class: "error-message"
-}
-const _hoisted_9 = { class: "password-strength" }
-const _hoisted_10 = { class: "strength-bar" }
-const _hoisted_11 = { class: "strength-text" }
-const _hoisted_12 = { class: "password-requirements" }
-const _hoisted_13 = { class: "form-group" }
-const _hoisted_14 = ["disabled"]
-const _hoisted_15 = {
- key: 0,
- class: "error-message"
-}
-const _hoisted_16 = { class: "form-actions" }
-const _hoisted_17 = ["disabled"]
-const _hoisted_18 = ["disabled"]
-const _hoisted_19 = {
- key: 0,
- class: "loading-spinner"
-}
-const _hoisted_20 = {
- key: 1,
- class: "force-change-notice"
-}
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ($props.visible)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "password-modal-overlay",
- onClick: _cache[11] || (_cache[11] = (...args) => ($setup.handleOverlayClick && $setup.handleOverlayClick(...args)))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "password-modal",
- onClick: _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.title), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.handleClose && $setup.handleClose(...args)))
- }, _cache[12] || (_cache[12] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", {
- onSubmit: _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.handleSubmit && $setup.handleSubmit(...args)), ["prevent"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 当前密码 "),
- (!$props.isForceChange)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_3, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "当前密码 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($setup.form.currentPassword) = $event)),
- type: "password",
- required: "",
- placeholder: "请输入当前密码",
- onInput: _cache[2] || (_cache[2] = (...args) => ($setup.clearCurrentPasswordError && $setup.clearCurrentPasswordError(...args))),
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({ 'error': $setup.errors.currentPassword }),
- disabled: $setup.loading,
- ref: "currentPasswordInput",
- tabindex: "1",
- autocomplete: "current-password"
- }, null, 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_4), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.form.currentPassword]
- ]),
- ($setup.errors.currentPassword)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_5, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.errors.currentPassword), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 新密码 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "新密码 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($setup.form.newPassword) = $event)),
- type: "password",
- required: "",
- placeholder: "请输入新密码",
- onInput: _cache[4] || (_cache[4] = (...args) => ($setup.handleNewPasswordInput && $setup.handleNewPasswordInput(...args))),
- onKeyup: _cache[5] || (_cache[5] = $event => ($setup.updateRequirements($setup.form.newPassword))),
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({ 'error': $setup.errors.newPassword }),
- disabled: $setup.loading,
- ref: "newPasswordInput",
- tabindex: "2",
- autocomplete: "new-password"
- }, null, 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_7), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.form.newPassword]
- ]),
- ($setup.errors.newPassword)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.errors.newPassword), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 密码强度指示器 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["strength-fill", $setup.strengthClass]),
- style: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeStyle)({ width: $setup.strengthPercentage + '%' })
- }, null, 6 /* CLASS, STYLE */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, " 强度: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.strengthText) + " (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.passwordLevel) + "级) ", 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 密码要求提示 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["requirement", { 'met': $setup.requirements.length }])
- }, " ✓ 密码长度" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.form.newPassword.length) + "位 ", 3 /* TEXT, CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["requirement", { 'met': $setup.requirements.uppercase }])
- }, " ✓ 包含大写字母 ", 2 /* CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["requirement", { 'met': $setup.requirements.lowercase }])
- }, " ✓ 包含小写字母 ", 2 /* CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["requirement", { 'met': $setup.requirements.numbers }])
- }, " ✓ 包含数字 ", 2 /* CLASS */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["requirement", { 'met': $setup.requirements.special }])
- }, " ✓ 包含特殊字符 ", 2 /* CLASS */)
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 确认新密码 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "确认新密码 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[6] || (_cache[6] = $event => (($setup.form.confirmPassword) = $event)),
- type: "password",
- required: "",
- placeholder: "请再次输入新密码",
- onInput: _cache[7] || (_cache[7] = (...args) => ($setup.handleConfirmPasswordInput && $setup.handleConfirmPasswordInput(...args))),
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)({ 'error': $setup.errors.confirmPassword }),
- disabled: $setup.loading,
- ref: "confirmPasswordInput",
- tabindex: "3",
- autocomplete: "new-password"
- }, null, 42 /* CLASS, PROPS, NEED_HYDRATION */, _hoisted_14), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.form.confirmPassword]
- ]),
- ($setup.errors.confirmPassword)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_15, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.errors.confirmPassword), 1 /* TEXT */))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 操作按钮 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "button",
- class: "btn btn-secondary",
- onClick: _cache[8] || (_cache[8] = (...args) => ($setup.handleClose && $setup.handleClose(...args))),
- disabled: $setup.loading
- }, " 取消 ", 8 /* PROPS */, _hoisted_17),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "submit",
- class: "btn btn-primary",
- disabled: $setup.loading || !$setup.isFormValid
- }, [
- ($setup.loading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_19))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.submitText), 1 /* TEXT */)
- ], 8 /* PROPS */, _hoisted_18)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 强制修改密码提示 "),
- ($props.isForceChange)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_20, _cache[16] || (_cache[16] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "notice-icon" }, "⚠️", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "notice-text" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("strong", null, "重要提示:"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)("您的密码已被重置,必须立即修改密码才能继续使用系统。 ")
- ], -1 /* CACHED */)
- ])))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
- ], 32 /* NEED_HYDRATION */)
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true)
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=template&id=1a74186c&scoped=true":
-/*!********************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/components/PasswordProfile.vue?vue&type=template&id=1a74186c&scoped=true ***!
- \********************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "password-profile" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, _cache[0] || (_cache[0] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "密码配置", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "密码配置功能正在开发中...", -1 /* CACHED */)
- ])))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=template&id=7889d364&scoped=true":
-/*!**************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserManagement.vue?vue&type=template&id=7889d364&scoped=true ***!
- \**************************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "user-management" }
-const _hoisted_2 = { class: "page-header" }
-const _hoisted_3 = { class: "search-bar" }
-const _hoisted_4 = { class: "search-input" }
-const _hoisted_5 = { class: "filters" }
-const _hoisted_6 = ["value"]
-const _hoisted_7 = { class: "user-table" }
-const _hoisted_8 = { class: "role-tags" }
-const _hoisted_9 = { class: "actions" }
-const _hoisted_10 = ["onClick"]
-const _hoisted_11 = ["onClick"]
-const _hoisted_12 = ["onClick"]
-const _hoisted_13 = { class: "pagination" }
-const _hoisted_14 = ["disabled"]
-const _hoisted_15 = { class: "page-info" }
-const _hoisted_16 = ["disabled"]
-const _hoisted_17 = { class: "modal-header" }
-const _hoisted_18 = { class: "modal-body" }
-const _hoisted_19 = { class: "form-group" }
-const _hoisted_20 = ["disabled"]
-const _hoisted_21 = {
- key: 0,
- class: "form-group"
-}
-const _hoisted_22 = { class: "form-group" }
-const _hoisted_23 = { class: "form-group" }
-const _hoisted_24 = { class: "form-group" }
-const _hoisted_25 = { class: "form-actions" }
-const _hoisted_26 = {
- type: "submit",
- class: "btn btn-primary"
-}
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- const _component_UserRoleAssignment = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("UserRoleAssignment")
-
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [
- _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "用户管理", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-primary",
- onClick: _cache[0] || (_cache[0] = $event => ($setup.showAddUserModal = true))
- }, _cache[20] || (_cache[20] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 添加用户 ", -1 /* CACHED */)
- ]))
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 搜索和筛选 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-search" }, null, -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($setup.searchQuery) = $event)),
- type: "text",
- placeholder: "搜索用户名、邮箱或手机号...",
- onInput: _cache[2] || (_cache[2] = (...args) => ($setup.handleSearch && $setup.handleSearch(...args)))
- }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.searchQuery]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($setup.statusFilter) = $event)),
- onChange: _cache[4] || (_cache[4] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args)))
- }, _cache[23] || (_cache[23] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "" }, "全部状态", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "1" }, "正常", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "2" }, "禁用", -1 /* CACHED */)
- ]), 544 /* NEED_HYDRATION, NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.statusFilter]
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[5] || (_cache[5] = $event => (($setup.roleFilter) = $event)),
- onChange: _cache[6] || (_cache[6] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args)))
- }, [
- _cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "" }, "全部角色", -1 /* CACHED */)),
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.roles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("option", {
- key: role.id,
- value: role.id
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 9 /* TEXT, PROPS */, _hoisted_6))
- }), 128 /* KEYED_FRAGMENT */))
- ], 544 /* NEED_HYDRATION, NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.roleFilter]
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户列表 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("table", null, [
- _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("thead", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tr", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "ID"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "用户名"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "邮箱"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "手机号"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "状态"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "角色"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "创建时间"),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "操作")
- ])
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tbody", null, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.filteredUsers, (user) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("tr", {
- key: user.id
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.id), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.username), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.email), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.phone), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['status-badge', user.status === 1 ? 'active' : 'inactive'])
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.status === 1 ? '正常' : '禁用'), 3 /* TEXT, CLASS */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)(user.roles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", {
- key: role.id,
- class: "role-tag"
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate(user.created_at)), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-info",
- onClick: $event => ($setup.editUser(user))
- }, [...(_cache[25] || (_cache[25] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-edit" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_10),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-primary",
- onClick: $event => ($setup.assignRoles(user))
- }, [...(_cache[26] || (_cache[26] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user-shield" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_11),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "btn btn-sm btn-danger",
- onClick: $event => ($setup.deleteUser(user.id))
- }, [...(_cache[27] || (_cache[27] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-trash" }, null, -1 /* CACHED */)
- ]))], 8 /* PROPS */, _hoisted_12)
- ])
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 分页 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- disabled: $setup.currentPage === 1,
- onClick: _cache[7] || (_cache[7] = $event => ($setup.changePage($setup.currentPage - 1))),
- class: "btn btn-sm"
- }, _cache[29] || (_cache[29] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-left" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 上一页 ", -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_14),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_15, " 第 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentPage) + " 页,共 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.totalPages) + " 页 ", 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- disabled: $setup.currentPage === $setup.totalPages,
- onClick: _cache[8] || (_cache[8] = $event => ($setup.changePage($setup.currentPage + 1))),
- class: "btn btn-sm"
- }, _cache[30] || (_cache[30] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 下一页 ", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-chevron-right" }, null, -1 /* CACHED */)
- ]), 8 /* PROPS */, _hoisted_16)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 添加/编辑用户模态框 "),
- ($setup.showAddUserModal || $setup.showEditUserModal)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: 0,
- class: "modal-overlay",
- onClick: _cache[18] || (_cache[18] = (...args) => ($setup.closeModal && $setup.closeModal(...args)))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", {
- class: "modal",
- onClick: _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.showEditUserModal ? '编辑用户' : '添加用户'), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- class: "close-btn",
- onClick: _cache[9] || (_cache[9] = (...args) => ($setup.closeModal && $setup.closeModal(...args)))
- }, "×")
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", {
- onSubmit: _cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.submitUser && $setup.submitUser(...args)), ["prevent"]))
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- _cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "用户名 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[10] || (_cache[10] = $event => (($setup.userForm.username) = $event)),
- type: "text",
- required: "",
- disabled: $setup.showEditUserModal
- }, null, 8 /* PROPS */, _hoisted_20), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.username]
- ])
- ]),
- (!$setup.showEditUserModal)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_21, [
- _cache[32] || (_cache[32] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "密码 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[11] || (_cache[11] = $event => (($setup.userForm.password) = $event)),
- type: "password",
- required: ""
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.password]
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- _cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "邮箱 *", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[12] || (_cache[12] = $event => (($setup.userForm.email) = $event)),
- type: "email",
- required: ""
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.email]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [
- _cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "手机号", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", {
- "onUpdate:modelValue": _cache[13] || (_cache[13] = $event => (($setup.userForm.phone) = $event)),
- type: "tel"
- }, null, 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.phone]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, [
- _cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "状态", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", {
- "onUpdate:modelValue": _cache[14] || (_cache[14] = $event => (($setup.userForm.status) = $event))
- }, _cache[35] || (_cache[35] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "1" }, "正常", -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "2" }, "禁用", -1 /* CACHED */)
- ]), 512 /* NEED_PATCH */), [
- [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.userForm.status]
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- type: "button",
- class: "btn btn-secondary",
- onClick: _cache[15] || (_cache[15] = (...args) => ($setup.closeModal && $setup.closeModal(...args)))
- }, " 取消 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.showEditUserModal ? '更新' : '创建'), 1 /* TEXT */)
- ])
- ], 32 /* NEED_HYDRATION */)
- ])
- ])
- ]))
- : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 角色分配对话框 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_UserRoleAssignment, {
- modelValue: $setup.showRoleAssignmentModal,
- "onUpdate:modelValue": _cache[19] || (_cache[19] = $event => (($setup.showRoleAssignmentModal) = $event)),
- user: $setup.selectedUser,
- onSaved: $setup.loadUsers
- }, null, 8 /* PROPS */, ["modelValue", "user", "onSaved"])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=template&id=8301bb50&scoped=true":
-/*!***********************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/user-management/views/UserProfile.vue?vue&type=template&id=8301bb50&scoped=true ***!
- \***********************************************************************************************************************************************************************************************************************************************/
-/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
-
-"use strict";
-__webpack_require__.r(__webpack_exports__);
-/* harmony export */ __webpack_require__.d(__webpack_exports__, {
-/* harmony export */ render: () => (/* binding */ render)
-/* harmony export */ });
-/* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js");
-
-
-const _hoisted_1 = { class: "user-profile" }
-const _hoisted_2 = {
- key: 0,
- class: "loading-container"
-}
-const _hoisted_3 = { class: "error-container" }
-const _hoisted_4 = { class: "profile-content" }
-const _hoisted_5 = { class: "profile-card" }
-const _hoisted_6 = { class: "card-content" }
-const _hoisted_7 = { class: "info-grid" }
-const _hoisted_8 = { class: "info-item" }
-const _hoisted_9 = { class: "info-item" }
-const _hoisted_10 = { class: "info-item" }
-const _hoisted_11 = { class: "info-item" }
-const _hoisted_12 = { class: "info-item" }
-const _hoisted_13 = { class: "info-item" }
-const _hoisted_14 = { class: "profile-card" }
-const _hoisted_15 = { class: "card-content" }
-const _hoisted_16 = { class: "info-grid" }
-const _hoisted_17 = { class: "info-item" }
-const _hoisted_18 = { class: "info-item" }
-const _hoisted_19 = { class: "profile-card" }
-const _hoisted_20 = { class: "card-content" }
-const _hoisted_21 = {
- key: 0,
- class: "roles-list"
-}
-const _hoisted_22 = { class: "role-header" }
-const _hoisted_23 = { class: "role-name" }
-const _hoisted_24 = { class: "role-description" }
-const _hoisted_25 = { class: "role-permissions" }
-const _hoisted_26 = { class: "permissions-grid" }
-const _hoisted_27 = {
- key: 1,
- class: "no-roles"
-}
-const _hoisted_28 = { class: "profile-actions" }
-const _hoisted_29 = { class: "empty-state" }
-
-function render(_ctx, _cache, $props, $setup, $data, $options) {
- const _component_PasswordChangeModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("PasswordChangeModal")
-
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [
- _cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "profile-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h1", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 个人资料")
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", { class: "profile-subtitle" }, "查看和管理您的账户信息")
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 加载状态 "),
- ($setup.loading)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_2, _cache[6] || (_cache[6] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "loading-spinner" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "正在加载用户信息...", -1 /* CACHED */)
- ])))
- : ($setup.error)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: 1 }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 错误状态 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [
- _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "error-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-exclamation-triangle" })
- ], -1 /* CACHED */)),
- _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "加载失败", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.error), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[0] || (_cache[0] = (...args) => ($setup.loadUserProfile && $setup.loadUserProfile(...args))),
- class: "retry-btn"
- }, _cache[7] || (_cache[7] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-redo" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 重试 ", -1 /* CACHED */)
- ]))
- ])
- ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
- : ($setup.userInfo)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: 2 }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户信息内容 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 基本信息卡片 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [
- _cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "card-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-info-circle" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 基本信息")
- ])
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_6, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [
- _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "用户ID", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.userInfo.id || 'N/A'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [
- _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "用户名", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.userInfo.username || $setup.userInfo.name || 'N/A'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [
- _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "邮箱", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.userInfo.email || 'N/A'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [
- _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "手机号", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.userInfo.phone || 'N/A'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [
- _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "状态", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", {
- class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['status-badge', $setup.getStatusClass($setup.userInfo.status)])
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.getStatusText($setup.userInfo.status)), 3 /* TEXT, CLASS */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [
- _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "注册时间", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate($setup.userInfo.created_at) || $setup.formatDate($setup.userInfo.createdAt) || 'N/A'), 1 /* TEXT */)
- ])
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 登录信息卡片 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_14, [
- _cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "card-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-lock" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 登录信息")
- ])
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [
- _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "上次登录时间", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate($setup.userInfo.last_login_at) || $setup.formatDate($setup.userInfo.lastLogin) || 'N/A'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [
- _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "上次登录IP", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.userInfo.last_login_ip || $setup.userInfo.lastLoginIP || 'N/A'), 1 /* TEXT */)
- ])
- ])
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 角色信息卡片 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [
- _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "card-header" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-crown" }),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 角色信息")
- ])
- ], -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [
- ($setup.userInfo.roles && $setup.userInfo.roles.length > 0)
- ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_21, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.userInfo.roles, (role) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", {
- key: role.id,
- class: "role-item"
- }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_23, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.description || '无描述'), 1 /* TEXT */)
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [
- _cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "权限列表:", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_26, [
- ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)(role.permissions, (permission) => {
- return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", {
- key: permission.id,
- class: "permission-tag"
- }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.name), 1 /* TEXT */))
- }), 128 /* KEYED_FRAGMENT */))
- ])
- ])
- ]))
- }), 128 /* KEYED_FRAGMENT */))
- ]))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_27, _cache[21] || (_cache[21] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "暂无角色信息", -1 /* CACHED */)
- ])))
- ])
- ]),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 操作按钮 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_28, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[1] || (_cache[1] = (...args) => ($setup.refreshProfile && $setup.refreshProfile(...args))),
- class: "action-btn refresh-btn"
- }, _cache[23] || (_cache[23] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-sync-alt" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 刷新信息 ", -1 /* CACHED */)
- ])),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[2] || (_cache[2] = (...args) => ($setup.changePassword && $setup.changePassword(...args))),
- class: "action-btn password-btn"
- }, _cache[24] || (_cache[24] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-lock" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 修改密码 ", -1 /* CACHED */)
- ]))
- ])
- ])
- ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */))
- : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, { key: 3 }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 空状态 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_29, [
- _cache[26] || (_cache[26] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "empty-icon" }, [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user" })
- ], -1 /* CACHED */)),
- _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "暂无用户信息", -1 /* CACHED */)),
- _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "请先登录以查看您的个人资料", -1 /* CACHED */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", {
- onClick: _cache[3] || (_cache[3] = (...args) => ($setup.goToLogin && $setup.goToLogin(...args))),
- class: "login-btn"
- }, _cache[25] || (_cache[25] = [
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-sign-in-alt" }, null, -1 /* CACHED */),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 去登录 ", -1 /* CACHED */)
- ]))
- ])
- ], 2112 /* STABLE_FRAGMENT, DEV_ROOT_FRAGMENT */)),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 密码修改弹窗 "),
- (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_PasswordChangeModal, {
- visible: $setup.showPasswordModal,
- "onUpdate:visible": _cache[4] || (_cache[4] = $event => (($setup.showPasswordModal) = $event)),
- "is-force-change": $setup.isForceChange,
- onClose: _cache[5] || (_cache[5] = $event => ($setup.showPasswordModal = false)),
- onSuccess: $setup.onPasswordChangeSuccess
- }, null, 8 /* PROPS */, ["visible", "is-force-change", "onSuccess"])
- ]))
-}
-
-/***/ }),
-
-/***/ "./node_modules/vue-style-loader/index.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=style&index=0&id=2fa9d48e&lang=css":
-/*!*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************!*\
- !*** ./node_modules/vue-style-loader/index.js??clonedRuleSet-12.use[0]!./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/App.vue?vue&type=style&index=0&id=2fa9d48e&lang=css ***!
- \*******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
-/***/ ((module, __unused_webpack_exports, __webpack_require__) => {
-
-// style-loader: Adds some css to the DOM by adding a