/******/ (() => { // 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/components/LoginModal.vue?vue&type=style&index=0&id=443b36ca&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/components/LoginModal.vue?vue&type=style&index=0&id=443b36ca&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-443b36ca] { 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-443b36ca] { 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-443b36ca 0.3s ease-out; } @keyframes modalSlideIn-443b36ca { from { opacity: 0; transform: translateY(-20px) scale(0.95); } to { opacity: 1; transform: translateY(0) scale(1); } } .login-modal-header[data-v-443b36ca] { 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-443b36ca] { margin: 0; font-size: 20px; font-weight: 600; color: var(--text-primary); } .close-btn[data-v-443b36ca] { 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-443b36ca]:hover { background: var(--bg-secondary); color: var(--text-primary); } .login-modal-body[data-v-443b36ca] { padding: 24px; } .login-form[data-v-443b36ca] { display: flex; flex-direction: column; gap: 20px; } .form-group[data-v-443b36ca] { display: flex; flex-direction: column; gap: 8px; } .form-group label[data-v-443b36ca] { font-weight: 500; color: var(--text-primary); font-size: 14px; } .form-group input[data-v-443b36ca] { 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; } .form-group input[data-v-443b36ca]: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-443b36ca]:disabled { opacity: 0.6; cursor: not-allowed; } .captcha-container[data-v-443b36ca] { display: flex; gap: 12px; align-items: stretch; } .captcha-container input[data-v-443b36ca] { flex: 1; } .captcha-image-container[data-v-443b36ca] { 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-443b36ca]:hover { border-color: var(--primary-color); } .captcha-image[data-v-443b36ca] { width: 100%; height: 100%; -o-object-fit: cover; object-fit: cover; } .captcha-placeholder[data-v-443b36ca] { 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-443b36ca]:hover { background: var(--bg-tertiary); color: var(--text-primary); } .captcha-hint[data-v-443b36ca] { font-size: 10px; opacity: 0.7; margin-top: 2px; } .captcha-loading-spinner[data-v-443b36ca] { width: 12px; height: 12px; border: 2px solid transparent; border-top: 2px solid currentColor; border-radius: 50%; animation: spin-443b36ca 1s linear infinite; margin-top: 4px; } .form-actions[data-v-443b36ca] { margin-top: 8px; } .login-btn[data-v-443b36ca] { 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-443b36ca] { background: var(--primary-color); color: #333333; border: 1px solid rgba(255, 255, 255, 0.1); } .theme-dark .login-btn[data-v-443b36ca]:hover:not(:disabled) { background: var(--primary-hover); color: #222222; } .login-btn[data-v-443b36ca]: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-443b36ca]:disabled { opacity: 0.6; cursor: not-allowed; transform: none; box-shadow: none; } /* 表单验证提示样式 */ .form-validation-hint[data-v-443b36ca] { margin-top: 8px; padding: 8px 12px; background: var(--bg-secondary); border: 1px solid var(--border-color); border-radius: 6px; font-size: 12px; color: var(--text-secondary); text-align: center; } .form-validation-hint span[data-v-443b36ca] { display: block; margin-bottom: 2px; } .form-validation-hint span[data-v-443b36ca]:last-child { margin-bottom: 0; } .loading-spinner[data-v-443b36ca] { width: 16px; height: 16px; border: 2px solid transparent; border-top: 2px solid currentColor; border-radius: 50%; animation: spin-443b36ca 1s linear infinite; } @keyframes spin-443b36ca { to { transform: rotate(360deg); } } .error-message[data-v-443b36ca] { 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); } /* 深色主题下的错误提示样式优化 */ .theme-dark .error-message[data-v-443b36ca] { 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-443b36ca] { padding: 16px 24px; border-top: 1px solid var(--border-color); background: var(--bg-secondary); } .login-tips[data-v-443b36ca] { margin: 0; font-size: 12px; color: var(--text-secondary); text-align: center; line-height: 1.5; } .login-tips span[data-v-443b36ca] { display: block; margin-bottom: 4px; } .login-tips span[data-v-443b36ca]:first-child { font-weight: 600; color: var(--text-primary); } /* 响应式设计 */ @media (max-width: 480px) { .login-modal[data-v-443b36ca] { width: 95%; margin: 20px; } .login-modal-header[data-v-443b36ca], .login-modal-body[data-v-443b36ca], .login-modal-footer[data-v-443b36ca] { padding: 16px 20px; } .captcha-container[data-v-443b36ca] { flex-direction: column; gap: 8px; } .captcha-image-container[data-v-443b36ca] { 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/components/MainLayout.vue?vue&type=style&index=0&id=a4b9ee6e&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/components/MainLayout.vue?vue&type=style&index=0&id=a4b9ee6e&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-a4b9ee6e] { 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-a4b9ee6e] { 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-a4b9ee6e] { display: flex; align-items: center; gap: 20px; } .logo h1[data-v-a4b9ee6e] { margin: 0; font-size: 24px; color: var(--accent-color); font-weight: bold; } .breadcrumb[data-v-a4b9ee6e] { display: flex; align-items: center; gap: 8px; color: var(--text-secondary); font-size: 14px; } .breadcrumb-item[data-v-a4b9ee6e] { color: var(--text-primary); } .separator[data-v-a4b9ee6e] { color: var(--text-muted); margin: 0 4px; } .header-right[data-v-a4b9ee6e] { display: flex; align-items: center; gap: 20px; } /* 消息中心 */ .message-center[data-v-a4b9ee6e] { position: relative; } .message-btn[data-v-a4b9ee6e] { background: none; border: none; font-size: 16px; /* 从20px缩小到16px(缩小一半) */ cursor: pointer; position: relative; padding: 8px; border-radius: 4px; transition: background-color 0.2s; } .message-btn[data-v-a4b9ee6e]:hover { background: #f5f5f5; } .badge[data-v-a4b9ee6e] { 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-a4b9ee6e] { 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-a4b9ee6e] { display: flex; justify-content: space-between; align-items: center; padding: 16px; border-bottom: 1px solid var(--border-color); } .message-header h3[data-v-a4b9ee6e] { margin: 0; font-size: 16px; color: var(--text-primary); } .close-btn[data-v-a4b9ee6e] { background: none; border: none; font-size: 20px; cursor: pointer; color: var(--text-muted); } .message-list[data-v-a4b9ee6e] { max-height: 400px; overflow-y: auto; } .message-item[data-v-a4b9ee6e] { display: flex; align-items: center; padding: 12px 16px; border-bottom: 1px solid var(--border-color); transition: background-color 0.2s; } .message-item[data-v-a4b9ee6e]:hover { background: var(--bg-secondary); } .message-icon[data-v-a4b9ee6e] { font-size: 20px; margin-right: 12px; color: var(--text-primary); } .message-content[data-v-a4b9ee6e] { flex: 1; } .message-title[data-v-a4b9ee6e] { font-weight: 500; margin-bottom: 4px; color: var(--text-primary); } .message-time[data-v-a4b9ee6e] { font-size: 12px; color: var(--text-muted); } .mark-read-btn[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: var(--bg-secondary); } /* 用户信息 */ .user-info[data-v-a4b9ee6e] { position: relative; } .user-avatar[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: #1565c0; } .user-avatar img[data-v-a4b9ee6e] { width: 100%; height: 100%; border-radius: 50%; -o-object-fit: cover; object-fit: cover; } .avatar-placeholder[data-v-a4b9ee6e] { font-size: 18px; } .user-menu[data-v-a4b9ee6e] { 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-a4b9ee6e] { padding: 16px; border-bottom: 1px solid var(--border-color); } .user-name[data-v-a4b9ee6e] { font-weight: 600; margin-bottom: 4px; color: var(--text-primary); } .user-email[data-v-a4b9ee6e] { font-size: 12px; color: var(--text-secondary); } .user-menu-items[data-v-a4b9ee6e] { padding: 8px 0; } .menu-item[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: var(--bg-secondary); } /* 主要内容区域 */ .main-content[data-v-a4b9ee6e] { flex: 1; display: flex; overflow: hidden; /* 高度由flex自动计算 */ } /* 左侧菜单 */ .sidebar[data-v-a4b9ee6e] { width: 250px; background: var(--sidebar-bg); border-right: 1px solid var(--border-color); overflow-y: auto; } .sidebar-nav[data-v-a4b9ee6e] { padding: 20px 0; } .nav-section[data-v-a4b9ee6e] { margin-bottom: 20px; /* 从30px减少到20px,因为删除了标题 */ } .nav-section[data-v-a4b9ee6e]:last-child { margin-bottom: 0; /* 最后一个section不需要底部间距 */ } .nav-title[data-v-a4b9ee6e] { padding: 0 20px; margin-bottom: 12px; font-size: 12px; font-weight: 600; color: #999; text-transform: none; /* 取消大写转换 */ letter-spacing: normal; /* 取消字母间距 */ } .nav-list[data-v-a4b9ee6e] { list-style: none; padding: 0; margin: 0; } .nav-item[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: var(--bg-secondary); color: var(--accent-color); } .nav-item.active[data-v-a4b9ee6e] { background: var(--bg-tertiary); color: var(--accent-color); border-right: 3px solid var(--accent-color); } .nav-icon[data-v-a4b9ee6e] { font-size: 12px; /* 从18px缩小到12px(缩小三分之一) */ margin-right: 12px; width: 16px; /* 从20px缩小到16px */ text-align: center; } .nav-text[data-v-a4b9ee6e] { flex: 1; } .favorite-btn[data-v-a4b9ee6e] { background: none; border: none; font-size: 12px; /* 从14px缩小到12px,与图标保持一致 */ cursor: pointer; opacity: 0.3; transition: opacity 0.2s; padding: 2px; /* 添加内边距 */ } .favorite-btn[data-v-a4b9ee6e]:hover, .favorite-btn.active[data-v-a4b9ee6e] { opacity: 1; } /* 右侧内容区域 */ .content-area[data-v-a4b9ee6e] { flex: 1; display: flex; flex-direction: column; overflow: hidden; /* 隐藏所有滚动条 */ /* 确保高度正确计算 */ height: 100%; } /* 内容选项卡 */ .content-tabs[data-v-a4b9ee6e] { 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-a4b9ee6e] { display: flex; align-items: center; flex: 1; overflow-x: auto; overflow-y: hidden; /* 确保垂直方向不滚动 */ height: 100%; /* 限制高度 */ } .tab-item[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: var(--bg-secondary); color: var(--text-primary); } .tab-item.active[data-v-a4b9ee6e] { 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-a4b9ee6e] { 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-a4b9ee6e]:hover { color: #dc3545; background: transparent; transform: none; } /* 活动状态的选项卡关闭图标使用浅色 */ .tab-item.active .tab-close[data-v-a4b9ee6e] { color: #ffffff; } .tab-item.active .tab-close[data-v-a4b9ee6e]:hover { color: #ffcccc; } .tab-title[data-v-a4b9ee6e] { flex: 1; text-align: center; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .tab-close[data-v-a4b9ee6e] { background: none; border: none; font-size: 16px; cursor: pointer; color: #999; padding: 2px; border-radius: 2px; transition: all 0.2s; } .tab-close[data-v-a4b9ee6e]:hover { background: #f0f0f0; color: #666; } .tab-actions[data-v-a4b9ee6e] { display: flex; align-items: center; justify-content: flex-end; padding-right: 10px; flex-shrink: 0; height: 100%; /* 确保高度一致 */ } .close-all-btn[data-v-a4b9ee6e] { 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-a4b9ee6e]:hover { background: #e9ecef; color: #495057; } .close-all-icon[data-v-a4b9ee6e] { font-size: 14px; font-weight: bold; line-height: 1; } /* 功能内容区 */ .content-body[data-v-a4b9ee6e] { flex: 1; overflow-y: auto; /* 只有内容区有垂直滚动条 */ overflow-x: hidden; /* 隐藏水平滚动条 */ background: var(--header-bg); position: relative; /* 高度由flex自动计算 */ } /* 确保内容可以滚动 */ .content-body[data-v-a4b9ee6e] > * { min-height: 100%; /* 确保子元素不会创建额外的滚动条 */ overflow: visible; } /* 登录按钮样式 */ .login-section[data-v-a4b9ee6e] { display: flex; align-items: center; } .login-btn[data-v-a4b9ee6e] { 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-a4b9ee6e] { background: var(--primary-color); color: #333333; border: 1px solid rgba(255, 255, 255, 0.1); } .theme-dark .login-btn[data-v-a4b9ee6e]:hover { background: var(--primary-hover); color: #222222; } .login-btn[data-v-a4b9ee6e]:hover { background: var(--primary-hover); transform: translateY(-1px); box-shadow: 0 2px 8px rgba(25, 118, 210, 0.3); } .login-btn .icon[data-v-a4b9ee6e] { font-size: 16px; } /* 响应式设计 */ @media (max-width: 768px) { .sidebar[data-v-a4b9ee6e] { width: 200px; } .header[data-v-a4b9ee6e] { padding: 0 15px; } .logo h1[data-v-a4b9ee6e] { font-size: 20px; } .breadcrumb[data-v-a4b9ee6e] { 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/components/StatusBar.vue?vue&type=style&index=0&id=126429ab&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/components/StatusBar.vue?vue&type=style&index=0&id=126429ab&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-126429ab] { 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-126429ab] { display: flex; align-items: center; } .status-right[data-v-126429ab] { display: flex; align-items: center; gap: 10px; /* 使用gap替代margin-right */ flex-wrap: nowrap; /* 防止换行 */ } .status-item[data-v-126429ab] { margin-right: 15px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: none; /* 移除最大宽度限制 */ flex-shrink: 0; /* 防止收缩 */ } /* 为服务地址项添加特殊样式 */ .status-item[data-v-126429ab]:contains("服务地址") { min-width: 120px; /* 设置最小宽度 */ max-width: 200px; /* 设置最大宽度 */ } .status-item[data-v-126429ab]:last-child { margin-right: 0; } /* 错误链接样式 */ .error-link[data-v-126429ab] { cursor: pointer; text-decoration: underline; color: #ff6b6b; transition: color 0.2s ease; } .error-link[data-v-126429ab]:hover { color: #ff8e8e; } /* 响应式设计 */ @media (max-width: 1200px) { .status-bar[data-v-126429ab] { padding: 0 8px; font-size: 10px; } .status-item[data-v-126429ab] { margin-right: 10px; } .status-right[data-v-126429ab] { gap: 8px; } } @media (max-width: 1000px) { .status-bar[data-v-126429ab] { padding: 0 6px; font-size: 9px; } .status-item[data-v-126429ab] { margin-right: 8px; } .status-right[data-v-126429ab] { 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/components/Toast.vue?vue&type=style&index=0&id=4eeeff11&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/components/Toast.vue?vue&type=style&index=0&id=4eeeff11&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-4eeeff11] { 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-4eeeff11] { border-left: 4px solid #4caf50; } .toast.error[data-v-4eeeff11] { border-left: 4px solid #f44336; } .toast.warning[data-v-4eeeff11] { border-left: 4px solid #ff9800; } .toast.info[data-v-4eeeff11] { border-left: 4px solid #2196f3; } .toast-icon[data-v-4eeeff11] { font-size: 20px; flex-shrink: 0; } .toast-content[data-v-4eeeff11] { flex: 1; min-width: 0; } .toast-title[data-v-4eeeff11] { font-weight: 600; color: var(--text-primary); margin-bottom: 4px; font-size: 14px; } .toast-message[data-v-4eeeff11] { color: var(--text-secondary); font-size: 13px; line-height: 1.4; } .toast-close[data-v-4eeeff11] { 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-4eeeff11]:hover { background: var(--bg-secondary); color: var(--text-primary); } /* 动画 */ .toast-enter-active[data-v-4eeeff11], .toast-leave-active[data-v-4eeeff11] { transition: all 0.3s ease; } .toast-enter-from[data-v-4eeeff11] { opacity: 0; transform: translateX(100%); } .toast-leave-to[data-v-4eeeff11] { opacity: 0; transform: translateX(100%); } /* 响应式 */ @media (max-width: 480px) { .toast[data-v-4eeeff11] { 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/views/History.vue?vue&type=style&index=0&id=5347d120&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/views/History.vue?vue&type=style&index=0&id=5347d120&scoped=true&lang=css ***! \***********************************************************************************************************************************************************************************************************************************************************************************************************************************************/ /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` .history-view[data-v-5347d120] { padding: 20px; max-width: 800px; margin: 0 auto; } .empty-state[data-v-5347d120] { text-align: center; padding: 40px; color: #888; } .history-list[data-v-5347d120] { margin-top: 20px; } .history-item[data-v-5347d120] { padding: 15px; margin-bottom: 10px; background-color: #f9f9f9; border-radius: 4px; display: flex; justify-content: space-between; align-items: center; } .history-date[data-v-5347d120] { color: #666; } .history-stats[data-v-5347d120] { display: flex; gap: 15px; } .stat[data-v-5347d120] { font-weight: bold; } .download[data-v-5347d120] { color: #42b983; } .upload[data-v-5347d120] { color: #3498db; } .ping[data-v-5347d120] { color: #e74c3c; } `, ""]); // Exports /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (___CSS_LOADER_EXPORT___); /***/ }), /***/ "./node_modules/css-loader/dist/cjs.js??clonedRuleSet-12.use[1]!./node_modules/vue-loader/dist/stylePostLoader.js!./node_modules/postcss-loader/dist/cjs.js??clonedRuleSet-12.use[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/views/Home.vue?vue&type=style&index=0&id=ecd3befa&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/views/Home.vue?vue&type=style&index=0&id=ecd3befa&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-ecd3befa] { min-height: 100%; background: var(--bg-primary); color: var(--text-primary); padding: 2rem; overflow-y: auto; height: 100%; /* 添加中文字体支持 */ font-family: 'Microsoft YaHei', 'PingFang SC', 'Hiragino Sans GB', 'WenQuanYi Micro Hei', Avenir, Helvetica, Arial, sans-serif; } /* 深色主题时使用更暗的渐变背景 */ .theme-dark .home[data-v-ecd3befa] { background: linear-gradient(135deg, #1f3a6b 0%, #2d4a8a 100%); } /* 浅色主题时的样式调整 */ .theme-light .home[data-v-ecd3befa] { background: var(--bg-primary); } .theme-light .welcome-card[data-v-ecd3befa], .theme-light .feature-card[data-v-ecd3befa], .theme-light .todo-section[data-v-ecd3befa], .theme-light .recent-section[data-v-ecd3befa] { box-shadow: 0 4px 12px var(--shadow-color); } /* 主要内容区域 */ .main-content[data-v-ecd3befa] { max-width: 1200px; margin: 0 auto; display: flex; flex-direction: column; gap: 2rem; min-height: 100%; } /* 欢迎区域 */ .welcome-section[data-v-ecd3befa] { text-align: center; margin-bottom: 2rem; } .welcome-card[data-v-ecd3befa] { 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-ecd3befa] { font-size: 2.5rem; margin-bottom: 1rem; font-weight: 300; } .subtitle[data-v-ecd3befa] { font-size: 1.2rem; margin-bottom: 2rem; opacity: 0.9; } .quick-stats[data-v-ecd3befa] { display: flex; justify-content: center; gap: 3rem; margin-top: 2rem; } .stat-item[data-v-ecd3befa] { text-align: center; } .stat-number[data-v-ecd3befa] { display: block; font-size: 2rem; font-weight: bold; color: #ffd700; } .stat-label[data-v-ecd3befa] { font-size: 0.9rem; opacity: 0.8; } /* 功能卡片区域 */ .features-section[data-v-ecd3befa] { display: grid; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); gap: 1.5rem; margin-bottom: 2rem; } .feature-card[data-v-ecd3befa] { 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-ecd3befa]:hover { transform: translateY(-5px); background: var(--bg-secondary); box-shadow: 0 10px 30px var(--shadow-color); } .feature-icon[data-v-ecd3befa] { font-size: 3rem; margin-bottom: 1rem; } .feature-card h3[data-v-ecd3befa] { font-size: 1.3rem; margin-bottom: 0.5rem; } .feature-card p[data-v-ecd3befa] { opacity: 0.8; line-height: 1.5; } /* 待办事项区域 */ .todo-section[data-v-ecd3befa] { 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-ecd3befa] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; } .section-header h3[data-v-ecd3befa] { margin: 0; } .add-todo-btn[data-v-ecd3befa] { 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-ecd3befa]:hover { background: var(--button-hover); } .todo-list[data-v-ecd3befa] { display: flex; flex-direction: column; gap: 0.5rem; } .todo-item[data-v-ecd3befa] { 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-ecd3befa]:hover { background: var(--bg-tertiary); } .todo-item.completed .todo-text[data-v-ecd3befa] { text-decoration: line-through; opacity: 0.6; } .todo-text[data-v-ecd3befa] { flex: 1; } .todo-date[data-v-ecd3befa] { color: var(--text-secondary); font-size: 0.9rem; } .delete-btn[data-v-ecd3befa] { background: none; border: none; cursor: pointer; font-size: 1rem; opacity: 0.7; transition: opacity 0.3s ease; } .delete-btn[data-v-ecd3befa]:hover { opacity: 1; } /* 最近活动区域 */ .recent-section[data-v-ecd3befa] { background: var(--card-bg); backdrop-filter: blur(10px); border-radius: 15px; padding: 2rem; border: 1px solid var(--border-color); } .recent-section h3[data-v-ecd3befa] { margin-bottom: 1.5rem; } .activity-list[data-v-ecd3befa] { display: flex; flex-direction: column; gap: 1rem; } .activity-item[data-v-ecd3befa] { display: flex; align-items: center; gap: 1rem; padding: 0.75rem; background: var(--bg-secondary); border-radius: 10px; } .activity-icon[data-v-ecd3befa] { font-size: 1.5rem; } .activity-content[data-v-ecd3befa] { flex: 1; } .activity-title[data-v-ecd3befa] { font-weight: 500; } .activity-time[data-v-ecd3befa] { color: var(--text-secondary); font-size: 0.9rem; } /* 响应式设计 */ @media (max-width: 768px) { .home[data-v-ecd3befa] { padding: 1rem; } .main-content[data-v-ecd3befa] { gap: 1.5rem; } .welcome-card[data-v-ecd3befa] { padding: 2rem 1rem; } .welcome-card h2[data-v-ecd3befa] { font-size: 2rem; } .quick-stats[data-v-ecd3befa] { flex-direction: column; gap: 1rem; } .features-section[data-v-ecd3befa] { grid-template-columns: 1fr; } .todo-section[data-v-ecd3befa], .recent-section[data-v-ecd3befa] { padding: 1.5rem; } } /* 欢迎页面登录相关样式 */ .welcome-header[data-v-ecd3befa] { display: flex; justify-content: space-between; align-items: center; gap: 2rem; } .welcome-text[data-v-ecd3befa] { flex: 1; } .login-section[data-v-ecd3befa] { flex-shrink: 0; } .login-btn[data-v-ecd3befa] { 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-ecd3befa]:hover { background: var(--accent-hover); transform: translateY(-2px); box-shadow: 0 8px 25px var(--shadow-color); } .login-prompt-section[data-v-ecd3befa] { text-align: center; margin-bottom: 2rem; } .login-prompt-card[data-v-ecd3befa] { 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-ecd3befa] { font-size: 4rem; margin-bottom: 1rem; opacity: 0.8; } .login-prompt-card h3[data-v-ecd3befa] { font-size: 1.5rem; margin-bottom: 1rem; color: var(--text-primary); } .login-prompt-card p[data-v-ecd3befa] { font-size: 1.1rem; margin-bottom: 2rem; opacity: 0.8; color: var(--text-secondary); } .prompt-login-btn[data-v-ecd3befa] { 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-ecd3befa]:hover { background: var(--accent-hover); transform: translateY(-2px); box-shadow: 0 8px 25px var(--shadow-color); } /* 深色主题下登录按钮的字体颜色 */ .theme-dark .login-btn[data-v-ecd3befa], .theme-dark .prompt-login-btn[data-v-ecd3befa] { 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/views/UserManagement.vue?vue&type=style&index=0&id=7338cb92&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/views/UserManagement.vue?vue&type=style&index=0&id=7338cb92&scoped=true&lang=css ***! \******************************************************************************************************************************************************************************************************************************************************************************************************************************************************/ /***/ ((module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/noSourceMaps.js */ "./node_modules/css-loader/dist/runtime/noSourceMaps.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../../../node_modules/css-loader/dist/runtime/api.js */ "./node_modules/css-loader/dist/runtime/api.js"); /* harmony import */ var _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1__); // Imports var ___CSS_LOADER_EXPORT___ = _node_modules_css_loader_dist_runtime_api_js__WEBPACK_IMPORTED_MODULE_1___default()((_node_modules_css_loader_dist_runtime_noSourceMaps_js__WEBPACK_IMPORTED_MODULE_0___default())); // Module ___CSS_LOADER_EXPORT___.push([module.id, ` .user-management[data-v-7338cb92] { padding: 20px; height: 100%; overflow-y: auto; } .page-header[data-v-7338cb92] { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; } .page-header h2[data-v-7338cb92] { margin: 0; color: var(--text-primary); } .search-bar[data-v-7338cb92] { display: flex; gap: 20px; margin-bottom: 20px; align-items: center; } .search-input[data-v-7338cb92] { position: relative; flex: 1; } .search-input i[data-v-7338cb92] { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); color: var(--text-muted); } .search-input input[data-v-7338cb92] { width: 100%; padding: 10px 10px 10px 35px; border: 1px solid var(--input-border); border-radius: 6px; font-size: 14px; background-color: var(--input-bg); color: var(--input-text); } .filters[data-v-7338cb92] { display: flex; gap: 10px; } .filters select[data-v-7338cb92] { padding: 8px 12px; border: 1px solid var(--input-border); border-radius: 4px; font-size: 14px; background-color: var(--input-bg); color: var(--input-text); } .user-table[data-v-7338cb92] { background: var(--card-bg); border-radius: 8px; box-shadow: 0 2px 8px var(--shadow-color); overflow: hidden; margin-bottom: 20px; } table[data-v-7338cb92] { width: 100%; border-collapse: collapse; } th[data-v-7338cb92], td[data-v-7338cb92] { padding: 12px; text-align: left; border-bottom: 1px solid var(--border-color); } th[data-v-7338cb92] { background: var(--bg-secondary); font-weight: 600; color: var(--text-primary); } .status-badge[data-v-7338cb92] { padding: 4px 8px; border-radius: 12px; font-size: 12px; font-weight: 500; } .status-badge.active[data-v-7338cb92] { background: #e8f5e8; color: #2e7d32; } .status-badge.inactive[data-v-7338cb92] { background: #ffebee; color: #c62828; } .role-tags[data-v-7338cb92] { display: flex; gap: 4px; flex-wrap: wrap; } .role-tag[data-v-7338cb92] { background: #e3f2fd; color: #1976d2; padding: 2px 6px; border-radius: 4px; font-size: 11px; } .actions[data-v-7338cb92] { display: flex; gap: 8px; } .btn[data-v-7338cb92] { padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; display: inline-flex; align-items: center; gap: 6px; transition: all 0.2s; } .btn-primary[data-v-7338cb92] { background: #1976d2; color: white; } .btn-primary[data-v-7338cb92]:hover { background: #1565c0; } .btn-info[data-v-7338cb92] { background: #0288d1; color: white; } .btn-danger[data-v-7338cb92] { background: #d32f2f; color: white; } .btn-secondary[data-v-7338cb92] { background: #757575; color: white; } .btn-sm[data-v-7338cb92] { padding: 6px 12px; font-size: 12px; } .btn[data-v-7338cb92]:hover { opacity: 0.9; } .btn[data-v-7338cb92]:disabled { opacity: 0.5; cursor: not-allowed; } .pagination[data-v-7338cb92] { display: flex; justify-content: center; align-items: center; gap: 20px; } .page-info[data-v-7338cb92] { color: #666; font-size: 14px; } .modal-overlay[data-v-7338cb92] { 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-7338cb92] { background: white; border-radius: 8px; width: 90%; max-width: 500px; max-height: 90vh; overflow-y: auto; } .modal-header[data-v-7338cb92] { display: flex; justify-content: space-between; align-items: center; padding: 20px; border-bottom: 1px solid #eee; } .modal-header h3[data-v-7338cb92] { margin: 0; } .close-btn[data-v-7338cb92] { background: none; border: none; font-size: 24px; cursor: pointer; color: #999; } .modal-body[data-v-7338cb92] { padding: 20px; } .form-group[data-v-7338cb92] { margin-bottom: 20px; } .form-group label[data-v-7338cb92] { display: block; margin-bottom: 8px; font-weight: 500; color: #333; } .form-group input[data-v-7338cb92], .form-group select[data-v-7338cb92] { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; } .role-checkboxes[data-v-7338cb92] { display: flex; flex-direction: column; gap: 8px; } .checkbox-item[data-v-7338cb92] { display: flex; align-items: center; gap: 8px; cursor: pointer; } .checkbox-item input[type="checkbox"][data-v-7338cb92] { width: auto; } .form-actions[data-v-7338cb92] { display: flex; gap: 12px; justify-content: flex-end; margin-top: 30px; } .icon[data-v-7338cb92] { font-size: 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/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 _components_StatusBar_vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./components/StatusBar.vue */ "./src/renderer/components/StatusBar.vue"); /* 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 import */ var _utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils/themeManager.js */ "./src/renderer/utils/themeManager.js"); // 引入主题配置文件 // 引入主题管理器 /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'App', components: { StatusBar: _components_StatusBar_vue__WEBPACK_IMPORTED_MODULE_0__["default"] }, mounted() { // 确保主题管理器在应用启动时初始化 if (_utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__["default"]) { console.log('主题管理器已初始化') } }, mounted() { // 请求初始状态 window.electronAPI?.sendStatusRequest(); } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/components/LoginModal.vue?vue&type=script&lang=js": /*!***********************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../services/userService */ "./src/renderer/services/userService.js"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'LoginModal', props: { visible: { type: Boolean, default: false } }, data() { return { loading: false, captchaLoading: false, errorMessage: '', captchaImage: '', captchaId: '', 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.refreshCaptcha() } } }, methods: { async handleLogin() { if (!this.isFormValid) { this.errorMessage = '请填写完整的登录信息' return } this.loading = true this.errorMessage = '' try { // 调用登录接口 const response = await _services_userService__WEBPACK_IMPORTED_MODULE_0__.userService.login({ username: this.loginForm.username, password: this.loginForm.password, captcha: this.loginForm.captcha, captchaId: this.captchaId }) // 登录成功 this.$emit('login-success', response) this.closeModal() // 显示成功提示 this.$emit('show-message', { type: 'success', title: '登录成功', content: `欢迎回来,${response.user?.username || '用户'}!` }) } catch (error) { this.errorMessage = error.message || '登录失败,请重试' // 登录失败时刷新验证码 this.refreshCaptcha() } finally { this.loading = false } }, async refreshCaptcha() { try { this.captchaLoading = true this.errorMessage = '' // 调用获取验证码接口 const response = await _services_userService__WEBPACK_IMPORTED_MODULE_0__.userService.getCaptcha() this.captchaImage = response.captchaImage this.captchaId = response.captchaID this.loginForm.captcha = '' console.log('验证码获取成功:', response) } catch (error) { console.error('获取验证码失败:', error) this.errorMessage = '获取验证码失败,请重试' this.captchaImage = '' this.captchaId = '' } finally { this.captchaLoading = false } }, resetForm() { this.loginForm = { username: '', password: '', captcha: '' } this.errorMessage = '' this.captchaImage = '' this.captchaId = '' }, closeModal() { this.$emit('update:visible', false) this.resetForm() }, handleOverlayClick() { this.closeModal() } } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/components/MainLayout.vue?vue&type=script&lang=js": /*!***********************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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 vue_router__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vue-router */ "./node_modules/vue-router/dist/vue-router.mjs"); /* harmony import */ var _services_userService__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/services/userService */ "./src/renderer/services/userService.js"); /* harmony import */ var _utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../utils/themeManager.js */ "./src/renderer/utils/themeManager.js"); /* harmony import */ var _LoginModal_vue__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./LoginModal.vue */ "./src/renderer/components/LoginModal.vue"); /* harmony import */ var _Toast_vue__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./Toast.vue */ "./src/renderer/components/Toast.vue"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'MainLayout', components: { LoginModal: _LoginModal_vue__WEBPACK_IMPORTED_MODULE_4__["default"], Toast: _Toast_vue__WEBPACK_IMPORTED_MODULE_5__["default"] }, provide() { return { isLoggedIn: this.isLoggedIn, currentUser: this.currentUser, showLoginModal: this.showLoginModal } }, setup() { const router = (0,vue_router__WEBPACK_IMPORTED_MODULE_1__.useRouter)() const route = (0,vue_router__WEBPACK_IMPORTED_MODULE_1__.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 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)({ name: '', email: '', avatar: null }) // 登录状态 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 }) 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 mainMenuItems = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([ { id: 'home', name: '欢迎', path: '/', icon: '🏠', favorite: false }, { id: 'speed-test', name: '速度测试', path: '/speed-test', icon: '⚡', favorite: false }, { id: 'user-management', name: '用户管理', path: '/user-management', icon: '👥', favorite: false }, { id: 'history', name: '历史记录', path: '/history', icon: '📊', favorite: false }, { id: 'settings', name: '用户设置', path: '/settings', icon: '⚙️', favorite: false } ]) 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 === '/speed-test') return ['欢迎', '速度测试'] if (path === '/history') return ['欢迎', '历史记录'] if (path === '/settings') return ['欢迎', '用户设置'] return ['欢迎'] }) // 方法 const toggleMessagePanel = () => { showMessagePanel.value = !showMessagePanel.value showUserMenu.value = false } const toggleUserMenu = () => { showUserMenu.value = !showUserMenu.value showMessagePanel.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 = mainMenuItems.value.find(i => i.id === itemId) if (item) { item.favorite = !item.favorite updateFavoriteMenu() } } const updateFavoriteMenu = () => { favoriteMenuItems.value = mainMenuItems.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 openProfile = () => { showUserMenu.value = false // 跳转到个人资料页面 } 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 handleLoginSuccess = (response) => { // 更新用户信息 if (response.user) { currentUser.name = response.user.username || response.user.name currentUser.email = response.user.email currentUser.avatar = response.user.avatar } // 更新登录状态 isLoggedIn.value = true // 保存用户信息到本地存储 localStorage.setItem('user', JSON.stringify(currentUser)) localStorage.setItem('isLoggedIn', 'true') // 关闭登录弹窗 showLoginModalFlag.value = false // 显示欢迎消息 console.log(`欢迎回来,${currentUser.name}!`) } 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 } const logout = async () => { try { await _services_userService__WEBPACK_IMPORTED_MODULE_2__.userService.logout() // 清除用户信息 currentUser.name = '' currentUser.email = '' currentUser.avatar = null isLoggedIn.value = false // 清除本地存储 localStorage.removeItem('user') localStorage.removeItem('isLoggedIn') localStorage.removeItem('token') // 关闭用户菜单 showUserMenu.value = false // 跳转到首页 router.push('/') } catch (error) { console.error('退出登录失败:', error) } } // 监听路由变化 ;(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 !== _utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__["default"].getCurrentTheme()) { _utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__["default"].setTheme(parsedSettings.theme) } } catch (error) { console.error('解析用户应用设置失败:', error) } } }, { immediate: false }) const loadAppSettings = () => { try { const savedSettings = localStorage.getItem('gofaster-settings') if (savedSettings) { const parsedSettings = JSON.parse(savedSettings) if (parsedSettings.appName) { appSettings.appName = parsedSettings.appName // 初始加载时也更新窗口标题 if (window.electronAPI && window.electronAPI.updateWindowTitle) { window.electronAPI.updateWindowTitle(parsedSettings.appName) } } } } catch (error) { console.error('加载用户应用设置失败:', error) } } ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => { // 初始化收藏菜单 updateFavoriteMenu() // 检查登录状态 const savedIsLoggedIn = localStorage.getItem('isLoggedIn') const savedUser = localStorage.getItem('user') if (savedIsLoggedIn === 'true' && savedUser) { try { const userData = JSON.parse(savedUser) Object.assign(currentUser, userData) 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) { _utils_themeManager_js__WEBPACK_IMPORTED_MODULE_3__["default"].setTheme(settings.theme) } } catch (error) { console.warn('加载用户主题设置失败:', error) } } // 监听全局登录弹窗事件 window.addEventListener('show-login-modal', () => { showLoginModalFlag.value = true }) }) return { showMessagePanel, showUserMenu, showLoginModalFlag, showToast, currentTab, openTabs, currentUser, isLoggedIn, appSettings, toastConfig, messages, mainMenuItems, favoriteMenuItems, unreadCount, currentRoute, breadcrumbs, toggleMessagePanel, toggleUserMenu, showLoginModal, handleMenuClick, switchTab, closeTab, closeAllTabs, toggleFavorite, markAsRead, formatTime, openProfile, openSettings, logout, handleLoginSuccess, handleShowMessage, loadAppSettings, handleAddTab, addTabIfNotExists } } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/components/StatusBar.vue?vue&type=script&lang=js": /*!**********************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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 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 default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'StatusBar', setup() { const serverUrl = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)((0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_1__.getFinalConfig)().serverUrl); const userInfo = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('未登录'); const errorCount = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0); const appVersion = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(({"NODE_ENV":"development","BASE_URL":""}).VUE_APP_VERSION || '1.0.0'); const memoryUsage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0); const systemMemoryUsage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('N/A'); // 更新内存使用情况 - 使用更准确的方法 let intervalId; (0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => { // 获取初始错误日志计数 getInitialErrorCount(); intervalId = setInterval(() => { updateMemoryUsage(); }, 3000); // 每3秒更新一次 }); (0,vue__WEBPACK_IMPORTED_MODULE_0__.onUnmounted)(() => { if (intervalId) { clearInterval(intervalId); } }); // 更新内存使用情况 const updateMemoryUsage = async () => { try { // 使用 Electron 的 IPC 获取进程内存信息 if (window.electronAPI && window.electronAPI.getProcessMemoryInfo) { const memoryInfo = await window.electronAPI.getProcessMemoryInfo(); if (memoryInfo && memoryInfo.privateBytes) { // privateBytes 是进程的私有内存使用量(字节) memoryUsage.value = (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); systemMemoryUsage.value = `${usedGB}/${totalGB} GB (${usedPercent}%)`; } } else { // 回退到浏览器API fallbackMemoryUsage(); } } catch (error) { console.warn('无法获取内存使用情况:', error); fallbackMemoryUsage(); } }; // 回退的内存获取方法 const fallbackMemoryUsage = () => { if (window.performance && window.performance.memory) { const memory = window.performance.memory; // 使用 usedJSHeapSize 作为JavaScript堆内存使用量 memoryUsage.value = (memory.usedJSHeapSize / (1024 * 1024)).toFixed(1); systemMemoryUsage.value = 'N/A (浏览器模式)'; } else { memoryUsage.value = 'N/A'; systemMemoryUsage.value = 'N/A'; } }; // 获取初始错误日志计数 const getInitialErrorCount = async () => { try { if (window.electronAPI && window.electronAPI.getErrorLogCount) { const result = await window.electronAPI.getErrorLogCount(); errorCount.value = result.count || 0; } } catch (error) { console.warn('无法获取初始错误日志计数:', error); } }; // 监听主进程消息 window.electronAPI?.onStatusUpdate((event, data) => { if (data.userInfo) userInfo.value = data.userInfo; if (data.errorCount !== undefined) errorCount.value = data.errorCount; }); // 监听错误日志更新 window.electronAPI?.onErrorLogUpdated((event, data) => { if (data.count !== undefined) { errorCount.value = data.count; } }); // 监听设置变化,更新服务地址 const updateServerUrl = () => { const config = (0,_config_app_config_js__WEBPACK_IMPORTED_MODULE_1__.getFinalConfig)(); serverUrl.value = config.serverUrl; }; // 监听localStorage变化 window.addEventListener('storage', updateServerUrl); // 监听自定义事件(当设置页面保存配置时触发) window.addEventListener('gofaster-settings-changed', updateServerUrl); // 打开日志文件夹 const openLogFolder = async () => { 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); } }; return { serverUrl, userInfo, errorCount, appVersion, memoryUsage, systemMemoryUsage, openLogFolder }; } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/components/Toast.vue?vue&type=script&lang=js": /*!******************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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: { icon() { const icons = { success: '✅', error: '❌', warning: '⚠️', info: 'ℹ️' } 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/views/History.vue?vue&type=script&lang=js": /*!***************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/views/History.vue?vue&type=script&lang=js ***! \***************************************************************************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": () => (__WEBPACK_DEFAULT_EXPORT__) /* harmony export */ }); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js"); /* harmony import */ var vuex__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! vuex */ "./node_modules/vuex/dist/vuex.esm-bundler.js"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'HistoryView', setup() { const store = (0,vuex__WEBPACK_IMPORTED_MODULE_1__.useStore)() ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => { store.dispatch('loadTestResults') }) const testResults = (0,vue__WEBPACK_IMPORTED_MODULE_0__.computed)(() => store.state.testResults) const formatDate = (timestamp) => { return new Date(timestamp).toLocaleString() } return { testResults, formatDate } } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/views/Home.vue?vue&type=script&lang=js": /*!************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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: '👤' }, currentDate: '', stats: { totalTests: 0, avgSpeed: '0 Mbps', bestSpeed: '0 Mbps' }, todoList: [ { id: 1, text: '完成网络速度测试', completed: false, date: '今天' }, { id: 2, text: '查看历史测试记录', completed: true, date: '昨天' }, { id: 3, text: '配置测试参数', completed: false, date: '明天' } ], recentActivities: [ { id: 1, icon: '⚡', title: '完成速度测试', time: '2小时前' }, { id: 2, icon: '📊', title: '查看测试报告', time: '昨天' }, { id: 3, icon: '⚙️', title: '更新设置', time: '3天前' } ], db: null // 新增:用于存储数据库实例 } }, methods: { updateCurrentDate() { const now = new Date(); const options = { year: 'numeric', month: 'long', day: 'numeric', weekday: 'long' }; this.currentDate = now.toLocaleDateString('zh-CN', options); }, async loadUserData() { try { // 从数据库加载用户数据 if (this.db && this.db.data && this.db.data.userInfo) { this.userInfo = this.db.data.userInfo; } } catch (error) { console.error('加载用户数据失败:', error); } }, async loadStats() { try { // 从数据库加载统计数据 if (this.db && this.db.data && this.db.data.stats) { this.stats = this.db.data.stats; } } catch (error) { console.error('加载统计数据失败:', error); } }, async loadTodoList() { try { // 从数据库加载待办事项 if (this.db && this.db.data && this.db.data.todoList) { this.todoList = this.db.data.todoList; } } catch (error) { console.error('加载待办事项失败:', error); } }, async loadRecentActivities() { try { // 从数据库加载最近活动 if (this.db && this.db.data && this.db.data.recentActivities) { this.recentActivities = this.db.data.recentActivities; } } catch (error) { console.error('加载最近活动失败:', error); } }, startSpeedTest() { this.$router.push('/speed-test'); }, viewHistory() { this.$router.push('/history'); }, openSettings() { console.log('打开用户设置'); // 通过事件通知父组件添加标签页 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/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('isLoggedIn', (newVal) => { if (newVal && this.currentUser) { this.userInfo.name = this.currentUser.name || this.userInfo.name; this.userInfo.email = this.currentUser.email || this.userInfo.email; } }, { immediate: true }); } }); /***/ }), /***/ "./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/views/UserManagement.vue?vue&type=script&lang=js": /*!**********************************************************************************************************************************!*\ !*** ./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/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__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/services/userService */ "./src/renderer/services/userService.js"); /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = ({ name: 'UserManagement', setup() { const users = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const roles = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)([]) const loading = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const currentPage = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(1) const pageSize = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(10) const total = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(0) const searchQuery = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('') const statusFilter = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('') const roleFilter = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)('') const showAddUserModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const showEditUserModal = (0,vue__WEBPACK_IMPORTED_MODULE_0__.ref)(false) const editingUser = (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)) } 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__WEBPACK_IMPORTED_MODULE_1__.userService.getUsers(currentPage.value, pageSize.value) users.value = response.data total.value = response.total } catch (error) { console.error('加载用户失败:', error) } finally { loading.value = false } } const loadRoles = async () => { try { const response = await _services_userService__WEBPACK_IMPORTED_MODULE_1__.userService.getRoles() roles.value = response.data } catch (error) { console.error('加载角色失败:', error) } } const handleSearch = () => { currentPage.value = 1 } const handleFilter = () => { currentPage.value = 1 } const changePage = (page) => { currentPage.value = page loadUsers() } const editUser = (user) => { editingUser.value = user Object.assign(userForm, { username: user.username, password: '', email: user.email, phone: user.phone, status: user.status, roleIds: user.roles.map(role => role.id) }) showEditUserModal.value = true } const submitUser = async () => { try { if (showEditUserModal.value) { await _services_userService__WEBPACK_IMPORTED_MODULE_1__.userService.updateUser(editingUser.value.id, userForm) } else { await _services_userService__WEBPACK_IMPORTED_MODULE_1__.userService.createUser(userForm) } closeModal() loadUsers() } catch (error) { console.error('保存用户失败:', error) } } const deleteUser = async (userId) => { if (confirm('确定要删除这个用户吗?')) { try { await _services_userService__WEBPACK_IMPORTED_MODULE_1__.userService.deleteUser(userId) loadUsers() } catch (error) { console.error('删除用户失败:', error) } } } const closeModal = () => { showAddUserModal.value = false showEditUserModal.value = false editingUser.value = null Object.assign(userForm, { username: '', password: '', email: '', phone: '', status: 1, roleIds: [] }) } const formatDate = (dateString) => { if (!dateString) return '' return new Date(dateString).toLocaleDateString('zh-CN') } ;(0,vue__WEBPACK_IMPORTED_MODULE_0__.onMounted)(() => { loadUsers() loadRoles() }) return { users, roles, loading, currentPage, pageSize, total, searchQuery, statusFilter, roleFilter, showAddUserModal, showEditUserModal, editingUser, userForm, totalPages, filteredUsers, loadUsers, loadRoles, handleSearch, handleFilter, changePage, editUser, submitUser, deleteUser, closeModal, formatDate } } }); /***/ }), /***/ "./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/components/LoginModal.vue?vue&type=template&id=443b36ca&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/components/LoginModal.vue?vue&type=template&id=443b36ca&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: "login-modal-header" } const _hoisted_2 = { class: "login-modal-body" } const _hoisted_3 = { class: "form-group" } const _hoisted_4 = ["disabled"] const _hoisted_5 = { class: "form-group" } const _hoisted_6 = ["disabled"] const _hoisted_7 = { class: "form-group" } const _hoisted_8 = { class: "captcha-container" } const _hoisted_9 = ["disabled"] const _hoisted_10 = { class: "captcha-image-container" } const _hoisted_11 = ["src"] const _hoisted_12 = { key: 0 } const _hoisted_13 = { key: 1 } const _hoisted_14 = { key: 2, class: "captcha-loading-spinner" } const _hoisted_15 = { class: "form-actions" } const _hoisted_16 = ["disabled"] const _hoisted_17 = { key: 0, class: "loading-spinner" } const _hoisted_18 = { key: 0, class: "form-validation-hint" } const _hoisted_19 = { key: 0 } const _hoisted_20 = { key: 1 } const _hoisted_21 = { key: 2 } const _hoisted_22 = { key: 3 } const _hoisted_23 = { key: 0, class: "error-message" } 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: "login-modal-overlay", onClick: _cache[8] || (_cache[8] = (...args) => ($options.handleOverlayClick && $options.handleOverlayClick(...args))) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "login-modal", onClick: _cache[7] || (_cache[7] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_1, [ _cache[9] || (_cache[9] = (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))) }, "×") ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", { onSubmit: _cache[6] || (_cache[6] = (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_3, [ _cache[10] || (_cache[10] = (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_4), [ [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_5, [ _cache[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", { for: "password" }, "密码", -1 /* CACHED */)), (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: "password", placeholder: "请输入密码", required: "", disabled: $data.loading }, null, 8 /* PROPS */, _hoisted_6), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.loginForm.password] ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 验证码 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [ _cache[12] || (_cache[12] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", { for: "captcha" }, "验证码", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { id: "captcha", "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($data.loginForm.captcha) = $event)), type: "text", placeholder: "请输入验证码", required: "", disabled: $data.loading, maxlength: "4" }, null, 8 /* PROPS */, _hoisted_9), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $data.loginForm.captcha] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_10, [ ($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[4] || (_cache[4] = (...args) => ($options.refreshCaptcha && $options.refreshCaptcha(...args))), class: "captcha-image" }, null, 8 /* PROPS */, _hoisted_11)) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", { key: 1, class: "captcha-placeholder", onClick: _cache[5] || (_cache[5] = (...args) => ($options.refreshCaptcha && $options.refreshCaptcha(...args))) }, [ ($data.captchaLoading) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_12, "验证码加载中...")) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_13, "点击获取验证码")), ($data.captchaLoading) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_14)) : (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_15, [ (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_17)) : (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_16), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 表单验证提示 "), (!$options.isFormValid && ($data.loginForm.username || $data.loginForm.password || $data.loginForm.captcha)) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_18, [ (!$data.loginForm.username.trim()) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_19, "请填写用户名")) : (!$data.loginForm.password.trim()) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_20, "请填写密码")) : (!$data.loginForm.captcha.trim()) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_21, "请填写验证码")) : (!$data.captchaImage) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", _hoisted_22, "请先获取验证码")) : (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)(" 错误提示 "), ($data.errorMessage) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_23, (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[13] || (_cache[13] = (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, "默认管理员账号:sysadmin"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", null, "默认密码:sysadmin@123") ]) ], -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/components/MainLayout.vue?vue&type=template&id=a4b9ee6e&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/components/MainLayout.vue?vue&type=template&id=a4b9ee6e&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 = { class: "user-menu-items" } const _hoisted_29 = { class: "main-content" } const _hoisted_30 = { class: "sidebar" } const _hoisted_31 = { class: "sidebar-nav" } const _hoisted_32 = { class: "nav-section" } const _hoisted_33 = { class: "nav-list" } const _hoisted_34 = { class: "nav-icon" } const _hoisted_35 = { class: "nav-text" } const _hoisted_36 = ["onClick"] const _hoisted_37 = { class: "nav-section" } const _hoisted_38 = { class: "nav-list" } const _hoisted_39 = { class: "nav-icon" } 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_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, "🚀 " + (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[10] || (_cache[10] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "📢", -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[11] || (_cache[11] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "消息", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "close-btn", onClick: _cache[1] || (_cache[1] = $event => ($setup.showMessagePanel = false)) }, "×") ]), (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)) }, " ✓ ", 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[12] || (_cache[12] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🔐", -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 */) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_28, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "menu-item", onClick: _cache[4] || (_cache[4] = (...args) => ($setup.openProfile && $setup.openProfile(...args))) }, _cache[13] || (_cache[13] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "👤", -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[14] || (_cache[14] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "⚙️", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 用户设置 ", -1 /* CACHED */) ])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "menu-item", onClick: _cache[6] || (_cache[6] = (...args) => ($setup.logout && $setup.logout(...args))) }, _cache[15] || (_cache[15] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🚪", -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_29, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 左侧菜单 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("aside", _hoisted_30, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("nav", _hoisted_31, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_32, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("ul", _hoisted_33, [ ((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", _hoisted_34, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.icon), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_35, (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"]) }, " ⭐ ", 8 /* PROPS */, _hoisted_36)) : (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_37, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("ul", _hoisted_38, [ ((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", _hoisted_39, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(item.icon), 1 /* TEXT */), (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"]) }, " ⭐ ", 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: "关闭标签页" }, " × ", 8 /* PROPS */, _hoisted_47)) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ], 10 /* CLASS, PROPS */, _hoisted_45)) }), 128 /* KEYED_FRAGMENT */)) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_48, [ ($setup.openTabs.length > 1) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("button", { key: 0, class: "close-all-btn", onClick: _cache[7] || (_cache[7] = (...args) => ($setup.closeAllTabs && $setup.closeAllTabs(...args))), title: "关闭所有标签页" }, _cache[16] || (_cache[16] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", { class: "close-all-icon" }, "⊗", -1 /* CACHED */) ]))) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 功能内容区 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_49, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_router_view, { onAddTab: $setup.handleAddTab }, null, 8 /* PROPS */, ["onAddTab"]) ]) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 登录弹窗 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_LoginModal, { visible: $setup.showLoginModalFlag, "onUpdate:visible": _cache[8] || (_cache[8] = $event => (($setup.showLoginModalFlag) = $event)), onLoginSuccess: $setup.handleLoginSuccess, onShowMessage: $setup.handleShowMessage }, null, 8 /* PROPS */, ["visible", "onLoginSuccess", "onShowMessage"]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" Toast 消息提示 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createVNode)(_component_Toast, { visible: $setup.showToast, "onUpdate:visible": _cache[9] || (_cache[9] = $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/components/StatusBar.vue?vue&type=template&id=126429ab&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/components/StatusBar.vue?vue&type=template&id=126429ab&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)($setup.userInfo), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, "版本: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.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)($setup.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) => ($setup.openLogFolder && $setup.openLogFolder(...args))), title: "点击打开日志文件夹" }, " 最近错误: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.errorCount), 1 /* TEXT */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, "内存: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.memoryUsage) + " MB", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, "系统内存: " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.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/components/Toast.vue?vue&type=template&id=4eeeff11&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/components/Toast.vue?vue&type=template&id=4eeeff11&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__.toDisplayString)($options.icon), 1 /* TEXT */), (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))) }, "×") ], 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/views/History.vue?vue&type=template&id=5347d120&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/views/History.vue?vue&type=template&id=5347d120&scoped=true ***! \*******************************************************************************************************************************************************************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ render: () => (/* binding */ render) /* harmony export */ }); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js"); const _hoisted_1 = { class: "history-view" } const _hoisted_2 = { key: 0, class: "empty-state" } const _hoisted_3 = { key: 1, class: "history-list" } const _hoisted_4 = { class: "history-date" } const _hoisted_5 = { class: "history-stats" } const _hoisted_6 = { class: "stat download" } const _hoisted_7 = { class: "stat upload" } const _hoisted_8 = { class: "stat ping" } function render(_ctx, _cache, $props, $setup, $data, $options) { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [ _cache[0] || (_cache[0] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h1", null, "Test History", -1 /* CACHED */)), ($setup.testResults.length === 0) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_2, " No speed tests recorded yet. ")) : ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_3, [ ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.testResults, (result, index) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", { key: index, class: "history-item" }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate(result.timestamp)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_6, "↓ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.download) + " Mbps", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_7, "↑ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.upload) + " Mbps", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_8, "↔ " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(result.ping) + " ms", 1 /* TEXT */) ]) ])) }), 128 /* KEYED_FRAGMENT */)) ])) ])) } /***/ }), /***/ "./node_modules/vue-loader/dist/templateLoader.js??ruleSet[1].rules[2]!./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/renderer/views/Home.vue?vue&type=template&id=ecd3befa&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/views/Home.vue?vue&type=template&id=ecd3befa&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: "login-section" } const _hoisted_12 = { key: 0, class: "features-section" } const _hoisted_13 = { class: "login-prompt-section" } const _hoisted_14 = { class: "login-prompt-card" } const _hoisted_15 = { key: 2, class: "todo-section" } const _hoisted_16 = { class: "section-header" } const _hoisted_17 = { class: "todo-list" } const _hoisted_18 = ["checked", "onChange"] const _hoisted_19 = { class: "todo-text" } const _hoisted_20 = { class: "todo-date" } const _hoisted_21 = ["onClick"] const _hoisted_22 = { key: 3, class: "recent-section" } const _hoisted_23 = { class: "activity-list" } const _hoisted_24 = { class: "activity-icon" } const _hoisted_25 = { class: "activity-content" } const _hoisted_26 = { class: "activity-title" } const _hoisted_27 = { 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, "登录后享受更多功能")) ]), (!$options.isLoggedIn) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_11, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "login-btn", onClick: _cache[0] || (_cache[0] = (...args) => ($options.showLoginModalHandler && $options.showLoginModalHandler(...args))) }, _cache[7] || (_cache[7] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🔐", -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)(" 功能卡片区域 "), ($options.isLoggedIn) ? ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("section", _hoisted_12, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-card", onClick: _cache[1] || (_cache[1] = (...args) => ($options.startSpeedTest && $options.startSpeedTest(...args))) }, _cache[8] || (_cache[8] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, "⚡", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "开始速度测试", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "测试您的网络连接速度", -1 /* CACHED */) ])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-card", onClick: _cache[2] || (_cache[2] = (...args) => ($options.viewHistory && $options.viewHistory(...args))) }, _cache[9] || (_cache[9] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, "📊", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "查看历史", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("p", null, "查看历史测试记录", -1 /* CACHED */) ])), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-card", onClick: _cache[3] || (_cache[3] = (...args) => ($options.openSettings && $options.openSettings(...args))) }, _cache[10] || (_cache[10] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, "⚙️", -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[4] || (_cache[4] = (...args) => ($options.exportData && $options.exportData(...args))) }, _cache[11] || (_cache[11] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "feature-icon" }, "📤", -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_13, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_14, [ _cache[13] || (_cache[13] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "prompt-icon" }, "🔒", -1 /* CACHED */)), _cache[14] || (_cache[14] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "需要登录", -1 /* CACHED */)), _cache[15] || (_cache[15] = (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[5] || (_cache[5] = (...args) => ($options.showLoginModalHandler && $options.showLoginModalHandler(...args))) }, _cache[12] || (_cache[12] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🔐", -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_15, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [ _cache[16] || (_cache[16] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, "📝 待办事项", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "add-todo-btn", onClick: _cache[6] || (_cache[6] = (...args) => ($options.addTodo && $options.addTodo(...args))) }, "+ 添加") ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [ ((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_18), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_19, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(todo.text), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_20, (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)) }, "🗑️", 8 /* PROPS */, _hoisted_21) ], 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_22, [ _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", 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)($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_24, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(activity.icon), 1 /* TEXT */), (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)(activity.title), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_27, (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/views/UserManagement.vue?vue&type=template&id=7338cb92&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/views/UserManagement.vue?vue&type=template&id=7338cb92&scoped=true ***! \**************************************************************************************************************************************************************************************************************************/ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ render: () => (/* binding */ render) /* harmony export */ }); /* harmony import */ var vue__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! vue */ "./node_modules/vue/dist/vue.runtime.esm-bundler.js"); const _hoisted_1 = { class: "user-management" } const _hoisted_2 = { class: "page-header" } const _hoisted_3 = { class: "search-bar" } const _hoisted_4 = { class: "search-input" } const _hoisted_5 = { class: "filters" } const _hoisted_6 = ["value"] const _hoisted_7 = { class: "user-table" } const _hoisted_8 = { class: "role-tags" } const _hoisted_9 = { class: "actions" } const _hoisted_10 = ["onClick"] const _hoisted_11 = ["onClick"] const _hoisted_12 = { class: "pagination" } const _hoisted_13 = ["disabled"] const _hoisted_14 = { class: "page-info" } const _hoisted_15 = ["disabled"] const _hoisted_16 = { class: "modal-header" } const _hoisted_17 = { class: "modal-body" } const _hoisted_18 = { class: "form-group" } const _hoisted_19 = ["disabled"] const _hoisted_20 = { key: 0, class: "form-group" } const _hoisted_21 = { class: "form-group" } const _hoisted_22 = { class: "form-group" } const _hoisted_23 = { class: "form-group" } const _hoisted_24 = { class: "form-group" } const _hoisted_25 = { class: "role-checkboxes" } const _hoisted_26 = ["value"] const _hoisted_27 = { class: "form-actions" } const _hoisted_28 = { type: "submit", class: "btn btn-primary" } function render(_ctx, _cache, $props, $setup, $data, $options) { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("div", _hoisted_1, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_2, [ _cache[21] || (_cache[21] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h2", null, "用户管理", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-primary", onClick: _cache[0] || (_cache[0] = $event => ($setup.showAddUserModal = true)) }, _cache[20] || (_cache[20] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "+", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" 添加用户 ", -1 /* CACHED */) ])) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 搜索和筛选 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_3, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_4, [ _cache[22] || (_cache[22] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🔍", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (($setup.searchQuery) = $event)), type: "text", placeholder: "搜索用户名、邮箱或手机号...", onInput: _cache[2] || (_cache[2] = (...args) => ($setup.handleSearch && $setup.handleSearch(...args))) }, null, 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.searchQuery] ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_5, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", { "onUpdate:modelValue": _cache[3] || (_cache[3] = $event => (($setup.statusFilter) = $event)), onChange: _cache[4] || (_cache[4] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args))) }, _cache[23] || (_cache[23] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "" }, "全部状态", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "1" }, "正常", -1 /* CACHED */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "2" }, "禁用", -1 /* CACHED */) ]), 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.statusFilter] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", { "onUpdate:modelValue": _cache[5] || (_cache[5] = $event => (($setup.roleFilter) = $event)), onChange: _cache[6] || (_cache[6] = (...args) => ($setup.handleFilter && $setup.handleFilter(...args))) }, [ _cache[24] || (_cache[24] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("option", { value: "" }, "全部角色", -1 /* CACHED */)), ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.roles, (role) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("option", { key: role.id, value: role.id }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 9 /* TEXT, PROPS */, _hoisted_6)) }), 128 /* KEYED_FRAGMENT */)) ], 544 /* NEED_HYDRATION, NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelSelect, $setup.roleFilter] ]) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)(" 用户列表 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_7, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("table", null, [ _cache[27] || (_cache[27] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("thead", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tr", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "ID"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "用户名"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "邮箱"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "手机号"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "状态"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "角色"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "创建时间"), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("th", null, "操作") ]) ], -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("tbody", null, [ ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)($setup.filteredUsers, (user) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("tr", { key: user.id }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.id), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.username), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.email), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.phone), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", { class: (0,vue__WEBPACK_IMPORTED_MODULE_0__.normalizeClass)(['status-badge', user.status === 1 ? 'active' : 'inactive']) }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(user.status === 1 ? '正常' : '禁用'), 3 /* TEXT, CLASS */) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_8, [ ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)(vue__WEBPACK_IMPORTED_MODULE_0__.Fragment, null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.renderList)(user.roles, (role) => { return ((0,vue__WEBPACK_IMPORTED_MODULE_0__.openBlock)(), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementBlock)("span", { key: role.id, class: "role-tag" }, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */)) }), 128 /* KEYED_FRAGMENT */)) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.formatDate(user.created_at)), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("td", null, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_9, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "btn btn-sm btn-info", onClick: $event => ($setup.editUser(user)) }, [...(_cache[25] || (_cache[25] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "✏️", -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[26] || (_cache[26] = [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("i", { class: "icon" }, "🗑️", -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__.createElementVNode)("button", { disabled: $setup.currentPage === 1, onClick: _cache[7] || (_cache[7] = $event => ($setup.changePage($setup.currentPage - 1))), class: "btn btn-sm" }, " 上一页 ", 8 /* PROPS */, _hoisted_13), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("span", _hoisted_14, " 第 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.currentPage) + " 页,共 " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.totalPages) + " 页 ", 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { disabled: $setup.currentPage === $setup.totalPages, onClick: _cache[8] || (_cache[8] = $event => ($setup.changePage($setup.currentPage + 1))), class: "btn btn-sm" }, " 下一页 ", 8 /* PROPS */, _hoisted_15) ]), (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[19] || (_cache[19] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", { class: "modal", onClick: _cache[18] || (_cache[18] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)(() => {}, ["stop"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_16, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("h3", null, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.showEditUserModal ? '编辑用户' : '添加用户'), 1 /* TEXT */), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { class: "close-btn", onClick: _cache[9] || (_cache[9] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, "×") ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_17, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("form", { onSubmit: _cache[17] || (_cache[17] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.withModifiers)((...args) => ($setup.submitUser && $setup.submitUser(...args)), ["prevent"])) }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_18, [ _cache[28] || (_cache[28] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "用户名 *", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { "onUpdate:modelValue": _cache[10] || (_cache[10] = $event => (($setup.userForm.username) = $event)), type: "text", required: "", disabled: $setup.showEditUserModal }, null, 8 /* PROPS */, _hoisted_19), [ [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_20, [ _cache[29] || (_cache[29] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "密码 *", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { "onUpdate:modelValue": _cache[11] || (_cache[11] = $event => (($setup.userForm.password) = $event)), type: "password", required: "" }, null, 512 /* NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.password] ]) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_21, [ _cache[30] || (_cache[30] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "邮箱 *", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { "onUpdate:modelValue": _cache[12] || (_cache[12] = $event => (($setup.userForm.email) = $event)), type: "email", required: "" }, null, 512 /* NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.email] ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_22, [ _cache[31] || (_cache[31] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "手机号", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { "onUpdate:modelValue": _cache[13] || (_cache[13] = $event => (($setup.userForm.phone) = $event)), type: "tel" }, null, 512 /* NEED_PATCH */), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelText, $setup.userForm.phone] ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_23, [ _cache[33] || (_cache[33] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "状态", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("select", { "onUpdate:modelValue": _cache[14] || (_cache[14] = $event => (($setup.userForm.status) = $event)) }, _cache[32] || (_cache[32] = [ (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_24, [ _cache[34] || (_cache[34] = (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("label", null, "角色", -1 /* CACHED */)), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_25, [ ((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)("label", { key: role.id, class: "checkbox-item" }, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.withDirectives)((0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("input", { type: "checkbox", value: role.id, "onUpdate:modelValue": _cache[15] || (_cache[15] = $event => (($setup.userForm.roleIds) = $event)) }, null, 8 /* PROPS */, _hoisted_26), [ [vue__WEBPACK_IMPORTED_MODULE_0__.vModelCheckbox, $setup.userForm.roleIds] ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createTextVNode)(" " + (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)(role.name), 1 /* TEXT */) ])) }), 128 /* KEYED_FRAGMENT */)) ]) ]), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("div", _hoisted_27, [ (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", { type: "button", class: "btn btn-secondary", onClick: _cache[16] || (_cache[16] = (...args) => ($setup.closeModal && $setup.closeModal(...args))) }, " 取消 "), (0,vue__WEBPACK_IMPORTED_MODULE_0__.createElementVNode)("button", _hoisted_28, (0,vue__WEBPACK_IMPORTED_MODULE_0__.toDisplayString)($setup.showEditUserModal ? '更新' : '创建'), 1 /* TEXT */) ]) ], 32 /* NEED_HYDRATION */) ]) ]) ])) : (0,vue__WEBPACK_IMPORTED_MODULE_0__.createCommentVNode)("v-if", true) ])) } /***/ }), /***/ "./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