diff --git a/new_web/merchant/CLAUDE.md b/new_web/merchant/CLAUDE.md index 59c514d..787c1ed 100644 --- a/new_web/merchant/CLAUDE.md +++ b/new_web/merchant/CLAUDE.md @@ -1,248 +1,236 @@ # 信息管理系统原型项目 +## 🚨 核心开发约束(必须严格遵守) + +### 文件分离原则 +1. **HTML内容必须独立存储** - 所有页面内容存储在 `pages/` 目录的独立HTML文件中 +2. **CSS样式必须独立存储** - 所有样式存储在 `css/` 目录的独立CSS文件中 +3. **JavaScript功能必须独立存储** - 所有页面功能存储在 `js/` 目录的独立JS文件中 + +### 严禁事项 ❌ +- **禁止在JavaScript中硬编码HTML内容** - 任何HTML标记都不能出现在JS文件中 +- **禁止在JavaScript中硬编码CSS样式** - 任何CSS样式都不能出现在JS文件中 +- **禁止在HTML中编写大段JavaScript代码** - 仅允许简单的事件调用 +- **禁止随意创建新文件** - 优先编辑现有文件,必须创建时需遵循规范 +- **禁止破坏现有架构模式** - 必须遵循动态加载和模块化原则 + +### 必须遵循 ✅ +- **所有页面内容存储在pages/目录** +- **所有页面样式存储在css/目录** +- **所有页面功能存储在js/目录** +- **JavaScript仅处理逻辑,通过fetch加载HTML和CSS** +- **每个JavaScript模块必须包含初始化函数** +- **使用中文界面文本** +- **遵循文件命名和结构约定** + ## 项目概述 -这是一个传统的中文信息管理系统原型,采用纯HTML/CSS/JavaScript技术栈,实现左侧菜单栏 + 中央tab展示区域的经典布局。项目专注于演示系统架构和交互流程,不追求视觉美观。 +这是一个传统的中文信息管理系统原型,采用纯HTML/CSS/JavaScript技术栈,实现左侧菜单栏 + 中央tab展示区域的经典布局。项目专注于演示系统架构和交互流程,严格遵循内容、样式、逻辑三分离原则。 -## 核心架构 +## 文件结构规范 -### 技术栈 -- **前端**: 纯HTML5 + CSS3 + 原生JavaScript ES6+ -- **架构模式**: 单页应用(SPA) + 动态内容加载 -- **样式系统**: 自定义CSS,无外部框架依赖 -- **模块化**: 页面内容与逻辑完全分离 - -### 文件结构 ``` merchant/ ├── index.html # 主框架页面 ├── styles.css # 全局样式文件 ├── script.js # 核心JavaScript逻辑 +├── css/ # 专用样式目录 +│ ├── coupon-modal.css # 优惠券弹窗样式 +│ └── ... # 其他专用样式 ├── js/ # 页面功能模块目录 -│ ├── level-settings.js # 等级设置页面功能 -│ └── member-view.js # 会员查看页面功能(待创建) +│ ├── level-settings.js # 等级设置页面功能 +│ ├── level-edit.js # 等级编辑页面功能 +│ └── ... # 其他页面功能 ├── pages/ # 页面内容目录 -│ ├── level-settings.html # 等级设置页面 -│ └── member-view.html # 会员查看页面 +│ ├── level-settings.html # 等级设置页面 +│ ├── coupon-modal.html # 优惠券弹窗内容 +│ └── ... # 其他页面内容 └── CLAUDE.md # 项目文档 ``` -### 架构特点 -1. **内容与逻辑分离**: 所有页面内容存储为独立HTML文件 -2. **模块化JavaScript**: 每个页面的功能逻辑独立存储在对应的JS文件中 -3. **动态加载**: 使用fetch API异步加载页面内容和对应的JavaScript模块 -4. **智能初始化**: 自动检测并加载页面对应的JavaScript文件,调用初始化函数 -5. **Tab管理**: 支持多页面同时打开,可独立关闭 -6. **菜单系统**: 二级菜单展开/收起,防重复打开 +## 开发流程规范 -## 核心功能 +### 1. 添加新功能的标准流程 -### 左侧菜单系统 -- **一级菜单**: 主功能模块入口 -- **二级菜单**: 具体功能页面,点击展开/收起 -- **当前实现**: 会员管理 > 等级设置、会员查看 +#### Step 1: 创建HTML内容文件 +```bash +# 在pages/目录创建页面内容 +pages/feature-name.html +``` -### 中央Tab系统 -- **多页面管理**: 支持同时打开多个页面tab -- **防重复**: 相同页面不会重复打开,直接激活已存在tab -- **可关闭**: 每个tab都有独立关闭按钮(首页除外) -- **智能切换**: 关闭当前tab时自动激活相邻tab +#### Step 2: 创建CSS样式文件(如需要) +```bash +# 在css/目录创建专用样式 +css/feature-name.css +``` -### 页面加载机制 -- **异步加载**: 使用`fetch`API动态加载HTML内容和JavaScript模块 -- **自动检测**: 根据页面名称自动查找对应的JavaScript文件 -- **智能缓存**: JavaScript模块避免重复加载,提高性能 -- **初始化调用**: 自动调用页面对应的初始化函数 -- **错误处理**: 包含完整的加载失败降级方案 +#### Step 3: 创建JavaScript功能文件 +```bash +# 在js/目录创建功能逻辑 +js/feature-name.js +``` -## 开发约束和规范 - -### 重要约束 ⚠️ -1. **禁止硬编码HTML**: 所有页面内容必须存储在独立的HTML文件中 -2. **模块化JavaScript**: 每个页面的JavaScript功能必须独立存储在对应的JS文件中 -3. **优先编辑现有文件**: 禁止随意创建新文件,优先修改现有文件 -4. **保持架构一致性**: 新页面必须遵循现有的加载和展示模式 -5. **中文本地化**: 所有界面文本必须使用中文 -6. **避免内联脚本**: 页面HTML中不应包含大段JavaScript代码 - -### JavaScript模块化规范 +#### Step 4: JavaScript模块标准结构 ```javascript -// 页面JavaScript文件结构示例:js/page-name.js +// js/feature-name.js /** - * 页面功能模块 - * 包含该页面的所有交互逻辑 + * 功能模块名称 + * 功能描述 */ // 页面初始化函数(必需) -function initPageName() { - console.log('页面已初始化'); - // 页面特定的初始化逻辑 - setupEventListeners(); +function initFeatureName() { + console.log('功能模块已初始化'); + // 如果需要CSS,动态加载 + loadFeatureCSS(); + // 其他初始化逻辑 } -// 页面功能函数 +// 加载专用CSS(如需要) +function loadFeatureCSS() { + if (!document.getElementById('featureCSS')) { + const link = document.createElement('link'); + link.id = 'featureCSS'; + link.rel = 'stylesheet'; + link.href = 'css/feature-name.css'; + document.head.appendChild(link); + } +} + +// 功能函数 function someFunction() { - // 功能实现 + // 功能实现,仅处理逻辑 + // 需要HTML时使用fetch加载 } -// 将需要在HTML中调用的函数暴露到全局作用域 +// 暴露到全局作用域供HTML调用 window.someFunction = someFunction; // 页面清理函数(可选) -function cleanupPageName() { +function cleanupFeatureName() { // 清理事件监听器等 } ``` -### 开发规范 -```javascript -// 添加新页面的步骤: -// 1. 在pages/目录创建对应的HTML文件 -// 2. 在js/目录创建对应的JavaScript文件 -// 3. 在HTML中添加新的菜单项,指向该页面 -// 4. 确保contentType参数与文件名匹配 +### 2. 动态内容加载规范 -// 正确的调用方式: -onclick="openTab('新页面', 'new-page')" -// 对应文件: -// - pages/new-page.html (页面内容) -// - js/new-page.js (页面功能) +#### HTML内容加载 +```javascript +// 正确的HTML加载方式 +async function loadHTMLContent() { + try { + const response = await fetch('pages/content.html'); + const htmlContent = await response.text(); + document.getElementById('container').innerHTML = htmlContent; + } catch (error) { + console.error('加载失败:', error); + } +} ``` -### 文件命名规范 -- 页面文件:`pages/功能名称.html` (使用kebab-case) -- JavaScript文件:`js/功能名称.js` (使用kebab-case,与页面文件名保持一致) -- 初始化函数:`init[功能名称CamelCase]()` (自动调用) -- contentType参数:与文件名保持一致 -- Tab标题:使用中文友好名称 +#### CSS样式加载 +```javascript +// 正确的CSS加载方式 +function loadCSS(cssFile, id) { + if (!document.getElementById(id)) { + const link = document.createElement('link'); + link.id = id; + link.rel = 'stylesheet'; + link.href = `css/${cssFile}`; + document.head.appendChild(link); + } +} +``` -## 核心函数说明 +### 3. 文件命名规范 +- **页面文件**: `pages/功能名称.html` (kebab-case) +- **样式文件**: `css/功能名称.css` (kebab-case) +- **脚本文件**: `js/功能名称.js` (kebab-case) +- **初始化函数**: `init[功能名称CamelCase]()` +- **CSS ID**: `功能名称CSS` (CamelCase) -### `openTab(title, contentType)` -- **参数**: title(中文标题), contentType(文件名前缀) -- **功能**: 创建新tab并异步加载页面内容 -- **特性**: 防重复打开、错误处理、自动激活 +## 架构特点 -### `loadPageContent(contentType)` -- **参数**: contentType(对应pages/目录下的文件名) -- **返回**: Promise HTML内容 -- **功能**: 异步加载页面HTML内容,并自动加载对应的JavaScript模块 -- **错误处理**: 加载失败时返回默认提示内容 +### 三分离原则 +1. **内容层(HTML)**: 存储页面结构和内容,不包含样式和逻辑 +2. **表现层(CSS)**: 存储样式定义,不包含内容和逻辑 +3. **逻辑层(JavaScript)**: 存储交互逻辑,通过API加载内容和样式 -### `loadPageScript(contentType)` -- **参数**: contentType(对应js/目录下的文件名) -- **功能**: 动态加载页面对应的JavaScript文件 -- **特性**: 避免重复加载,自动调用初始化函数 -- **命名转换**: 自动将kebab-case转换为CamelCase调用初始化函数 +### 动态加载机制 +- **按需加载**: 只有需要时才加载对应的HTML、CSS、JS +- **智能缓存**: 避免重复加载已加载的资源 +- **错误处理**: 完整的加载失败降级方案 +- **自动初始化**: 自动调用页面对应的初始化函数 -### `toggleSubmenu(submenuId)` -- **参数**: submenuId(子菜单DOM元素ID) -- **功能**: 切换子菜单展开/收起状态 -- **特性**: 互斥展开(同时只能展开一个子菜单) +### 模块化管理 +- **独立开发**: 每个功能模块可独立开发和维护 +- **标准接口**: 统一的初始化和清理函数接口 +- **全局暴露**: 需要在HTML中调用的函数暴露到window对象 -## 扩展指南 +## 核心功能 -### 添加新的功能模块 -1. **创建一级菜单**: - ```html - - ``` +### 左侧菜单系统 +- 一级菜单:主功能模块入口 +- 二级菜单:具体功能页面,支持展开/收起 +- 互斥展开:同时只能展开一个子菜单 -2. **添加二级菜单项**: - ```html - - ``` +### 中央Tab系统 +- 多页面管理:支持同时打开多个页面tab +- 防重复打开:相同页面直接激活已存在tab +- 智能关闭:关闭当前tab时自动激活相邻tab -3. **创建页面内容和功能**: - ```bash - # 在pages/目录创建对应HTML文件 - pages/function-name.html - - # 在js/目录创建对应JavaScript文件 - js/function-name.js - ``` +## 开发示例 -4. **JavaScript模块结构**: - ```javascript - // js/function-name.js - function initFunctionName() { - console.log('功能模块已初始化'); - // 初始化逻辑 - } - - function someFeature() { - // 功能实现 - } - - // 暴露到全局作用域供HTML调用 - window.someFeature = someFeature; - ``` +### 弹窗功能示例 +以优惠券弹窗为例,展示标准的三分离开发模式: -### 页面内容模板 +1. **HTML内容** (`pages/coupon-modal.html`) ```html -
-

页面标题

- - -
- - + ``` +2. **CSS样式** (`css/coupon-modal.css`) +```css +.modal-overlay { + /* 弹窗样式定义 */ +} +``` + +3. **JavaScript逻辑** (`js/level-edit.js`) +```javascript +async function showCouponModal(level) { + // 加载CSS + loadCouponModalCSS(); + // 加载HTML + const response = await fetch('pages/coupon-modal.html'); + const modalHtml = await response.text(); + document.body.insertAdjacentHTML('beforeend', modalHtml); +} +``` + ## 样式系统 -### CSS类命名规范 -- `.page-content`: 页面内容容器 -- `.form-group`: 表单字段组 -- `.btn`, `.btn-primary`: 按钮样式 -- `.table`: 数据表格 -- `.menu-item`, `.submenu-item`: 菜单项 +### 全局样式 +- `styles.css`: 基础框架样式 +- 主题色彩:深蓝色主调,蓝色高亮 -### 主题色彩 -- 主色调:深蓝色 `#2c3e50` -- 高亮色:蓝色 `#3498db` -- 背景色:浅灰 `#f5f5f5` -- 边框色:灰色 `#bdc3c7` +### 模块样式 +- 每个功能模块可有独立的CSS文件 +- 按需动态加载,避免样式冲突 +- 使用有意义的CSS类名 -## 测试和部署 +## 技术要求 -### 本地运行 +### 运行环境 ```bash -# 推荐使用本地HTTP服务器(必需,因为使用了fetch API) +# 必须使用HTTP服务器(fetch API要求) python -m http.server 8000 # 或 npx serve . -# 然后访问 http://localhost:8000 ``` ### 浏览器兼容性 @@ -251,44 +239,20 @@ npx serve . - Safari 12+ - Edge 79+ -### 快捷键 -- `ESC`: 关闭当前激活的tab(首页除外) - -## 注意事项 - -### 开发限制 -- ❌ 不要在JavaScript中硬编码HTML内容 -- ❌ 不要在页面HTML中编写大段JavaScript代码 -- ❌ 不要随意创建新文件,优先编辑现有文件 -- ❌ 不要破坏现有的架构模式 -- ❌ 不要跳过JavaScript模块的初始化函数 -- ✅ 所有页面内容必须存储在pages/目录 -- ✅ 所有页面功能必须存储在js/目录对应文件中 -- ✅ 每个JavaScript模块必须包含初始化函数 -- ✅ 使用中文界面文本 -- ✅ 遵循现有的命名和结构约定 - -### 技术限制 -- 必须运行在HTTP服务器环境(不支持file://协议) -- 依赖现代浏览器的fetch API和ES6特性 -- 所有数据都是前端模拟,无后端API集成 - ## 项目目标 -此项目是一个快速原型系统,用于演示传统管理系统的布局意图和交互流程。专注于功能架构而非视觉设计,为后续开发提供清晰的技术基础和扩展方向。 +此项目是快速原型系统,用于演示传统管理系统的布局和交互流程。严格遵循内容、样式、逻辑分离原则,为团队协作和后续开发提供清晰的技术基础。 -## JavaScript模块化架构优势 +## 开发检查清单 -### 维护性 -- **代码分离**: 每个页面的功能逻辑独立,便于维护和调试 -- **模块清晰**: 避免全局script.js文件过于庞大 -- **团队协作**: 不同开发者可以独立开发不同页面的功能 +在开发任何功能前,请确认: -### 性能优化 -- **按需加载**: 只有打开页面时才加载对应的JavaScript文件 -- **避免重复**: 已加载的模块不会重复加载 -- **内存管理**: 可以在页面关闭时进行资源清理 +- [ ] 是否创建了独立的HTML文件存储内容? +- [ ] 是否创建了独立的CSS文件存储样式? +- [ ] JavaScript中是否避免了硬编码HTML和CSS? +- [ ] 是否使用fetch API动态加载内容和样式? +- [ ] 是否包含了初始化函数? +- [ ] 是否将需要调用的函数暴露到全局作用域? +- [ ] 文件命名是否遵循kebab-case规范? +- [ ] 是否使用了中文界面文本? -### 可扩展性 -- **标准化流程**: 新增页面功能有明确的开发流程 -- **自动化集成**: 新JavaScript模块会被系统自动检测和加载 -- **灵活扩展**: 可以轻松为现有页面添加新功能 \ No newline at end of file +**记住:内容、样式、逻辑三分离是本项目的核心原则,违反此原则的代码不被接受。** \ No newline at end of file diff --git a/new_web/merchant/css/coupon-modal.css b/new_web/merchant/css/coupon-modal.css new file mode 100644 index 0000000..6915154 --- /dev/null +++ b/new_web/merchant/css/coupon-modal.css @@ -0,0 +1,123 @@ +.modal-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-color: rgba(0, 0, 0, 0.5); + display: flex; + justify-content: center; + align-items: center; + z-index: 1000; +} + +.modal-content { + background: white; + border-radius: 8px; + width: 400px; + max-width: 90vw; + max-height: 90vh; + overflow-y: auto; +} + +.modal-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 20px; + border-bottom: 1px solid #eee; +} + +.modal-header h3 { + margin: 0; + font-size: 18px; + color: #333; +} + +.modal-close { + background: none; + border: none; + font-size: 24px; + cursor: pointer; + color: #999; + padding: 0; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.modal-close:hover { + color: #333; +} + +.modal-body { + padding: 20px; +} + +.modal-footer { + display: flex; + justify-content: flex-end; + gap: 10px; + padding: 20px; + border-top: 1px solid #eee; +} + +.form-group { + margin-bottom: 16px; +} + +.form-group label { + display: block; + margin-bottom: 8px; + font-weight: 500; + color: #333; +} + +.required { + color: #e74c3c; + margin-right: 4px; +} + +.input-with-dropdown { + position: relative; + display: flex; +} + +.input-with-dropdown .form-input { + flex: 1; + padding-right: 40px; +} + +.dropdown-btn { + position: absolute; + right: 8px; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + cursor: pointer; + color: #666; + font-size: 12px; +} + +.btn-secondary { + background-color: #f8f9fa; + color: #6c757d; + border: 1px solid #dee2e6; +} + +.btn-secondary:hover { + background-color: #e9ecef; +} + +.btn-primary { + background-color: #007bff; + color: white; + border: 1px solid #007bff; +} + +.btn-primary:hover { + background-color: #0056b3; +} \ No newline at end of file diff --git a/new_web/merchant/js/level-edit.js b/new_web/merchant/js/level-edit.js index 88733f1..5f396e1 100644 --- a/new_web/merchant/js/level-edit.js +++ b/new_web/merchant/js/level-edit.js @@ -192,7 +192,73 @@ function updateEditTable(editData) { // 添加优惠券功能 function addCoupon(level) { - alert(`为${level}添加生日优惠券功能开发中...`); + showCouponModal(level); +} + +// 显示优惠券添加弹窗 +async function showCouponModal(level) { + try { + // 加载CSS样式 + loadCouponModalCSS(); + + // 加载HTML内容 + const response = await fetch('pages/coupon-modal.html'); + const modalHtml = await response.text(); + + // 添加到页面 + document.body.insertAdjacentHTML('beforeend', modalHtml); + + // 存储当前等级信息 + window.currentCouponLevel = level; + + } catch (error) { + console.error('加载优惠券弹窗失败:', error); + alert('加载弹窗失败,请重试'); + } +} + +// 加载优惠券弹窗CSS +function loadCouponModalCSS() { + if (!document.getElementById('couponModalCSS')) { + const link = document.createElement('link'); + link.id = 'couponModalCSS'; + link.rel = 'stylesheet'; + link.href = 'css/coupon-modal.css'; + document.head.appendChild(link); + } +} + +// 关闭优惠券弹窗 +function closeCouponModal() { + const modal = document.getElementById('couponModal'); + if (modal) { + modal.remove(); + } +} + +// 确认添加优惠券 +function confirmAddCoupon() { + const couponName = document.getElementById('couponName').value; + const threshold = document.getElementById('couponThreshold').value; + const discount = document.getElementById('couponDiscount').value; + const validity = document.getElementById('couponValidity').value; + const level = window.currentCouponLevel; + + if (!couponName.trim()) { + alert('请输入优惠券名称'); + return; + } + + console.log('添加优惠券:', { + level: level, + name: couponName, + threshold: threshold, + discount: discount, + validity: validity + }); + + alert(`已为${level}添加优惠券"${couponName}"`); + closeCouponModal(); } // 保存等级编辑 @@ -232,6 +298,8 @@ function collectFormData() { // 将需要在HTML中调用的函数暴露到全局作用域 window.addCoupon = addCoupon; window.saveLevelEdit = saveLevelEdit; +window.closeCouponModal = closeCouponModal; +window.confirmAddCoupon = confirmAddCoupon; // 页面清理函数(可选) function cleanupLevelEdit() { diff --git a/new_web/merchant/pages/coupon-modal.html b/new_web/merchant/pages/coupon-modal.html new file mode 100644 index 0000000..5cf0d2a --- /dev/null +++ b/new_web/merchant/pages/coupon-modal.html @@ -0,0 +1,39 @@ + \ No newline at end of file