mahjong_group/docs/1.0.0/历史需求/站内信页面问题修复说明.md
2026-01-01 14:39:23 +08:00

11 KiB
Raw Blame History

站内信页面问题修复说明

修复日期

2025年12月7日

问题描述

站内信管理页面存在以下问题:

  1. 发送全员广播按钮无反应 - 点击"发送全员广播"按钮没有任何响应
  2. 广播发送页面取消按钮无效 - 点击"取消"按钮无法关闭弹窗
  3. 查看详情页面显示乱码 - 查看消息详情时页面显示为HTML代码而非正常内容
  4. 详情页面关闭按钮无效 - 点击"关闭"按钮无法关闭弹窗

问题原因分析

1. 按钮事件监听问题

原因: 原代码使用了 table.on('toolbar') 事件监听,但按钮放在了自定义的 pagebar 区域 影响: 导致按钮的 lay-event 无法被正确捕获

2. 页面模板结构不规范

原因: details.htmlbroadcast.html 的模板结构与其他页面不一致

  • 缺少 <script type="text/html" template> 包裹
  • 数据访问方式错误(应使用 d.params.data 而非直接 d
  • 缺少必要的初始化脚本

影响: 页面渲染失败,显示为源代码

3. 事件绑定方式不当

原因: 在页面模板内部直接绑定事件,而非在父页面统一管理 影响: 表单提交、按钮点击等事件无法正常工作

修复方案

修复文件清单

  1. CoreCms.Net.Web.Admin\wwwroot\views\sq\sqmessage\index.html
  2. CoreCms.Net.Web.Admin\wwwroot\views\sq\sqmessage\details.html
  3. CoreCms.Net.Web.Admin\wwwroot\views\sq\sqmessage\broadcast.html

具体修复内容

1. index.html - 主页面

修复点1恢复 pagebar 配置

// 在 table.render 配置中添加
pagebar: '#LAY-app-SQMessage-pagebar',
className: 'pagebarbox',

修复点2分离工具栏和操作按钮

<!-- 搜索工具栏 -->
<script type="text/html" id="LAY-app-SQMessage-toolbar">
    <!-- 搜索表单 -->
</script>

<!-- 操作按钮栏 -->
<script type="text/html" id="LAY-app-SQMessage-pagebar">
    <div class="layui-btn-container">
        <button class="layui-btn layui-btn-sm layui-bg-green" lay-event="sendBroadcast">发送全员广播</button>
        <button class="layui-btn layui-btn-sm" lay-event="batchDelete">批量删除</button>
    </div>
</script>

修复点3修改事件监听方式

// 从 table.on('toolbar') 改为 table.on('pagebar')
table.on('pagebar(LAY-app-SQMessage-tableBox)', function (obj) {
    // 事件处理逻辑
});

修复点4统一管理弹窗事件

function sendBroadcast() {
    admin.popup({
        title: '发送全员广播',
        area: ['800px', '600px'],
        id: 'LAY-popup-SQMessage-broadcast',
        success: function (layero, index) {
            view(this.id).render('sq/sqmessage/broadcast', {}).done(function () {
                // 在这里监听表单提交事件
                form.on('submit(LAY-app-SQMessage-broadcastForm-submit)', function (data) {
                    // 提交逻辑
                });
                form.render();
            });
        }
    });
}

修复点5修正数据传递方式

// 查看详情时,数据要包装在 data 对象中
view(this.id).render('sq/sqmessage/details', { data: data })

2. details.html - 详情页面

修复点1使用标准模板结构

<script type="text/html" template lay-done="layui.data.done(d);">
    <div style="overflow: auto;height: 100%;width: 100%;">
        <div class="layui-form coreshop-form layui-form-pane">
            <!-- 表单内容 -->
        </div>
    </div>
</script>

修复点2修正数据访问路径

<!-- 从 {{d.id}} 改为 -->
{{ d.params.data.id || '' }}

修复点3优化布局结构

  • 使用 layui-rowlayui-col-space15 实现响应式布局
  • 使用 layui-form-mid 显示只读数据
  • 移除不必要的关闭按钮(弹窗自带关闭功能)

修复点4添加初始化脚本

<script>
    var debug = layui.setter.debug;
    layui.data.done = function (d) {
        if (debug) { console.log(d.params.data); }
        
        layui.use(['admin', 'form'], function () {
            var form = layui.form;
            form.render(null, 'LAY-app-SQMessage-detailsForm');
        });
    };
</script>

3. broadcast.html - 广播发送页面

修复点1使用标准模板结构

<script type="text/html" template lay-done="layui.data.done(d);">
    <div style="overflow: auto;height: 100%;width: 100%;">
        <div class="layui-form coreshop-form layui-form-pane">
            <!-- 表单内容 -->
        </div>
    </div>
</script>

修复点2规范表单元素

<div class="layui-form-item">
    <label class="layui-form-label layui-form-required">消息标题</label>
    <div class="layui-input-block">
        <input type="text" name="title" lay-verify="required" lay-verType="tips" 
               placeholder="请输入消息标题" class="layui-input" 
               maxlength="200" lay-reqText="请输入消息标题">
    </div>
</div>

修复点3隐藏提交按钮由父页面控制

<div class="layui-form-item text-right core-hidden">
    <input type="button" class="layui-btn" 
           lay-submit 
           lay-filter="LAY-app-SQMessage-broadcastForm-submit" 
           id="LAY-app-SQMessage-broadcastForm-submit" 
           value="立即发送">
</div>

修复点4移除页面内的事件监听

// 删除原有的表单提交和取消按钮事件
// 这些事件统一由 index.html 管理

技术要点总结

1. Layui 弹窗页面开发规范

页面结构标准格式

<script type="text/html" template lay-done="layui.data.done(d);">
    <div style="overflow: auto;height: 100%;width: 100%;">
        <div class="layui-form coreshop-form layui-form-pane" 
             lay-filter="表单名" 
             id="表单ID" 
             style="width: 99%;">
            <!-- 表单内容 -->
            
            <!-- 隐藏的提交按钮用于父页面触发 -->
            <div class="layui-form-item text-right core-hidden">
                <input type="button" class="layui-btn" 
                       lay-submit 
                       lay-filter="提交过滤器名" 
                       value="提交">
            </div>
        </div>
    </div>
</script>

<script>
    var debug = layui.setter.debug;
    layui.data.done = function (d) {
        if (debug) { console.log(d.params); }
        
        layui.use(['admin', 'form', 'coreHelper'], function () {
            var form = layui.form;
            // 初始化表单
            form.render(null, '表单名');
        });
    };
</script>

数据访问规范

  • 详情页面: d.params.data.字段名
  • 创建页面: d.params.data.字段名(后端返回的初始数据)
  • 编辑页面: d.params.data.字段名

布局规范

<!-- 使用栅格布局 -->
<div class="layui-row layui-col-space15">
    <div class="layui-col-md6">
        <div class="layui-form-item">
            <label class="layui-form-label">标签</label>
            <div class="layui-input-block">
                <!-- 表单元素 或 显示元素 -->
            </div>
        </div>
    </div>
</div>

2. Layui Table 事件监听规范

toolbar vs pagebar

  • toolbar 搜索筛选等工具栏,事件监听用 table.on('toolbar')
  • pagebar 操作按钮栏(如添加、删除等),事件监听用 table.on('pagebar')
// 配置
table.render({
    toolbar: '#搜索工具栏ID',
    pagebar: '#操作按钮栏ID',
    className: 'pagebarbox',  // 必须添加
    // ...其他配置
});

// 监听
table.on('pagebar(表格过滤器名)', function (obj) {
    switch (obj.event) {
        case '事件名':
            // 处理逻辑
            break;
    }
});

3. 弹窗事件管理规范

正确做法:在父页面统一管理

function openPopup() {
    admin.popup({
        title: '标题',
        area: ['宽度', '高度'],
        id: '弹窗ID',
        success: function (layero, index) {
            view(this.id).render('页面路径', { data: 数据 }).done(function () {
                // 在这里监听表单事件
                form.on('submit(表单过滤器)', function (data) {
                    var field = data.field;
                    // 提交逻辑
                    admin.closeThisTabs();  // 关闭弹窗
                    table.reload('表格ID');  // 刷新列表
                    return false;
                });
                form.render();
            });
        }
    });
}

错误做法:在子页面绑定事件

// ❌ 不要在弹窗页面内部这样写
$('#按钮ID').on('click', function () {
    var index = parent.layer.getFrameIndex(window.name);
    parent.layer.close(index);
});

验证测试

修复完成后,请测试以下功能:

测试清单

  • 1. 点击"发送全员广播"按钮能正常打开弹窗
  • 2. 广播发送页面显示正常(无乱码)
  • 3. 填写标题和内容后点击"立即发送"能成功发送
  • 4. 发送成功后弹窗自动关闭,列表刷新
  • 5. 点击弹窗右上角"X"能正常关闭
  • 6. 点击"查看"按钮能正常打开详情页面
  • 7. 详情页面显示正常(无乱码),数据正确
  • 8. 点击详情弹窗右上角"X"能正常关闭
  • 9. 批量删除功能正常
  • 10. 搜索筛选功能正常

经验总结

开发建议

  1. 遵循项目现有规范

    • 新页面开发时,先查看现有页面的实现方式
    • 保持代码风格和结构的一致性
  2. 弹窗页面开发要点

    • 必须使用 <script type="text/html" template> 包裹
    • 数据通过 d.params.data 访问
    • 事件统一在父页面管理
    • 提交按钮设为隐藏(core-hidden
  3. 调试技巧

    • 开启 debug 模式:if (debug) { console.log(d); }
    • 检查数据结构:查看 d.params 的内容
    • 验证事件绑定:在事件处理函数中添加 console.log
  4. 常见错误

    • 忘记添加 pagebar 配置和 className: 'pagebarbox'
    • 事件监听用错(toolbar vs pagebar
    • 数据访问路径错误(d.xxx vs d.params.data.xxx
    • 在子页面绑定事件而非父页面

参考页面

本次修复参考了以下页面的实现方式:

  • CoreCms.Net.Web.Admin\wwwroot\views\sq\sqrooms\index.html
  • CoreCms.Net.Web.Admin\wwwroot\views\sq\sqrooms\details.html
  • CoreCms.Net.Web.Admin\wwwroot\views\sq\sqrooms\create.html

这些页面的实现方式符合项目规范,可作为开发模板参考。