From d50fa3d633ec013b91dd5f9f16302c6d723ff214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=85=AC=E6=98=8E?= <83812544+Ed1s0nZ@users.noreply.github.com> Date: Sat, 17 Jan 2026 00:07:26 +0800 Subject: [PATCH] Add files via upload --- web/static/css/style.css | 338 ++++++++++++++++++++++++++++++++++++++- web/static/js/roles.js | 150 +++++++++++------ web/static/js/router.js | 18 +++ web/static/js/skills.js | 89 ++++++----- web/templates/index.html | 42 +++-- 5 files changed, 521 insertions(+), 116 deletions(-) diff --git a/web/static/css/style.css b/web/static/css/style.css index 556eb300..8e84ec82 100644 --- a/web/static/css/style.css +++ b/web/static/css/style.css @@ -3363,7 +3363,7 @@ header { } .pagination-fixed .pagination-info .pagination-page-size select { - padding: 4px 8px; + padding: 4px 24px 4px 8px; border-radius: 6px; border: 1px solid var(--border-color); background: var(--bg-primary); @@ -3371,12 +3371,25 @@ header { font-size: 0.8125rem; cursor: pointer; transition: all 0.2s ease; + width: auto; min-width: 60px; + max-width: 80px; font-weight: 500; /* 更柔和的边框 */ border-color: rgba(233, 236, 239, 0.8); /* 确保四个角都是圆角 */ border-radius: 8px !important; + /* 确保下拉框不被拉伸 */ + flex-shrink: 0; + box-sizing: border-box; + /* 确保下拉箭头正确显示 */ + appearance: none; + -webkit-appearance: none; + -moz-appearance: none; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23666' d='M6 9L1 4h10z'/%3E%3C/svg%3E"); + background-repeat: no-repeat; + background-position: right 8px center; + background-size: 12px; } .pagination-fixed .pagination-info .pagination-page-size select:focus { @@ -8600,6 +8613,159 @@ header { gap: 12px; } +/* 角色搜索框样式 */ +.roles-search-box { + position: relative; + margin-bottom: 20px; +} + +.roles-search-box input { + width: 100%; + padding: 10px 40px 10px 16px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: var(--bg-primary); + color: var(--text-primary); + font-size: 0.9375rem; + transition: all 0.2s; +} + +.roles-search-box input:focus { + outline: none; + border-color: var(--accent-color); + box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.1); +} + +.roles-search-clear { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + color: var(--text-secondary); + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; +} + +.roles-search-clear:hover { + color: var(--text-primary); +} + +/* 角色卡片网格布局 */ +.roles-grid { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); + gap: 20px; + padding: 0; +} + +/* 角色卡片样式 */ +.role-card { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 20px; + display: flex; + flex-direction: column; + gap: 12px; + transition: all 0.2s; + cursor: default; +} + +.role-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + border-color: var(--accent-color); + transform: translateY(-2px); +} + +.role-card-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 12px; +} + +.role-card-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--text-primary); + margin: 0; + flex: 1; + line-height: 1.4; + display: flex; + align-items: center; + gap: 8px; +} + +.role-card-icon { + font-size: 1.25rem; + line-height: 1; + flex-shrink: 0; +} + +.role-card-badge { + padding: 4px 10px; + border-radius: 12px; + font-size: 0.75rem; + font-weight: 600; + white-space: nowrap; + flex-shrink: 0; +} + +.role-card-badge.enabled { + background: rgba(40, 167, 69, 0.12); + color: var(--success-color); +} + +.role-card-badge.disabled { + background: rgba(220, 53, 69, 0.12); + color: var(--error-color); +} + +.role-card-description { + font-size: 0.875rem; + color: var(--text-secondary); + line-height: 1.5; + flex: 1; + min-height: 40px; +} + +.role-card-tools { + display: flex; + gap: 8px; + font-size: 0.8125rem; + color: var(--text-secondary); + padding-top: 8px; + border-top: 1px solid var(--border-color); +} + +.role-card-tools-label { + font-weight: 500; + white-space: nowrap; +} + +.role-card-tools-value { + color: var(--text-primary); + flex: 1; + word-break: break-word; +} + +.role-card-actions { + display: flex; + gap: 8px; + margin-top: 4px; +} + +.btn-small { + padding: 6px 12px; + font-size: 0.8125rem; +} + .role-item { display: flex; justify-content: space-between; @@ -9251,7 +9417,7 @@ header { /* Skills管理页面样式 */ .skills-controls { - margin-bottom: 16px; + margin-bottom: 8px; } .skills-stats-bar { @@ -9305,6 +9471,174 @@ header { margin-bottom: 16px; } +/* 技能搜索框样式 */ +.skills-search-box { + position: relative; + margin-bottom: 12px; +} + +.skills-search-box input { + width: 100%; + padding: 8px 40px 8px 16px; + border: 1px solid var(--border-color); + border-radius: 8px; + background: var(--bg-primary); + color: var(--text-primary); + font-size: 0.9375rem; + transition: all 0.2s; +} + +.skills-search-box input:focus { + outline: none; + border-color: var(--accent-color); + box-shadow: 0 0 0 3px rgba(0, 102, 255, 0.1); +} + +.skills-search-clear { + position: absolute; + right: 12px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + color: var(--text-secondary); + padding: 4px; + display: flex; + align-items: center; + justify-content: center; + transition: color 0.2s; +} + +.skills-search-clear:hover { + color: var(--text-primary); +} + +/* 技能卡片网格布局 */ +.skills-grid { + display: grid; + /* 优化网格布局:使用 auto-fit 让卡片更好地分布,减少最小宽度以容纳更多列 */ + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 16px; + padding: 0; + /* 确保列表可以滚动,不会把分页栏推出视口 */ + flex: 1; + overflow-y: auto; + overflow-x: hidden; + min-height: 0; + /* 统一同一行卡片的高度 */ + align-items: stretch; + /* 让卡片在容器中更好地分布,避免都聚集在左侧 */ + justify-items: stretch; +} + +/* 技能卡片样式 */ +.skill-card { + background: var(--bg-primary); + border: 1px solid var(--border-color); + border-radius: 12px; + padding: 16px; + display: flex; + flex-direction: column; + gap: 10px; + transition: all 0.2s; + cursor: default; + /* 统一卡片高度:让卡片填满网格单元格高度 */ + align-items: stretch; + height: 100%; + /* 确保卡片宽度填满网格单元格 */ + width: 100%; + box-sizing: border-box; +} + +.skill-card:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1); + border-color: var(--accent-color); + transform: translateY(-2px); +} + +.skill-card-header { + display: flex; + justify-content: space-between; + align-items: flex-start; + gap: 12px; +} + +.skill-card-title { + font-size: 1.125rem; + font-weight: 600; + color: var(--text-primary); + margin: 0; + /* 移除 flex: 1,让标题只占据实际需要的高度 */ + line-height: 1.4; + word-break: break-word; + overflow-wrap: break-word; + /* 限制标题最多显示2行 */ + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.skill-card-description { + font-size: 0.875rem; + color: var(--text-secondary); + line-height: 1.6; + /* 让描述区域占据剩余空间,统一卡片高度 */ + flex: 1; + min-height: 48px; + /* 优化文字排版 */ + word-break: break-word; + overflow-wrap: break-word; + /* 限制描述的最大行数,保持卡片整洁 */ + display: -webkit-box; + -webkit-line-clamp: 3; + -webkit-box-orient: vertical; + overflow: hidden; +} + +.skill-card-actions { + display: flex; + gap: 8px; + margin-top: auto; + /* 使用 margin-top: auto 将按钮推到底部,统一卡片布局 */ + flex-shrink: 0; +} + +/* 技能卡片响应式布局优化 */ +@media (min-width: 1400px) { + .skills-grid { + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 20px; + } +} + +@media (max-width: 1200px) { + .skills-grid { + grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); + gap: 16px; + } +} + +@media (max-width: 768px) { + .skills-grid { + grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); + gap: 12px; + } + + .skill-card { + padding: 14px; + gap: 8px; + } +} + +@media (max-width: 480px) { + .skills-grid { + grid-template-columns: 1fr; + gap: 12px; + } +} + .skill-item { background: var(--bg-primary); border: 1px solid var(--border-color); diff --git a/web/static/js/roles.js b/web/static/js/roles.js index deaa5728..5053a948 100644 --- a/web/static/js/roles.js +++ b/web/static/js/roles.js @@ -1,6 +1,8 @@ // 角色管理相关功能 let currentRole = localStorage.getItem('currentRole') || ''; let roles = []; +let rolesSearchKeyword = ''; // 角色搜索关键词 +let rolesSearchTimeout = null; // 搜索防抖定时器 let allRoleTools = []; // 存储所有工具列表(用于角色工具选择) let roleToolsPagination = { page: 1, @@ -258,6 +260,7 @@ async function refreshRoles() { } // 始终更新侧边栏角色选择列表 renderRoleSelectionSidebar(); + showNotification('已刷新', 'success'); } // 渲染角色列表 @@ -265,30 +268,25 @@ function renderRolesList() { const rolesList = document.getElementById('roles-list'); if (!rolesList) return; - if (roles.length === 0) { - rolesList.innerHTML = '
${escapeHtml(skill.description)}
` : ''} -