三级菜单UI
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
yiqiu
2026-01-11 12:18:49 +08:00
parent 0edd3f5632
commit 9b65213048

View File

@@ -1,4 +1,31 @@
<link rel="stylesheet" href="/plugins/addon/theme_configurator/template/admin/theme.css" /> <link rel="stylesheet" href="/plugins/addon/theme_configurator/template/admin/theme.css" />
<style>
/* 优化输入框和下拉框的focus样式 */
input[type="text"]:focus,
input[type="number"]:focus,
textarea:focus,
select:focus {
outline: none !important;
border-color: #1890ff !important;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2) !important;
}
/* 表格内的输入框样式优化 */
.nav-config-table input:focus,
.nav-config-table select:focus {
outline: none !important;
border-color: #1890ff !important;
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.15) !important;
}
/* 移除所有输入框的默认outline */
input,
select,
textarea {
outline: none;
}
</style>
<div id="theme-config-app" class="admin-container"> <div id="theme-config-app" class="admin-container">
<!-- 顶部工具栏 --> <!-- 顶部工具栏 -->
@@ -194,7 +221,7 @@
</div> </div>
<div class="section-body"> <div class="section-body">
<div id="headerNavList"></div> <div id="headerNavList"></div>
<button class="btn btn-secondary" id="addHeaderNavBtn">+ 添加导航</button> <!-- 添加导航按钮已整合到表格底部 -->
</div> </div>
</div> </div>
<div class="section-card"> <div class="section-card">
@@ -763,7 +790,7 @@
<td style="padding:6px 8px; border:1px solid #e8e8e8;"> <td style="padding:6px 8px; border:1px solid #e8e8e8;">
<select data-hnav-grandchild="${navIndex}.${childIndex}.${grandIndex}" data-field="country_code" style="width:100%; padding:4px; border:1px solid #d9d9d9; font-size:11px;"> <select data-hnav-grandchild="${navIndex}.${childIndex}.${grandIndex}" data-field="country_code" style="width:100%; padding:4px; border:1px solid #d9d9d9; font-size:11px;">
<option value="">无地区</option> <option value="">无地区</option>
${countryOptions.map(code => `<option value="${code}" ${selectedCountry === code ? 'selected' : ''}>${code}</option>`).join('')} ${countryOptions.map(country => `<option value="${country.code}" ${selectedCountry === country.code ? 'selected' : ''}>${country.name}(${country.code})</option>`).join('')}
</select> </select>
</td> </td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;"> <td style="padding:6px 8px; border:1px solid #e8e8e8;">
@@ -803,13 +830,35 @@
// 获取国家/地区代码列表(只使用方形图标) // 获取国家/地区代码列表(只使用方形图标)
function getCountryOptions() { function getCountryOptions() {
// 常用国家/地区代码列表(方形图标) // 返回带中文名称的地区选项
return [ return [
'CN', 'HK', 'TW', 'MO', // 中国及特别行政区 { code: 'CN', name: '中国' },
'US', 'JP', 'KR', 'SG', 'GB', // 常用国家 { code: 'HK', name: '香港' },
'DE', 'FR', 'CA', 'AU', 'IN', // 其他常用 { code: 'TW', name: '台湾' },
'TH', 'MY', 'ID', 'PH', 'VN', // 东南亚 { code: 'MO', name: '澳门' },
'AE', 'RU', 'BR', 'IT', 'ES', 'NL', 'CH', 'SE' // 其他 { code: 'US', name: '美国' },
{ code: 'JP', name: '日本' },
{ code: 'KR', name: '韩国' },
{ code: 'SG', name: '新加坡' },
{ code: 'GB', name: '英国' },
{ code: 'DE', name: '德国' },
{ code: 'FR', name: '法国' },
{ code: 'CA', name: '加拿大' },
{ code: 'AU', name: '澳大利亚' },
{ code: 'IN', name: '印度' },
{ code: 'TH', name: '泰国' },
{ code: 'MY', name: '马来西亚' },
{ code: 'ID', name: '印度尼西亚' },
{ code: 'PH', name: '菲律宾' },
{ code: 'VN', name: '越南' },
{ code: 'AE', name: '阿联酋' },
{ code: 'RU', name: '俄罗斯' },
{ code: 'BR', name: '巴西' },
{ code: 'IT', name: '意大利' },
{ code: 'ES', name: '西班牙' },
{ code: 'NL', name: '荷兰' },
{ code: 'CH', name: '瑞士' },
{ code: 'SE', name: '瑞典' }
]; ];
} }
@@ -1021,62 +1070,103 @@
function renderFooterNav(navs) { function renderFooterNav(navs) {
const container = document.getElementById('footerNavList'); const container = document.getElementById('footerNavList');
if (!container) return; if (!container) return;
container.innerHTML = '';
navs.forEach((col, index) => {
const hasChildren = Array.isArray(col.children) && col.children.length > 0;
const item = document.createElement('div');
item.className = 'config-item';
item.style.borderLeft = '3px solid #1890ff'; // 蓝色标识
item.innerHTML = `
<div class="config-item__header" style="background:#e6f7ff;">
<h4 style="color:#1890ff;">栏目 ${index + 1}: ${col.name || '(未命名)'}</h4>
<div style="display: flex; gap: 4px;">
<button class="btn btn-primary btn-sm" id="toggle-footer-${index}" onclick="toggleFooterNavChildren(${index})" style="font-size:12px;">${hasChildren && col.children.length > 0 ? '收起链接列表' : '展开链接列表'}</button>
<button class="btn-icon btn-icon-danger" onclick="removeFooterNav(${index})">×</button>
</div>
</div>
<div class="config-item__body">
<div class="form-item">
<label>栏目名称</label>
<input type="text" class="form-control" data-fnav="${index}" data-field="name" value="${col.name || ''}" placeholder="热门云产品">
</div>
<div id="footer-nav-children-${index}" style="display:${hasChildren ? 'block' : 'none'}; margin-top:12px; padding-top:12px; border-top:1px solid #d9d9d9;">
<h5 style="margin:0 0 8px; font-size:13px; color:#1890ff;">链接列表</h5>
<div id="footer-nav-children-list-${index}"></div>
<button class="btn btn-primary btn-sm" onclick="addFooterNavChild(${index})" style="margin-top:8px;">+ 添加链接</button>
</div>
</div>
`;
container.appendChild(item);
if (hasChildren) { let html = `
renderFooterNavChildren(index, col.children); <table class="nav-config-table" style="width:100%; border-collapse:collapse; font-size:12px;">
<thead>
<tr style="background:#f5f5f5;">
<th style="width:40px; padding:8px; border:1px solid #e0e0e0;">级</th>
<th style="width:220px; padding:8px; border:1px solid #e0e0e0;">名称</th>
<th style="width:220px; padding:8px; border:1px solid #e0e0e0;">链接</th>
<th style="width:80px; padding:8px; border:1px solid #e0e0e0;">选项</th>
<th style="width:100px; padding:8px; border:1px solid #e0e0e0;">操作</th>
</tr>
</thead>
<tbody id="footer-nav-tbody">
`;
navs.forEach((col, navIndex) => {
// 一级栏目行
html += `
<tr style="background:#fafafa; border-left:3px solid #1890ff;">
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<span style="display:inline-block; padding:2px 6px; background:#1890ff; color:#fff; border-radius:3px; font-size:10px;">1级</span>
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<input type="text" data-fnav="${navIndex}" data-field="name" value="${col.name || ''}" placeholder="栏目名称(如:热门云产品)" style="width:100%; padding:4px; border:1px solid #d9d9d9; font-size:12px;">
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8; text-align:center; color:#999;">-</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8; text-align:center; color:#999;">-</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<button onclick="toggleFooterChildren(${navIndex})" style="padding:2px 8px; background:#1890ff; color:#fff; border:none; border-radius:2px; font-size:11px; cursor:pointer; margin-right:4px;">+链接</button>
<button onclick="removeFooterNav(${navIndex})" style="padding:2px 8px; background:#ff4d4f; color:#fff; border:none; border-radius:2px; font-size:11px; cursor:pointer;">删</button>
</td>
</tr>
`;
// 二级链接(默认隐藏)
if (col.children && col.children.length > 0) {
col.children.forEach((child, childIndex) => {
html += `
<tr id="footer-child-${navIndex}-${childIndex}" style="display:none; background:#e6f7ff; border-left:3px solid #52c41a;">
<td style="padding:6px 8px 6px 32px; border:1px solid #e8e8e8;">
<span style="display:inline-block; padding:2px 6px; background:#52c41a; color:#fff; border-radius:3px; font-size:10px;">2级</span>
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<input type="text" data-fnav-child="${navIndex}.${childIndex}" data-field="name" value="${child.name || ''}" placeholder="链接名称" style="width:100%; padding:4px; border:1px solid #d9d9d9; font-size:12px;">
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<input type="text" data-fnav-child="${navIndex}.${childIndex}" data-field="url" value="${child.url || ''}" placeholder="链接地址" style="width:100%; padding:4px; border:1px solid #d9d9d9; font-size:12px;">
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<label style="font-size:11px; margin:0;"><input type="checkbox" data-fnav-child="${navIndex}.${childIndex}" data-field="blank" ${child.blank ? 'checked' : ''}> 新窗口</label>
</td>
<td style="padding:6px 8px; border:1px solid #e8e8e8;">
<button onclick="removeFooterNavChild(${navIndex}, ${childIndex})" style="padding:2px 8px; background:#ff4d4f; color:#fff; border:none; border-radius:2px; font-size:11px; cursor:pointer;">删</button>
</td>
</tr>
`;
});
} }
}); });
html += `
</tbody>
</table>
<button onclick="addFooterNav()" style="margin-top:12px; padding:6px 16px; background:#1890ff; color:#fff; border:none; border-radius:3px; cursor:pointer;">+ 添加底部栏目</button>
`;
container.innerHTML = html;
} }
function renderFooterNavChildren(navIndex, children) { function renderFooterNavChildren(navIndex, children) {
const container = document.getElementById(`footer-nav-children-list-${navIndex}`); // 改为表格渲染,此函数已废弃
if (!container) return;
container.innerHTML = '';
children.forEach((child, childIndex) => {
const item = document.createElement('div');
item.style.cssText = 'padding:8px; margin-bottom:8px; background:#f0f8ff; border-radius:4px; border-left:2px solid #1890ff;';
item.innerHTML = `
<div style="display:flex; justify-content:space-between; align-items:start;">
<div style="flex:1; display:grid; gap:8px;">
<input type="text" class="form-control" data-fnav-child="${navIndex}.${childIndex}" data-field="name" value="${child.name || ''}" placeholder="链接名称">
<input type="text" class="form-control" data-fnav-child="${navIndex}.${childIndex}" data-field="url" value="${child.url || ''}" placeholder="链接地址">
<label style="font-size:12px;"><input type="checkbox" data-fnav-child="${navIndex}.${childIndex}" data-field="blank" ${child.blank ? 'checked' : ''}> 新窗口打开</label>
</div>
<button class="btn-icon btn-icon-danger" onclick="removeFooterNavChild(${navIndex}, ${childIndex})" style="margin-left:8px;">×</button>
</div>
`;
container.appendChild(item);
});
} }
// 展开/收起底部导航的子链接
window.toggleFooterChildren = function (navIndex) {
const navs = collectFooterNav();
const col = navs[navIndex];
if (!col || !col.children || col.children.length === 0) {
// 没有子链接,添加子链接
addFooterNavChild(navIndex);
return;
}
// 切换子链接显示状态
col.children.forEach((_, childIndex) => {
const row = document.getElementById(`footer-child-${navIndex}-${childIndex}`);
if (row) {
row.style.display = row.style.display === 'none' ? 'table-row' : 'none';
}
});
};
// 旧函数保留兼容
window.toggleFooterNavChildren = function (navIndex) {
toggleFooterChildren(navIndex);
};
function collectFooterNav() { function collectFooterNav() {
const navs = []; const navs = [];