综述: 优化iframe内容显示,实现无缝全屏效果

- 修改index.html标题为"商家端后台"
- 调整菜单项结构,保持权限管理功能
- 更新iframe内容显示逻辑,实现无缝全屏效果
- 优化页面结构和显示体验
This commit is contained in:
linbin 2025-09-06 15:02:17 +08:00
parent 2d9f7390c5
commit 7bc839ba00
7 changed files with 1049 additions and 85 deletions

View File

@ -0,0 +1,10 @@
{
"id": "approval_1757137638926_bvxb2x9yr",
"title": "商家端账号分配权限功能需求文档",
"filePath": ".spec-workflow/specs/merchant-account-permission/requirements.md",
"type": "document",
"status": "pending",
"createdAt": "2025-09-06T05:47:18.926Z",
"category": "spec",
"categoryName": "merchant-account-permission"
}

View File

@ -0,0 +1,10 @@
{
"id": "approval_1757138004604_1ga5ibp7w",
"title": "商家端账号权限分配页面-简化版需求",
"filePath": ".spec-workflow/specs/merchant-account-permission/requirements.md",
"type": "document",
"status": "pending",
"createdAt": "2025-09-06T05:53:24.604Z",
"category": "spec",
"categoryName": "merchant-account-permission"
}

View File

@ -0,0 +1,10 @@
{
"id": "approval_1757138141783_3vwoymq9y",
"title": "商家端账号权限分配页面需求文档 - 已修改确认版",
"filePath": ".spec-workflow/specs/merchant-account-permission/requirements.md",
"type": "document",
"status": "pending",
"createdAt": "2025-09-06T05:55:41.783Z",
"category": "spec",
"categoryName": "merchant-account-permission"
}

View File

@ -0,0 +1,170 @@
# Design Document
## Overview
商家端账号权限分配页面是一个独立的前端HTML页面基于平台端权限分配页面的设计模式进行适配改造。主要替换菜市场选择功能为商家身份选择保持一致的UI风格和交互体验。
## 技术决策
### 代码复用策略
完全复用平台端权限分配.html的CSS样式和JavaScript交互逻辑仅修改以下部分
- 替换菜市场选择下拉框为商家身份选择
- 更新相关文案和提示信息
- 调整数据结构(移除菜市场数据,增加身份类型数据)
### 文件组织
- **位置**: `/Users/linbin/Documents/代码/dmjs-demo/商家端web/1 权限管理/账号权限分配.html`
- **类型**: 独立HTML文件包含内联CSS和JavaScript
- **依赖**: 纯前端实现,无需外部库依赖
## 架构设计
### 组件结构
```
账号权限分配页面
├── 布局容器 (Container)
│ ├── 头部区域 (Header)
│ │ ├── 页面标题
│ │ └── 操作按钮区域
│ ├── 内容区域 (Content)
│ │ ├── 账号创建表单区域
│ │ │ ├── 身份选择下拉框
│ │ │ └── 手机号输入框
│ │ ├── 权限分配树形区域
│ │ │ └── 权限复选框树
│ │ └── 操作按钮区域
│ └── 交互逻辑层 (JavaScript)
│ ├── 身份选择处理
│ ├── 权限树渲染
│ ├── 表单验证
│ └── 数据收集与提交
```
### 核心修改点
1. **身份选择组件**: 替换原有的菜市场复杂下拉选择为简单的select下拉框
2. **数据结构简化**: 移除菜市场搜索过滤逻辑,使用固定的身份选项
3. **验证逻辑调整**: 验证身份选择而非菜市场选择
## 数据模型
### 身份类型定义
```javascript
const identityTypes = [
{ id: 1, name: '子经营者', code: 'SUB_MERCHANT' },
{ id: 2, name: '商户', code: 'MERCHANT' }
];
```
### 表单数据结构
```javascript
const formData = {
identity: {
id: number,
name: string,
code: string
},
phoneNumber: string,
permissions: string[], // 权限代码数组
timestamp: string
};
```
## 组件实现
### HTML结构修改
1. 替换`菜市场选择 *`为`创建账号身份 *`
2. 删除复杂的菜市场下拉组件使用标准select元素
3. 更新相关表单验证和错误提示
### CSS复用策略
完全复用参考文件的样式系统,包括:
- 颜色方案(渐变头部、按钮色彩体系)
- 布局系统(响应式网格、卡片设计)
- 交互动画hover效果、阴影过渡
- 移动端适配规则
### JavaScript功能模块
#### 身份选择模块
```javascript
// 初始化身份选项
function initIdentityOptions() {
// 渲染select选项
}
// 处理身份选择变化
function handleIdentityChange(identity) {
// 更新选中状态
// 可选:根据身份类型显示推荐的权限
}
```
#### 权限管理模块(复用原逻辑)
```javascript
// 权限树构建与渲染(完全复用)
function buildPermissionTree(permissions) { /* 复用 */ }
function createPermissionNode(item) { /* 复用 */ }
function togglePermissionChildren(btn, li) { /* 复用 */ }
```
#### 表单验证模块
```javascript
// 修改验证逻辑:身份选择 + 手机号 + 权限
function validateForm() {
// 验证身份已选择
// 验证手机号格式
// 验证至少选择一个权限
}
```
## 错误处理
### 前端验证错误
1. **未选择身份**: 显示"请选择账号身份"提示
2. **手机号格式错误**: 显示"请输入正确的手机号格式"提示
3. **未选择权限**: 显示"请至少选择一个权限"提示
### 用户输入处理
- 手机号输入自动过滤非数字字符
- 表单提交前进行完整性检查
- 重置操作需要二次确认
## 浏览器兼容性
### 支持浏览器
- Chrome 80+, Firefox 75+, Safari 13+, Edge 80+
- 移动端浏览器iOS Safari, Chrome Mobile
### 降级处理
- IE11基本功能可用样式简化处理
- 旧版浏览器使用polyfill处理classList等API
## 性能优化
### 加载优化
- 内联CSS和JavaScript避免额外HTTP请求
- 权限树使用虚拟化渲染(节点数量>100时
- 图片资源使用base64编码如需图标
### 运行时优化
- 事件委托处理权限树点击
- 防抖处理输入框实时验证
- 使用DocumentFragment批量DOM操作
## 测试策略
### 功能测试
1. 身份选择下拉框交互测试
2. 权限树展开/收起功能测试
3. 表单验证逻辑测试
4. 数据收集和提交测试
### 跨浏览器测试
1. 主流浏览器样式一致性测试
2. 移动端响应式布局测试
3. 触摸事件兼容性测试
### 边界条件测试
1. 空表单提交测试
2. 权限循环引用测试
3. 大数据量权限树渲染测试

View File

@ -0,0 +1,86 @@
# Requirements Document
## Introduction
为商家端创建一个账号分配权限的前端页面提供简洁直观的界面让商家管理员能够为账号分配权限。页面采用与平台端权限分配相似的UI设计确保用户体验的一致性。
## Alignment with Product Vision
此功能支持商户管理平台的"简洁易用"愿景,通过统一的界面设计和交互体验,让商家能够高效地完成账号权限分配,避免复杂的学习成本。
## Requirements
### Requirement 1: 页面结构与样式
**User Story:** 作为前端开发人员,我想要创建一个与平台端权限分配页面风格一致的商家端权限分配页面,确保用户体验的连续性。
#### Acceptance Criteria
1. WHEN 用户访问商家端权限分配页面 THEN 系统 SHALL 显示具有渐变头部banner的全屏容器
2. IF 屏幕尺寸 <= 768px THEN 系统 SHALL 自动应用响应式布局适配移动设备
3. WHEN 页面加载完成时 THEN 系统 SHALL 应用参考文件中定义的颜色方案(#2c3e50, #3498db等)
4. IF 用户点击重置按钮 THEN 系统 SHALL 清空所有表单输入和权限选择
### Requirement 2: 账号创建区域布局
**User Story:** 作为商家管理员,我想要通过表单创建新账号并指定其身份类型,以便为不同类型的用户分配相应权限。
#### Acceptance Criteria
1. WHEN 进入账号创建区域 THEN 系统 SHALL 显示创建账号身份下拉框(替代原菜市场选择)
2. IF 身份下拉框获得焦点 THEN 系统 SHALL 显示可选身份:子经营者、商户
3. WHEN 用户选择身份后 THEN 系统 SHALL 显示对应权限建议(如需要)
4. IF 手机号输入框输入非数字字符 THEN 系统 SHALL 自动过滤并只允许输入数字
### Requirement 3: 权限分配树形结构
**User Story:** 作为商家管理员,我想要通过树形结构查看和分配权限,确保能够精确控制每个账号的功能访问范围。
#### Acceptance Criteria
1. WHEN 显示权限分配区域 THEN 系统 SHALL 渲染层次化的权限树结构
2. IF 父权限被选中 THEN 系统 SHALL 自动选中所有子权限
3. WHEN 子权限被取消时 THEN 系统 SHALL 检查是否需要取消父权限(无其他选中子项时)
4. IF 点击权限复选框或标签 THEN 系统 SHALL 切换该权限的选中状态
### Requirement 4: 文件位置与集成
**User Story:** 作为系统集成人员,我想要将前端文件放置在标准的权限管理目录下,确保项目结构的一致性和可维护性。
#### Acceptance Criteria
1. WHEN 创建前端文件时 THEN 系统 SHALL 将文件保存到"1 权限管理"文件夹下
2. IF 文件夹不存在 THEN 系统 SHALL 提示创建相应目录结构
3. WHEN 文件命名时 THEN 系统 SHALL 建议使用描述性文件名如"账号权限分配.html"
4. IF 页面需要后端API集成 THEN 系统 SHALL 提供API接口调用的示例代码
## Non-Functional Requirements
### Code Architecture and Modularity
- **Single Responsibility Principle**: 样式定义、数据结构、业务逻辑、DOM操作应分离到独立区域
- **Modular Design**: 权限树渲染和交互逻辑应封装为可复用函数
- **Dependency Management**: JavaScript代码应使用原生API避免引入外部依赖
- **Clear Interfaces**: 表单验证、数据收集、API调用应定义清晰的函数接口
### Performance
- 页面加载时间 < 2秒本地文件加载
- 权限树渲染时间 < 500ms50个权限节点以内
- 表单验证响应时间 < 100ms
- 支持同时处理不超过20个并发用户操作
### Security
- 前端验证仅作为用户体验优化,后端必须进行最终验证
- 所有用户输入必须进行基本的XSS防护处理
- 敏感操作需要在后端记录操作日志
- 手机号等个人信息应在前端进行脱敏显示
### Usability
- 页面布局应遵循无障碍设计原则
- 所有交互元素需具备清晰的可点击区域
- 颜色对比度符合WCAG 2.1 AA标准
- 移动端触摸目标尺寸不低于44x44像素
### Browser Compatibility
- 支持Chrome 80+, Firefox 75+, Safari 13+, Edge 80+
- 在IE11上保持基本功能可用性降级处理
- CSS Grid和Flexbox用于布局提供老浏览器降级方案

View File

@ -0,0 +1,756 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>账号权限分配</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f5f7fa;
color: #333;
height: 100vh;
margin: 0;
padding: 0;
}
.container {
width: 100%;
height: 100vh;
margin: 0;
background-color: #fff;
border-radius: 0;
box-shadow: none;
overflow-y: auto;
}
.header {
background: linear-gradient(135deg, #2c3e50, #3498db);
color: #fff;
padding: 20px 30px;
display: flex;
justify-content: space-between;
align-items: center;
}
.header h1 {
font-size: 1.8rem;
font-weight: 600;
}
.header-actions {
display: flex;
gap: 10px;
}
.btn {
padding: 10px 20px;
border: none;
border-radius: 5px;
cursor: pointer;
font-size: 14px;
font-weight: 500;
transition: all 0.3s ease;
display: inline-flex;
align-items: center;
gap: 5px;
}
.btn-primary {
background-color: #3498db;
color: #fff;
}
.btn-primary:hover {
background-color: #2980b9;
transform: translateY(-2px);
}
.btn-success {
background-color: #27ae60;
color: #fff;
}
.btn-success:hover {
background-color: #229954;
}
.btn-warning {
background-color: #f39c12;
color: #fff;
}
.btn-warning:hover {
background-color: #e67e22;
}
/* 内容区域 */
.content {
padding: 30px;
}
.section {
margin-bottom: 40px;
}
.section-title {
font-size: 1.4rem;
font-weight: 600;
color: #2c3e50;
margin-bottom: 20px;
padding-bottom: 10px;
border-bottom: 2px solid #ecf0f1;
}
/* 账号创建区域 */
.account-form {
background-color: #f8f9fa;
padding: 25px;
border-radius: 8px;
border: 1px solid #dee2e6;
}
.form-row {
display: flex;
gap: 20px;
align-items: end;
}
.form-group {
flex: 1;
margin-bottom: 20px;
}
.form-group label {
display: block;
margin-bottom: 8px;
font-weight: 500;
color: #2c3e50;
}
.form-group input,
.form-group select {
width: 100%;
padding: 12px 15px;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 14px;
transition: border-color 0.3s ease;
}
.form-group input:focus,
.form-group select:focus {
outline: none;
border-color: #3498db;
box-shadow: 0 0 5px rgba(52, 152, 219, 0.3);
}
/* 权限分配区域 */
.permissions-container {
background-color: #f8f9fa;
padding: 25px;
border-radius: 8px;
border: 1px solid #dee2e6;
max-height: 500px;
overflow-y: auto;
}
.permission-tree {
list-style: none;
}
.permission-item {
margin-bottom: 8px;
}
.permission-node {
display: flex;
align-items: center;
padding: 12px 15px;
border-radius: 6px;
transition: all 0.3s ease;
cursor: pointer;
background-color: #fff;
border: 1px solid #e9ecef;
margin-bottom: 5px;
}
.permission-node:hover {
background-color: #f8f9fa;
border-color: #3498db;
box-shadow: 0 2px 8px rgba(52, 152, 219, 0.15);
}
.permission-node.selected {
background-color: #e3f2fd;
border-color: #3498db;
}
.permission-checkbox {
margin-right: 12px;
width: 18px;
height: 18px;
cursor: pointer;
accent-color: #3498db;
}
.expand-btn {
background: #3498db;
border: none;
cursor: pointer;
padding: 2px 8px;
margin-right: 12px;
color: #fff;
font-size: 14px;
transition: all 0.3s ease;
min-width: 28px;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
}
.expand-btn.collapsed {
transform: rotate(-90deg);
}
.permission-label {
font-size: 14px;
color: #2c3e50;
user-select: none;
flex: 1;
font-weight: 500;
}
.permission-children {
margin-left: 35px;
margin-top: 8px;
border-left: 2px solid #3498db;
padding-left: 20px;
display: none;
position: relative;
}
.permission-children::before {
content: '';
position: absolute;
left: 0;
top: -8px;
height: calc(100% + 16px);
width: 2px;
background-color: #3498db;
}
.permission-children.expanded {
display: block;
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-5px); }
to { opacity: 1; transform: translateY(0); }
}
.permission-item.parent > .permission-node {
background-color: #edf7ff;
border-color: #bbdefb;
font-weight: 600;
}
.permission-item.child .permission-node {
margin-left: 15px;
background-color: #f8f9fa;
}
/* 操作区域 */
.actions {
display: flex;
justify-content: flex-end;
gap: 10px;
padding-top: 20px;
border-top: 1px solid #dee2e6;
margin-top: 30px;
}
/* 响应式设计 */
@media (max-width: 768px) {
.container {
margin: 0;
border-radius: 0;
}
.header {
padding: 15px 20px;
flex-direction: column;
gap: 15px;
}
.content {
padding: 20px;
}
.form-row {
flex-direction: column;
gap: 0;
}
}
</style>
</head>
<body>
<div class="container">
<!-- 头部 -->
<div class="header">
<h1>账号权限分配</h1>
<div class="header-actions">
<button class="btn btn-warning" onclick="resetForm()">
🔄 重置
</button>
</div>
</div>
<!-- 内容区域 -->
<div class="content">
<!-- 账号创建区域 -->
<div class="section">
<h2 class="section-title">账号信息</h2>
<div class="account-form">
<div class="form-row">
<div class="form-group">
<label for="identitySelect">创建账号身份 *</label>
<select id="identitySelect" onchange="handleIdentityChange()">
<option value="">请选择账号身份</option>
<option value="sub_merchant">子经营者</option>
<option value="merchant">商户</option>
</select>
</div>
<div class="form-group">
<label for="phoneNumber">账号手机号 *</label>
<input type="tel" id="phoneNumber" placeholder="请输入手机号" maxlength="11">
</div>
</div>
</div>
</div>
<!-- 权限分配区域 -->
<div class="section">
<h2 class="section-title">权限分配</h2>
<div class="permissions-container">
<ul id="permissionTree" class="permission-tree">
<!-- 权限树将通过JavaScript动态生成 -->
</ul>
</div>
</div>
<!-- 操作按钮 -->
<div class="actions">
<button class="btn btn-warning" onclick="cancelAssignment()">取消</button>
<button class="btn btn-success" onclick="saveAssignment()">💾 保存分配</button>
</div>
</div>
</div>
<script>
// 身份类型数据
const identityTypes = [
{ id: 1, name: '子经营者', code: 'sub_merchant' },
{ id: 2, name: '商户', code: 'merchant' }
];
// 权限数据(从权限编辑页面获取的示例数据)
const permissions = [
{
id: 1,
code: 'SYSTEM',
name: '系统管理',
description: '系统管理模块',
parentCode: '',
type: 'menu'
},
{
id: 2,
code: 'SYSTEM_USER',
name: '用户管理',
description: '用户管理功能',
parentCode: 'SYSTEM',
type: 'menu'
},
{
id: 3,
code: 'SYSTEM_USER_ADD',
name: '添加用户',
description: '添加新用户按钮',
parentCode: 'SYSTEM_USER',
type: 'button'
},
{
id: 4,
code: 'SYSTEM_USER_EDIT',
name: '编辑用户',
description: '编辑用户信息按钮',
parentCode: 'SYSTEM_USER',
type: 'button'
},
{
id: 5,
code: 'SYSTEM_ROLE',
name: '角色管理',
description: '角色管理功能',
parentCode: 'SYSTEM',
type: 'menu'
},
{
id: 6,
code: 'CONTENT',
name: '内容管理',
description: '内容管理模块',
parentCode: '',
type: 'menu'
}
];
let selectedIdentity = null;
let selectedPermissions = new Set();
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
initPermissionTree();
bindEvents();
});
// 初始化身份选项已改为静态select无需动态初始化
function handleIdentityChange() {
const select = document.getElementById('identitySelect');
const selectedValue = select.value;
if (selectedValue) {
selectedIdentity = identityTypes.find(type => type.code === selectedValue);
console.log('已选择身份:', selectedIdentity);
// 这里可以根据身份类型推荐相应的权限
recommendPermissionsForIdentity(selectedIdentity);
} else {
selectedIdentity = null;
}
}
// 根据身份类型推荐权限
function recommendPermissionsForIdentity(identity) {
// 根据不同身份推荐默认权限
const recommendedPermissions = [];
if (identity.code === 'sub_merchant') {
// 子经营者推荐基础权限
recommendedPermissions.push('CONTENT');
} else if (identity.code === 'merchant') {
// 商户推荐更多权限
recommendedPermissions.push('SYSTEM', 'CONTENT');
}
// 自动勾选推荐的权限
recommendedPermissions.forEach(permissionCode => {
const checkbox = document.querySelector(`[data-permission-code="${permissionCode}"]`);
if (checkbox && !checkbox.checked) {
checkbox.checked = true;
selectedPermissions.add(permissionCode);
updatePermissionDisplay();
}
});
}
// 初始化权限树
function initPermissionTree() {
const tree = buildPermissionTree(permissions);
const treeContainer = document.getElementById('permissionTree');
treeContainer.innerHTML = '';
tree.forEach(item => {
treeContainer.appendChild(createPermissionNode(item));
});
}
// 构建权限树
function buildPermissionTree(data) {
const map = {};
const roots = [];
// 创建映射
data.forEach(item => {
map[item.code] = { ...item, children: [] };
});
// 构建树结构
data.forEach(item => {
if (item.parentCode && map[item.parentCode]) {
map[item.parentCode].children.push(map[item.code]);
} else {
roots.push(map[item.code]);
}
});
return roots;
}
// 创建权限节点
function createPermissionNode(item) {
const li = document.createElement('li');
li.className = 'permission-item ' + (item.children.length > 0 ? 'parent' : 'child');
const nodeDiv = document.createElement('div');
nodeDiv.className = 'permission-node';
// 展开/收起按钮
if (item.children.length > 0) {
const expandBtn = document.createElement('button');
expandBtn.className = 'expand-btn';
expandBtn.textContent = '▼';
expandBtn.onclick = (e) => {
e.stopPropagation();
togglePermissionChildren(expandBtn, li);
};
nodeDiv.appendChild(expandBtn);
} else {
// 占位符保持对齐
const placeholder = document.createElement('span');
placeholder.style.width = '28px';
placeholder.style.display = 'inline-block';
nodeDiv.appendChild(placeholder);
}
// 复选框
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.className = 'permission-checkbox';
checkbox.dataset.permissionCode = item.code;
checkbox.onchange = (e) => handlePermissionChange(e, item);
nodeDiv.appendChild(checkbox);
// 权限标签
const label = document.createElement('span');
label.className = 'permission-label';
label.textContent = `${item.name}${item.description || item.code}`;
label.onclick = () => checkbox.click();
nodeDiv.appendChild(label);
li.appendChild(nodeDiv);
// 子权限
if (item.children.length > 0) {
const childrenContainer = document.createElement('ul');
childrenContainer.className = 'permission-children';
item.children.forEach(child => {
childrenContainer.appendChild(createPermissionNode(child));
});
li.appendChild(childrenContainer);
}
return li;
}
// 切换权限子节点显示
function togglePermissionChildren(btn, li) {
const children = li.querySelector('.permission-children');
if (!children) return;
const isExpanded = children.classList.contains('expanded');
children.classList.toggle('expanded');
btn.textContent = isExpanded ? '▶' : '▼';
btn.classList.toggle('collapsed', isExpanded);
}
// 处理权限选择变化
function handlePermissionChange(event, permission) {
const checkbox = event.target;
const isChecked = checkbox.checked;
const permissionCode = permission.code;
const node = checkbox.closest('.permission-node');
// 更新节点选中样式
if (node) {
if (isChecked) {
node.classList.add('selected');
} else {
node.classList.remove('selected');
}
}
if (isChecked) {
selectedPermissions.add(permissionCode);
// 选中子级权限时,自动选中所有父级权限
selectParentPermissions(permission);
// 如果是父权限,自动选中所有子权限
if (permission.children && permission.children.length > 0) {
selectChildrenPermissions(permission, true);
}
} else {
selectedPermissions.delete(permissionCode);
// 如果是父权限,自动取消所有子权限
if (permission.children && permission.children.length > 0) {
selectChildrenPermissions(permission, false);
}
// 如果是子权限,检查是否需要取消父权限
uncheckParentIfNeeded(permission);
}
updatePermissionDisplay();
}
// 选择所有父级权限
function selectParentPermissions(permission) {
if (!permission.parentCode) return;
// 查找父权限
const parent = permissions.find(p => p.code === permission.parentCode);
if (!parent) return;
// 选中父权限
const parentCheckbox = document.querySelector(`[data-permission-code="${parent.code}"]`);
if (parentCheckbox && !parentCheckbox.checked) {
parentCheckbox.checked = true;
selectedPermissions.add(parent.code);
}
// 递归选中上级父权限
selectParentPermissions(parent);
}
// 选择/取消子权限
function selectChildrenPermissions(parent, select) {
if (!parent.children) return;
parent.children.forEach(child => {
const childCheckbox = document.querySelector(`[data-permission-code="${child.code}"]`);
if (childCheckbox) {
childCheckbox.checked = select;
if (select) {
selectedPermissions.add(child.code);
} else {
selectedPermissions.delete(child.code);
}
// 递归处理子权限
selectChildrenPermissions(child, select);
}
});
}
// 检查是否需要取消父权限选择
function uncheckParentIfNeeded(permission) {
if (!permission.parentCode) return;
// 查找父权限
const parent = permissions.find(p => p.code === permission.parentCode);
if (!parent) return;
// 检查父权限的所有子权限是否都未选中
const siblings = permissions.filter(p => p.parentCode === parent.code);
const hasSelectedSibling = siblings.some(sibling => selectedPermissions.has(sibling.code));
if (!hasSelectedSibling) {
const parentCheckbox = document.querySelector(`[data-permission-code="${parent.code}"]`);
if (parentCheckbox) {
parentCheckbox.checked = false;
selectedPermissions.delete(parent.code);
// 递归检查上级父权限
uncheckParentIfNeeded(parent);
}
}
}
// 更新权限显示
function updatePermissionDisplay() {
// 这里可以添加一些UI反馈比如显示已选权限数量等
console.log('已选择权限:', Array.from(selectedPermissions));
}
// 绑定事件
function bindEvents() {
// 手机号输入验证
document.getElementById('phoneNumber').addEventListener('input', function(e) {
let value = e.target.value.replace(/\D/g, '');
if (value.length > 11) {
value = value.slice(0, 11);
}
e.target.value = value;
});
}
// 重置表单
function resetForm() {
if (confirm('确定要重置所有信息吗?')) {
// 重置身份选择
selectedIdentity = null;
document.getElementById('identitySelect').value = '';
// 重置手机号
document.getElementById('phoneNumber').value = '';
// 重置权限选择
selectedPermissions.clear();
document.querySelectorAll('.permission-checkbox').forEach(checkbox => {
checkbox.checked = false;
});
// 重置权限样式
document.querySelectorAll('.permission-node').forEach(node => {
node.classList.remove('selected');
});
}
}
// 取消分配
function cancelAssignment() {
if (confirm('确定要取消权限分配吗?未保存的更改将丢失。')) {
window.history.back();
}
}
// 保存权限分配
function saveAssignment() {
// 验证身份选择
if (!selectedIdentity) {
alert('请选择账号身份!');
return;
}
// 验证手机号
const phoneNumber = document.getElementById('phoneNumber').value.trim();
if (!phoneNumber) {
alert('请输入手机号!');
return;
}
if (!/^1[3-9]\d{9}$/.test(phoneNumber)) {
alert('请输入正确的手机号格式!');
return;
}
// 验证权限选择
if (selectedPermissions.size === 0) {
alert('请至少选择一个权限!');
return;
}
// 构建保存数据
const assignmentData = {
identity: selectedIdentity,
phoneNumber: phoneNumber,
permissions: Array.from(selectedPermissions)
};
console.log('保存权限分配数据:', assignmentData);
// 这里应该调用API保存数据
alert('权限分配保存成功!');
// 可选:保存后重置表单
// resetForm();
}
</script>
</body>
</html>

View File

@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>大妈系统平</title>
<title>商家端后</title>
<style>
/* CSS样式将在这里添加 */
* {
@ -205,13 +205,7 @@
<h2>大妈系统平台</h2>
</div>
<ul class="menu">
<li class="menu-item">
<a>
<i>🏠</i>
<span>首页</span>
</a>
</li>
<li class="menu-item">
<li class="menu-item">
<a>
<i>📊</i>
<span>权限管理</span>
@ -220,7 +214,7 @@
<li class="submenu-item">
<a>
<i>📈</i>
<span>权限编辑</span>
<span>账号权限分配</span>
</a>
</li>
<li class="submenu-item">
@ -237,79 +231,7 @@
</li>
</ul>
</li>
<li class="menu-item">
<a>
<i>📦</i>
<span>产品管理</span>
</a>
<ul class="submenu">
<li class="submenu-item">
<a>
<i></i>
<span>新增产品</span>
</a>
</li>
<li class="submenu-item">
<a>
<i>✏️</i>
<span>编辑产品</span>
</a>
</li>
<li class="submenu-item">
<a>
<i>🗑️</i>
<span>删除产品</span>
</a>
</li>
</ul>
</li>
<li class="menu-item">
<a>
<i>👥</i>
<span>用户管理</span>
</a>
<ul class="submenu">
<li class="submenu-item">
<a>
<i>📋</i>
<span>用户列表</span>
</a>
</li>
<li class="submenu-item">
<a>
<i>🔒</i>
<span>权限设置</span>
</a>
</li>
</ul>
</li>
<li class="menu-item">
<a>
<i>⚙️</i>
<span>系统设置</span>
</a>
<ul class="submenu">
<li class="submenu-item">
<a>
<i>🌐</i>
<span>常规设置</span>
</a>
</li>
<li class="submenu-item">
<a>
<i>🎨</i>
<span>外观设置</span>
</a>
</li>
<li class="submenu-item">
<a>
<i>🔌</i>
<span>插件管理</span>
</a>
</li>
</ul>
</li>
</ul>
</ul>
</div>
<!-- 内容区域 -->
@ -385,13 +307,13 @@
// 移除内容区域标题的显示逻辑直接在iframe中显示页面
// 如果是权限编辑或市场经营者创建显示iframe
if (title === '权限编辑') {
if (title === '账号权限分配') {
contentBody.innerHTML = `
<iframe class="content-iframe" src="权限管理/权限编辑.html" onload="injectFullScreenStyles(this)"></iframe>
<iframe class="content-iframe" src="1 权限管理/账号权限分配.html" onload="injectFullScreenStyles(this)"></iframe>
`;
} else if (title === '市场经营者创建') {
contentBody.innerHTML = `
<iframe class="content-iframe" src="权限管理/权限分配.html" onload="injectFullScreenStyles(this)"></iframe>
<iframe class="content-iframe" src="1 权限管理/市场经营者创建.html" onload="injectFullScreenStyles(this)"></iframe>
`;
} else {
// 其他菜单项直接在内容区域显示iframe