Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
@@ -1,16 +1,14 @@
|
||||
package com.openhis.web.doctorstation.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.template.domain.DoctorPhrase;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IDoctorPhraseAppService {
|
||||
R<?> getDoctorPhraseList();
|
||||
List<DoctorPhrase> getDoctorPhraseList();
|
||||
List<DoctorPhrase> searchDoctorPhraseList(String phraseName, Integer phraseType);
|
||||
Boolean addDoctorPhrase(DoctorPhrase doctorPhrase);
|
||||
Boolean updateDoctorPhrase(DoctorPhrase doctorPhrase);
|
||||
Boolean deleteDoctorPhrase(Integer doctorPhraseId);
|
||||
|
||||
R<?> searchDoctorPhraseList(String phraseName ,Integer phraseType);
|
||||
|
||||
R<?> addDoctorPhrase(DoctorPhrase doctorPhrase);
|
||||
|
||||
R<?> updateDoctorPhrase(DoctorPhrase doctorPhrase);
|
||||
|
||||
R<?> deleteDoctorPhrase(Integer doctorPhraseId);
|
||||
}
|
||||
|
||||
@@ -2,30 +2,71 @@ package com.openhis.web.doctorstation.appservice.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.openhis.common.enums.BindingType;
|
||||
import com.openhis.template.domain.DoctorPhrase;
|
||||
import com.openhis.template.service.IDoctorPhraseService;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorPhraseAppService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DoctorPhraseAppServiceImpl implements IDoctorPhraseAppService {
|
||||
|
||||
@Resource
|
||||
private IDoctorPhraseService doctorPhraseService;
|
||||
|
||||
@Override
|
||||
public R<?> getDoctorPhraseList() {
|
||||
List<DoctorPhrase> list = doctorPhraseService.list();
|
||||
return R.ok(list);
|
||||
@Override
|
||||
public List<DoctorPhrase> getDoctorPhraseList() {
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("orgId: {}", orgId);
|
||||
}
|
||||
LambdaQueryWrapper<DoctorPhrase> wrapper = new LambdaQueryWrapper<>();
|
||||
|
||||
// 1. 获取当前登录用户信息
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
// 2. 权限判定:非管理员才需要过滤
|
||||
// 如果是超级管理员,默认可以看到所有
|
||||
if (!SecurityUtils.isAdmin(userId)) {
|
||||
// 3. 获取当前医生的科室编码
|
||||
String deptCode = "";
|
||||
if (orgId != null) {
|
||||
deptCode = String.valueOf(orgId);
|
||||
}
|
||||
// final 变量用于 Lambda 表达式
|
||||
String finalDeptCode = deptCode;
|
||||
// 4. 核心逻辑:三级数据共享
|
||||
wrapper.and(w -> w
|
||||
.eq(DoctorPhrase::getStaffId, userId.intValue()) // 1. 个人的:只看 staffId 是我的
|
||||
.or(o -> o.eq(DoctorPhrase::getPhraseType, BindingType.HOSPITAL.getValue())) // 2. 全院的:类型为 3
|
||||
.or(o -> o.eq(DoctorPhrase::getPhraseType, BindingType.ORGANIZATION.getValue()) // 3. 科室的:类型为 2 且 科室编码匹配
|
||||
.eq(DoctorPhrase::getDeptCode, finalDeptCode))
|
||||
);
|
||||
}
|
||||
// 5. 按排序号排序(可选优化,让常用语显示更整齐)
|
||||
List<DoctorPhrase> list = doctorPhraseService.list(wrapper);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> searchDoctorPhraseList(String phraseName,Integer phraseType) {
|
||||
public List<DoctorPhrase> searchDoctorPhraseList(String phraseName,Integer phraseType) {
|
||||
// 1. 获取当前登录用户信息
|
||||
Long userId = SecurityUtils.getUserId();
|
||||
//2.获取到当前医生当前科室的id
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Search phrase - orgId: {}, phraseName: {}, phraseType: {}", orgId, phraseName, phraseType);
|
||||
}
|
||||
String deptCode = "";
|
||||
if (orgId != null) {
|
||||
deptCode = String.valueOf(orgId);
|
||||
}
|
||||
String finalDeptCode = deptCode;
|
||||
LambdaQueryWrapper<DoctorPhrase> wrapper = new LambdaQueryWrapper<>();
|
||||
if (phraseName !=null && ObjectUtil.isNotEmpty(phraseName)) {
|
||||
wrapper.like(DoctorPhrase::getPhraseName, phraseName);
|
||||
@@ -33,50 +74,135 @@ public class DoctorPhraseAppServiceImpl implements IDoctorPhraseAppService {
|
||||
if (phraseType !=null && ObjectUtil.isNotEmpty(phraseType)) {
|
||||
wrapper.eq(DoctorPhrase::getPhraseType, phraseType);
|
||||
}
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
if (!SecurityUtils.isAdmin(currentUserId)) {
|
||||
// 建议统一使用 staffId 进行业务隔离
|
||||
wrapper.and(w -> w
|
||||
.eq(DoctorPhrase::getStaffId, userId.intValue()) // 1. 个人的:只看 staffId 是我的
|
||||
.or(o -> o.eq(DoctorPhrase::getPhraseType, BindingType.HOSPITAL.getValue())) // 2. 全院的:类型为 3
|
||||
.or(o -> o.eq(DoctorPhrase::getPhraseType, BindingType.ORGANIZATION.getValue()) // 3. 科室的:类型为 2 且 科室编码匹配
|
||||
.eq(DoctorPhrase::getDeptCode, finalDeptCode))
|
||||
);
|
||||
}
|
||||
//2.查询
|
||||
List<DoctorPhrase> list = doctorPhraseService.list(wrapper);
|
||||
return R.ok(list);
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> addDoctorPhrase(DoctorPhrase doctorPhrase) {
|
||||
//1.数据校验
|
||||
if(ObjectUtil.isEmpty(doctorPhrase)){
|
||||
return R.fail("医生常用语不能为空");
|
||||
public Boolean addDoctorPhrase(DoctorPhrase doctorPhrase) {
|
||||
// 1. 基础校验
|
||||
if (ObjectUtil.isEmpty(doctorPhrase) || ObjectUtil.isEmpty(doctorPhrase.getPhraseName())) {
|
||||
throw new IllegalArgumentException("新增失败:常用语名称不能为空");
|
||||
}
|
||||
//2.名称唯一性校验
|
||||
LambdaUpdateWrapper<DoctorPhrase> wrapper = new LambdaUpdateWrapper<>();
|
||||
wrapper.eq(DoctorPhrase::getPhraseName, doctorPhrase.getPhraseName());
|
||||
DoctorPhrase one = doctorPhraseService.getOne(wrapper);
|
||||
if(ObjectUtil.isNotEmpty(one)){
|
||||
return R.fail("该名称已经存在");
|
||||
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
|
||||
/*
|
||||
* 如果前端没传类型,必须给个默认值(比如 1-个人)
|
||||
* 否则存成 NULL,查询列表时会被过滤掉,导致"新增了却看不见"
|
||||
*/
|
||||
if (doctorPhrase.getPhraseType() == null) {
|
||||
doctorPhrase.setPhraseType(BindingType.PERSONAL.getValue());
|
||||
}
|
||||
//3.新增
|
||||
boolean save = doctorPhraseService.save(doctorPhrase);
|
||||
System.out.println(save);
|
||||
return R.ok(save);
|
||||
|
||||
// 2. 注入归属信息
|
||||
doctorPhrase.setStaffId(currentUserId.intValue());
|
||||
doctorPhrase.setCreatorId(currentUserId.intValue());
|
||||
|
||||
// 注入科室 (处理 null 情况)
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
if (orgId != null) {
|
||||
// 检查dept_code字段长度,避免数据库错误
|
||||
String deptCode = String.valueOf(orgId);
|
||||
if (deptCode.length() > 50) { // 假设字段长度为50,根据实际情况调整
|
||||
// 如果超过字段长度限制,可以考虑截断或抛出有意义的错误
|
||||
throw new IllegalArgumentException("科室ID过长,无法保存");
|
||||
}
|
||||
doctorPhrase.setDeptCode(deptCode);
|
||||
}
|
||||
|
||||
// =========== 【修复点 2】查重范围限制在"个人" ===========
|
||||
// 使用 QueryWrapper 而不是 UpdateWrapper
|
||||
LambdaQueryWrapper<DoctorPhrase> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(DoctorPhrase::getPhraseName, doctorPhrase.getPhraseName())
|
||||
.eq(DoctorPhrase::getStaffId, currentUserId.intValue()); // 重点:只查自己名下的!
|
||||
|
||||
if (doctorPhraseService.count(queryWrapper) > 0) {
|
||||
throw new IllegalArgumentException("新增失败:您已存在同名的常用语");
|
||||
}
|
||||
|
||||
return doctorPhraseService.save(doctorPhrase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> updateDoctorPhrase(DoctorPhrase doctorPhrase) {
|
||||
//1.数据校验
|
||||
if(ObjectUtil.isEmpty(doctorPhrase)){
|
||||
return R.fail("医生常用语不能为空");
|
||||
public Boolean updateDoctorPhrase(DoctorPhrase doctorPhrase) {
|
||||
// 1. 基础校验
|
||||
if (ObjectUtil.isEmpty(doctorPhrase) || doctorPhrase.getId() == null) {
|
||||
throw new IllegalArgumentException("修改失败:ID不能为空");
|
||||
}
|
||||
//2.更新
|
||||
boolean updateById = doctorPhraseService.updateById(doctorPhrase);
|
||||
return R.ok(updateById);
|
||||
|
||||
// 2. 查旧数据
|
||||
DoctorPhrase original = doctorPhraseService.getById(doctorPhrase.getId());
|
||||
if (original == null) {
|
||||
throw new IllegalArgumentException("修改失败:该常用语不存在或已被删除");
|
||||
}
|
||||
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
|
||||
// 3. 【权限校验优化】
|
||||
if (!SecurityUtils.isAdmin(currentUserId)) {
|
||||
// 规则 A:严禁修改全院公共模板 (Type=3)
|
||||
// 这一步是关键!之前你的代码漏了这里,所以普通医生可能改动全院模板
|
||||
if (BindingType.HOSPITAL.getValue().equals(original.getPhraseType())) {
|
||||
throw new SecurityException("无权操作:全院公共常用语仅限管理员修改");
|
||||
}
|
||||
|
||||
// 规则 B:严禁修改他人的模板
|
||||
if (!original.getStaffId().equals(currentUserId.intValue())) {
|
||||
throw new SecurityException("无权操作:您只能修改自己创建的常用语");
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 数据保护:防止篡改归属
|
||||
doctorPhrase.setStaffId(original.getStaffId());
|
||||
doctorPhrase.setCreatorId(original.getCreatorId());
|
||||
Long orgId = SecurityUtils.getLoginUser().getOrgId();
|
||||
if (orgId != null) {
|
||||
// 检查dept_code字段长度,避免数据库错误
|
||||
String deptCode = String.valueOf(orgId);
|
||||
if (deptCode.length() > 50) { // 假设字段长度为50,根据实际情况调整
|
||||
throw new IllegalArgumentException("科室ID过长,无法保存");
|
||||
}
|
||||
doctorPhrase.setDeptCode(deptCode);
|
||||
}
|
||||
|
||||
return doctorPhraseService.updateById(doctorPhrase);
|
||||
}
|
||||
|
||||
@Override
|
||||
public R<?> deleteDoctorPhrase(Integer doctorPhraseId) {
|
||||
//1.数据校验
|
||||
if(doctorPhraseId == null){
|
||||
return R.fail("ID不能为空");
|
||||
public Boolean deleteDoctorPhrase(Integer doctorPhraseId) {
|
||||
if (doctorPhraseId == null) {
|
||||
throw new IllegalArgumentException("删除失败:ID不能为空");
|
||||
}
|
||||
//2.删除
|
||||
boolean removeById = doctorPhraseService.removeById(doctorPhraseId);
|
||||
return R.ok(removeById);
|
||||
|
||||
DoctorPhrase original = doctorPhraseService.getById(doctorPhraseId);
|
||||
if (original == null) {
|
||||
throw new IllegalArgumentException("删除失败:数据不存在");
|
||||
}
|
||||
|
||||
Long currentUserId = SecurityUtils.getUserId();
|
||||
|
||||
// 权限校验
|
||||
if (!SecurityUtils.isAdmin(currentUserId)) {
|
||||
if (BindingType.HOSPITAL.getValue().equals(original.getPhraseType())) {
|
||||
throw new SecurityException("无权操作:全院公共常用语仅限管理员删除");
|
||||
}
|
||||
if (!original.getStaffId().equals(currentUserId.intValue())) {
|
||||
throw new SecurityException("无权操作:您只能删除自己创建的常用语");
|
||||
}
|
||||
}
|
||||
return doctorPhraseService.removeById(doctorPhraseId);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -111,6 +111,8 @@ public class DoctorStationMainAppServiceImpl implements IDoctorStationMainAppSer
|
||||
e.setAge(e.getBirthDate() != null ? AgeCalculatorUtil.getAge(e.getBirthDate()) : "");
|
||||
// 就诊状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(EncounterStatus.class, e.getStatusEnum()));
|
||||
// 初复诊
|
||||
e.setFirstEnum_enumText(EnumUtils.getInfoByValue(EncounterType.class, e.getFirstEnum()));
|
||||
});
|
||||
return patientInfo;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.openhis.web.doctorstation.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.openhis.common.enums.BindingType;
|
||||
import com.openhis.template.domain.DoctorPhrase;
|
||||
import com.openhis.web.doctorstation.appservice.IDoctorPhraseAppService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
@@ -23,7 +24,13 @@ public class DoctorPhraseController {
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
public R<?> getDoctorPhraseList(){
|
||||
return R.ok(doctorPhraseAppService.getDoctorPhraseList());
|
||||
try {
|
||||
return R.ok(doctorPhraseAppService.getDoctorPhraseList());
|
||||
} catch (Exception e) {
|
||||
// 系统异常,使用error级别日志
|
||||
log.error("获取医生常用语列表系统异常", e);
|
||||
return R.fail("获取医生常用语列表失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,7 +44,13 @@ public class DoctorPhraseController {
|
||||
@RequestParam(required = false) Integer phraseType,
|
||||
@RequestParam(required = false) String phraseName
|
||||
){
|
||||
return R.ok(doctorPhraseAppService.searchDoctorPhraseList(phraseName,phraseType));
|
||||
try {
|
||||
return R.ok(doctorPhraseAppService.searchDoctorPhraseList(phraseName, phraseType));
|
||||
} catch (Exception e) {
|
||||
// 系统异常,使用error级别日志
|
||||
log.error("查询医生常用语系统异常", e);
|
||||
return R.fail("查询医生常用语失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,7 +61,22 @@ public class DoctorPhraseController {
|
||||
*/
|
||||
@PostMapping("/add")
|
||||
public R<?> addDoctorPhrase(@RequestBody DoctorPhrase doctorPhrase){
|
||||
return R.ok(doctorPhraseAppService.addDoctorPhrase(doctorPhrase));
|
||||
try {
|
||||
Boolean result = doctorPhraseAppService.addDoctorPhrase(doctorPhrase);
|
||||
if (result != null && result) {
|
||||
return R.ok("新增成功");
|
||||
} else {
|
||||
return R.fail("新增失败");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 参数错误异常,使用warn级别日志
|
||||
log.warn("新增医生常用语参数错误: {}", e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// 系统异常,使用error级别日志
|
||||
log.error("新增医生常用语系统异常", e);
|
||||
return R.fail("新增失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +87,26 @@ public class DoctorPhraseController {
|
||||
*/
|
||||
@PutMapping("/update")
|
||||
public R<?> updateDoctorPhrase(@RequestBody DoctorPhrase doctorPhrase){
|
||||
return R.ok(doctorPhraseAppService.updateDoctorPhrase(doctorPhrase));
|
||||
try {
|
||||
Boolean result = doctorPhraseAppService.updateDoctorPhrase(doctorPhrase);
|
||||
if (result != null && result) {
|
||||
return R.ok("更新成功");
|
||||
} else {
|
||||
return R.fail("更新失败");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 参数错误异常,使用warn级别日志
|
||||
log.warn("更新医生常用语参数错误: {}", e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
} catch (SecurityException e) {
|
||||
// 权限相关异常,使用warn级别日志
|
||||
log.warn("更新医生常用语权限异常: {}", e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// 系统异常,使用error级别日志
|
||||
log.error("更新医生常用语系统异常", e);
|
||||
return R.fail("更新失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,7 +117,26 @@ public class DoctorPhraseController {
|
||||
*/
|
||||
@DeleteMapping("/delete/{DoctorPhraseId}")
|
||||
public R<?> deleteDoctorPhrase(@PathVariable Integer DoctorPhraseId){
|
||||
return R.ok(doctorPhraseAppService.deleteDoctorPhrase(DoctorPhraseId));
|
||||
try {
|
||||
Boolean result = doctorPhraseAppService.deleteDoctorPhrase(DoctorPhraseId);
|
||||
if (result != null && result) {
|
||||
return R.ok("删除成功");
|
||||
} else {
|
||||
return R.fail("删除失败");
|
||||
}
|
||||
} catch (IllegalArgumentException e) {
|
||||
// 参数错误异常,使用warn级别日志
|
||||
log.warn("删除医生常用语参数错误: {}", e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
} catch (SecurityException e) {
|
||||
// 权限相关异常,使用warn级别日志
|
||||
log.warn("删除医生常用语权限异常: {}", e.getMessage());
|
||||
return R.fail(e.getMessage());
|
||||
} catch (Exception e) {
|
||||
// 系统异常,使用error级别日志
|
||||
log.error("删除医生常用语系统异常", e);
|
||||
return R.fail("删除失败: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -133,4 +133,10 @@ public class PatientInfoDto {
|
||||
* 过号时间
|
||||
*/
|
||||
private Date missedTime;
|
||||
|
||||
/**
|
||||
* 初复诊标识
|
||||
*/
|
||||
private Integer firstEnum;
|
||||
private String firstEnum_enumText;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
T10.jz_practitioner_user_id,
|
||||
T10.bus_no,
|
||||
T10.identifier_no,
|
||||
T10.missed_time
|
||||
T10.missed_time,
|
||||
T10.first_enum,
|
||||
T10.first_enum_enumText
|
||||
from
|
||||
(
|
||||
SELECT T1.tenant_id AS tenant_id,
|
||||
@@ -52,7 +54,13 @@
|
||||
T1.organization_id AS org_id,
|
||||
T8.bus_no AS bus_no,
|
||||
T9.identifier_no AS identifier_no,
|
||||
T1.missed_time AS missed_time
|
||||
T1.missed_time AS missed_time,
|
||||
T1.first_enum AS first_enum,
|
||||
CASE
|
||||
WHEN T1.first_enum = 1 THEN '初诊'
|
||||
WHEN T1.first_enum = 2 THEN '复诊'
|
||||
ELSE NULL
|
||||
END AS first_enum_enumText
|
||||
FROM adm_encounter AS T1
|
||||
LEFT JOIN adm_organization AS T2 ON T1.organization_id = T2.ID AND T2.delete_flag = '0'
|
||||
LEFT JOIN adm_healthcare_service AS T3 ON T1.service_type_id = T3.ID AND T3.delete_flag = '0'
|
||||
|
||||
Reference in New Issue
Block a user