/******/ (() => { // 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/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/RolePermissionAssignment.vue?vue&type=style&index=0&id=91c1b50a&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/RolePermissionAssignment.vue?vue&type=style&index=0&id=91c1b50a&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-permission-assignment[data-v-91c1b50a] { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } .large-modal[data-v-91c1b50a] { width: 90%; max-width: 1200px; height: 80vh; max-height: 800px; } .modal-overlay[data-v-91c1b50a] { 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-91c1b50a] { background: white; border-radius: 8px; box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15); display: flex; flex-direction: column; max-height: 90vh; } .modal-header[data-v-91c1b50a] { display: flex; justify-content: space-between; align-items: center; padding: 20px 24px; border-bottom: 1px solid #e5e7eb; background: #f9fafb; border-radius: 8px 8px 0 0; } .modal-header h3[data-v-91c1b50a] { margin: 0; color: #1f2937; font-size: 18px; font-weight: 600; } .close-btn[data-v-91c1b50a] { background: none; border: none; font-size: 18px; cursor: pointer; color: #6b7280; padding: 4px; border-radius: 4px; transition: all 0.2s; } .close-btn[data-v-91c1b50a]:hover { background: #e5e7eb; color: #374151; } .modal-body[data-v-91c1b50a] { flex: 1; padding: 24px; overflow-y: auto; } .modal-footer[data-v-91c1b50a] { display: flex; justify-content: flex-end; gap: 12px; padding: 20px 24px; border-top: 1px solid #e5e7eb; background: #f9fafb; border-radius: 0 0 8px 8px; } .loading[data-v-91c1b50a] { display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 40px; color: #6b7280; } .loading i[data-v-91c1b50a] { font-size: 24px; margin-bottom: 12px; } .role-info[data-v-91c1b50a] { margin-bottom: 24px; padding: 16px; background: #f8fafc; border-radius: 8px; border: 1px solid #e2e8f0; } .role-details h4[data-v-91c1b50a] { margin: 0 0 8px 0; color: #1e293b; font-size: 16px; font-weight: 600; } .role-description[data-v-91c1b50a] { margin: 0 0 12px 0; color: #64748b; font-size: 14px; } .role-stats[data-v-91c1b50a] { display: flex; gap: 16px; } .stat-item[data-v-91c1b50a] { display: flex; align-items: center; gap: 6px; color: #475569; font-size: 14px; } .stat-item i[data-v-91c1b50a] { color: #3b82f6; } .permission-assignment[data-v-91c1b50a] { border: 1px solid #e2e8f0; border-radius: 8px; overflow: hidden; } .assignment-tabs[data-v-91c1b50a] { display: flex; background: #f1f5f9; border-bottom: 1px solid #e2e8f0; } .tab-btn[data-v-91c1b50a] { flex: 1; padding: 12px 16px; background: none; border: none; cursor: pointer; font-size: 14px; font-weight: 500; color: #64748b; transition: all 0.2s; display: flex; align-items: center; justify-content: center; gap: 8px; } .tab-btn.active[data-v-91c1b50a] { background: white; color: #3b82f6; border-bottom: 2px solid #3b82f6; } .tab-btn[data-v-91c1b50a]:hover:not(.active) { background: #e2e8f0; color: #475569; } .permission-list[data-v-91c1b50a] { padding: 20px; } .list-header[data-v-91c1b50a] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; } .list-header h5[data-v-91c1b50a] { margin: 0; color: #1e293b; font-size: 16px; font-weight: 600; } .list-actions[data-v-91c1b50a] { display: flex; gap: 8px; } .empty-state[data-v-91c1b50a] { text-align: center; padding: 40px 20px; color: #64748b; } .empty-state i[data-v-91c1b50a] { font-size: 48px; margin-bottom: 16px; opacity: 0.5; } .empty-state p[data-v-91c1b50a] { margin: 0; font-size: 14px; } .permission-items[data-v-91c1b50a] { display: flex; flex-direction: column; gap: 8px; } .permission-item[data-v-91c1b50a] { display: flex; align-items: center; padding: 12px; border: 1px solid #e2e8f0; border-radius: 6px; cursor: pointer; transition: all 0.2s; background: white; } .permission-item[data-v-91c1b50a]:hover { border-color: #3b82f6; box-shadow: 0 2px 4px rgba(59, 130, 246, 0.1); } .permission-item.selected[data-v-91c1b50a] { border-color: #3b82f6; background: #eff6ff; } .permission-checkbox[data-v-91c1b50a] { margin-right: 12px; } .permission-checkbox input[type="checkbox"][data-v-91c1b50a] { width: 16px; height: 16px; cursor: pointer; } .permission-info[data-v-91c1b50a] { flex: 1; } .permission-name[data-v-91c1b50a] { font-weight: 500; color: #1e293b; margin-bottom: 4px; } .permission-details[data-v-91c1b50a] { display: flex; gap: 12px; margin-bottom: 4px; } .permission-code[data-v-91c1b50a] { font-family: 'Courier New', monospace; font-size: 12px; color: #64748b; background: #f1f5f9; padding: 2px 6px; border-radius: 4px; } .permission-resource[data-v-91c1b50a] { font-size: 12px; color: #8b5cf6; background: #f3f4f6; padding: 2px 6px; border-radius: 4px; } .permission-description[data-v-91c1b50a] { font-size: 12px; color: #64748b; line-height: 1.4; } .permission-actions[data-v-91c1b50a] { margin-left: 12px; } .btn[data-v-91c1b50a] { padding: 6px 12px; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; font-weight: 500; transition: all 0.2s; display: inline-flex; align-items: center; gap: 4px; } .btn-sm[data-v-91c1b50a] { padding: 4px 8px; font-size: 11px; } .btn-primary[data-v-91c1b50a] { background: #3b82f6; color: white; } .btn-primary[data-v-91c1b50a]:hover:not(:disabled) { background: #2563eb; } .btn-primary[data-v-91c1b50a]:disabled { background: #9ca3af; cursor: not-allowed; } .btn-danger[data-v-91c1b50a] { background: #ef4444; color: white; } .btn-danger[data-v-91c1b50a]:hover:not(:disabled) { background: #dc2626; } .btn-danger[data-v-91c1b50a]:disabled { background: #9ca3af; cursor: not-allowed; } .btn-secondary[data-v-91c1b50a] { background: #6b7280; color: white; } .btn-secondary[data-v-91c1b50a]:hover:not(:disabled) { background: #4b5563; } .btn-secondary[data-v-91c1b50a]:disabled { background: #9ca3af; 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/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__); /* harmony import */ var _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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../../../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]!../../../assets/common-styles.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]!./src/renderer/assets/common-styles.css"); // 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())); ___CSS_LOADER_EXPORT___.i(_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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__["default"]); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` /* 角色管理特定样式 */ .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); } .role-description[data-v-03643bfa] { color: var(--text-secondary); font-size: 12px; margin-top: 4px; } .permission-count[data-v-03643bfa] { background: #e3f2fd; color: #1976d2; padding: 2px 6px; border-radius: 4px; font-size: 12px; } .form-group textarea[data-v-03643bfa] { resize: vertical; min-height: 80px; } `, ""]); // 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/route-sync/RouteSyncTest.vue?vue&type=style&index=0&id=618a5171&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/route-sync/RouteSyncTest.vue?vue&type=style&index=0&id=618a5171&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, ` .route-sync-test[data-v-618a5171] { padding: 20px; max-width: 1200px; margin: 0 auto; } .test-section[data-v-618a5171] { margin-bottom: 30px; padding: 20px; border: 1px solid #ddd; border-radius: 8px; background-color: #f9f9f9; } .test-section h3[data-v-618a5171] { margin-top: 0; color: #333; } button[data-v-618a5171] { background-color: #007bff; color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; margin-right: 10px; } button[data-v-618a5171]:hover { background-color: #0056b3; } button[data-v-618a5171]:disabled { background-color: #6c757d; cursor: not-allowed; } .result[data-v-618a5171] { margin-top: 15px; padding: 15px; background-color: white; border-radius: 4px; border: 1px solid #ddd; } .result h4[data-v-618a5171] { margin-top: 0; color: #333; } .result pre[data-v-618a5171] { background-color: #f8f9fa; padding: 10px; border-radius: 4px; overflow-x: auto; font-size: 12px; line-height: 1.4; } .loading[data-v-618a5171] { text-align: center; padding: 20px; color: #666; } `, ""]); // 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__); /* harmony import */ var _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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../../../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]!../../../assets/common-styles.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]!./src/renderer/assets/common-styles.css"); // 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())); ___CSS_LOADER_EXPORT___.i(_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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__["default"]); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` /* 系统设置特定样式 */ .settings-content[data-v-69b5cd1d] { max-width: 800px; } /* 开关样式 */ .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-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__); /* harmony import */ var _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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../../../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]!../../../assets/common-styles.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]!./src/renderer/assets/common-styles.css"); // 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())); ___CSS_LOADER_EXPORT___.i(_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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__["default"]); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` /* 用户管理特定样式 */ .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; } .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__); /* harmony import */ var _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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! -!../../../../../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]!../../../assets/common-styles.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]!./src/renderer/assets/common-styles.css"); // 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())); ___CSS_LOADER_EXPORT___.i(_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_assets_common_styles_css__WEBPACK_IMPORTED_MODULE_2__["default"]); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` /* 个人资料特定样式 */ .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: 12px; margin-top: 20px; } .retry-btn[data-v-8301bb50]:hover { background: #c53030; } .status-badge.pending[data-v-8301bb50] { background: #fff3cd; color: #856404; } .status-badge.unknown[data-v-8301bb50] { background: #e2e3e5; color: #383d41; } .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; font-size: 12px; } .empty-state p[data-v-8301bb50] { color: var(--text-secondary); margin-bottom: 30px; font-size: 12px; } .login-btn[data-v-8301bb50] { background: #1976d2; color: white; border: none; padding: 12px 32px; border-radius: 6px; cursor: pointer; font-size: 12px; font-weight: 500; } .login-btn[data-v-8301bb50]:hover { background: #1565c0; } `, ""]); // 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]!./src/renderer/assets/common-styles.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]!./src/renderer/assets/common-styles.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, `/* ===== 通用管理页面样式 ===== */ /* 页面容器 */ .management-page { padding: 20px; padding-top: 10px; } /* 搜索栏样式 */ .search-bar { display: flex; gap: 20px; margin-bottom: 6px; margin-top: 0; align-items: center; flex-wrap: wrap; justify-content: space-between; } .search-input { position: relative; flex: 0 0 280px; min-width: 200px; max-width: 350px; } .search-input i { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-muted); font-size: 12px; } /* 输入控件统一样式 */ .search-input input, .setting-item input[type="text"], .setting-item input[type="number"], .setting-item select { width: 100%; padding: 4px 12px; border: 1px solid var(--input-border); border-radius: 6px; font-size: 12px; background-color: var(--input-bg); color: var(--input-text); box-sizing: border-box; } /* 搜索输入框特殊样式(左侧图标) */ .search-input input { padding-left: 35px; } /* 设置项输入框特殊样式(最小宽度) */ .setting-item input[type="text"], .setting-item input[type="number"], .setting-item select { min-width: 200px; } /* 输入控件焦点样式 */ .search-input input:focus, .setting-item input[type="text"]:focus, .setting-item input[type="number"]:focus, .setting-item select:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } .filters { display: flex; gap: 15px; flex-wrap: wrap; flex: 1; justify-content: flex-end; align-items: center; min-width: 0; } .filters select { padding: 8px 12px; border: 1px solid var(--input-border); border-radius: 6px; font-size: 12px; background-color: var(--input-bg); color: var(--input-text); min-width: 100px; max-width: 150px; flex: 0 0 auto; box-sizing: border-box; } .filters select:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } /* 表格样式 */ .data-table { background: var(--card-bg); border-radius: 8px; box-shadow: 0 2px 8px var(--shadow-color); overflow: hidden; margin-bottom: 20px; } table { width: 100%; border-collapse: collapse; } th, td { padding: 8px; text-align: left; border-bottom: 1px solid var(--border-color); font-size: 12px; } th { background: var(--bg-secondary); font-weight: normal; color: var(--text-primary); font-size: 14px; } /* 状态徽章 */ .status-badge { padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: normal; } .status-badge.active { background: #e8f5e8; color: #2e7d32; } .status-badge.inactive { background: #ffebee; color: #c62828; } /* 角色标签 */ .role-tags { display: flex; gap: 4px; flex-wrap: wrap; } .role-tag { background: #e3f2fd; color: #1976d2; padding: 2px 6px; border-radius: 4px; font-size: 14px; } /* 操作按钮 */ .actions { display: flex; gap: 8px; } .btn { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 12px; display: inline-flex; align-items: center; gap: 6px; transition: all 0.2s; } .btn-primary { background: #1976d2; color: white; } .btn-primary:hover { background: #1565c0; } .btn-info { background: #0288d1; color: white; } .btn-danger { background: #d32f2f; color: white; } .btn-sm { padding: 6px 12px; font-size: 10px; } /* 表格操作按钮样式优化 */ .actions .btn-sm { background: none; border: none; padding: 6px 10px; margin: 0 -2px; color: var(--text-primary); transition: all 0.2s; } .actions .btn-sm i { font-size: 14px; } .actions .btn-sm:hover { background: var(--bg-secondary); color: var(--accent-color); transform: scale(1.1); } .actions .btn-sm.btn-info:hover { color: #2196f3; } .actions .btn-sm.btn-primary:hover { color: #1976d2; } .actions .btn-sm.btn-danger:hover { color: #d32f2f; } /* 分页样式 */ .pagination { display: flex; justify-content: center; align-items: center; gap: 20px; margin-top: 16px; } .page-info { color: var(--text-secondary); font-size: 12px; margin: 0 15px; } /* 分页导航链接样式 */ .pagination-nav { display: flex; align-items: center; gap: 8px; } .pagination-link { color: var(--accent-color); text-decoration: none; padding: 4px 8px; border-radius: 4px; font-size: 12px; transition: all 0.2s; cursor: pointer; } .pagination-link:hover { background: var(--bg-secondary); color: var(--accent-hover); } .pagination-link.disabled { color: var(--text-muted); cursor: not-allowed; pointer-events: none; } .pagination-link.active { background: var(--accent-color); color: white; } /* 分页设置区域 */ .pagination-settings { display: flex; align-items: center; gap: 10px; margin-left: 20px; } .pagination-settings label { font-size: 12px; color: var(--text-secondary); margin: 0; } .pagination-settings select { padding: 4px 8px; border: 1px solid var(--input-border); border-radius: 4px; font-size: 12px; background-color: var(--input-bg); color: var(--input-text); min-width: 60px; } .pagination-settings select:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } /* 跳转页面输入框 */ .page-jump { display: flex; align-items: center; gap: 5px; font-size: 12px; } .page-jump span { font-size: 12px; color: var(--text-secondary); } .page-jump input { width: 50px; padding: 4px 8px; border: 1px solid var(--input-border); border-radius: 4px; font-size: 12px; background-color: var(--input-bg); color: var(--input-text); text-align: center; } .page-jump input:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } .page-jump button { color: var(--accent-color); background: none; border: none; font-size: 12px; cursor: pointer; padding: 4px 8px; border-radius: 4px; transition: all 0.2s; } .page-jump button:hover { background: var(--bg-secondary); color: var(--accent-hover); } /* 分页按钮字体大小统一 */ .pagination .btn-sm { font-size: 10px; } /* ===== 个人资料页面样式 ===== */ /* 个人资料容器 */ .user-profile { padding: 20px; } /* 页面头部 - 统一样式 */ .page-header, .profile-header { text-align: center; margin-bottom: 32px; } .page-header h2, .profile-header h1 { font-size: 16px; color: var(--text-primary); margin-bottom: 10px; margin: 0; } .profile-subtitle { font-size: 12px; color: var(--text-secondary); margin: 0; } /* 内容区域 */ .profile-content { max-width: 800px; margin: 0 auto; } /* 卡片样式 - 统一样式 */ .profile-card, .settings-section { background: var(--card-bg); border-radius: 8px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 8px var(--shadow-color); } /* 卡片头部 - 统一样式 */ .card-header, .settings-section h3 { margin: 0 0 20px 0; color: var(--text-primary); font-size: 14px; border-bottom: 2px solid var(--border-color); padding-bottom: 12px; } .card-header h2, .settings-section h3 { margin: 0; font-size: 14px; color: var(--text-primary); } /* 页面标题和分组标题图标样式 - 统一样式 */ .page-header h2 i, .profile-header h1 i, .card-header h2 i, .settings-section h3 i { margin-right: 8px; color: var(--accent-color); font-size: 0.9em; } /* 信息网格 */ .info-grid { display: flex; flex-direction: column; gap: 0; } /* 字段项 - 统一样式 */ .info-item, .setting-item { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; margin-bottom: 6px; padding: 6px 0; border-bottom: 1px solid #f5f5f5; } .info-item:last-child, .setting-item:last-child { border-bottom: none; margin-bottom: 0; } /* 字段标签 - 统一样式 */ .info-item label, .setting-item label { font-weight: 500; color: var(--text-primary); min-width: 200px; font-size: 12px; } .info-item span { color: var(--text-primary); font-size: 12px; text-align: right; flex: 1; } /* 角色列表 */ .roles-list { display: flex; flex-direction: column; gap: 16px; } .role-item { background: var(--card-bg); border-radius: 8px; padding: 16px; border: 1px solid var(--border-color); margin-bottom: 12px; } .role-header { margin-bottom: 12px; } .role-name { display: block; font-size: 12px; font-weight: 600; color: var(--text-primary); margin-bottom: 8px; } .role-description { color: var(--text-secondary); font-size: 12px; } .role-permissions h4 { margin: 0 0 8px 0; color: var(--text-primary); font-size: 12px; } .permissions-grid { display: flex; flex-wrap: wrap; gap: 8px; } .permission-tag { background: var(--accent-color); color: white; padding: 4px 12px; border-radius: 16px; font-size: 12px; border: none; } .no-roles { text-align: center; color: var(--text-secondary); padding: 40px 20px; font-size: 12px; } /* 操作按钮区域 - 统一样式 */ .profile-actions, .settings-actions { display: flex; gap: 16px; justify-content: flex-end; margin-top: 32px; } /* ===== 模态框样式 ===== */ .modal-overlay { 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 { background: white; border-radius: 8px; width: 90%; max-width: 500px; max-height: 90vh; overflow-y: auto; box-sizing: border-box; } .modal-header { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid #eee; } .modal-header h3 { margin: 0; font-size: 14px; font-weight: normal; } .close-btn { background: none; border: none; font-size: 14px; cursor: pointer; color: #999; } .modal-body { padding: 20px; box-sizing: border-box; } .form-group { margin-bottom: 20px; } .form-group label { display: block; margin-bottom: 8px; font-weight: normal; color: #333; font-size: 14px; } .form-group input, .form-group select, .form-group textarea { width: 100%; padding: 8px 12px; border: 1px solid var(--input-border); border-radius: 6px; font-size: 12px; background-color: var(--input-bg); color: var(--input-text); box-sizing: border-box; } .form-group input:focus, .form-group select:focus, .form-group textarea:focus { outline: none; border-color: var(--accent-color); box-shadow: 0 0 0 2px rgba(74, 158, 255, 0.2); } .form-actions { display: flex; gap: 12px; justify-content: flex-end; margin-top: 30px; } /* ===== 响应式设计 ===== */ @media (max-width: 768px) { .management-page, .user-profile { padding: 15px; } .search-bar { flex-direction: column; align-items: stretch; gap: 15px; justify-content: flex-start; } .search-input { flex: 1; min-width: auto; max-width: none; } .filters { justify-content: space-between; flex: none; } .filters select { flex: 1; min-width: auto; max-width: none; } .profile-header h1 { font-size: 16px; } .info-item { flex-direction: column; align-items: flex-start; gap: 12px; } .info-item label { min-width: auto; } .info-item span { text-align: left; } .profile-actions { flex-direction: column; align-items: center; } .action-btn { 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/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: '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: '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 === '/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 clearCache = async () => { try { console.log('🧹 开始清理缓存...') // 询问用户是否要清理用户设置 const clearSettings = confirm('是否要清理用户设置?\n\n选择"确定"将清理所有设置(包括主题、记住密码等)\n选择"取消"将保留用户设置,只清理其他缓存') if (clearSettings) { // 清理所有localStorage const keysToClear = [ 'gofaster-settings', 'isLoggedIn', 'token', 'user', 'app-settings', 'theme-settings', 'user-preferences' ] keysToClear.forEach(key => { if (localStorage.getItem(key)) { localStorage.removeItem(key) console.log('✅ 已清理localStorage键:', key) } }) // 清理所有以gofaster开头的键 const allKeys = Object.keys(localStorage) allKeys.forEach(key => { if (key.startsWith('gofaster') || key.startsWith('electron')) { localStorage.removeItem(key) console.log('✅ 已清理localStorage键:', key) } }) } else { // 只清理非设置相关的缓存 const keysToClear = [ 'isLoggedIn', 'token', 'user', 'app-settings', 'theme-settings' ] keysToClear.forEach(key => { if (localStorage.getItem(key)) { localStorage.removeItem(key) console.log('✅ 已清理localStorage键:', key) } }) // 清理以electron开头的键,但保留gofaster-settings const allKeys = Object.keys(localStorage) allKeys.forEach(key => { if (key.startsWith('electron')) { localStorage.removeItem(key) console.log('✅ 已清理localStorage键:', key) } }) } // 通过IPC清理Electron缓存 if (window.electronAPI && window.electronAPI.clearElectronCache) { const result = await window.electronAPI.clearElectronCache() if (result.success) { showToastMessage('success', '缓存清理成功', result.message) } else { showToastMessage('warning', '缓存清理部分失败', result.message) } } else { showToastMessage('warning', '缓存清理', 'localStorage已清理,但无法清理Electron缓存') } console.log('✅ 缓存清理完成') } catch (error) { console.error('❌ 清理缓存失败:', error) showToastMessage('error', '缓存清理失败', '清理缓存时发生错误: ' + error.message) } } 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)(() => { // 不再自动清理localStorage,保留用户设置 console.log('🔧 应用启动,保留用户设置...') // 初始化收藏菜单 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: { totalUsers: 0, lastLogin: null, profileComplete: false }, 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-user', title: '更新个人资料', time: '2小时前' }, { id: 2, icon: 'fas fa-cog', title: '修改系统设置', time: '昨天' }, { id: 3, icon: 'fas fa-shield-alt', 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); } }, 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/RolePermissionAssignment.vue?vue&type=script&lang=js": /*!*************************************************************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/role-management/components/RolePermissionAssignment.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: 'RolePermissionAssignment', props: { modelValue: { type: Boolean, default: false }, role: { type: Object, default: null } }, emits: ['update:modelValue', 'permissions-updated'], setup(props, { emit }) { const visible = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const currentRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null) const allPermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const assignedPermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const selectedAssignedPermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const selectedAvailablePermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const activeTab = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('assigned') // 计算可分配权限 const availablePermissions = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => { const assignedIds = assignedPermissions.value.map(p => p.id) return allPermissions.value.filter(p => !assignedIds.includes(p.id)) }) // 监听visible变化 ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.watch)(() => props.modelValue, (newVal) => { visible.value = newVal if (newVal && props.role) { currentRole.value = props.role loadData() } }) // 加载数据 const loadData = async () => { if (!currentRole.value) return loading.value = true try { await Promise.all([ loadAllPermissions(), loadRolePermissions() ]) } catch (error) { console.error('加载权限数据失败:', error) } finally { loading.value = false } } // 加载所有权限 const loadAllPermissions = async () => { try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getPermissions() if (response.code === 200) { allPermissions.value = response.data || [] } } catch (error) { console.error('加载权限列表失败:', error) } } // 加载角色权限 const loadRolePermissions = async () => { try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].getRolePermissions(currentRole.value.id) if (response.code === 200) { assignedPermissions.value = response.data || [] } } catch (error) { console.error('加载角色权限失败:', error) } } // 切换已分配权限选择 const toggleAssignedPermission = (permissionId) => { const index = selectedAssignedPermissions.value.indexOf(permissionId) if (index > -1) { selectedAssignedPermissions.value.splice(index, 1) } else { selectedAssignedPermissions.value.push(permissionId) } } // 切换可分配权限选择 const toggleAvailablePermission = (permissionId) => { const index = selectedAvailablePermissions.value.indexOf(permissionId) if (index > -1) { selectedAvailablePermissions.value.splice(index, 1) } else { selectedAvailablePermissions.value.push(permissionId) } } // 清除已分配权限选择 const clearAssignedSelection = () => { selectedAssignedPermissions.value = [] } // 清除可分配权限选择 const clearAvailableSelection = () => { selectedAvailablePermissions.value = [] } // 分配单个权限 const assignPermission = async (permissionId) => { try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].assignPermissionsToRole(currentRole.value.id, [permissionId]) if (response.code === 200) { await loadRolePermissions() emit('permissions-updated') } } catch (error) { console.error('分配权限失败:', error) } } // 移除单个权限 const removePermission = async (permissionId) => { try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].removePermissionsFromRole(currentRole.value.id, [permissionId]) if (response.code === 200) { await loadRolePermissions() emit('permissions-updated') } } catch (error) { console.error('移除权限失败:', error) } } // 批量分配权限 const assignSelectedPermissions = async () => { if (selectedAvailablePermissions.value.length === 0) return try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].assignPermissionsToRole( currentRole.value.id, selectedAvailablePermissions.value ) if (response.code === 200) { selectedAvailablePermissions.value = [] await loadRolePermissions() emit('permissions-updated') } } catch (error) { console.error('批量分配权限失败:', error) } } // 批量移除权限 const removeSelectedPermissions = async () => { if (selectedAssignedPermissions.value.length === 0) return try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__["default"].removePermissionsFromRole( currentRole.value.id, selectedAssignedPermissions.value ) if (response.code === 200) { selectedAssignedPermissions.value = [] await loadRolePermissions() emit('permissions-updated') } } catch (error) { console.error('批量移除权限失败:', error) } } // 刷新权限 const refreshPermissions = async () => { await loadData() } // 关闭对话框 const handleClose = () => { visible.value = false emit('update:modelValue', false) // 重置状态 selectedAssignedPermissions.value = [] selectedAvailablePermissions.value = [] activeTab.value = 'assigned' } return { visible, loading, currentRole, allPermissions, assignedPermissions, availablePermissions, selectedAssignedPermissions, selectedAvailablePermissions, activeTab, toggleAssignedPermission, toggleAvailablePermission, clearAssignedSelection, clearAvailableSelection, assignPermission, removePermission, assignSelectedPermissions, removeSelectedPermissions, refreshPermissions, 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/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 import */ var _components_RolePermissionAssignment_vue__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../components/RolePermissionAssignment.vue */ "./src/renderer/modules/role-management/components/RolePermissionAssignment.vue"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'RoleManagement', components: { RolePermissionAssignment: _components_RolePermissionAssignment_vue__WEBPACK_IMPORTED_MODULE_2__["default"] }, 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 showPermissionDialog = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const editingRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null) const selectedRole = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(null) 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 searchQuery = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('') const jumpPage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('') const roleForm = (0,vue__WEBPACK_IMPORTED_MODULE_0__.reactive)({ name: '', code: '', description: '' }) // 过滤后的角色列表 const filteredRoles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => { if (!searchQuery.value) { return roles.value } const query = searchQuery.value.toLowerCase() return roles.value.filter(role => role.name.toLowerCase().includes(query) || role.code.toLowerCase().includes(query) || role.description?.toLowerCase().includes(query) ) }) // 搜索处理 const handleSearch = () => { currentPage.value = 1 } // 获取角色列表 const loadRoles = async () => { loading.value = true try { const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.getRoles(currentPage.value, pageSize.value) console.log('🔍 [角色管理] 获取角色列表响应:', response) // 根据后端API响应结构提取数据 if (response.code === 200 && response.data) { roles.value = response.data.data || [] total.value = response.data.total || 0 console.log('🔍 [角色管理] 角色数据:', { roles: roles.value, total: total.value, page: currentPage.value, pageSize: pageSize.value, totalPages: Math.ceil((response.data.total || 0) / pageSize.value), shouldShowPagination: (response.data.total || 0) > 0 }) } else { console.error('获取角色列表失败: 响应格式错误', response) alert('获取角色列表失败: 响应格式错误') } } catch (error) { console.error('获取角色列表失败:', error) alert('获取角色列表失败: ' + (error.response?.data?.message || error.message)) } 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) console.log('🔍 [角色管理] 更新角色响应:', response) if (response.code === 200) { alert('角色更新成功') await loadRoles() // 重新加载角色列表 } else { alert('角色更新失败: ' + response.message) } } else { // 创建角色 const response = await _services_roleService_js__WEBPACK_IMPORTED_MODULE_1__.roleService.createRole(roleForm) console.log('🔍 [角色管理] 创建角色响应:', response) if (response.code === 200) { alert('角色创建成功') await loadRoles() // 重新加载角色列表 } else { alert('角色创建失败: ' + response.message) } } showCreateDialog.value = false resetForm() } catch (error) { console.error('保存角色失败:', error) alert('操作失败: ' + (error.response?.data?.message || error.message)) } 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) console.log('🔍 [角色管理] 删除角色响应:', response) alert('角色删除成功') await loadRoles() // 重新加载角色列表 } catch (error) { console.error('删除角色失败:', error) alert('删除失败: ' + (error.response?.data?.message || error.message)) } } } // 重置表单 const resetForm = () => { editingRole.value = null roleForm.name = '' roleForm.code = '' roleForm.description = '' } // 分页处理 const handleCurrentChange = (val) => { if (val >= 1 && val <= Math.ceil(total.value / pageSize.value)) { currentPage.value = val loadRoles() } } const handlePageSizeChange = () => { currentPage.value = 1 loadRoles() } const handleJumpPage = () => { const totalPages = Math.ceil(total.value / pageSize.value) if (jumpPage.value && jumpPage.value >= 1 && jumpPage.value <= totalPages) { handleCurrentChange(jumpPage.value) jumpPage.value = '' } } // 格式化日期 const formatDate = (dateStr) => { if (!dateStr) return '' return new Date(dateStr).toLocaleString('zh-CN') } // 分配权限 const assignPermissions = (role) => { selectedRole.value = role showPermissionDialog.value = true } // 处理权限更新 const handlePermissionsUpdated = () => { console.log('权限分配已更新') // 可以在这里添加一些提示或刷新逻辑 } ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => { loadRoles() }) return { loading, saving, showCreateDialog, showPermissionDialog, editingRole, selectedRole, roles, currentPage, pageSize, total, searchQuery, jumpPage, roleForm, filteredRoles, createNewRole, editRole, saveRole, deleteRole, assignPermissions, handlePermissionsUpdated, handleCurrentChange, handlePageSizeChange, handleJumpPage, handleSearch, formatDate } } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/route-sync/RouteSyncTest.vue?vue&type=script&lang=js": /*!**********************************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/modules/route-sync/RouteSyncTest.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 _RouteCollector__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./RouteCollector */ "./src/renderer/modules/route-sync/RouteCollector.js"); /* harmony import */ var _RouteMapper__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./RouteMapper */ "./src/renderer/modules/route-sync/RouteMapper.js"); /* harmony import */ var _RouteSyncService__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./RouteSyncService */ "./src/renderer/modules/route-sync/RouteSyncService.js"); /* harmony import */ var _RouteSyncManager__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./RouteSyncManager */ "./src/renderer/modules/route-sync/RouteSyncManager.js"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'RouteSyncTest', data() { return { loading: false, routeCollectionResult: null, routeMappingResult: null, syncResult: null, manualSyncResult: null } }, methods: { async testRouteCollection() { this.loading = true try { const collector = new _RouteCollector__WEBPACK_IMPORTED_MODULE_0__.RouteCollector() const routes = collector.collectRoutes() this.routeCollectionResult = { totalRoutes: routes.length, routes: routes, menuRoutes: collector.getMenuRoutes(), routesByModule: collector.getRoutesByModule() } console.log('✅ 路由收集测试完成') } catch (error) { console.error('❌ 路由收集测试失败:', error) this.routeCollectionResult = { error: error.message } } finally { this.loading = false } }, async testRouteMapping() { this.loading = true try { const collector = new _RouteCollector__WEBPACK_IMPORTED_MODULE_0__.RouteCollector() const routes = collector.collectRoutes() const mapper = new _RouteMapper__WEBPACK_IMPORTED_MODULE_1__.RouteMapper() const mappings = mapper.generateRouteMappings(routes) const validation = mapper.validateMappings(mappings) this.routeMappingResult = { totalMappings: mappings.length, mappings: mappings, validation: validation, isValid: validation.isValid } console.log('✅ 路由映射测试完成') } catch (error) { console.error('❌ 路由映射测试失败:', error) this.routeMappingResult = { error: error.message } } finally { this.loading = false } }, async testRouteSync() { this.loading = true try { const syncService = new _RouteSyncService__WEBPACK_IMPORTED_MODULE_2__.RouteSyncService('http://localhost:8080') const success = await syncService.syncRoutes() this.syncResult = { success: success, syncStatus: syncService.getSyncStatus(), syncStats: syncService.getSyncStats() } console.log('✅ 路由同步测试完成') } catch (error) { console.error('❌ 路由同步测试失败:', error) this.syncResult = { error: error.message } } finally { this.loading = false } }, async manualSync() { this.loading = true try { const success = await _RouteSyncManager__WEBPACK_IMPORTED_MODULE_3__["default"].manualSync() this.manualSyncResult = { success: success, syncStatus: _RouteSyncManager__WEBPACK_IMPORTED_MODULE_3__["default"].getSyncStatus(), syncStats: _RouteSyncManager__WEBPACK_IMPORTED_MODULE_3__["default"].getSyncStats() } console.log('✅ 手动同步完成') } catch (error) { console.error('❌ 手动同步失败:', error) this.manualSyncResult = { error: error.message } } finally { this.loading = false } } } }); /***/ }), /***/ "./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 jumpPage = (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) => { if (page >= 1 && page <= totalPages.value) { currentPage.value = page loadUsers() } } const handlePageSizeChange = () => { currentPage.value = 1 loadUsers() } const handleJumpPage = () => { if (jumpPage.value && jumpPage.value >= 1 && jumpPage.value <= totalPages.value) { changePage(jumpPage.value) jumpPage.value = '' } } 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, jumpPage, showAddUserModal, showEditUserModal, showRoleAssignmentModal, editingUser, selectedUser, userForm, totalPages, filteredUsers, loadUsers, loadRoles, handleSearch, handleFilter, changePage, handlePageSizeChange, handleJumpPage, 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/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[13] || (_cache[13] = (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[14] || (_cache[14] = (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[16] || (_cache[16] = (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[15] || (_cache[15] = [ (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[17] || (_cache[17] = [ (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[18] || (_cache[18] = [ (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[19] || (_cache[19] = [ (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[20] || (_cache[20] = [ (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) => (_ctx.clearCache && _ctx.clearCache(...args))) }, _cache[21] || (_cache[21] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-broom" }, 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[7] || (_cache[7] = (...args) => ($setup.logout && $setup.logout(...args))) }, _cache[22] || (_cache[22] = [ (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[23] || (_cache[23] = [ (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[24] || (_cache[24] = [ (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[25] || (_cache[25] = [ (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[8] || (_cache[8] = (...args) => ($setup.closeAllTabs && $setup.closeAllTabs(...args))), title: "关闭所有标签页" }, _cache[26] || (_cache[26] = [ (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[9] || (_cache[9] = $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[10] || (_cache[10] = $event => (($setup.showPasswordModal) = $event)), "is-force-change": $setup.isForceChange, onClose: _cache[11] || (_cache[11] = $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[12] || (_cache[12] = $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.openSettings && $options.openSettings(...args))) }, _cache[4] || (_cache[4] = [ (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[1] || (_cache[1] = (...args) => ($options.exportData && $options.exportData(...args))) }, _cache[5] || (_cache[5] = [ (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[7] || (_cache[7] = (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[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "需要登录", -1 /* CACHED */)), _cache[9] || (_cache[9] = (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[2] || (_cache[2] = (...args) => ($options.showLoginModalHandler && $options.showLoginModalHandler(...args))) }, _cache[6] || (_cache[6] = [ (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[11] || (_cache[11] = (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[3] || (_cache[3] = (...args) => ($options.addTodo && $options.addTodo(...args))) }, _cache[10] || (_cache[10] = [ (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[12] || (_cache[12] = [ (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[13] || (_cache[13] = (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/RolePermissionAssignment.vue?vue&type=template&id=91c1b50a&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/RolePermissionAssignment.vue?vue&type=template&id=91c1b50a&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-permission-assignment" } const _hoisted_2 = { class: "modal-header" } const _hoisted_3 = { class: "modal-body" } const _hoisted_4 = { key: 0, class: "loading" } const _hoisted_5 = { key: 1, class: "permission-content" } const _hoisted_6 = { class: "role-info" } const _hoisted_7 = { class: "role-details" } const _hoisted_8 = { class: "role-description" } const _hoisted_9 = { class: "role-stats" } const _hoisted_10 = { class: "stat-item" } const _hoisted_11 = { class: "stat-item" } const _hoisted_12 = { class: "permission-assignment" } const _hoisted_13 = { class: "assignment-tabs" } const _hoisted_14 = { key: 0, class: "permission-list assigned-permissions" } const _hoisted_15 = { class: "list-header" } const _hoisted_16 = { class: "list-actions" } const _hoisted_17 = ["disabled"] const _hoisted_18 = { key: 0, class: "empty-state" } const _hoisted_19 = { key: 1, class: "permission-items" } const _hoisted_20 = ["onClick"] const _hoisted_21 = { class: "permission-checkbox" } const _hoisted_22 = ["checked", "onChange"] const _hoisted_23 = { class: "permission-info" } const _hoisted_24 = { class: "permission-name" } const _hoisted_25 = { class: "permission-details" } const _hoisted_26 = { class: "permission-code" } const _hoisted_27 = { class: "permission-resource" } const _hoisted_28 = { class: "permission-description" } const _hoisted_29 = { class: "permission-actions" } const _hoisted_30 = ["onClick"] const _hoisted_31 = { key: 1, class: "permission-list available-permissions" } const _hoisted_32 = { class: "list-header" } const _hoisted_33 = { class: "list-actions" } const _hoisted_34 = ["disabled"] const _hoisted_35 = { key: 0, class: "empty-state" } const _hoisted_36 = { key: 1, class: "permission-items" } const _hoisted_37 = ["onClick"] const _hoisted_38 = { class: "permission-checkbox" } const _hoisted_39 = ["checked", "onChange"] const _hoisted_40 = { class: "permission-info" } const _hoisted_41 = { class: "permission-name" } const _hoisted_42 = { class: "permission-details" } const _hoisted_43 = { class: "permission-code" } const _hoisted_44 = { class: "permission-resource" } const _hoisted_45 = { class: "permission-description" } const _hoisted_46 = { class: "permission-actions" } const _hoisted_47 = ["onClick"] const _hoisted_48 = { class: "modal-footer" } const _hoisted_49 = ["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[10] || (_cache[10] = (...args) => ($setup.handleClose && $setup.handleClose(...args))) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "modal large-modal", onClick: _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "角色权限分配 - " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentRole?.name), 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[11] || (_cache[11] = [ (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.loading) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_4, _cache[12] || (_cache[12] = [ (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 */) ]))) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_5, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 角色信息 "), (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)("h4", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentRole?.name), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", _hoisted_8, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentRole?.description), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_10, [ _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-shield-alt" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 已分配权限: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.assignedPermissions.length), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_11, [ _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-list" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 总权限数: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.allPermissions.length), 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", _hoisted_13, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["tab-btn", { active: $setup.activeTab === 'assigned' }]), onClick: _cache[1] || (_cache[1] = $event => ($setup.activeTab = 'assigned')) }, [ _cache[15] || (_cache[15] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-check-circle" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 已分配权限 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.assignedPermissions.length) + ") ", 1 /* TEXT */) ], 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["tab-btn", { active: $setup.activeTab === 'available' }]), onClick: _cache[2] || (_cache[2] = $event => ($setup.activeTab = 'available')) }, [ _cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus-circle" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 可分配权限 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.availablePermissions.length) + ") ", 1 /* TEXT */) ], 2 /* CLASS */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 已分配权限列表 "), ($setup.activeTab === 'assigned') ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_14, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [ _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h5", null, "已分配权限", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-danger", onClick: _cache[3] || (_cache[3] = (...args) => ($setup.removeSelectedPermissions && $setup.removeSelectedPermissions(...args))), disabled: $setup.selectedAssignedPermissions.length === 0 }, [ _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-minus" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 移除选中 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.selectedAssignedPermissions.length) + ") ", 1 /* TEXT */) ], 8 /* PROPS */, _hoisted_17), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-secondary", onClick: _cache[4] || (_cache[4] = (...args) => ($setup.clearAssignedSelection && $setup.clearAssignedSelection(...args))) }, " 清除选择 ") ]) ]), ($setup.assignedPermissions.length === 0) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_18, _cache[19] || (_cache[19] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-inbox" }, 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)("div", _hoisted_19, [ ((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.assignedPermissions, (permission) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", { key: permission.id, class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["permission-item", { selected: $setup.selectedAssignedPermissions.includes(permission.id) }]), onClick: $event => ($setup.toggleAssignedPermission(permission.id)) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { type: "checkbox", checked: $setup.selectedAssignedPermissions.includes(permission.id), onChange: $event => ($setup.toggleAssignedPermission(permission.id)) }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_22) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_24, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.name), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_26, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.code), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_27, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.resource), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.description), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_29, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-danger", onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => ($setup.removePermission(permission.id)), ["stop"]), title: "移除权限" }, [...(_cache[20] || (_cache[20] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-minus" }, null, -1 /* CACHED */) ]))], 8 /* PROPS */, _hoisted_30) ]) ], 10 /* CLASS, PROPS */, _hoisted_20)) }), 128 /* KEYED_FRAGMENT */)) ])) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 可分配权限列表 "), ($setup.activeTab === 'available') ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_31, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_32, [ _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h5", null, "可分配权限", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_33, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-primary", onClick: _cache[5] || (_cache[5] = (...args) => ($setup.assignSelectedPermissions && $setup.assignSelectedPermissions(...args))), disabled: $setup.selectedAvailablePermissions.length === 0 }, [ _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 分配选中 (" + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.selectedAvailablePermissions.length) + ") ", 1 /* TEXT */) ], 8 /* PROPS */, _hoisted_34), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-secondary", onClick: _cache[6] || (_cache[6] = (...args) => ($setup.clearAvailableSelection && $setup.clearAvailableSelection(...args))) }, " 清除选择 ") ]) ]), ($setup.availablePermissions.length === 0) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_35, _cache[23] || (_cache[23] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-check-circle" }, 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)("div", _hoisted_36, [ ((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.availablePermissions, (permission) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", { key: permission.id, class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(["permission-item", { selected: $setup.selectedAvailablePermissions.includes(permission.id) }]), onClick: $event => ($setup.toggleAvailablePermission(permission.id)) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_38, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { type: "checkbox", checked: $setup.selectedAvailablePermissions.includes(permission.id), onChange: $event => ($setup.toggleAvailablePermission(permission.id)) }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_39) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_40, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_41, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.name), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_42, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_43, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.code), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_44, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.resource), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_45, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(permission.description), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_46, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-primary", onClick: (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)($event => ($setup.assignPermission(permission.id)), ["stop"]), title: "分配权限" }, [...(_cache[24] || (_cache[24] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-plus" }, null, -1 /* CACHED */) ]))], 8 /* PROPS */, _hoisted_47) ]) ], 10 /* CLASS, PROPS */, _hoisted_37)) }), 128 /* KEYED_FRAGMENT */)) ])) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]) ])) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_48, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-secondary", onClick: _cache[7] || (_cache[7] = (...args) => ($setup.handleClose && $setup.handleClose(...args))) }, "关闭"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-primary", onClick: _cache[8] || (_cache[8] = (...args) => ($setup.refreshPermissions && $setup.refreshPermissions(...args))), disabled: $setup.loading }, _cache[25] || (_cache[25] = [ (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 */) ]), 8 /* PROPS */, _hoisted_49) ]) ]) ])) : (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/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 management-page" } const _hoisted_2 = { class: "search-bar" } const _hoisted_3 = { class: "search-input" } const _hoisted_4 = { class: "filters" } const _hoisted_5 = { class: "role-table data-table" } 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 = ["onClick"] const _hoisted_13 = { class: "pagination" } const _hoisted_14 = { class: "pagination-nav" } const _hoisted_15 = { class: "page-info" } const _hoisted_16 = { class: "pagination-settings" } const _hoisted_17 = { class: "page-jump" } const _hoisted_18 = ["max"] const _hoisted_19 = { class: "modal-header" } const _hoisted_20 = { class: "modal-body" } const _hoisted_21 = { class: "form-group" } const _hoisted_22 = { class: "form-group" } const _hoisted_23 = { class: "form-group" } const _hoisted_24 = { class: "form-actions" } const _hoisted_25 = ["disabled"] function render(_ctx, _cache, $props, $setup, $data, $options) { const _component_RolePermissionAssignment = (0,vue__WEBPACK_IMPORTED_MODULE_0__.resolveComponent)("RolePermissionAssignment") 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, [ _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[0] || (_cache[0] = $event => (($setup.searchQuery) = $event)), type: "text", placeholder: "搜索角色名称或代码...", onInput: _cache[1] || (_cache[1] = (...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_4, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-primary", onClick: _cache[2] || (_cache[2] = (...args) => ($setup.createNewRole && $setup.createNewRole(...args))) }, _cache[23] || (_cache[23] = [ (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[24] || (_cache[24] = [ (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[26] || (_cache[26] = (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[3] || (_cache[3] = (...args) => ($setup.createNewRole && $setup.createNewRole(...args))) }, _cache[25] || (_cache[25] = [ (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[30] || (_cache[30] = (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.filteredRoles, (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)), title: "编辑角色" }, [...(_cache[27] || (_cache[27] = [ (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.assignPermissions(role)), title: "分配权限" }, [...(_cache[28] || (_cache[28] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-shield-alt" }, null, -1 /* CACHED */) ]))], 8 /* PROPS */, _hoisted_11), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-danger", onClick: $event => ($setup.deleteRole(role)), title: "删除角色" }, [...(_cache[29] || (_cache[29] = [ (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__.createCommentVNode)(" 分页导航 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_14, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === 1 }]), onClick: _cache[4] || (_cache[4] = $event => ($setup.handleCurrentChange(1))), title: "首页" }, _cache[31] || (_cache[31] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-double-left" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === 1 }]), onClick: _cache[5] || (_cache[5] = $event => ($setup.handleCurrentChange($setup.currentPage - 1))), title: "上一页" }, _cache[32] || (_cache[32] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-left" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (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)(Math.ceil($setup.total / $setup.pageSize)) + " 页 (共 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.total) + " 条记录) ", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage >= Math.ceil($setup.total / $setup.pageSize) }]), onClick: _cache[6] || (_cache[6] = $event => ($setup.handleCurrentChange($setup.currentPage + 1))), title: "下一页" }, _cache[33] || (_cache[33] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-right" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage >= Math.ceil($setup.total / $setup.pageSize) }]), onClick: _cache[7] || (_cache[7] = $event => ($setup.handleCurrentChange(Math.ceil($setup.total / $setup.pageSize)))), title: "尾页" }, _cache[34] || (_cache[34] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-double-right" }, null, -1 /* CACHED */) ]), 2 /* CLASS */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 分页设置 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [ _cache[38] || (_cache[38] = (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[8] || (_cache[8] = $event => (($setup.pageSize) = $event)), onChange: _cache[9] || (_cache[9] = (...args) => ($setup.handlePageSizeChange && $setup.handlePageSizeChange(...args))) }, _cache[35] || (_cache[35] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("", 5) ]), 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.pageSize] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [ _cache[36] || (_cache[36] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", 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.jumpPage) = $event)), type: "number", min: "1", max: Math.ceil($setup.total / $setup.pageSize), onKeyup: _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withKeys)((...args) => ($setup.handleJumpPage && $setup.handleJumpPage(...args)), ["enter"])), placeholder: "页码" }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_18), [ [ vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.jumpPage, void 0, { number: true } ] ]), _cache[37] || (_cache[37] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "页", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[12] || (_cache[12] = (...args) => ($setup.handleJumpPage && $setup.handleJumpPage(...args))) }, "跳转") ]) ]) ]), (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[20] || (_cache[20] = $event => ($setup.showCreateDialog = false)) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "modal", onClick: _cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [ (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[13] || (_cache[13] = $event => ($setup.showCreateDialog = false)) }, _cache[39] || (_cache[39] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-times" }, null, -1 /* CACHED */) ])) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", { onSubmit: _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.saveRole && $setup.saveRole(...args)), ["prevent"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [ _cache[40] || (_cache[40] = (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[14] || (_cache[14] = $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_22, [ _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)("input", { "onUpdate:modelValue": _cache[15] || (_cache[15] = $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_23, [ _cache[42] || (_cache[42] = (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[16] || (_cache[16] = $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_24, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { type: "button", class: "btn btn-secondary", onClick: _cache[17] || (_cache[17] = $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_25) ]) ], 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_RolePermissionAssignment, { modelValue: $setup.showPermissionDialog, "onUpdate:modelValue": _cache[21] || (_cache[21] = $event => (($setup.showPermissionDialog) = $event)), role: $setup.selectedRole, onPermissionsUpdated: $setup.handlePermissionsUpdated }, null, 8 /* PROPS */, ["modelValue", "role", "onPermissionsUpdated"]) ])) } /***/ }), /***/ "./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/route-sync/RouteSyncTest.vue?vue&type=template&id=618a5171&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/route-sync/RouteSyncTest.vue?vue&type=template&id=618a5171&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: "route-sync-test" } const _hoisted_2 = { class: "test-section" } const _hoisted_3 = ["disabled"] const _hoisted_4 = { key: 0, class: "result" } const _hoisted_5 = { class: "test-section" } const _hoisted_6 = ["disabled"] const _hoisted_7 = { key: 0, class: "result" } const _hoisted_8 = { class: "test-section" } const _hoisted_9 = ["disabled"] const _hoisted_10 = { key: 0, class: "result" } const _hoisted_11 = { class: "test-section" } const _hoisted_12 = ["disabled"] const _hoisted_13 = { key: 0, class: "result" } const _hoisted_14 = { key: 0, class: "loading" } 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[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "路由同步测试", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [ _cache[5] || (_cache[5] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "1. 路由收集测试", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[0] || (_cache[0] = (...args) => ($options.testRouteCollection && $options.testRouteCollection(...args))), disabled: $data.loading }, "测试路由收集", 8 /* PROPS */, _hoisted_3), ($data.routeCollectionResult) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_4, [ _cache[4] || (_cache[4] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "收集结果:", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("pre", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(JSON.stringify($data.routeCollectionResult, null, 2)), 1 /* TEXT */) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [ _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "2. 路由映射测试", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[1] || (_cache[1] = (...args) => ($options.testRouteMapping && $options.testRouteMapping(...args))), disabled: $data.loading }, "测试路由映射", 8 /* PROPS */, _hoisted_6), ($data.routeMappingResult) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_7, [ _cache[6] || (_cache[6] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "映射结果:", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("pre", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(JSON.stringify($data.routeMappingResult, null, 2)), 1 /* TEXT */) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [ _cache[9] || (_cache[9] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "3. 路由同步测试", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[2] || (_cache[2] = (...args) => ($options.testRouteSync && $options.testRouteSync(...args))), disabled: $data.loading }, "测试路由同步", 8 /* PROPS */, _hoisted_9), ($data.syncResult) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_10, [ _cache[8] || (_cache[8] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "同步结果:", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("pre", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(JSON.stringify($data.syncResult, null, 2)), 1 /* TEXT */) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_11, [ _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "4. 手动同步", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[3] || (_cache[3] = (...args) => ($options.manualSync && $options.manualSync(...args))), disabled: $data.loading }, "手动同步", 8 /* PROPS */, _hoisted_12), ($data.manualSyncResult) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_13, [ _cache[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "手动同步结果:", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("pre", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(JSON.stringify($data.manualSyncResult, null, 2)), 1 /* TEXT */) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]), ($data.loading) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_14, _cache[12] || (_cache[12] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "正在执行测试...", -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/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 management-page" } 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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-cog" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 用户设置") ]) ], -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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user-cog" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 个人偏好") ], -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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-tools" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 应用设置") ], -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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user-shield" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 用户设置") ], -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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-bell" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 通知偏好") ], -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, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-database" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 数据管理") ], -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 management-page" } const _hoisted_2 = { class: "search-bar" } const _hoisted_3 = { class: "search-input" } const _hoisted_4 = { class: "filters" } const _hoisted_5 = ["value"] const _hoisted_6 = { class: "user-table data-table" } const _hoisted_7 = { class: "role-tags" } const _hoisted_8 = { class: "actions" } const _hoisted_9 = ["onClick"] const _hoisted_10 = ["onClick"] const _hoisted_11 = ["onClick"] const _hoisted_12 = { class: "pagination" } const _hoisted_13 = { class: "pagination-nav" } const _hoisted_14 = { class: "page-info" } const _hoisted_15 = { class: "pagination-settings" } const _hoisted_16 = { class: "page-jump" } const _hoisted_17 = ["max"] const _hoisted_18 = { class: "modal-header" } const _hoisted_19 = { class: "modal-body" } const _hoisted_20 = { class: "form-group" } const _hoisted_21 = ["disabled"] const _hoisted_22 = { key: 0, class: "form-group" } const _hoisted_23 = { class: "form-group" } const _hoisted_24 = { class: "form-group" } const _hoisted_25 = { class: "form-group" } const _hoisted_26 = { class: "form-actions" } const _hoisted_27 = { 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__.createCommentVNode)(" 搜索和筛选 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [ _cache[27] || (_cache[27] = (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[0] || (_cache[0] = $event => (($setup.searchQuery) = $event)), type: "text", placeholder: "搜索用户名、邮箱或手机号...", onInput: _cache[1] || (_cache[1] = (...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_4, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", { "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => (($setup.statusFilter) = $event)), onChange: _cache[3] || (_cache[3] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args))) }, _cache[28] || (_cache[28] = [ (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[4] || (_cache[4] = $event => (($setup.roleFilter) = $event)), onChange: _cache[5] || (_cache[5] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args))) }, [ _cache[29] || (_cache[29] = (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_5)) }), 128 /* KEYED_FRAGMENT */)) ], 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.roleFilter] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-primary", onClick: _cache[6] || (_cache[6] = $event => ($setup.showAddUserModal = true)) }, _cache[30] || (_cache[30] = [ (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_6, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("table", null, [ _cache[34] || (_cache[34] = (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_7, [ ((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_8, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-info", onClick: $event => ($setup.editUser(user)) }, [...(_cache[31] || (_cache[31] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-edit" }, null, -1 /* CACHED */) ]))], 8 /* PROPS */, _hoisted_9), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-primary", onClick: $event => ($setup.assignRoles(user)) }, [...(_cache[32] || (_cache[32] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-user-shield" }, null, -1 /* CACHED */) ]))], 8 /* PROPS */, _hoisted_10), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-danger", onClick: $event => ($setup.deleteUser(user.id)) }, [...(_cache[33] || (_cache[33] = [ (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)(" 分页 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_12, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 分页导航 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_13, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === 1 }]), onClick: _cache[7] || (_cache[7] = $event => ($setup.changePage(1))), title: "首页" }, _cache[35] || (_cache[35] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-double-left" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === 1 }]), onClick: _cache[8] || (_cache[8] = $event => ($setup.changePage($setup.currentPage - 1))), title: "上一页" }, _cache[36] || (_cache[36] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-left" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (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)($setup.totalPages) + " 页 (共 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.total) + " 条记录) ", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === $setup.totalPages }]), onClick: _cache[9] || (_cache[9] = $event => ($setup.changePage($setup.currentPage + 1))), title: "下一页" }, _cache[37] || (_cache[37] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-right" }, null, -1 /* CACHED */) ]), 2 /* CLASS */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("a", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['pagination-link', { disabled: $setup.currentPage === $setup.totalPages }]), onClick: _cache[10] || (_cache[10] = $event => ($setup.changePage($setup.totalPages))), title: "尾页" }, _cache[38] || (_cache[38] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-angle-double-right" }, null, -1 /* CACHED */) ]), 2 /* CLASS */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 分页设置 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [ _cache[42] || (_cache[42] = (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[11] || (_cache[11] = $event => (($setup.pageSize) = $event)), onChange: _cache[12] || (_cache[12] = (...args) => ($setup.handlePageSizeChange && $setup.handlePageSizeChange(...args))) }, _cache[39] || (_cache[39] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createStaticVNode)("", 5) ]), 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.pageSize] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [ _cache[40] || (_cache[40] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", 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.jumpPage) = $event)), type: "number", min: "1", max: $setup.totalPages, onKeyup: _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withKeys)((...args) => ($setup.handleJumpPage && $setup.handleJumpPage(...args)), ["enter"])), placeholder: "页码" }, null, 40 /* PROPS, NEED_HYDRATION */, _hoisted_17), [ [ vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.jumpPage, void 0, { number: true } ] ]), _cache[41] || (_cache[41] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "页", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[15] || (_cache[15] = (...args) => ($setup.handleJumpPage && $setup.handleJumpPage(...args))) }, "跳转") ]) ]) ]), (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[25] || (_cache[25] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "modal", onClick: _cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [ (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[16] || (_cache[16] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, "×") ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_19, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", { onSubmit: _cache[23] || (_cache[23] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.submitUser && $setup.submitUser(...args)), ["prevent"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_20, [ _cache[43] || (_cache[43] = (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[17] || (_cache[17] = $event => (($setup.userForm.username) = $event)), type: "text", required: "", disabled: $setup.showEditUserModal }, null, 8 /* PROPS */, _hoisted_21), [ [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_22, [ _cache[44] || (_cache[44] = (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[18] || (_cache[18] = $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_23, [ _cache[45] || (_cache[45] = (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[19] || (_cache[19] = $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_24, [ _cache[46] || (_cache[46] = (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[20] || (_cache[20] = $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_25, [ _cache[48] || (_cache[48] = (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[21] || (_cache[21] = $event => (($setup.userForm.status) = $event)) }, _cache[47] || (_cache[47] = [ (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_26, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { type: "button", class: "btn btn-secondary", onClick: _cache[22] || (_cache[22] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, " 取消 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", _hoisted_27, (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[26] || (_cache[26] = $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 management-page" } const _hoisted_2 = { key: 0, class: "loading-container" } const _hoisted_3 = { class: "error-container" } const _hoisted_4 = { class: "settings-content" } const _hoisted_5 = { class: "settings-section" } const _hoisted_6 = { class: "info-grid" } const _hoisted_7 = { class: "info-item" } 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: "settings-section" } const _hoisted_14 = { class: "info-grid" } const _hoisted_15 = { class: "info-item" } const _hoisted_16 = { class: "info-item" } const _hoisted_17 = { class: "settings-section" } const _hoisted_18 = { key: 0, class: "roles-list" } const _hoisted_19 = { class: "role-header" } const _hoisted_20 = { class: "role-name" } const _hoisted_21 = { class: "role-description" } const _hoisted_22 = { class: "role-permissions" } const _hoisted_23 = { class: "permissions-grid" } const _hoisted_24 = { key: 1, class: "no-roles" } const _hoisted_25 = { class: "settings-actions" } const _hoisted_26 = { 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: "page-header" }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", 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)("h3", 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, [ _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_8, [ _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_9, [ _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_10, [ _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_11, [ _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_12, [ _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_13, [ _cache[19] || (_cache[19] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", 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_14, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_15, [ _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_16, [ _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_17, [ _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "fas fa-crown" }), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 角色信息") ], -1 /* CACHED */)), ($setup.userInfo.roles && $setup.userInfo.roles.length > 0) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_18, [ ((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_19, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_20, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_21, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.description || '无描述'), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [ _cache[20] || (_cache[20] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h4", null, "权限列表:", -1 /* CACHED */)), (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)(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_24, _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_25, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { onClick: _cache[1] || (_cache[1] = (...args) => ($setup.refreshProfile && $setup.refreshProfile(...args))), class: "btn btn-secondary" }, _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: "btn btn-primary" }, _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_26, [ _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