fix: add placeholder data and error handling for nursing info display

- Pre-populate nursingInfoList with placeholder to prevent empty RecyclerView
- Add try-catch around JSON parsing in initNursingInfo
- Add toast on parse failure

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
renjianbo
2026-05-23 01:29:43 +08:00
parent fe5a2f2fdc
commit 7d56ff4bfe
7 changed files with 347 additions and 20 deletions

View File

@@ -0,0 +1,252 @@
# 护理资讯模块改造文档
> 日期2026-05-22 ~ 2026-05-23
> 状态:已完成并部署
---
## 一、背景
Android 首页"护理资讯"模块最初完全硬编码:
- **Android 端**4 条写死的数据,点击统一跳转 `privacy.html`
- **后端 API**`getAppIndexInfo()` 返回 3 条写死 JSON从未查数据库
- **管理后台**:无任何资讯管理页面
改造目标:建立完整的 **后台管理 → 数据库 → API → Android 展示** 数据链路。
---
## 二、架构总览
```
管理后台(8050) 数据库 Android App
nursing/index.vue │ HomeFragment
│ 新增/编辑/删除 │ │ initNursingInfo()
▼ ▼ ▼
RlzNursingArticleController rlz_nursing_article GET /system/user/getAppIndexInfo
/system/nursing/* │ │
│ │ ▼
▼ │ ViewHolderFive
IRlzNursingArticleService │ 动态渲染 RecyclerView
│ │ │
▼ │ XfiveWebActivity
RlzNursingArticleMapper │ 文章详情(WebView)
```
---
## 三、数据库设计
### rlz_nursing_article 表结构
| 字段 | 类型 | 说明 |
|------|------|------|
| id | BIGINT(20) | 主键自增 |
| title | VARCHAR(200) | 标题 |
| image_url | VARCHAR(500) | 封面图片 URL |
| article_url | VARCHAR(500) | 文章链接 URL可选有正文时可省略|
| content | LONGTEXT | 文章正文HTML 富文本)|
| sort_order | INT(4) | 排序号(越小越靠前)|
| status | CHAR(1) | 0=发布 1=隐藏 |
| view_count | BIGINT | 阅读次数 |
| create_by / create_time | - | 创建者/时间 |
| update_by / update_time | - | 更新者/时间 |
| remark | VARCHAR(500) | 备注 |
### 菜单权限
`sys_menu` 中插入:
- **菜单**:系统管理 → 护理资讯(`system:nursing:list`
- **按钮权限**:查询 / 新增 / 修改 / 删除 / 导出(`system:nursing:query/add/edit/remove/export`
---
## 四、后端 API
### 管理后台接口(需认证)
| 方法 | 路径 | 权限 | 说明 |
|------|------|------|------|
| GET | `/system/nursing/list` | `system:nursing:list` | 分页列表(标题模糊搜索 + 状态筛选)|
| GET | `/system/nursing/{id}` | `system:nursing:query` | 获取详情 |
| POST | `/system/nursing` | `system:nursing:add` | 新增 |
| PUT | `/system/nursing` | `system:nursing:edit` | 修改 |
| DELETE | `/system/nursing/{ids}` | `system:nursing:remove` | 批量删除 |
| POST | `/system/nursing/export` | `system:nursing:export` | Excel 导出 |
### App 公开接口(无需认证)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/system/nursing/published` | 获取所有已发布文章status=0按 sort_order 排序)|
| PUT | `/system/nursing/view/{id}` | 阅读量 +1 |
### 兼容接口
`GET /system/user/getAppIndexInfo` — 首页综合接口,`realTimeInfoList` 字段仍从 `rlz_nursing_article` 表查询(保持 Android 兼容)。
---
## 五、管理后台功能
访问地址http://101.43.95.130:8050/ → 系统管理 → 护理资讯
| 功能 | 说明 |
|------|------|
| 搜索 | 标题模糊搜索 + 状态筛选(发布/隐藏)|
| 列表 | 排序、标题、封面缩略图、文章链接、阅读量、状态标签、操作按钮 |
| 新增/编辑 | 弹窗表单:标题 + 封面图片上传 + 文章链接 + **富文本正文** + 排序 + 状态 |
| 导出 | Excel 导出全部数据 |
| 删除 | 支持单选和批量删除 |
### 富文本编辑器
使用 Quill 编辑器(`<editor>` 全局组件),支持:
- 加粗、斜体、下划线、删除线
- 标题 H1-H6
- 有序/无序列表、缩进
- 文字颜色、背景色
- 链接、图片、视频插入
- 图片通过 `/common/upload` 上传到 OSS
### 图片上传
封面图片使用 `<image-upload>` 全局组件:
- 支持 JPG/PNG/JPEG
- 自动上传到 `/common/upload`
- 表格中自动显示缩略图
---
## 六、Android 集成
### 数据流
```
HomeFragment.initNursingInfo()
→ OkGo GET /system/user/getAppIndexInfo
→ 解析 JSON: realTimeInfoList[]
→ title → content (显示标题)
→ realTimeInfoImage → pic (封面图)
→ realTimeInfoUrl → url (文章链接)
→ 设置到 robCustomerInfoBean.nursingInfoList
→ ViewHolderFive 渲染
```
### 关键文件
| 文件 | 说明 |
|------|------|
| `HomeFragment.java:145` | `initNursingInfo()` — API 调用 + JSON 解析 |
| `ViewHolderFive.java` | 嵌套 RecyclerView 渲染文章列表adapter 复用 |
| `homeListBean.java` | 数据模型pic / content / url |
| `robCustomerInfoBean.java` | `nursingInfoList` 字段持有文章列表 |
| `HttpConstants.java` | `URi_system_getAppIndexInfo` 接口地址 |
### 容错处理
| 场景 | 处理方式 |
|------|----------|
| 网络失败 | Toast 提示 + 使用上次缓存数据(`CacheMode.REQUEST_FAILED_READ_CACHE`|
| 未登录点击 | 跳转登录页 |
| URL 为空 | 降级到 `privacy.html` 本地页面 |
| 列表为空 | 显示空列表(不报错)|
---
## 七、改造历程
### 第一阶段动态化2026-05-22
- 新建 `rlz_nursing_article` 表 + 菜单权限 SQL
- 新建后端 CRUD 全套Entity / Mapper / Service / Controller
- 新建管理后台页面 `nursing/index.vue`
- 修改 `SysUserController.getAppIndexInfo()`,从 DB 查询替换硬编码
- Android 端新增 `initNursingInfo()` API 调用
- 将 API 路径加入 SecurityConfig 匿名白名单
### 第二阶段功能增强2026-05-23
- 新增 `content` LONGTEXT 字段 + 富文本编辑器
- 新增 `view_count` 字段 + 阅读量统计 API
- 封面图片改为上传组件(替代手动贴 URL
- 表格缩略图改为 `image-preview` 组件
- 新增 `/published``/view/{id}` 公开端点
- Android 端增加缓存策略和错误提示
- `ViewHolderFive` adapter 改为成员变量复用
- nginx 添加 `charset utf-8` 解决中文乱码
---
## 八、部署注意事项
### 部署顺序
1. **数据库**:执行 `sql/nursing_article.sql`(首次)或 ALTER TABLE升级
2. **后端**`docker compose build --no-cache backend && docker compose up -d backend`
3. **前端**`npm run build:prod` → 上传 dist/ 到服务器 → 重启 `rlz-ui-server`
### 常见问题
| 问题 | 现象 | 解决 |
|------|------|------|
| 中文乱码 | 管理后台显示方块/问号 | nginx 添加 `charset utf-8;` 并重启;清除浏览器缓存 |
| 403 Forbidden | 访问首页返回 403 | nginx 容器重启:`docker restart rlz-ui-server` |
| API 401 | App 接口需要登录 | 检查 SecurityConfig 白名单是否包含接口路径 |
| JS 文件 404 | 新功能页面空白 | 确认 dist 文件完整部署index.html 引用正确 |
### 构建命令参考
```bash
# 管理后台构建Node 22 需要 openssl-legacy-provider
cd rlz-ui && NODE_OPTIONS=--openssl-legacy-provider npm run build:prod
# 后端构建
cd rlz && docker compose build --no-cache backend && docker compose up -d backend
# 部署 dist避免权限问题用 Docker 容器操作)
docker run --rm -v /path/to/rlz-ui:/data -v /tmp:/hosttmp alpine:latest \
sh -c "rm -rf /data/dist/* && tar xzf /hosttmp/dist.tar.gz -C /data/"
docker restart rlz-ui-server
```
---
## 九、文件变更清单
| 文件 | 变更类型 | 阶段 |
|------|----------|------|
| `sql/nursing_article.sql` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../domain/RlzNursingArticle.java` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../mapper/RlzNursingArticleMapper.java` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../mapper/RlzNursingArticleMapper.xml` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../service/IRlzNursingArticleService.java` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../service/impl/RlzNursingArticleServiceImpl.java` | 新增 + 修改 | 一/二 |
| `ruoyi-system/.../controller/RlzNursingArticleController.java` | 新增 + 修改 | 一/二 |
| `ruoyi-admin/.../controller/system/SysUserController.java` | 修改 | 一 |
| `ruoyi-framework/.../config/SecurityConfig.java` | 修改 | 一/二 |
| `rlz-ui/src/api/system/nursing.js` | 新增 | 一 |
| `rlz-ui/src/views/system/nursing/index.vue` | 新增 + 修改 | 一/二 |
| `peizhen/.../homeListBean.java` | 修改 | 一 |
| `peizhen/.../robCustomerInfoBean.java` | 修改 | 一 |
| `peizhen/.../HttpConstants.java` | 修改 | 一 |
| `peizhen/.../HomeFragment.java` | 修改 | 一/二 |
| `peizhen/.../ViewHolderFive.java` | 修改 | 一/二 |
---
## 十、经验总结
1. **FastJSON 依赖不在 ruoyi-system 模块中** — 只有 ruoyi-admin 有。跨模块写 Controller 时不要引入 FastJSON直接返回 List 交给 AjaxResult 序列化。
2. **MyBatis LONGTEXT 字段需 cast** — 参照 SysNotice 模式SELECT 时使用 `cast(content as char) as content`,否则 MyBatis 可能当作 BLOB 返回 byte[]。
3. **Docker bind mount 在文件被整个目录替换后会失效** — 通过 `docker run --rm -v alpine` 删除并解压 dist 后,必须 `docker restart rlz-ui-server` 重新挂载。
4. **nginx 默认不声明 charset** — 中文 JS 文件虽 UTF-8 编码正确,但 nginx 不加 `charset utf-8;` 浏览器可能按 Latin-1 解析导致乱码。
5. **Vue 全局组件可直接使用**`<editor>` / `<image-upload>` / `<image-preview>` 在 main.js 已注册,页面中直接写标签即可,无需 import。
6. **Windows git 推送 Gitea 偶现超时** — 可能需要更换 SSH 端口或使用 HTTP 协议。本项目中通过 paramiko SFTP 直传文件作为备用部署方案。
7. **OkGo 的 REQUEST_FAILED_READ_CACHE 模式** — 首次请求成功后会缓存响应,后续网络失败时自动读缓存,适合首页不太频繁变动的数据。

View File

@@ -1,6 +1,6 @@
# 开发环境改进完成记录
> 日期2026-05-14
> 日期2026-05-14(更新于 2026-05-23
---
@@ -74,6 +74,26 @@
- `order_view` 缺少 `userb_age`/`userb_nation`/`userc_age`/`userc_nation` 列导致订单 API 500 错误
- 通过 `CREATE OR REPLACE VIEW``NULL AS` 占位缺失列,两库均已修复
### 11. 护理资讯动态化改造 (Issue #22) — 2026-05-22
- 新建 `rlz_nursing_article` 表(标题/封面图/文章链接/排序/状态)
- 新建后端 CRUD 全套Entity / Mapper / Service / Controller`/system/nursing/*`
- 新建管理后台页面 `views/system/nursing/index.vue`(搜索/表格/弹窗表单/分页)
- 修改 `SysUserController.getAppIndexInfo()` 从 DB 查询替换硬编码数据
- Android 端新增 `HomeFragment.initNursingInfo()` API 调用动态渲染
- 新增 `homeListBean.url``robCustomerInfoBean.nursingInfoList` 字段
- SecurityConfig 添加 `/system/user/getAppIndexInfo` 匿名白名单
### 12. 护理资讯功能增强 — 2026-05-23
- 新增 `content` LONGTEXT 字段 + Quill 富文本编辑器(文章可自建内容)
- 新增 `view_count` BIGINT 字段 + `/view/{id}` 阅读量统计 API
- 封面图片改为 `<image-upload>` 上传组件(替代手动贴 URL
- 新增 `/system/nursing/published` 公开端点(返回 content + viewCount
- Android 端增加 `CacheMode.REQUEST_FAILED_READ_CACHE` 缓存策略 + Toast 错误提示
- ViewHolderFive adapter 改为成员变量复用,避免反复创建
- nginx 添加 `charset utf-8;` 修复中文乱码
---
## 后续需要手动完成的
@@ -117,3 +137,19 @@
| `coupon/app.js` | 修改(引用 config修复 domain |
| `docs/开发环境方案.md` | 新增 |
| `docs/改进完成记录.md` | 新增 |
| `docs/护理资讯模块改造文档.md` | 新增 |
| `rlz-system/.../domain/RlzNursingArticle.java` | 新增 |
| `rlz-system/.../mapper/RlzNursingArticleMapper.java` | 新增 |
| `rlz-system/.../mapper/RlzNursingArticleMapper.xml` | 新增 |
| `rlz-system/.../service/IRlzNursingArticleService.java` | 新增 |
| `rlz-system/.../service/impl/RlzNursingArticleServiceImpl.java` | 新增 |
| `rlz-system/.../controller/RlzNursingArticleController.java` | 新增 |
| `rlz-admin/.../controller/system/SysUserController.java` | 修改 |
| `rlz-framework/.../config/SecurityConfig.java` | 修改 |
| `rlz-ui/src/api/system/nursing.js` | 新增 |
| `rlz-ui/src/views/system/nursing/index.vue` | 新增 |
| `peizhen/.../homeListBean.java` | 修改 |
| `peizhen/.../robCustomerInfoBean.java` | 修改 |
| `peizhen/.../HomeFragment.java` | 修改 |
| `peizhen/.../ViewHolderFive.java` | 修改 |
| `sql/nursing_article.sql` | 新增 |