349 lines
11 KiB
Markdown
349 lines
11 KiB
Markdown
# 站内信页面问题修复说明
|
||
|
||
## 修复日期
|
||
2025年12月7日
|
||
|
||
## 问题描述
|
||
|
||
站内信管理页面存在以下问题:
|
||
1. **发送全员广播按钮无反应** - 点击"发送全员广播"按钮没有任何响应
|
||
2. **广播发送页面取消按钮无效** - 点击"取消"按钮无法关闭弹窗
|
||
3. **查看详情页面显示乱码** - 查看消息详情时,页面显示为HTML代码而非正常内容
|
||
4. **详情页面关闭按钮无效** - 点击"关闭"按钮无法关闭弹窗
|
||
|
||
## 问题原因分析
|
||
|
||
### 1. 按钮事件监听问题
|
||
**原因:** 原代码使用了 `table.on('toolbar')` 事件监听,但按钮放在了自定义的 `pagebar` 区域
|
||
**影响:** 导致按钮的 `lay-event` 无法被正确捕获
|
||
|
||
### 2. 页面模板结构不规范
|
||
**原因:** `details.html` 和 `broadcast.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 配置**
|
||
```javascript
|
||
// 在 table.render 配置中添加
|
||
pagebar: '#LAY-app-SQMessage-pagebar',
|
||
className: 'pagebarbox',
|
||
```
|
||
|
||
**修复点2:分离工具栏和操作按钮**
|
||
```html
|
||
<!-- 搜索工具栏 -->
|
||
<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:修改事件监听方式**
|
||
```javascript
|
||
// 从 table.on('toolbar') 改为 table.on('pagebar')
|
||
table.on('pagebar(LAY-app-SQMessage-tableBox)', function (obj) {
|
||
// 事件处理逻辑
|
||
});
|
||
```
|
||
|
||
**修复点4:统一管理弹窗事件**
|
||
```javascript
|
||
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:修正数据传递方式**
|
||
```javascript
|
||
// 查看详情时,数据要包装在 data 对象中
|
||
view(this.id).render('sq/sqmessage/details', { data: data })
|
||
```
|
||
|
||
#### 2. details.html - 详情页面
|
||
|
||
**修复点1:使用标准模板结构**
|
||
```html
|
||
<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:修正数据访问路径**
|
||
```html
|
||
<!-- 从 {{d.id}} 改为 -->
|
||
{{ d.params.data.id || '' }}
|
||
```
|
||
|
||
**修复点3:优化布局结构**
|
||
- 使用 `layui-row` 和 `layui-col-space15` 实现响应式布局
|
||
- 使用 `layui-form-mid` 显示只读数据
|
||
- 移除不必要的关闭按钮(弹窗自带关闭功能)
|
||
|
||
**修复点4:添加初始化脚本**
|
||
```javascript
|
||
<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:使用标准模板结构**
|
||
```html
|
||
<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:规范表单元素**
|
||
```html
|
||
<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:隐藏提交按钮(由父页面控制)**
|
||
```html
|
||
<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:移除页面内的事件监听**
|
||
```javascript
|
||
// 删除原有的表单提交和取消按钮事件
|
||
// 这些事件统一由 index.html 管理
|
||
```
|
||
|
||
## 技术要点总结
|
||
|
||
### 1. Layui 弹窗页面开发规范
|
||
|
||
#### 页面结构标准格式
|
||
```html
|
||
<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.字段名`
|
||
|
||
#### 布局规范
|
||
```html
|
||
<!-- 使用栅格布局 -->
|
||
<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')`
|
||
|
||
```javascript
|
||
// 配置
|
||
table.render({
|
||
toolbar: '#搜索工具栏ID',
|
||
pagebar: '#操作按钮栏ID',
|
||
className: 'pagebarbox', // 必须添加
|
||
// ...其他配置
|
||
});
|
||
|
||
// 监听
|
||
table.on('pagebar(表格过滤器名)', function (obj) {
|
||
switch (obj.event) {
|
||
case '事件名':
|
||
// 处理逻辑
|
||
break;
|
||
}
|
||
});
|
||
```
|
||
|
||
### 3. 弹窗事件管理规范
|
||
|
||
**正确做法:在父页面统一管理**
|
||
```javascript
|
||
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();
|
||
});
|
||
}
|
||
});
|
||
}
|
||
```
|
||
|
||
**错误做法:在子页面绑定事件**
|
||
```javascript
|
||
// ❌ 不要在弹窗页面内部这样写
|
||
$('#按钮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`
|
||
|
||
这些页面的实现方式符合项目规范,可作为开发模板参考。
|