2 changed files with 502 additions and 4 deletions
@ -0,0 +1,498 @@ |
|||
# statistics/statistics 页面配套后端接口文档 |
|||
|
|||
## 一、整体架构 |
|||
|
|||
``` |
|||
Controller (StatisticsController.java) |
|||
↓ |
|||
Service 接口 (StatisticsService.java) |
|||
↓ |
|||
Service 实现 (StatisticsServiceImpl.java) |
|||
↓ |
|||
DAO 接口 (StatisticsDao.java) |
|||
↓ |
|||
MyBatis XML (StatisticsDao.xml) |
|||
``` |
|||
|
|||
涉及数据库表:`ems_evaluation`(评估)、`pms_patient`(患者)、`pms_patient_body`(患者身体数据)、`pms_patient_diagnosis`(患者诊断)、`pms_patient_personal`(个人信息)、`rms_report`(报告)、`rms_report_scale_score`(报告量表得分)、`qms_scale`(量表)、`hms_version`(版本)、`ums_user`(用户)、`ums_dept`(部门)、`tb_icd`(ICD疾病编码) |
|||
|
|||
--- |
|||
|
|||
## 二、Controller 层 |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-web-admin\src\main\java\com\ccsens\admin\controller\StatisticsController.java` |
|||
|
|||
- 类注解:`@Slf4j` `@Api(tags = "大屏统计")` `@RestController` `@RequestMapping("/homePage")` |
|||
- 所有接口均为 `@Anonymous`(匿名可访问),`POST` 方法 |
|||
- 每个接口都有相同的科室权限解析逻辑(见下方"公共逻辑") |
|||
|
|||
### 接口清单(共 14 个) |
|||
|
|||
| 序号 | 接口路径 | 方法 | 返回类型 | Swagger 说明 | |
|||
|------|----------|------|----------|-------------| |
|||
| 1 | `/homePage/nntotal` | POST | `JsonResponse<HomeDpVo.Zhsjgl>` | 获取综合数据概览 | |
|||
| 2 | `/homePage/nnbmihjxy` | POST | `JsonResponse<HomeDpVo.Bmi>` | BMI/吸烟饮酒统计 | |
|||
| 3 | `/homePage/nnlast` | POST | `JsonResponse<List<HomeDpVo.Pgqk>>` | 最新评估情况 | |
|||
| 4 | `/homePage/nnage` | POST | `JsonResponse<HomeDpVo.Nlfb>` | 年龄分布 | |
|||
| 5 | `/homePage/nntgb` | POST | `JsonResponse<HomeDpVo.Tz>` | T值分析 | |
|||
| 6 | `/homePage/nnicd` | POST | `JsonResponse<List<HomeDpVo.Jbph>>` | 疾病排行 | |
|||
| 7 | `/homePage/nnmap` | POST | `JsonResponse<List<HomeDpVo.Dt>>` | 地图数据 | |
|||
| 8 | `/homePage/nnscale` | POST | `JsonResponse<List<HomeDpVo.Pgjg>>` | 评估结果统计 | |
|||
| 9 | `/homePage/qualificationStatistics` | POST | `JsonResponse<List<HomeDpVo.QualificationStatistics>>` | 学历统计 | |
|||
| 10 | `/homePage/jzStatistics` | POST | `JsonResponse<HomeDpVo.JzStatistics>` | 就诊数量统计 | |
|||
| 11 | `/homePage/scaleStatistics` | POST | `JsonResponse<List<HomeDpVo.ScaleStatistics>>` | 测评量表统计 | |
|||
| 12 | `/homePage/versionStatistics` | POST | `JsonResponse<List<HomeDpVo.VersionStatistics>>` | 测评版本统计 | |
|||
| 13 | `/homePage/userStatistics` | POST | `JsonResponse<List<HomeDpVo.UserStatistics>>` | 测评师工作量统计 | |
|||
| 14 | `/homePage/sexStatistics` | POST | `JsonResponse<HomeDpVo.SexStatistics>` | 性别统计 | |
|||
| 15 | `/homePage/xyYjStatistics` | POST | `JsonResponse<HomeDpVo.XyYjStatistics>` | 吸烟饮酒统计 | |
|||
|
|||
### 公共逻辑:科室权限解析 deptIdList |
|||
|
|||
每个 Controller 方法都重复以下逻辑(约 20 行): |
|||
|
|||
```java |
|||
List<Long> deptIdList = new ArrayList<>(); |
|||
if (dto.getDeptId() == null) { |
|||
try { |
|||
// 1. 尝试从 header 获取 ksId → 查询权限部门 |
|||
Long ksId = dto.getKsId(); |
|||
HttpServletRequest request = ((ServletRequestAttributes) |
|||
RequestContextHolder.getRequestAttributes()).getRequest(); |
|||
String header = request.getHeader(WebConstant.HEADER_KEY_KS_ID); |
|||
if (StrUtil.isNotEmpty(header)) { |
|||
ksId = Long.parseLong(header); |
|||
} |
|||
deptIdList.addAll(sysPowerService.queryPowerDept(ksId)); |
|||
} catch (Exception e) { |
|||
// 2. 失败时回退:从 header 获取 deptId → 查询权限部门 |
|||
HttpServletRequest request = ((ServletRequestAttributes) |
|||
RequestContextHolder.getRequestAttributes()).getRequest(); |
|||
String deptId = request.getHeader(WebConstant.HEADER_KEY_DEPT_ID); |
|||
if (StrUtil.isNotEmpty(deptId)) { |
|||
deptIdList.addAll(sysPowerService.queryPowerDept(Long.parseLong(deptId))); |
|||
} |
|||
} |
|||
} else { |
|||
deptIdList.add(dto.getDeptId()); |
|||
} |
|||
``` |
|||
|
|||
> ⚠️ **注意**:此逻辑在 15 个方法中完全重复,建议抽取为公共方法。 |
|||
|
|||
--- |
|||
|
|||
## 三、Service 层 |
|||
|
|||
### 3.1 接口 |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\java\com\ccsens\system\service\StatisticsService.java` |
|||
|
|||
定义了 15 个方法,与 Controller 一一对应: |
|||
|
|||
```java |
|||
HomeDpVo.Zhsjgl nntotal(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.Bmi nnbmihjxy(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.Pgqk> nnlast(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.Nlfb nnage(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.Tz nntgb(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.Jbph> nnicd(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.Dt> nnmap(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.Pgjg> nnscale(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.QualificationStatistics> qualificationStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.JzStatistics jzStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.ScaleStatistics> scaleStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.VersionStatistics> versionStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
List<HomeDpVo.UserStatistics> userStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.SexStatistics sexStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
HomeDpVo.XyYjStatistics xyYjStatistics(StatisticsDto.Query dto, List<Long> deptIdLIst); |
|||
``` |
|||
|
|||
### 3.2 实现 |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\java\com\ccsens\system\service\impl\StatisticsServiceImpl.java` |
|||
|
|||
#### 公共逻辑:时间类型转换 `getDateByType()` |
|||
|
|||
每个 Service 方法调用 DAO 前,都先调用此方法转换时间参数: |
|||
|
|||
```java |
|||
if (dto.getTimeType() != null) { |
|||
List<Date> dateByType = getDateByType(dto.getTimeType(), dto.getBeginTime()); |
|||
dto.setBeginTime(dateByType.get(0)); |
|||
dto.setEndTime(dateByType.get(1)); |
|||
} |
|||
``` |
|||
|
|||
转换规则: |
|||
|
|||
| timeType | 含义 | beginTime | endTime | |
|||
|----------|------|-----------|---------| |
|||
| 0 | 本周 | `DateUtil.beginOfWeek(beginTime)` | `DateUtil.endOfWeek(beginTime)` | |
|||
| 1 | 本月 | `DateUtil.beginOfMonth(beginTime)` | `DateUtil.endOfMonth(beginTime)` | |
|||
| 2 | 本年 | `DateUtil.beginOfYear(beginTime)` | `DateUtil.endOfYear(beginTime)` | |
|||
|
|||
#### 各方法特殊逻辑 |
|||
|
|||
**`nntotal`** — 综合数据概览: |
|||
- 先查 `statisticsDao.nntotal()` 获取评估统计 |
|||
- 再分别查 `statisticsDao.getPatientNum()` 获取患者总数、男性数、女性数(sex 参数:null=全部, 0=男, 1=女) |
|||
- 结果对象为 null 时初始化为空对象 |
|||
|
|||
**`sexStatistics`** — 性别统计: |
|||
- new 空对象后,分别调用 `getPatientNum(dto, (byte)0, deptIdLIst)` 和 `getPatientNum(dto, (byte)1, deptIdLIst)` 填充 boy/girl |
|||
|
|||
**`jzStatistics`** — 就诊统计: |
|||
- 调用 `statisticsDao.JzStatistics()` 获取门诊/住院数量及平均/最高/最低评估次数 |
|||
- 结果 null 时返回空 `JzStatistics` 对象 |
|||
- `JzStatistics.getTotal()` 计算方式:`mzNum + zyNum` |
|||
|
|||
**其余方法**均为直接透传 DAO 调用。 |
|||
|
|||
--- |
|||
|
|||
## 四、DAO 层 |
|||
|
|||
### 4.1 DAO 接口 |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\java\com\ccsens\system\persist\dao\StatisticsDao.java` |
|||
|
|||
定义了 18 个方法(比 Service 多 2 个通用查询方法): |
|||
|
|||
| 方法 | 返回类型 | 说明 | |
|||
|------|----------|------| |
|||
| `nntotal` | `HomeDpVo.Zhsjgl` | 综合数据统计 | |
|||
| `getPatientNum` | `Integer` | 通用:按性别统计患者数 | |
|||
| `nnbmihjxy` | `HomeDpVo.Bmi` | BMI/吸烟饮酒 | |
|||
| `nnlast` | `List<HomeDpVo.Pgqk>` | 最新评估情况 | |
|||
| `nnage` | `HomeDpVo.Nlfb` | 年龄分布 | |
|||
| `nntgb` | `HomeDpVo.Tz` | T值分析 | |
|||
| `nnYpzb` | `HomeDpVo.Ypzb` | 药品占比(未暴露到Controller) | |
|||
| `nnicd` | `List<HomeDpVo.Jbph>` | 疾病排行 | |
|||
| `nnmap` | `List<HomeDpVo.Dt>` | 地图数据 | |
|||
| `nnscale` | `List<HomeDpVo.Pgjg>` | 评估结果统计 | |
|||
| `qualificationStatistics` | `List<HomeDpVo.QualificationStatistics>` | 学历统计 | |
|||
| `JzStatistics` | `HomeDpVo.JzStatistics` | 就诊统计(含avg/max/min) | |
|||
| `JzStatisticsNum` | `HomeDpVo.JzStatistics` | 就诊统计(仅avg/max/min,当前未使用) | |
|||
| `scaleStatistics` | `List<HomeDpVo.ScaleStatistics>` | 量表统计 | |
|||
| `versionStatistics` | `List<HomeDpVo.VersionStatistics>` | 版本统计 | |
|||
| `userStatistics` | `List<HomeDpVo.UserStatistics>` | 用户工作量统计 | |
|||
| `sexStatistics` | `HomeDpVo.SexStatistics` | 性别统计(DAO中直接查boy/girl) | |
|||
| `xyYjStatistics` | `HomeDpVo.XyYjStatistics` | 吸烟饮酒统计 | |
|||
|
|||
### 4.2 MyBatis XML |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\resources\mapper\dao\StatisticsDao.xml` |
|||
|
|||
#### SQL 通用模式 |
|||
|
|||
所有查询 SQL 都包含以下条件片段: |
|||
|
|||
```xml |
|||
<!-- 时间过滤 --> |
|||
<if test="dto.beginTime != null"> |
|||
AND xxx.create_time >= #{dto.beginTime} |
|||
</if> |
|||
<if test="dto.endTime != null"> |
|||
AND xxx.create_time <= #{dto.endTime} |
|||
</if> |
|||
|
|||
<!-- 部门过滤 --> |
|||
<if test="deptIdLIst != null and deptIdLIst.size() > 0"> |
|||
AND u.dept_id IN |
|||
<foreach item="item" collection="deptIdLIst" separator="," close=")" index="index" open="("> |
|||
#{item} |
|||
</foreach> |
|||
</if> |
|||
``` |
|||
|
|||
#### 各 SQL 详情 |
|||
|
|||
**1. `nntotal` — 综合数据概览** |
|||
|
|||
```sql |
|||
-- 来源表:ems_evaluation e + ums_user u |
|||
-- 统计: |
|||
-- asstotal = COUNT(DISTINCT e.id) 评估总人次 |
|||
-- ptotal = (子查询) 患者总数 |
|||
-- mtotal = (子查询 sex=0) 男性患者数 |
|||
-- ftotal = (子查询 sex=1) 女性患者数 |
|||
-- v2total = SUM(version=1) 版本1评估数 |
|||
-- v3total = SUM(version=0) 版本0评估数 |
|||
-- 子查询来源:pms_patient |
|||
``` |
|||
|
|||
**2. `getPatientNum` — 通用患者数量查询** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + ums_user u |
|||
-- 条件:p.del_flag = 0, 可选 sex 过滤 |
|||
-- 返回:COUNT(DISTINCT p.id) |
|||
``` |
|||
|
|||
**3. `nnbmihjxy` — BMI 统计** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + pms_patient_body pb + ums_user u |
|||
-- 按体重/身高² 分级统计: |
|||
-- bmi1: < 18.5 (过轻) |
|||
-- bmi2: 18.5 ~ 24 (正常) |
|||
-- bmi3: 24 ~ 28 (超重) |
|||
-- bmi4: 28 ~ 32 (肥胖) |
|||
-- bmi5: >= 32 (非常肥胖) |
|||
-- 注意:公式中使用 weight*10000 而非 10000,可能存在计算偏差 |
|||
``` |
|||
|
|||
**4. `nnlast` — 最新评估情况** |
|||
|
|||
```sql |
|||
-- 来源表:ems_evaluation e + pms_patient p + ums_user u |
|||
-- 条件:e.patient_id != 0 |
|||
-- 排序:e.create_time DESC |
|||
``` |
|||
|
|||
**5. `nntgb` — T值分析** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + ums_user u |
|||
-- t1: tz >= -1 (正常) |
|||
-- t2: -2.5 < tz < -1 (骨量减少) |
|||
-- t3: tz <= -2.5 (骨质疏松) |
|||
``` |
|||
|
|||
**6. `nnYpzb` — 药品占比(未暴露Controller)** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient_body b + ums_user u |
|||
-- 统计每种 drug_name 的数量及占比 |
|||
-- 按 total DESC 排序 |
|||
``` |
|||
|
|||
**7. `nnicd` — 疾病排行** |
|||
|
|||
```sql |
|||
-- 来源表:tb_icd t + pms_patient_diagnosis b + pms_patient_body pb + pms_patient p + ums_user u |
|||
-- 关联条件:t.icd_no = b.diagnosis_code, b.patient_id = pb.patient_id |
|||
-- 按 icd_name GROUP BY,COUNT DESC 排序 |
|||
``` |
|||
|
|||
**8. `nnage` — 年龄分布** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + ums_user u |
|||
-- 子查询计算 TIMESTAMPDIFF(YEAR, birthday, CURDATE()) AS age |
|||
-- 外层按年龄段 SUM CASE WHEN: |
|||
-- lt60 (< 60), f60t69 (60-69), f70t79 (70-79), f80t89 (80-89), f90t (>= 90) |
|||
``` |
|||
|
|||
**9. `nnmap` — 地图数据** |
|||
|
|||
```sql |
|||
-- 来源表:ums_dept |
|||
-- 条件:parent_id = 0 (顶级部门) |
|||
-- 返回:dept_name, lng, lat |
|||
``` |
|||
|
|||
**10. `nnscale` — 评估结果统计** |
|||
|
|||
```sql |
|||
-- 来源表:ems_evaluation e → rms_report rr → rms_report_scale_score rs → qms_scale s + ums_user u + pms_patient p |
|||
-- 硬编码过滤 12 个 scale_code:DCYY-TP, CIRS-G, theFRAILscale, MNA, SARC-CALF, AS, ADL, MMSE, HAMD, HAMA, PSQI, CAM |
|||
-- 统计:abnormal (need_plan=1), normal (need_plan=2) |
|||
-- 注:Pgjg.getName() 中做了 code→中文名 的硬编码映射 |
|||
``` |
|||
|
|||
**11. `qualificationStatistics` — 学历统计** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + ums_user u |
|||
-- 按 educational_status GROUP BY,按 qualification DESC 排序 |
|||
-- 学历码映射(前端做):1=文盲, 2=小学, 3=初中, 4=高中/技校/中专, 5=大专/大学, 6=研究生及以上 |
|||
``` |
|||
|
|||
**12. `JzStatistics` — 就诊统计** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient_body b → pms_patient p → ems_evaluation e → ums_user u |
|||
-- 子查询按 b.id GROUP BY 统计每条就诊记录的评估次数 |
|||
-- 外层: |
|||
-- mzNum: visit_type=0 |
|||
-- zyNum: visit_type=1 |
|||
-- avgNum/avgNum/minNum: 基于每个就诊的 evaluation_count 计算 |
|||
-- 部门过滤同时检查 u.dept_id 和 b.dept_id |
|||
``` |
|||
|
|||
**13. `JzStatisticsNum` — 就诊统计(仅数值,当前未使用)** |
|||
|
|||
```sql |
|||
-- 来源表:ems_evaluation e + ums_user u |
|||
-- 按 visit_no GROUP BY 统计评估次数 |
|||
-- 计算 avgNum/avgNum/minNum |
|||
-- 条件:e.visit_no != '0' AND e.visit_no IS NOT NULL |
|||
``` |
|||
|
|||
**14. `scaleStatistics` — 量表统计** |
|||
|
|||
```sql |
|||
-- 来源表:ems_evaluation e → rms_report rr → rms_report_scale_score rs → qms_scale qs + ums_user u + pms_patient p |
|||
-- 条件:e.del_flag=0 AND qs.del_flag=0 |
|||
-- 按 rs.scale_code GROUP BY |
|||
-- 按 num DESC 排序 |
|||
``` |
|||
|
|||
**15. `versionStatistics` — 版本统计** |
|||
|
|||
```sql |
|||
-- 来源表:hms_version hv → ems_evaluation ee → rms_report r + ums_user u |
|||
-- 条件:hv.del_flag=0 |
|||
-- 按 hv.id GROUP BY |
|||
-- 按 num DESC 排序 |
|||
``` |
|||
|
|||
**16. `userStatistics` — 用户工作量统计** |
|||
|
|||
```sql |
|||
-- 来源表:ums_user u → ems_evaluation ee → rms_report r |
|||
-- 条件:u.del_flag=0 |
|||
-- 按 u.user_id GROUP BY |
|||
-- 按 num DESC 排序 |
|||
``` |
|||
|
|||
**17. `sexStatistics` — 性别统计** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + ums_user u |
|||
-- boy = COUNT(sex=0), girl = COUNT(sex=1) |
|||
``` |
|||
|
|||
**18. `xyYjStatistics` — 吸烟饮酒统计** |
|||
|
|||
```sql |
|||
-- 来源表:pms_patient p + pms_patient_personal pp + ums_user u |
|||
-- 吸烟:smokingCurrent (有吸烟史+未戒烟), smokingNone (无吸烟史), smokingQuit (有吸烟史+已戒烟) |
|||
-- 饮酒:drinkCurrent (有饮酒史+未戒酒), drinkNone (无饮酒史), drinkQuit (有饮酒史+已戒酒) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 五、DTO / VO |
|||
|
|||
### 5.1 入参 DTO |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\java\com\ccsens\system\domain\dto\StatisticsDto.java` |
|||
|
|||
```java |
|||
@Data |
|||
public class StatisticsDto { |
|||
@Data |
|||
public static class Query { |
|||
@ApiModelProperty("时间类型 0周 1月 2年") |
|||
private Byte timeType; |
|||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
|||
private Date beginTime; |
|||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8") |
|||
private Date endTime; |
|||
private Long deptId; // 前端选择的部门ID |
|||
@ApiModelProperty("科室id,为了选择科室查看数据用") |
|||
private Long ksId; // header 透传的科室ID |
|||
} |
|||
} |
|||
``` |
|||
|
|||
### 5.2 出参 VO |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\ruisi_java\ruisi-system\src\main\java\com\ccsens\system\domain\vo\HomeDpVo.java` |
|||
|
|||
| 内部类 | 字段 | 说明 | |
|||
|--------|------|------| |
|||
| `Zhsjgl` | asstotal, ftotal, mtotal, ptotal, plantotal, v1total, v1totalo, v2total, v3count, v3total | 综合数据概览 | |
|||
| `Ypzb` | value | 药品占比(当前未使用) | |
|||
| `Bmi` | bmi1~bmi5, bothno, bothyes, onlydrink, onlysmoking | BMI/吸烟饮酒 | |
|||
| `Pgqk` | name_m, create_by, update_time | 评估情况 | |
|||
| `Nlfb` | all_count, lt60, f60t69, f70t79, f80t89, f90t | 年龄分布 | |
|||
| `Tz` | t1, t2, t3, al, gb, gbratio | T值分析 | |
|||
| `Jbph` | icd_no, name, code, value | 疾病排行 | |
|||
| `Pgjg` | alltotal, name, ntotal, ptotal, sort, scaleCode, normal, abnormal | 评估结果(getName()含code→中文映射) | |
|||
| `Dt` | area_code, latitude, level, longitude, name, orgnum, pname, sysOrgCode | 地图数据 | |
|||
| `QualificationStatistics` | qualification, num | 学历统计 | |
|||
| `JzStatistics` | mzNum, zyNum, avgNum, maxNum, minNum, total(getTotal()=mzNum+zyNum) | 就诊统计 | |
|||
| `VersionStatistics` | id, version, num | 版本统计 | |
|||
| `ScaleStatistics` | code, name, num | 量表统计 | |
|||
| `UserStatistics` | userId, nickName, userName, num | 用户工作量 | |
|||
| `SexStatistics` | boy, girl | 性别统计 | |
|||
| `XyYjStatistics` | smokingCurrent/None/Quit, drinkCurrent/None/Quit | 吸烟饮酒统计 | |
|||
|
|||
### Pgjg 特殊逻辑:`getName()` 中的硬编码映射 |
|||
|
|||
```java |
|||
public String getName() { |
|||
switch (name) { |
|||
case "DCYY-TP": return "多重用药"; |
|||
case "CIRS-G": return "老年共病"; |
|||
case "theFRAILscale": return "衰弱评估"; |
|||
case "MNA": return "营养不良"; |
|||
case "SARC-Calf": return "跌倒风险"; |
|||
case "AS": return "疼痛评估"; |
|||
case "ADL": return "日常生活能力"; |
|||
case "MMSE": return "认知障碍"; |
|||
case "HAMA": return "焦虑评估"; |
|||
case "HAMD": return "抑郁评估"; |
|||
case "PSQI": return "睡眠评估"; |
|||
case "CAM": return "谵妄评估"; |
|||
} |
|||
return name.replaceAll("\\(.*?\\)", ""); // 兜底:去掉括号及内容 |
|||
} |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 六、前端调用的 API 函数 |
|||
|
|||
**文件路径:** `E:\yfrs\cga_v2\web_admin\src\views\index.js` |
|||
|
|||
```javascript |
|||
// 统计页面实际调用的函数及对应接口: |
|||
visitInfoStatistics(param) → POST /homePage/jzStatistics // 就诊统计 |
|||
nntotal(param) → POST /homePage/nntotal // 综合数据/患者总数 |
|||
sexStatistics(param) → POST /homePage/sexStatistics // 性别分布 |
|||
qualificationStatistics(param) → POST /homePage/qualificationStatistics // 学历分布 |
|||
nnage(param) → POST /homePage/nnage // 年龄分布 |
|||
versionStatistics(param) → POST /homePage/versionStatistics // 版本统计 |
|||
scaleStatistics(param) → POST /homePage/scaleStatistics // 量表统计 |
|||
nnicd(param) → POST /homePage/nnicd // 诊断统计 |
|||
nnscale(param) → POST /homePage/nnscale // 评估结果统计 |
|||
userStatistics(param) → POST /homePage/userStatistics // 工作量统计 |
|||
``` |
|||
|
|||
科室树数据来自:`GET /system/user/deptTree`(定义在 `E:\yfrs\cga_v2\web_admin\src\api\system\user.js`) |
|||
|
|||
--- |
|||
|
|||
## 七、数据库表关系图 |
|||
|
|||
``` |
|||
pms_patient (患者) |
|||
├── pms_patient_body (患者就诊/身体数据) → ems_evaluation (评估记录) |
|||
│ └── pms_patient_diagnosis (诊断) ← tb_icd (ICD编码) |
|||
├── pms_patient_personal (个人信息: 吸烟饮酒等) |
|||
└── [关联] ums_user (用户/测评师) |
|||
└── ums_dept (部门) |
|||
|
|||
ems_evaluation (评估记录) |
|||
├── rms_report (报告) |
|||
│ └── rms_report_scale_score (量表得分) |
|||
│ └── qms_scale (量表定义) |
|||
├── hms_version (版本) |
|||
└── ums_user (测评师) |
|||
``` |
|||
|
|||
--- |
|||
|
|||
## 八、潜在优化建议 |
|||
|
|||
1. **Controller 层代码重复**:15 个方法都有相同的 deptIdList 解析逻辑(~20行),建议抽取到公共方法或 AOP 切面中 |
|||
2. **Service 层代码重复**:每个方法都有相同的 `getDateByType()` 调用,同样可抽取 |
|||
3. **硬编码量表列表**:`nnscale` SQL 和 `Pgjg.getName()` 中都有硬编码的 12 个量表 code/中文名,建议移入数据库配置表 |
|||
4. **BMI 计算公式**:`weight/(height*height/10000)` 实际等价于 `weight/(height²)*10000`,与标准 BMI = `weight/height²`(height 以 m 为单位)公式不一致 |
|||
5. **两个 `JzStatistics` SQL**:`JzStatistics` 和 `JzStatisticsNum` 功能有重叠,`JzStatisticsNum` 当前未被使用 |
|||
6. **N+1 查询问题**:`nntotal` 方法调用了 4 次 DAO(nntotal + 3 次 getPatientNum),可在 SQL 层面合并 |
|||
7. **`sexStatistics` DAO 方法未暴露**:DAO 中有独立的 `sexStatistics` 方法,但 Service 实现用的是 `getPatientNum` 分两次查询 |
|||
Loading…
Reference in new issue