This commit is contained in:
abing
2025-06-13 11:40:16 +08:00
parent 437bf23f09
commit 6f846f5410
1787 changed files with 212112 additions and 0 deletions

View File

@@ -0,0 +1,198 @@
package com.core.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.annotation.Anonymous;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysUser;
import com.core.system.domain.SysTenant;
import com.core.system.service.ISysTenantService;
/**
* 租户信息controller
*
* @author system
*/
@RestController
@RequestMapping("/system/tenant")
public class SysTenantController extends BaseController {
@Autowired
private ISysTenantService sysTenantService;
/**
* 查询租户分页列表
*
* @param tenantId 租户ID查询
* @param tenantCode 租户编码模糊查询
* @param tenantName 租户名称模糊查询
* @param status 状态
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户分页列表
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/page")
public R<IPage<SysTenant>> getTenantPage(@RequestParam(required = false) Integer tenantId,
@RequestParam(required = false) String tenantCode, @RequestParam(required = false) String tenantName,
@RequestParam(required = false) String status, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return sysTenantService.getTenantPage(tenantId, tenantCode, tenantName, status, pageNum, pageSize);
}
/**
* 查询租户详情
*
* @param tenantId 租户ID
* @return 租户分页列表
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/{tenantId}")
public R<SysTenant> getTenantDetail(@PathVariable Integer tenantId) {
return R.ok(sysTenantService.getById(tenantId));
}
/**
* 查询租户所属用户分页列表
*
* @param tenantId 租户ID查询
* @param userName 用户昵称模糊查询
* @param nickName 用户昵称模糊查询
* @param phoneNumber 手机号码模糊查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户所属用户分页列表
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/user/page")
public R<IPage<SysUser>> getTenantUserPage(@RequestParam(required = false) Integer tenantId,
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
@RequestParam(required = false) String phoneNumber, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return sysTenantService.getTenantUserPage(tenantId, userName, nickName, phoneNumber, pageNum, pageSize);
}
/**
* 新增租户
*
* @param sysTenant 租户实体
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PostMapping
public R<?> addTenant(@RequestBody SysTenant sysTenant) {
sysTenantService.save(sysTenant);
return R.ok("新增成功");
}
/**
* 修改租户
*
* @param sysTenant 租户实体
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PutMapping
public R<?> editTenant(@RequestBody SysTenant sysTenant) {
sysTenantService.updateById(sysTenant);
return R.ok("修改成功");
}
/**
* 删除租户
*
* @param tenantIdList 租户ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@DeleteMapping
public R<?> delTenant(@RequestBody List<Integer> tenantIdList) {
return sysTenantService.delTenant(tenantIdList);
}
/**
* 启用租户
*
* @param tenantIdList 租户ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PutMapping("/enable")
public R<?> enableTenant(@RequestBody List<Integer> tenantIdList) {
sysTenantService.enableTenant(tenantIdList);
return R.ok("启用成功");
}
/**
* 停用租户
*
* @param tenantIdList 租户ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PutMapping("/disable")
public R<?> disableTenant(@RequestBody List<Integer> tenantIdList) {
sysTenantService.disableTenant(tenantIdList);
return R.ok("停用成功");
}
/**
* 查询租户未绑定的用户列表
*
* @param tenantId 租户ID
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/{tenantId}/unbind-users")
public R<IPage<SysUser>> getUnbindTenantUserList(@PathVariable Integer tenantId,
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
@RequestParam(required = false) String phoneNumber, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return sysTenantService.getUnbindTenantUserList(tenantId, userName, nickName, phoneNumber, pageNum, pageSize);
}
/**
* 绑定租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PostMapping("/{tenantId}/bind-users")
public R<?> bindTenantUser(@PathVariable Integer tenantId, @RequestBody List<Long> userIdList) {
return sysTenantService.bindTenantUser(tenantId, userIdList);
}
/**
* 解绑租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PostMapping("/{tenantId}/unbind-users")
public R<?> unbindTenantUser(@PathVariable Integer tenantId, @RequestBody List<Long> userIdList) {
return sysTenantService.unbindTenantUser(tenantId, userIdList);
}
/**
* 查询用户绑定的租户列表
*
* @param username 用户账号
* @return 用户绑定的租户列表
*/
@Anonymous
@GetMapping("/user-bind/{username}")
public R<List<SysTenant>> getUserBindTenantList(@PathVariable String username) {
return sysTenantService.getUserBindTenantList(username);
}
}

View File

@@ -0,0 +1,139 @@
package com.core.web.controller.system;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.R;
import com.core.common.enums.TenantOptionDict;
import com.core.system.domain.SysTenantOption;
import com.core.system.domain.dto.SysTenantOptionDto;
import com.core.system.service.ISysTenantOptionService;
/**
* 租户配置项信息controller
*
* @author system
*/
@RestController
@RequestMapping("/system/tenant-option")
public class SysTenantOptionController extends BaseController {
@Autowired
private ISysTenantOptionService sysTenantOptionService;
/**
* 查询租户配置项分页列表
*
* @param tenantId 租户ID查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户配置项分页列表
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/page")
public R<IPage<SysTenantOption>> getTenantOptionPage(@RequestParam Integer tenantId,
@RequestParam(required = false) String optionCode, @RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize) {
return sysTenantOptionService.getTenantOptionPage(tenantId, optionCode, pageNum, pageSize);
}
/**
* 查询租户配置项详情
*
* @param id ID
* @return 租户配置项详情
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/{id}")
public R<?> getTenantOptionDetail(@PathVariable Long id) {
return R.ok(sysTenantOptionService.getById(id));
}
/**
* 新增租户配置项
*
* @param sysTenantOption 租户配置项实体
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PostMapping
public R<?> addTenantOption(@RequestBody SysTenantOption sysTenantOption) {
return sysTenantOptionService.addTenantOption(sysTenantOption);
}
/**
* 修改租户配置项
*
* @param sysTenantOption 租户配置项实体
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@PutMapping
public R<?> editTenantOption(@RequestBody SysTenantOption sysTenantOption) {
sysTenantOptionService.updateById(sysTenantOption);
return R.ok("修改成功");
}
/**
* 删除租户配置项
*
* @param tenantIdList 租户配置项ID列表
* @return 结果
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@DeleteMapping
public R<?> delTenantOption(@RequestBody List<Integer> tenantIdList) {
sysTenantOptionService.removeBatchByIds(tenantIdList);
return R.ok("删除成功");
}
/**
* 查询租户配置项下拉列表
*
* @return 租户配置项下拉列表
*/
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
@GetMapping("/dropdown")
public R<List<SysTenantOptionDto>> getDropdown() {
return R.ok(sysTenantOptionService.getTenantOptionDropdown());
}
// TODO: 出于安全性考虑,下面两项配置接口是否开放再议
/**
* 查询全部租户配置项
*
* @param tenantId 租户ID
* @return 全部租户配置项
*/
// @GetMapping("/all")
public R<List<SysTenantOptionDto>> getAllTenantOption(@RequestParam Integer tenantId) {
return R.ok(sysTenantOptionService.getAllTenantOption(tenantId));
}
/**
* 查询指定的租户配置项内容
*
* @param tenantId 租户ID
* @param optionCode 配置项编码
* @return 指定的租户配置项内容不存在返回NULL
*/
// @GetMapping("/content")
public R<SysTenantOptionDto> getTenantOptionContent(@RequestParam Integer tenantId,
@RequestParam String optionCode) {
TenantOptionDict tenantOptionDict = TenantOptionDict.getByCode(optionCode);
if (tenantOptionDict == null) {
return R.fail("未知配置项");
}
SysTenantOptionDto sysTenantOptionDto =
sysTenantOptionService.getTenantOptionContent(tenantId, tenantOptionDict);
if (sysTenantOptionDto == null) {
return R.fail("此项未配置");
}
return R.ok(sysTenantOptionDto);
}
}

View File

@@ -0,0 +1,26 @@
package com.core.common.enums;
/**
* 删除标志
*
* @author system
*/
public enum DeleteFlag {
NOT_DELETED("0", "未删除"), DELETED("1", "已删除");
private final String code;
private final String info;
DeleteFlag(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
}

View File

@@ -0,0 +1,193 @@
package com.core.common.enums;
/**
* 租户配置项字典不存在DB中以此文件为基准新增修改只需在这里改
*
* @author system
*/
public enum TenantOptionDict {
/**
* 医院名称
*/
HOSPITAL_NAME("hospitalName", "医院名称"),
/**
* 定点医药机构编号
*/
FIXMEDINS_CODE("fixmedinsCode", "定点医药机构编号"),
/**
* 电子发票appid
*/
APP_ID("app_id", "电子发票appid"),
/**
* 电子发票key
*/
KEY("key", "电子发票key"),
/**
* 电子发票url
*/
URL("url", "电子发票url"),
/**
* 医保开关
*/
YB_SWITCH("yb_switch", "医保开关"),
/**
* 客户端私钥
*/
CLI_PRV_KEY("cliPrvKey", "客户端私钥"),
/**
* 客户端公钥
*/
CLI_PUB_KEY("cliPubKey", "客户端公钥"),
/**
* 服务端公钥
*/
SERVER_PUB_KEY("serverPubKey", "服务端公钥"),
/**
* 定点医药机构名称
*/
FIXMEDINS_NAME("fixmedinsName", "定点医药机构名称"),
/**
* 行政区划
*/
ADMVS("admvs", "行政区划"),
/**
* 授权范围
*/
SCOPE("scope", "授权范围"),
/**
* 授权类型
*/
GRANT_TYPE("grantType", "授权类型"),
/**
* 密码
*/
PASSWORD("password", "密码"),
/**
* 用户名
*/
USERNAME("username", "用户名"),
/**
* 客户端安全码
*/
CLIENT_SECRET("clientSecret", "客户端安全码"),
/**
* 客户端ID
*/
CLIENT_ID("clientId", "客户端ID"),
/**
* 生产环境客户端公钥
*/
PROD_CLI_PUB_KEY("prod_cliPubKey", "生产环境客户端公钥"),
/**
* 生产环境客户端私钥
*/
PROD_CLI_PRV_KEY("prod_cliPrvKey", "生产环境客户端私钥"),
/**
* 生产环境客户端ID
*/
PROD_CLIENT_ID("prod_clientId", "生产环境客户端ID"),
/**
* 文件路径
*/
FILE_PATH("filePath", "文件路径"),
/**
* 电子地址
*/
ELE_ADDRESS("eleAddress", "电子地址"),
/**
* 服务地址
*/
ADDRESS("address", "服务地址"),
/**
* 超时时间
*/
TIME("time", "超时时间"),
/**
* 是否加密
*/
IS_ENCRYPT("isEncrypt", "是否加密"),
/**
* 医保区划
*/
INSUPLC_ADMDVS("insuplc_admdvs", "医保区划"),
/**
* 电子处方appId
*/
PRE_APP_ID("pre_app_id", "电子处方appId"),
/**
* 电子处方appSecret
*/
PRE_APP_SECRET("pre_app_secret", "电子处方appSecret"),
/**
* 电子处方私钥
*/
APP_PRVKEY("APP_PRVKEY", "电子处方私钥"),
/**
* 电子处方公钥
*/
PLAF_PUBKEY("PLAF_PUBKEY", "电子处方公钥"),
/**
* 医保客户端ID
*/
YB_CLIENT_ID("ybClientId", "医保客户端ID"),
/**
* 医保客户端安全码
*/
YB_CLIENT_SECRET("ybClientSecret", "医保客户端安全码"),
/**
* 医保用户名
*/
YB_USERNAME("ybUsername", "医保用户名"),
/**
* 医保密码
*/
YB_PASSWORD("ybPassword", "医保密码"),
/**
* 医保授权类型
*/
YB_GRANT_TYPE("ybGrantType", "医保授权类型"),
/**
* 医保授权范围
*/
YB_SCOPE("ybScope", "医保授权范围"),
/**
* 医保密钥
*/
YB_CLI_PRV_KEY("ybCliPrvKey", "医保密钥"),
/**
* 医保服务URL
*/
YB_URL("ybUrl", "医保服务URL"),
/**
* 医院等级
*/
HOSPITAL_LV("hospital_lv", "医院等级");
private final String code;
private final String name;
TenantOptionDict(String code, String name) {
this.code = code;
this.name = name;
}
public String getCode() {
return code;
}
public String getName() {
return name;
}
public static TenantOptionDict getByCode(String code) {
if (code == null) {
return null;
}
for (TenantOptionDict val : values()) {
if (val.getCode().equals(code)) {
return val;
}
}
return null;
}
}

View File

@@ -0,0 +1,26 @@
package com.core.common.enums;
/**
* 租户状态
*
* @author system
*/
public enum TenantStatus {
ENABLE("0", "启用"), DISABLE("1", "停用");
private final String code;
private final String info;
TenantStatus(String code, String info) {
this.code = code;
this.info = info;
}
public String getCode() {
return code;
}
public String getInfo() {
return info;
}
}

View File

@@ -0,0 +1,20 @@
package com.core.framework.config;
/**
* TenantContext类 来管理线程局部变量中的租户ID
*/
public class TenantContext {
private static final ThreadLocal<Integer> CURRENT_TENANT = new ThreadLocal<>();
public static void setCurrentTenant(Integer tenantId) {
CURRENT_TENANT.set(tenantId);
}
public static Integer getCurrentTenant() {
return CURRENT_TENANT.get();
}
public static void clear() {
CURRENT_TENANT.remove();
}
}

View File

@@ -0,0 +1,79 @@
package com.core.system.domain;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 租户信息表
*
* @author system
*/
@Data
@TableName("sys_tenant")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class SysTenant implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 租户ID使用数据库序列生成
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 租户编码
*/
private String tenantCode;
/**
* 租户名称
*/
private String tenantName;
/**
* 状态0正常 1停用
*/
private String status;
/**
* 删除状态0未删除 1已删除
*/
private String deleteFlag;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
/**
* 备注
*/
private String remark;
}

View File

@@ -0,0 +1,75 @@
package com.core.system.domain;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.*;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 租户配置项表
*
* @author system
*/
@Data
@TableName("sys_tenant_option")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class SysTenantOption implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID使用数据库序列生成
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 租户ID
*/
private Integer tenantId;
/**
* 配置项编码
*/
private String optionCode;
/**
* 配置项名称
*/
@TableField(exist = false)
private String optionName;
/**
* 配置项内容
*/
private String optionContent;
/**
* 创建人
*/
@TableField(fill = FieldFill.INSERT)
private String createBy;
/**
* 创建时间
*/
@TableField(fill = FieldFill.INSERT)
private Date createTime;
/**
* 更新人
*/
@TableField(fill = FieldFill.UPDATE)
private String updateBy;
/**
* 更新时间
*/
@TableField(fill = FieldFill.UPDATE)
private Date updateTime;
}

View File

@@ -0,0 +1,41 @@
package com.core.system.domain;
import java.io.Serializable;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 用户租户绑定表
*
* @author system
*/
@Data
@TableName("sys_user_tenant")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class SysUserTenant implements Serializable {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(type = IdType.AUTO)
private Long id;
/**
* 用户ID
*/
private Long userId;
/**
* 租户ID
*/
private Integer tenantId;
}

View File

@@ -0,0 +1,32 @@
package com.core.system.domain.dto;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
/**
* 租户配置项Dto
*
* @author system
*/
@Data
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
public class SysTenantOptionDto {
/**
* 编码
*/
private String code;
/**
* 名称
*/
private String name;
/**
* 内容
*/
private String content;
}

View File

@@ -0,0 +1,16 @@
package com.core.system.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.core.system.domain.SysTenant;
/**
* 租户信息表Mapper接口
*
* @author system
*/
@Mapper
public interface SysTenantMapper extends BaseMapper<SysTenant> {
}

View File

@@ -0,0 +1,16 @@
package com.core.system.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.core.system.domain.SysTenantOption;
/**
* 租户配置项表Mapper接口
*
* @author system
*/
@Mapper
public interface SysTenantOptionMapper extends BaseMapper<SysTenantOption> {
}

View File

@@ -0,0 +1,16 @@
package com.core.system.mapper;
import org.apache.ibatis.annotations.Mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.core.system.domain.SysUserTenant;
/**
* 用户租户绑定表Mapper接口
*
* @author system
*/
@Mapper
public interface SysUserTenantMapper extends BaseMapper<SysUserTenant> {
}

View File

@@ -0,0 +1,62 @@
package com.core.system.service;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.core.common.core.domain.R;
import com.core.common.enums.TenantOptionDict;
import com.core.system.domain.SysTenantOption;
import com.core.system.domain.dto.SysTenantOptionDto;
/**
* 租户配置项表Service接口
*
* @author system
*/
public interface ISysTenantOptionService extends IService<SysTenantOption> {
/**
* 查询租户配置项分页列表
*
* @param tenantId 租户ID查询
* @param optionCode 配置项编码查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户配置项分页列表
*/
R<IPage<SysTenantOption>> getTenantOptionPage(Integer tenantId, String optionCode, Integer pageNum,
Integer pageSize);
/**
* 新增租户配置项
*
* @param sysTenantOption 租户配置项实体
* @return 结果
*/
R<?> addTenantOption(SysTenantOption sysTenantOption);
/**
* 查询租户配置项下拉列表
*
* @return 租户配置项下拉列表
*/
List<SysTenantOptionDto> getTenantOptionDropdown();
/**
* 查询全部租户配置项
*
* @param tenantId 租户ID
* @return 全部租户配置项
*/
List<SysTenantOptionDto> getAllTenantOption(Integer tenantId);
/**
* 查询指定的租户配置项内容
*
* @param tenantId 租户ID
* @param tenantOptionDict 配置项字典枚举
* @return 指定的租户配置项内容不存在返回NULL
*/
SysTenantOptionDto getTenantOptionContent(Integer tenantId, TenantOptionDict tenantOptionDict);
}

View File

@@ -0,0 +1,114 @@
package com.core.system.service;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysUser;
import com.core.system.domain.SysTenant;
/**
* 租户信息表Service接口
*
* @author system
*/
public interface ISysTenantService extends IService<SysTenant> {
/**
* 查询租户分页列表
*
* @param tenantId 租户ID查询
* @param tenantCode 租户编码模糊查询
* @param tenantName 租户名称模糊查询
* @param status 状态
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户分页列表
*/
R<IPage<SysTenant>> getTenantPage(Integer tenantId, String tenantCode, String tenantName, String status,
Integer pageNum, Integer pageSize);
/**
* 查询租户所属用户分页列表
*
* @param tenantId 租户ID查询
* @param userName 用户名称模糊查询
* @param nickName 用户昵称模糊查询
* @param phoneNumber 手机号码模糊查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户所属用户分页列表
*/
R<IPage<SysUser>> getTenantUserPage(Integer tenantId, String userName, String nickName, String phoneNumber,
Integer pageNum, Integer pageSize);
/**
* 删除租户
*
* @param tenantIdList 租户ID列表
* @return 结果
*/
R<?> delTenant(List<Integer> tenantIdList);
/**
* 启用租户
*
* @param tenantIdList 租户ID列表
*/
void enableTenant(List<Integer> tenantIdList);
/**
* 停用租户
*
* @param tenantIdList 租户ID列表
*/
void disableTenant(List<Integer> tenantIdList);
/**
* 查询租户未绑定的用户列表
*
* @param tenantId 租户ID
* @param userName 用户名称模糊查询
* @param nickName 用户昵称模糊查询
* @param phoneNumber 手机号码模糊查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 结果
*/
R<IPage<SysUser>> getUnbindTenantUserList(Integer tenantId, String userName, String nickName, String phoneNumber,
Integer pageNum, Integer pageSize);
/**
* 绑定租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
R<?> bindTenantUser(Integer tenantId, List<Long> userIdList);
/**
* 解绑租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
R<?> unbindTenantUser(Integer tenantId, List<Long> userIdList);
/**
* 查询用户绑定的租户列表
*
* @param username 用户账号
* @return 用户绑定的租户列表
*/
R<List<SysTenant>> getUserBindTenantList(String username);
/**
* 初始化租户绑定
*
* @param userId 用户ID
*/
void initTenantBind(Long userId);
}

View File

@@ -0,0 +1,13 @@
package com.core.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.core.system.domain.SysUserTenant;
/**
* 用户租户绑定表Service接口
*
* @author system
*/
public interface ISysUserTenantService extends IService<SysUserTenant> {
}

View File

@@ -0,0 +1,144 @@
package com.core.system.service.impl;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.common.core.domain.R;
import com.core.common.enums.TenantOptionDict;
import com.core.common.utils.StringUtils;
import com.core.system.domain.SysTenantOption;
import com.core.system.domain.dto.SysTenantOptionDto;
import com.core.system.mapper.SysTenantOptionMapper;
import com.core.system.service.ISysTenantOptionService;
/**
* 租户配置项表Service业务层处理
*
* @author system
*/
@Service
public class SysTenantOptionServiceImpl extends ServiceImpl<SysTenantOptionMapper, SysTenantOption>
implements ISysTenantOptionService {
/**
* 查询租户配置项分页列表
*
* @param tenantId 租户ID查询
* @param optionCode 配置项编码查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户配置项分页列表
*/
@Override
public R<IPage<SysTenantOption>> getTenantOptionPage(Integer tenantId, String optionCode, Integer pageNum,
Integer pageSize) {
LambdaQueryWrapper<SysTenantOption> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 指定租户ID
if (tenantId != null) {
lambdaQueryWrapper.eq(SysTenantOption::getTenantId, tenantId);
}
// 指定配置项编码
if (StringUtils.isNotEmpty(optionCode)) {
lambdaQueryWrapper.eq(SysTenantOption::getOptionCode, optionCode);
}
IPage<SysTenantOption> page = baseMapper.selectPage(new Page<>(pageNum, pageSize), lambdaQueryWrapper);
// 获取配置项名称
for (SysTenantOption record : page.getRecords()) {
TenantOptionDict tenantOptionDict = TenantOptionDict.getByCode(record.getOptionCode());
if (tenantOptionDict != null) {
record.setOptionName(tenantOptionDict.getName());
}
}
return R.ok(page);
}
/**
* 新增租户配置项
*
* @param sysTenantOption 租户配置项实体
* @return 结果
*/
@Override
public R<?> addTenantOption(SysTenantOption sysTenantOption) {
List<SysTenantOption> existOptionCodeList = baseMapper.selectList(
new LambdaQueryWrapper<SysTenantOption>().eq(SysTenantOption::getTenantId, sysTenantOption.getTenantId())
.eq(SysTenantOption::getOptionCode, sysTenantOption.getOptionCode()));
if (!existOptionCodeList.isEmpty()) {
return R.fail("当前租户已存在该配置项");
}
baseMapper.insert(sysTenantOption);
return R.ok();
}
/**
* 查询租户配置项下拉列表
*
* @return 租户配置项下拉列表
*/
@Override
public List<SysTenantOptionDto> getTenantOptionDropdown() {
List<SysTenantOptionDto> optionDtoList = new ArrayList<>();
SysTenantOptionDto optionDto;
// 遍历租户配置项字典枚举类
for (TenantOptionDict dict : TenantOptionDict.values()) {
optionDto = new SysTenantOptionDto();
optionDto.setCode(dict.getCode());
optionDto.setName(dict.getName());
optionDtoList.add(optionDto);
}
return optionDtoList;
}
/**
* 查询全部租户配置项
*
* @param tenantId 租户ID
* @return 全部租户配置项
*/
@Override
public List<SysTenantOptionDto> getAllTenantOption(Integer tenantId) {
List<SysTenantOption> sysTenantOptionList =
baseMapper.selectList(new LambdaQueryWrapper<SysTenantOption>().eq(SysTenantOption::getTenantId, tenantId));
List<SysTenantOptionDto> optionDtoList = new ArrayList<>();
SysTenantOptionDto optionDto;
// 遍历该租户的所有配置
for (SysTenantOption option : sysTenantOptionList) {
optionDto = new SysTenantOptionDto();
// 获取配置项名称
TenantOptionDict tenantOptionDict = TenantOptionDict.getByCode(option.getOptionCode());
if (tenantOptionDict != null) {
optionDto.setName(tenantOptionDict.getName());
}
optionDto.setCode(option.getOptionCode());
optionDto.setContent(option.getOptionContent());
optionDtoList.add(optionDto);
}
return optionDtoList;
}
/**
* 查询指定的租户配置项内容
*
* @param tenantId 租户ID
* @param tenantOptionDict 配置项字典枚举
* @return 指定的租户配置项内容不存在返回NULL
*/
@Override
public SysTenantOptionDto getTenantOptionContent(Integer tenantId, TenantOptionDict tenantOptionDict) {
List<SysTenantOption> sysTenantOptionList = baseMapper.selectList(new LambdaQueryWrapper<SysTenantOption>()
.eq(SysTenantOption::getTenantId, tenantId).eq(SysTenantOption::getOptionCode, tenantOptionDict.getCode()));
if (sysTenantOptionList.isEmpty()) {
return null;
}
SysTenantOption sysTenantOption = sysTenantOptionList.get(0);
return new SysTenantOptionDto().setCode(sysTenantOption.getOptionCode())
.setName(sysTenantOption.getOptionName()).setContent(sysTenantOption.getOptionContent());
}
}

View File

@@ -0,0 +1,384 @@
package com.core.system.service.impl;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.common.constant.CacheConstants;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysUser;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.core.redis.RedisCache;
import com.core.common.enums.DeleteFlag;
import com.core.common.enums.TenantStatus;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.StringUtils;
import com.core.system.domain.SysTenant;
import com.core.system.domain.SysUserTenant;
import com.core.system.mapper.SysTenantMapper;
import com.core.system.mapper.SysUserMapper;
import com.core.system.mapper.SysUserTenantMapper;
import com.core.system.service.ISysTenantService;
/**
* 租户信息表Service业务层处理
*
* @author system
*/
@Service
public class SysTenantServiceImpl extends ServiceImpl<SysTenantMapper, SysTenant> implements ISysTenantService {
@Autowired
private SysUserTenantMapper sysUserTenantMapper;
@Autowired
private SysUserMapper sysUserMapper;
@Autowired
private RedisCache redisCache;
/**
* 查询租户分页列表
*
* @param tenantId 租户ID查询
* @param tenantCode 租户编码模糊查询
* @param tenantName 租户名称模糊查询
* @param status 状态
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户分页列表
*/
@Override
public R<IPage<SysTenant>> getTenantPage(Integer tenantId, String tenantCode, String tenantName, String status,
Integer pageNum, Integer pageSize) {
LambdaQueryWrapper<SysTenant> lambdaQueryWrapper = new LambdaQueryWrapper<>();
// 指定租户ID
if (tenantId != null) {
lambdaQueryWrapper.eq(SysTenant::getId, tenantId);
}
// 指定租户编码
if (StringUtils.isNotEmpty(tenantCode)) {
lambdaQueryWrapper.like(SysTenant::getTenantCode, tenantCode);
}
// 指定租户名称
if (StringUtils.isNotEmpty(tenantName)) {
lambdaQueryWrapper.like(SysTenant::getTenantName, tenantName);
}
// 指定状态
if (StringUtils.isNotEmpty(status)) {
lambdaQueryWrapper.eq(SysTenant::getStatus, status);
}
// 未删除
lambdaQueryWrapper.eq(SysTenant::getDeleteFlag, DeleteFlag.NOT_DELETED.getCode());
lambdaQueryWrapper.orderByDesc(SysTenant::getId);
return R.ok(baseMapper.selectPage(new Page<>(pageNum, pageSize), lambdaQueryWrapper));
}
/**
* 查询租户所属用户分页列表
*
* @param tenantId 租户ID查询
* @param userName 用户名称模糊查询
* @param nickName 用户昵称模糊查询
* @param phoneNumber 手机号码模糊查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 租户所属用户分页列表
*/
@Override
public R<IPage<SysUser>> getTenantUserPage(Integer tenantId, String userName, String nickName, String phoneNumber,
Integer pageNum, Integer pageSize) {
// 租户ID不可为空
if (tenantId == null) {
return R.fail("请指定租户");
}
// 查询租户绑定的所有用户ID
List<SysUserTenant> userTenantList = sysUserTenantMapper
.selectList(new LambdaUpdateWrapper<SysUserTenant>().eq(SysUserTenant::getTenantId, tenantId));
IPage<SysUser> page = new Page<>(pageNum, pageSize);
if (userTenantList.isEmpty()) {
// 无人绑定返回空分页列表
page.setTotal(0L);
page.setRecords(Collections.emptyList());
return R.ok(page);
}
List<Long> userIdList = userTenantList.stream().map(SysUserTenant::getUserId).collect(Collectors.toList());
// 查询租户绑定的用户分页列表
LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (StringUtils.isNotEmpty(userName)) {
lambdaQueryWrapper.like(SysUser::getUserName, userName);
}
if (StringUtils.isNotEmpty(nickName)) {
lambdaQueryWrapper.like(SysUser::getNickName, nickName);
}
if (StringUtils.isNotEmpty(phoneNumber)) {
lambdaQueryWrapper.like(SysUser::getPhonenumber, phoneNumber);
}
lambdaQueryWrapper.in(SysUser::getUserId, userIdList);
lambdaQueryWrapper.orderByDesc(SysUser::getUserId);
return R.ok(sysUserMapper.selectPage(page, lambdaQueryWrapper));
}
/**
* 删除租户
*
* @param tenantIdList 租户ID列表
*/
@Override
public R<?> delTenant(List<Integer> tenantIdList) {
if (!tenantIdList.isEmpty()) {
List<SysUserTenant> sysUserTenantList = sysUserTenantMapper
.selectList(new LambdaQueryWrapper<SysUserTenant>().in(SysUserTenant::getTenantId, tenantIdList));
if (!sysUserTenantList.isEmpty()) {
return R.fail("该租户还存在绑定的用户,请确认");
}
baseMapper.update(new SysTenant(), new LambdaUpdateWrapper<SysTenant>()
.set(SysTenant::getDeleteFlag, DeleteFlag.DELETED.getCode()).in(SysTenant::getId, tenantIdList));
}
return R.ok();
}
/**
* 启用租户
*
* @param tenantIdList 租户ID列表
*/
@Override
public void enableTenant(List<Integer> tenantIdList) {
if (!tenantIdList.isEmpty()) {
baseMapper.update(new SysTenant(), new LambdaUpdateWrapper<SysTenant>()
.set(SysTenant::getStatus, TenantStatus.ENABLE.getCode()).in(SysTenant::getId, tenantIdList));
}
}
/**
* 停用租户
*
* @param tenantIdList 租户ID列表
*/
@Override
public void disableTenant(List<Integer> tenantIdList) {
if (!tenantIdList.isEmpty()) {
baseMapper.update(new SysTenant(), new LambdaUpdateWrapper<SysTenant>()
.set(SysTenant::getStatus, TenantStatus.DISABLE.getCode()).in(SysTenant::getId, tenantIdList));
// 强退租户所属的所有用户
forceLogoutByTenantId(tenantIdList);
}
}
/**
* 查询租户未绑定的用户列表
*
* @param tenantId 租户ID
* @param userName 用户名称模糊查询
* @param nickName 用户昵称模糊查询
* @param phoneNumber 手机号码模糊查询
* @param pageNum 当前页
* @param pageSize 每页多少条
* @return 结果
*/
@Override
public R<IPage<SysUser>> getUnbindTenantUserList(Integer tenantId, String userName, String nickName,
String phoneNumber, Integer pageNum, Integer pageSize) {
// 租户ID不可为空
if (tenantId == null) {
return R.fail("请指定租户");
}
// 查询已绑定的用户ID
List<SysUserTenant> sysUserTenantList = sysUserTenantMapper
.selectList(new LambdaUpdateWrapper<SysUserTenant>().eq(SysUserTenant::getTenantId, tenantId));
List<Long> userIdList = sysUserTenantList.stream().map(SysUserTenant::getUserId).collect(Collectors.toList());
// 查询未绑定的用户列表
LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<>();
if (!userIdList.isEmpty()) {
lambdaQueryWrapper.notIn(SysUser::getUserId, userIdList);
}
if (StringUtils.isNotEmpty(phoneNumber)) {
lambdaQueryWrapper.like(SysUser::getPhonenumber, phoneNumber);
}
if (StringUtils.isNotEmpty(nickName)) {
lambdaQueryWrapper.like(SysUser::getNickName, nickName);
}
if (StringUtils.isNotEmpty(userName)) {
lambdaQueryWrapper.like(SysUser::getUserName, userName);
}
lambdaQueryWrapper.eq(SysUser::getDeleteFlag, DeleteFlag.NOT_DELETED.getCode());
lambdaQueryWrapper.orderByDesc(SysUser::getUserId);
return R.ok(sysUserMapper.selectPage(new Page<>(pageNum, pageSize), lambdaQueryWrapper));
}
/**
* 绑定租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
@Override
public R<?> bindTenantUser(Integer tenantId, List<Long> userIdList) {
// 租户ID不可为空
if (tenantId == null) {
return R.fail("请指定租户");
}
// 用户ID列表不可为空
if (userIdList.isEmpty()) {
return R.fail("请选择绑定的用户");
}
// 创建用户与租户间的绑定
SysUserTenant sysUserTenant;
for (Long userId : userIdList) {
sysUserTenant = new SysUserTenant();
sysUserTenant.setTenantId(tenantId).setUserId(userId);
sysUserTenantMapper.insert(sysUserTenant);
}
return R.ok();
}
/**
* 解绑租户用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
* @return 结果
*/
@Override
public R<?> unbindTenantUser(Integer tenantId, List<Long> userIdList) {
// 租户ID不可为空
if (tenantId == null) {
return R.fail("请指定租户");
}
// 用户ID列表不可为空
if (userIdList.isEmpty()) {
return R.fail("请选择解绑的用户");
}
// 删除用户与租户间的绑定
sysUserTenantMapper.delete(new LambdaQueryWrapper<SysUserTenant>().eq(SysUserTenant::getTenantId, tenantId)
.in(SysUserTenant::getUserId, userIdList));
// 强退用户
forceLogoutByUserId(tenantId, userIdList);
return R.ok();
}
/**
* 查询用户绑定的租户列表
*
* @param username 用户账号
* @return 用户绑定的租户列表
*/
@Override
public R<List<SysTenant>> getUserBindTenantList(String username) {
SysUser sysUser = sysUserMapper.selectUserByUserName(username);
if (sysUser == null) {
return R.ok(Collections.emptyList());
}
// 查询已绑定的租户列表
List<SysUserTenant> sysUserTenantList = sysUserTenantMapper
.selectList(new LambdaUpdateWrapper<SysUserTenant>().eq(SysUserTenant::getUserId, sysUser.getUserId()));
List<Integer> tenantIdList =
sysUserTenantList.stream().map(SysUserTenant::getTenantId).collect(Collectors.toList());
if (tenantIdList.isEmpty()) {
return R.ok(Collections.emptyList());
}
List<SysTenant> userBindTenantList =
baseMapper.selectList(new LambdaUpdateWrapper<SysTenant>().in(SysTenant::getId, tenantIdList));
// 优先将上次选择的租户排在前面
try {
Integer cacheTenant = redisCache.getCacheObject(CacheConstants.LOGIN_SELECTED_TENANT + username);
if (cacheTenant != null) {
userBindTenantList
.sort(Comparator.comparing(e -> !cacheTenant.equals(e.getId()), Comparator.naturalOrder()));
}
} catch (Exception ignored) {
}
return R.ok(userBindTenantList);
}
/**
* 初始化租户绑定
*
* @param userId 用户ID
*/
@Override
public void initTenantBind(Long userId) {
if (userId == null) {
return;
}
// 查询当前登录者租户
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return;
}
if (loginUser.getTenantId() == null) {
return;
}
// 查询绑定是否已存在
List<SysUserTenant> existBind = sysUserTenantMapper.selectList(new LambdaQueryWrapper<SysUserTenant>()
.eq(SysUserTenant::getUserId, userId).eq(SysUserTenant::getTenantId, loginUser.getTenantId()));
if (!existBind.isEmpty()) {
return;
}
// 新增绑定关系
sysUserTenantMapper.insert(new SysUserTenant().setUserId(userId).setTenantId(loginUser.getTenantId()));
}
/**
* 强退租户所属的所有用户
*
* @param tenantIdList 租户ID列表
*/
private void forceLogoutByTenantId(List<Integer> tenantIdList) {
if (tenantIdList.isEmpty()) {
return;
}
// 查询租户所属的所有用户信息
List<SysUserTenant> sysUserTenantList = sysUserTenantMapper
.selectList(new LambdaQueryWrapper<SysUserTenant>().in(SysUserTenant::getTenantId, tenantIdList));
if (sysUserTenantList.isEmpty()) {
return;
}
List<String> tenantUserStringList =
sysUserTenantList.stream().map(e -> e.getTenantId() + "_" + e.getUserId()).collect(Collectors.toList());
// 遍历所有当前登录用户,强退该租户的用户
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
for (String key : keys) {
LoginUser user = redisCache.getCacheObject(key);
if (user != null) {
if (user.getTenantId() != null && user.getUserId() != null) {
if (tenantUserStringList.contains(user.getTenantId() + "_" + user.getUserId())) {
redisCache.deleteObject(key);
}
}
}
}
}
/**
* 强退用户
*
* @param tenantId 租户ID
* @param userIdList 用户ID列表
*/
private void forceLogoutByUserId(Integer tenantId, List<Long> userIdList) {
if (tenantId == null || userIdList.isEmpty()) {
return;
}
// 遍历所有当前登录用户,强退该用户
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
for (String key : keys) {
LoginUser user = redisCache.getCacheObject(key);
if (user != null) {
if (tenantId.equals(user.getTenantId()) && userIdList.contains(user.getUserId())) {
redisCache.deleteObject(key);
}
}
}
}
}

View File

@@ -0,0 +1,19 @@
package com.core.system.service.impl;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.core.system.domain.SysUserTenant;
import com.core.system.mapper.SysUserTenantMapper;
import com.core.system.service.ISysUserTenantService;
/**
* 用户租户绑定表Service业务层处理
*
* @author system
*/
@Service
public class SysUserTenantServiceImpl extends ServiceImpl<SysUserTenantMapper, SysUserTenant>
implements ISysUserTenantService {
}

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.core.system.mapper.SysUserPostMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.core.system.mapper.SysTenantOptionMapper">
</mapper>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.core.system.mapper.SysUserPostMapper">
</mapper>

View File

@@ -0,0 +1,24 @@
package com.openhis.config;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
/**
* http相关配置
*
* @author system
*/
@Data
@Component
@ConfigurationProperties(prefix = "http")
@PropertySource(value = {"classpath:http.yml"})
public class HttpConfig {
private String appId;
private String key;
private String url;
private String fixmedinsCode;
}

View File

@@ -0,0 +1,154 @@
package com.openhis.quartz.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.core.common.annotation.Log;
import com.core.common.constant.Constants;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.core.common.core.page.TableDataInfo;
import com.core.common.enums.BusinessType;
import com.core.common.exception.job.TaskException;
import com.core.common.utils.StringUtils;
import com.core.common.utils.poi.ExcelUtil;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.CronUtils;
import com.openhis.quartz.service.ISysJobService;
import com.openhis.quartz.util.ScheduleUtils;
/**
* 调度任务信息操作处理
*
* @author system
*/
@RestController
@RequestMapping("/monitor/job")
public class SysJobController extends BaseController {
@Autowired
private ISysJobService jobService;
/**
* 查询定时任务列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
@GetMapping("/list")
public TableDataInfo list(SysJob sysJob) {
startPage();
List<SysJob> list = jobService.selectJobList(sysJob);
return getDataTable(list);
}
/**
* 导出定时任务列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
@Log(title = "定时任务", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysJob sysJob) {
List<SysJob> list = jobService.selectJobList(sysJob);
ExcelUtil<SysJob> util = new ExcelUtil<SysJob>(SysJob.class);
util.exportExcel(response, list, "定时任务");
}
/**
* 获取定时任务详细信息
*/
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
@GetMapping(value = "/{jobId}")
public AjaxResult getInfo(@PathVariable("jobId") Long jobId) {
return success(jobService.selectJobById(jobId));
}
/**
* 新增定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:add')")
@Log(title = "定时任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody SysJob job) throws SchedulerException, TaskException {
if (!CronUtils.isValid(job.getCronExpression())) {
return error("新增任务'" + job.getJobName() + "'失败Cron表达式不正确");
} else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS})) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.HTTP, Constants.HTTPS})) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串存在违规");
} else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) {
return error("新增任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
}
job.setCreateBy(getUsername());
return toAjax(jobService.insertJob(job));
}
/**
* 修改定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:edit')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody SysJob job) throws SchedulerException, TaskException {
if (!CronUtils.isValid(job.getCronExpression())) {
return error("修改任务'" + job.getJobName() + "'失败Cron表达式不正确");
} else if (StringUtils.containsIgnoreCase(job.getInvokeTarget(), Constants.LOOKUP_RMI)) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'rmi'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.LOOKUP_LDAP, Constants.LOOKUP_LDAPS})) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'ldap(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(),
new String[] {Constants.HTTP, Constants.HTTPS})) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不允许'http(s)'调用");
} else if (StringUtils.containsAnyIgnoreCase(job.getInvokeTarget(), Constants.JOB_ERROR_STR)) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串存在违规");
} else if (!ScheduleUtils.whiteList(job.getInvokeTarget())) {
return error("修改任务'" + job.getJobName() + "'失败,目标字符串不在白名单内");
}
job.setUpdateBy(getUsername());
return toAjax(jobService.updateJob(job));
}
/**
* 定时任务状态修改
*/
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysJob job) throws SchedulerException {
SysJob newJob = jobService.selectJobById(job.getJobId());
newJob.setStatus(job.getStatus());
return toAjax(jobService.changeStatus(newJob));
}
/**
* 定时任务立即执行一次
*/
@PreAuthorize("@ss.hasPermi('monitor:job:changeStatus')")
@Log(title = "定时任务", businessType = BusinessType.UPDATE)
@PutMapping("/run")
public AjaxResult run(@RequestBody SysJob job) throws SchedulerException {
boolean result = jobService.run(job);
return result ? success() : error("任务不存在或已过期!");
}
/**
* 删除定时任务
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "定时任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{jobIds}")
public AjaxResult remove(@PathVariable Long[] jobIds) throws SchedulerException, TaskException {
jobService.deleteJobByIds(jobIds);
return success();
}
}

View File

@@ -0,0 +1,83 @@
package com.openhis.quartz.controller;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import com.core.common.annotation.Log;
import com.core.common.core.controller.BaseController;
import com.core.common.core.domain.AjaxResult;
import com.core.common.core.page.TableDataInfo;
import com.core.common.enums.BusinessType;
import com.core.common.utils.poi.ExcelUtil;
import com.core.quartz.domain.SysJobLog;
import com.openhis.quartz.service.ISysJobLogService;
/**
* 调度日志操作处理
*
* @author system
*/
@RestController
@RequestMapping("/monitor/jobLog")
public class SysJobLogController extends BaseController {
@Autowired
private ISysJobLogService jobLogService;
/**
* 查询定时任务调度日志列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:list')")
@GetMapping("/list")
public TableDataInfo list(SysJobLog sysJobLog) {
startPage();
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
return getDataTable(list);
}
/**
* 导出定时任务调度日志列表
*/
@PreAuthorize("@ss.hasPermi('monitor:job:export')")
@Log(title = "任务调度日志", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SysJobLog sysJobLog) {
List<SysJobLog> list = jobLogService.selectJobLogList(sysJobLog);
ExcelUtil<SysJobLog> util = new ExcelUtil<SysJobLog>(SysJobLog.class);
util.exportExcel(response, list, "调度日志");
}
/**
* 根据调度编号获取详细信息
*/
@PreAuthorize("@ss.hasPermi('monitor:job:query')")
@GetMapping(value = "/{jobLogId}")
public AjaxResult getInfo(@PathVariable Long jobLogId) {
return success(jobLogService.selectJobLogById(jobLogId));
}
/**
* 删除定时任务调度日志
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "定时任务调度日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{jobLogIds}")
public AjaxResult remove(@PathVariable Long[] jobLogIds) {
return toAjax(jobLogService.deleteJobLogByIds(jobLogIds));
}
/**
* 清空定时任务调度日志
*/
@PreAuthorize("@ss.hasPermi('monitor:job:remove')")
@Log(title = "调度日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean")
public AjaxResult clean() {
jobLogService.cleanJobLog();
return success();
}
}

View File

@@ -0,0 +1,56 @@
package com.openhis.quartz.service;
import java.util.List;
import com.core.quartz.domain.SysJobLog;
/**
* 定时任务调度日志信息信息 服务层
*
* @author system
*/
public interface ISysJobLogService {
/**
* 获取quartz调度器日志的计划任务
*
* @param jobLog 调度日志信息
* @return 调度任务日志集合
*/
public List<SysJobLog> selectJobLogList(SysJobLog jobLog);
/**
* 通过调度任务日志ID查询调度信息
*
* @param jobLogId 调度任务日志ID
* @return 调度任务日志对象信息
*/
public SysJobLog selectJobLogById(Long jobLogId);
/**
* 新增任务日志
*
* @param jobLog 调度日志信息
*/
public void addJobLog(SysJobLog jobLog);
/**
* 批量删除调度日志信息
*
* @param logIds 需要删除的日志ID
* @return 结果
*/
public int deleteJobLogByIds(Long[] logIds);
/**
* 删除任务日志
*
* @param jobId 调度日志ID
* @return 结果
*/
public int deleteJobLogById(Long jobId);
/**
* 清空任务日志
*/
public void cleanJobLog();
}

View File

@@ -0,0 +1,103 @@
package com.openhis.quartz.service;
import java.util.List;
import org.quartz.SchedulerException;
import com.core.common.exception.job.TaskException;
import com.core.quartz.domain.SysJob;
/**
* 定时任务调度信息信息 服务层
*
* @author system
*/
public interface ISysJobService {
/**
* 获取quartz调度器的计划任务
*
* @param job 调度信息
* @return 调度任务集合
*/
public List<SysJob> selectJobList(SysJob job);
/**
* 通过调度任务ID查询调度信息
*
* @param jobId 调度任务ID
* @return 调度任务对象信息
*/
public SysJob selectJobById(Long jobId);
/**
* 暂停任务
*
* @param job 调度信息
* @return 结果
*/
public int pauseJob(SysJob job) throws SchedulerException;
/**
* 恢复任务
*
* @param job 调度信息
* @return 结果
*/
public int resumeJob(SysJob job) throws SchedulerException;
/**
* 删除任务后所对应的trigger也将被删除
*
* @param job 调度信息
* @return 结果
*/
public int deleteJob(SysJob job) throws SchedulerException;
/**
* 批量删除调度信息
*
* @param jobIds 需要删除的任务ID
* @return 结果
*/
public void deleteJobByIds(Long[] jobIds) throws SchedulerException;
/**
* 任务调度状态修改
*
* @param job 调度信息
* @return 结果
*/
public int changeStatus(SysJob job) throws SchedulerException;
/**
* 立即运行任务
*
* @param job 调度信息
* @return 结果
*/
public boolean run(SysJob job) throws SchedulerException;
/**
* 新增任务
*
* @param job 调度信息
* @return 结果
*/
public int insertJob(SysJob job) throws SchedulerException, TaskException;
/**
* 更新任务
*
* @param job 调度信息
* @return 结果
*/
public int updateJob(SysJob job) throws SchedulerException, TaskException;
/**
* 校验cron表达式是否有效
*
* @param cronExpression 表达式
* @return 结果
*/
public boolean checkCronExpressionIsValid(String cronExpression);
}

View File

@@ -0,0 +1,82 @@
package com.openhis.quartz.service.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.core.quartz.domain.SysJobLog;
import com.core.quartz.mapper.SysJobLogMapper;
import com.openhis.quartz.service.ISysJobLogService;
/**
* 定时任务调度日志信息 服务层
*
* @author system
*/
@Service
public class SysJobLogServiceImpl implements ISysJobLogService {
@Autowired
private SysJobLogMapper jobLogMapper;
/**
* 获取quartz调度器日志的计划任务
*
* @param jobLog 调度日志信息
* @return 调度任务日志集合
*/
@Override
public List<SysJobLog> selectJobLogList(SysJobLog jobLog) {
return jobLogMapper.selectJobLogList(jobLog);
}
/**
* 通过调度任务日志ID查询调度信息
*
* @param jobLogId 调度任务日志ID
* @return 调度任务日志对象信息
*/
@Override
public SysJobLog selectJobLogById(Long jobLogId) {
return jobLogMapper.selectJobLogById(jobLogId);
}
/**
* 新增任务日志
*
* @param jobLog 调度日志信息
*/
@Override
public void addJobLog(SysJobLog jobLog) {
jobLogMapper.insertJobLog(jobLog);
}
/**
* 批量删除调度日志信息
*
* @param logIds 需要删除的数据ID
* @return 结果
*/
@Override
public int deleteJobLogByIds(Long[] logIds) {
return jobLogMapper.deleteJobLogByIds(logIds);
}
/**
* 删除任务日志
*
* @param jobId 调度日志ID
*/
@Override
public int deleteJobLogById(Long jobId) {
return jobLogMapper.deleteJobLogById(jobId);
}
/**
* 清空任务日志
*/
@Override
public void cleanJobLog() {
jobLogMapper.cleanJobLog();
}
}

View File

@@ -0,0 +1,238 @@
package com.openhis.quartz.service.impl;
import java.util.List;
import javax.annotation.PostConstruct;
import org.quartz.JobDataMap;
import org.quartz.JobKey;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.core.common.constant.ScheduleConstants;
import com.core.common.exception.job.TaskException;
import com.core.quartz.domain.SysJob;
import com.core.quartz.mapper.SysJobMapper;
import com.core.quartz.util.CronUtils;
import com.openhis.quartz.service.ISysJobService;
import com.openhis.quartz.util.ScheduleUtils;
/**
* 定时任务调度信息 服务层
*
* @author system
*/
@Service
public class SysJobServiceImpl implements ISysJobService {
@Autowired
private Scheduler scheduler;
@Autowired
private SysJobMapper jobMapper;
/**
* 项目启动时,初始化定时器 主要是防止手动修改数据库导致未同步到定时任务处理不能手动修改数据库ID和任务组名否则会导致脏数据
*/
@PostConstruct
public void init() throws SchedulerException, TaskException {
scheduler.clear();
List<SysJob> jobList = jobMapper.selectJobAll();
for (SysJob job : jobList) {
ScheduleUtils.createScheduleJob(scheduler, job);
}
}
/**
* 获取quartz调度器的计划任务列表
*
* @param job 调度信息
* @return
*/
@Override
public List<SysJob> selectJobList(SysJob job) {
return jobMapper.selectJobList(job);
}
/**
* 通过调度任务ID查询调度信息
*
* @param jobId 调度任务ID
* @return 调度任务对象信息
*/
@Override
public SysJob selectJobById(Long jobId) {
return jobMapper.selectJobById(jobId);
}
/**
* 暂停任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int pauseJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 恢复任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int resumeJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
job.setStatus(ScheduleConstants.Status.NORMAL.getValue());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
scheduler.resumeJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 删除任务后所对应的trigger也将被删除
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int deleteJob(SysJob job) throws SchedulerException {
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
int rows = jobMapper.deleteJobById(jobId);
if (rows > 0) {
scheduler.deleteJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
return rows;
}
/**
* 批量删除调度信息
*
* @param jobIds 需要删除的任务ID
* @return 结果
*/
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobByIds(Long[] jobIds) throws SchedulerException {
for (Long jobId : jobIds) {
SysJob job = jobMapper.selectJobById(jobId);
deleteJob(job);
}
}
/**
* 任务调度状态修改
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int changeStatus(SysJob job) throws SchedulerException {
int rows = 0;
String status = job.getStatus();
if (ScheduleConstants.Status.NORMAL.getValue().equals(status)) {
rows = resumeJob(job);
} else if (ScheduleConstants.Status.PAUSE.getValue().equals(status)) {
rows = pauseJob(job);
}
return rows;
}
/**
* 立即运行任务
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public boolean run(SysJob job) throws SchedulerException {
boolean result = false;
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
SysJob properties = selectJobById(job.getJobId());
// 参数
JobDataMap dataMap = new JobDataMap();
dataMap.put(ScheduleConstants.TASK_PROPERTIES, properties);
JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey)) {
result = true;
scheduler.triggerJob(jobKey, dataMap);
}
return result;
}
/**
* 新增任务
*
* @param job 调度信息 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int insertJob(SysJob job) throws SchedulerException, TaskException {
job.setStatus(ScheduleConstants.Status.PAUSE.getValue());
int rows = jobMapper.insertJob(job);
if (rows > 0) {
ScheduleUtils.createScheduleJob(scheduler, job);
}
return rows;
}
/**
* 更新任务的时间表达式
*
* @param job 调度信息
*/
@Override
@Transactional(rollbackFor = Exception.class)
public int updateJob(SysJob job) throws SchedulerException, TaskException {
SysJob properties = selectJobById(job.getJobId());
int rows = jobMapper.updateJob(job);
if (rows > 0) {
updateSchedulerJob(job, properties.getJobGroup());
}
return rows;
}
/**
* 更新任务
*
* @param job 任务对象
* @param jobGroup 任务组名
*/
public void updateSchedulerJob(SysJob job, String jobGroup) throws SchedulerException, TaskException {
Long jobId = job.getJobId();
// 判断是否存在
JobKey jobKey = ScheduleUtils.getJobKey(jobId, jobGroup);
if (scheduler.checkExists(jobKey)) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(jobKey);
}
ScheduleUtils.createScheduleJob(scheduler, job);
}
/**
* 校验cron表达式是否有效
*
* @param cronExpression 表达式
* @return 结果
*/
@Override
public boolean checkCronExpressionIsValid(String cronExpression) {
return CronUtils.isValid(cronExpression);
}
}

View File

@@ -0,0 +1,35 @@
package com.openhis.quartz.task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.core.common.core.domain.R;
import com.core.common.utils.DateUtils;
import com.openhis.web.basedatamanage.appservice.IOrganizationAppService;
import lombok.extern.slf4j.Slf4j;
/**
* 定时任务例子
*
* @author system
*/
@Slf4j
@Component("exampleTask")
public class ExampleTask {
@Autowired
private IOrganizationAppService organizationAppService;
/**
* 定时获取机构信息
*/
public void getOrgInfo() {
log.info("定时获取机构信息START时间{}", DateUtils.getDate());
// 处理部分
R<?> r = organizationAppService.getOrgInfo(1907249098877554689L);
log.info("定时获取机构信息END机构信息{},时间:{}", r.getData(), DateUtils.getDate());
}
}

View File

@@ -0,0 +1,47 @@
package com.openhis.quartz.task;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
import com.core.common.utils.StringUtils;
import com.core.framework.config.TenantContext;
import com.openhis.administration.domain.Location;
import com.openhis.administration.service.ILocationService;
/**
* 定时任务调度测试
*
* @author system
*/
@Component("ryTask")
public class RyTask {
@Resource
ILocationService locationService;
public void ryMultipleParams(String s, Boolean b, Long l, Double d, Integer i) {
// 定时任务指定租户id,示例
try {
Integer tenantId = i;
// 设置当前线程的租户ID
TenantContext.setCurrentTenant(tenantId);
List<Location> pharmacyList = locationService.getPharmacyList();
System.out.println(StringUtils.format("执行多参方法: 字符串类型{},布尔类型{},长整型{},浮点型{},整形{}", s, b, l, d, i));
} finally {
// 清除线程局部变量,防止内存泄漏
TenantContext.clear();
}
}
public void ryParams(String params) {
System.out.println("执行有参方法:" + params);
}
public void ryNoParams() {
System.out.println("执行无参方法");
}
}

View File

@@ -0,0 +1,98 @@
package com.openhis.quartz.util;
import java.util.Date;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.core.common.constant.Constants;
import com.core.common.constant.ScheduleConstants;
import com.core.common.utils.ExceptionUtil;
import com.core.common.utils.StringUtils;
import com.core.common.utils.bean.BeanUtils;
import com.core.common.utils.spring.SpringUtils;
import com.core.quartz.domain.SysJob;
import com.core.quartz.domain.SysJobLog;
import com.openhis.quartz.service.ISysJobLogService;
/**
* 抽象quartz调用
*
* @author system
*/
public abstract class AbstractQuartzJob implements Job {
private static final Logger log = LoggerFactory.getLogger(AbstractQuartzJob.class);
/**
* 线程本地变量
*/
private static ThreadLocal<Date> threadLocal = new ThreadLocal<>();
@Override
public void execute(JobExecutionContext context) throws JobExecutionException {
SysJob sysJob = new SysJob();
BeanUtils.copyBeanProp(sysJob, context.getMergedJobDataMap().get(ScheduleConstants.TASK_PROPERTIES));
try {
before(context, sysJob);
if (sysJob != null) {
doExecute(context, sysJob);
}
after(context, sysJob, null);
} catch (Exception e) {
log.error("任务执行异常 - ", e);
after(context, sysJob, e);
}
}
/**
* 执行前
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
*/
protected void before(JobExecutionContext context, SysJob sysJob) {
threadLocal.set(new Date());
}
/**
* 执行后
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
*/
protected void after(JobExecutionContext context, SysJob sysJob, Exception e) {
Date startTime = threadLocal.get();
threadLocal.remove();
final SysJobLog sysJobLog = new SysJobLog();
sysJobLog.setJobName(sysJob.getJobName());
sysJobLog.setJobGroup(sysJob.getJobGroup());
sysJobLog.setInvokeTarget(sysJob.getInvokeTarget());
sysJobLog.setStartTime(startTime);
sysJobLog.setStopTime(new Date());
long runMs = sysJobLog.getStopTime().getTime() - sysJobLog.getStartTime().getTime();
sysJobLog.setJobMessage(sysJobLog.getJobName() + " 总共耗时:" + runMs + "毫秒");
if (e != null) {
sysJobLog.setStatus(Constants.FAIL);
String errorMsg = StringUtils.substring(ExceptionUtil.getExceptionMessage(e), 0, 2000);
sysJobLog.setExceptionInfo(errorMsg);
} else {
sysJobLog.setStatus(Constants.SUCCESS);
}
// 写入数据库当中
SpringUtils.getBean(ISysJobLogService.class).addJobLog(sysJobLog);
}
/**
* 执行方法,由子类重载
*
* @param context 工作执行上下文对象
* @param sysJob 系统计划任务
* @throws Exception 执行过程中的异常
*/
protected abstract void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception;
}

View File

@@ -0,0 +1,21 @@
package com.openhis.quartz.util;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.JobInvokeUtil;
/**
* 定时任务处理(禁止并发执行)
*
* @author system
*
*/
@DisallowConcurrentExecution
public class QuartzDisallowConcurrentExecution extends AbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception {
JobInvokeUtil.invokeMethod(sysJob);
}
}

View File

@@ -0,0 +1,19 @@
package com.openhis.quartz.util;
import org.quartz.JobExecutionContext;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.JobInvokeUtil;
/**
* 定时任务处理(允许并发执行)
*
* @author system
*
*/
public class QuartzJobExecution extends AbstractQuartzJob {
@Override
protected void doExecute(JobExecutionContext context, SysJob sysJob) throws Exception {
JobInvokeUtil.invokeMethod(sysJob);
}
}

View File

@@ -0,0 +1,123 @@
package com.openhis.quartz.util;
import org.quartz.*;
import com.core.common.constant.Constants;
import com.core.common.constant.ScheduleConstants;
import com.core.common.exception.job.TaskException;
import com.core.common.exception.job.TaskException.Code;
import com.core.common.utils.StringUtils;
import com.core.common.utils.spring.SpringUtils;
import com.core.quartz.domain.SysJob;
import com.core.quartz.util.CronUtils;
/**
* 定时任务工具类
*
* @author system
*
*/
public class ScheduleUtils {
/**
* 得到quartz任务类
*
* @param sysJob 执行计划
* @return 具体执行任务类
*/
private static Class<? extends Job> getQuartzJobClass(SysJob sysJob) {
boolean isConcurrent = "0".equals(sysJob.getConcurrent());
return isConcurrent ? QuartzJobExecution.class : QuartzDisallowConcurrentExecution.class;
}
/**
* 构建任务触发对象
*/
public static TriggerKey getTriggerKey(Long jobId, String jobGroup) {
return TriggerKey.triggerKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 构建任务键对象
*/
public static JobKey getJobKey(Long jobId, String jobGroup) {
return JobKey.jobKey(ScheduleConstants.TASK_CLASS_NAME + jobId, jobGroup);
}
/**
* 创建定时任务
*/
public static void createScheduleJob(Scheduler scheduler, SysJob job) throws SchedulerException, TaskException {
Class<? extends Job> jobClass = getQuartzJobClass(job);
// 构建job信息
Long jobId = job.getJobId();
String jobGroup = job.getJobGroup();
JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(getJobKey(jobId, jobGroup)).build();
// 表达式调度构建器
CronScheduleBuilder cronScheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
cronScheduleBuilder = handleCronScheduleMisfirePolicy(job, cronScheduleBuilder);
// 按新的cronExpression表达式构建一个新的trigger
CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(getTriggerKey(jobId, jobGroup))
.withSchedule(cronScheduleBuilder).build();
// 放入参数,运行时的方法可以获取
jobDetail.getJobDataMap().put(ScheduleConstants.TASK_PROPERTIES, job);
// 判断是否存在
if (scheduler.checkExists(getJobKey(jobId, jobGroup))) {
// 防止创建时存在数据问题 先移除,然后在执行创建操作
scheduler.deleteJob(getJobKey(jobId, jobGroup));
}
// 判断任务是否过期
if (StringUtils.isNotNull(CronUtils.getNextExecution(job.getCronExpression()))) {
// 执行调度任务
scheduler.scheduleJob(jobDetail, trigger);
}
// 暂停任务
if (job.getStatus().equals(ScheduleConstants.Status.PAUSE.getValue())) {
scheduler.pauseJob(ScheduleUtils.getJobKey(jobId, jobGroup));
}
}
/**
* 设置定时任务策略
*/
public static CronScheduleBuilder handleCronScheduleMisfirePolicy(SysJob job, CronScheduleBuilder cb)
throws TaskException {
switch (job.getMisfirePolicy()) {
case ScheduleConstants.MISFIRE_DEFAULT:
return cb;
case ScheduleConstants.MISFIRE_IGNORE_MISFIRES:
return cb.withMisfireHandlingInstructionIgnoreMisfires();
case ScheduleConstants.MISFIRE_FIRE_AND_PROCEED:
return cb.withMisfireHandlingInstructionFireAndProceed();
case ScheduleConstants.MISFIRE_DO_NOTHING:
return cb.withMisfireHandlingInstructionDoNothing();
default:
throw new TaskException(
"The task misfire policy '" + job.getMisfirePolicy() + "' cannot be used in cron schedule tasks",
Code.CONFIG_ERROR);
}
}
/**
* 检查包名是否为白名单配置
*
* @param invokeTarget 目标字符串
* @return 结果
*/
public static boolean whiteList(String invokeTarget) {
String packageName = StringUtils.substringBefore(invokeTarget, "(");
int count = StringUtils.countMatches(packageName, ".");
if (count > 1) {
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
}
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
String beanPackageName = obj.getClass().getPackage().getName();
return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
&& !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
}
}

View File

@@ -0,0 +1,121 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.controller;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.web.basedatamanage.appservice.ILocationAppService;
import com.openhis.web.basedatamanage.dto.LocationAddOrEditDto;
import com.openhis.web.basedatamanage.dto.LocationPageParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 位置管理Controller业务层处理
*
* @author
* @date 2025-02-21
*/
@RestController
@RequestMapping("/base-data-manage/location")
@Slf4j
@AllArgsConstructor
public class LocationController {
@Resource
private ILocationAppService locationAppService;
/**
* 位置初始化
*
* @return 初始化信息
*/
@GetMapping(value = "/init")
public R<?> init() {
return locationAppService.locationInit();
}
/**
* 位置分页列表-树型
*
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return 位置分页列表
*/
@GetMapping(value = "/location-page-tree")
public R<?> getLocationPage(@RequestParam(required = false, value = "formKey", defaultValue = "") Integer formKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return locationAppService.getLocationTree(formKey, pageNo, pageSize);
}
/**
* 位置分页列表
*
* @param locationPageParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询条件
* @param request 请求
* @return 位置分页列表
*/
@GetMapping(value = "/location-page")
public R<?> getLocationPage(LocationPageParam locationPageParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
return locationAppService.getLocationPage(locationPageParam, searchKey, pageNo, pageSize, request);
}
/**
* 获取位置信息详情
*
* @param locationId 位置Id
* @return 位置信息
*/
@GetMapping("/location")
public R<?> getLocationById(@RequestParam Long locationId) {
return locationAppService.getLocationById(locationId);
}
/**
* 新增位置信息
*
* @param locationAddOrEditDto 库房位置信息
* @return 操作结果
*/
@PostMapping("/location")
public R<?> addLocation(@Validated @RequestBody LocationAddOrEditDto locationAddOrEditDto) {
return locationAppService.addLocation(locationAddOrEditDto);
}
/**
* 编辑位置信息
*
* @param locationAddOrEditDto 库房位置信息
* @return 操作结果
*/
@PutMapping("/location")
public R<?> editLocation(@Validated @RequestBody LocationAddOrEditDto locationAddOrEditDto) {
return locationAppService.editLocation(locationAddOrEditDto);
}
/**
* 删除位置信息
*
* @param busNo 位置信息编码
* @return 操作结果
*/
@DeleteMapping("/location")
public R<?> deleteLocation(@RequestParam String busNo) {
return locationAppService.deleteLocation(busNo);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
* 位置信息新增编辑dto
*
* @author zwh
* @date 2025-03-31
*/
@Data
@Accessors(chain = true)
public class LocationAddOrEditDto {
/** ID */
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/** 编码 */
private String busNo;
/** 名称 */
@NotNull
private String name;
/** 物理形式枚举 */
@NotNull
private String formEnum;
/** 机构编码 */
private Long organizationId;
}

View File

@@ -0,0 +1,85 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import java.util.ArrayList;
import java.util.List;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author
* @date 2025-02-21
*/
@Data
@Accessors(chain = true)
public class LocationDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 编码 */
@NotBlank(message = "位置编码不能为空")
private String busNo;
/** 名称 */
@NotBlank(message = "位置名称不能为空")
private String name;
/** 状态编码 */
@NotNull(message = "状态编码不能为空")
// private LocationStatus statusEnum;
private Integer statusEnum;
private String statusEnum_enumText;
/** 操作状态 */
@NotNull(message = "操作状态不能为空")
// private LocationBedStatus operationalEnum;
private Integer operationalEnum;
private String operationalEnum_enumText;
/** 模式编码 */
@NotNull(message = "模式编码不能为空")
// private LocationMode modeEnum;
private Integer modeEnum;
private String modeEnum_enumText;
/** 模式编码 */
private String typeCode;
/** 功能编码 */
@NotBlank(message = "功能编码不能为空")
private String typeJson;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 物理形式枚举 */
@NotNull(message = "物理形式枚举不能为空")
// private LocationForm formEnum;
private Integer formEnum;
private String formEnum_enumText;
/** 机构编码 */
@NotNull(message = "机构编码不能为空")
@JsonSerialize(using = ToStringSerializer.class)
private Long organizationId;
/** 显示顺序 */
private Integer displayOrder;
/** 子集合 */
private List<LocationDto> children = new ArrayList<>();
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 位置信息
*
* @author zwh
* @date 2025-03-31
*/
@Data
@Accessors(chain = true)
public class LocationInfoDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 编码 */
private String busNo;
/** 名称 */
private String name;
/** 状态编码 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 操作状态 */
private Integer operationalEnum;
private String operationalEnum_enumText;
/** 物理形式枚举 */
private Integer formEnum;
private String formEnum_enumText;
/** 机构编码 */
@Dict(dictCode = "id",dictText = "name",dictTable = "adm_organization")
@JsonSerialize(using = ToStringSerializer.class)
private Long organizationId;
private String organizationId_dictText;
}

View File

@@ -0,0 +1,36 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 位置信息初始化dto
*
* @author zwh
* @date 2025-03-31
*/
@Data
@Accessors(chain = true)
public class LocationInitDto {
private List<LocationInitDto.locationStatusOption> locationStatusOptions;
/**
* 位置状态
*/
@Data
public static class locationStatusOption {
private Integer value;
private String info;
public locationStatusOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import java.util.List;
import javax.validation.constraints.NotEmpty;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 位置信息分页查询条件
*
* @author zwh
* @date 2025-03-31
*/
@Data
@Accessors(chain = true)
public class LocationPageParam {
/** 编码 */
private String busNo;
/** 状态编码 */
private Integer statusEnum;
/** 位置类型 */
private Integer formEnum;
/**
* 位置分页默认初始类型(前端传)
*/
@NotEmpty
private List<Integer> locationFormList;
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.enums.OrganizationClass;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* @author
* @date 2025-02-21
*/
@Data
@Accessors(chain = true)
public class OrganizationDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 编码 */
private String busNo;
/** 名称 */
private String name;
/** 活动标识 */
private Integer activeFlag;
private String activeFlag_dictText;
/** 机构类型枚举 */
private Integer typeEnum;
private String typeEnum_dictText;
/** 机构分类枚举 */
private Integer classEnum;
private String classEnum_dictText;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 医保码 */
private String ybNo;
/** 医保名称 */
private String ybName;
/** 显示顺序 */
private Integer displayOrder;
/** 子集合 */
private List<OrganizationDto> children = new ArrayList<>();
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.basedatamanage.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 可选择切换科室 dto
*/
@Data
@Accessors(chain = true)
public class SelectableOrgDto {
/** 科室ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long orgId;
/**
* 科室名称
*/
private String orgName;
}

View File

@@ -0,0 +1,23 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.catalogmanage.appservice;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.ybcatalog.domain.CatalogZySyndrome;
import javax.servlet.http.HttpServletRequest;
/**
* 医保目录服务层
*
* @author SunJQ
* @date 2025-04-09
*/
public interface ICatalogService {
R<?> getPage(Integer catalogType, String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request);
}

View File

@@ -0,0 +1,296 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.catalogmanage.appservice.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.constant.YbCommonConstants;
import com.openhis.common.enums.CatalogType;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.catalogmanage.appservice.ICatalogService;
import com.openhis.web.catalogmanage.mapper.CatalogMapper;
import com.openhis.ybcatalog.domain.*;
import com.openhis.ybcatalog.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashSet;
/**
* 医保目录服务层
*
* @author SunJQ
* @date 2025-04-09
*/
@Service
public class CatalogServiceImpl implements ICatalogService {
@Autowired
CatalogMapper catalogMapper;
@Autowired
ICatalogDrugInfoService iCatalogDrugInfoService;
@Autowired
ICatalogMedicalServiceService iCatalogMedicalServiceService;
@Autowired
ICatalogMedicalConsumablesService iCatalogMedicalConsumablesService;
@Autowired
ICatalogSurgeryStandardDirectoryService iCatalogSurgeryStandardDirectoryService;
@Autowired
ICatalogZyDiseaseDiagnosisService iCatalogZyDiseaseDiagnosisService;
@Autowired
ICatalogWesternDiseaseService iCatalogWesternDiseaseService;
@Autowired
ICatalogZySyndromeService iCatalogZySyndromeService;
@Autowired
ICatalogMedicalHerbInfoService iCatalogMedicalHerbInfoService;
@Override
public R<?> getPage(Integer catalogType, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request) {
// 分类
CatalogType catalog = CatalogType.getByValue(catalogType);
if (catalog == null) {
return R.fail(
MessageUtils.createMessage(PromptMsgConstant.Yb.M00001, new String[] {String.valueOf(catalogType)}));
}
// 查询对应的目录
switch (catalog) {
case CATALOG_TYPE_1301:
return get1301Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1302:
return get1302Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1305:
return get1305Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1306:
return get1306Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1307:
return get1307Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1308:
return get1308Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1314:
return get1314Page(searchKey, pageNo, pageSize, request);
case CATALOG_TYPE_1315:
return get1315Page(searchKey, pageNo, pageSize, request);
default:
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Yb.M00001,
new String[] {String.valueOf(catalogType)}));
}
}
/**
* 中医证候目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1315Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogZySyndrome> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.SyndromeTypeCode,
// YBCommonConstants.FieldName.SyndromeTypeName, YBCommonConstants.FieldName.UniqueRecordId)),
// request);
//
// return R.ok(catalogMapper.get1315Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogZySyndrome> queryWrapper = new QueryWrapper<>();
queryWrapper.like(YbCommonConstants.FieldName.SyndromeTypeCode, searchKey).or()
.like(YbCommonConstants.FieldName.SyndromeTypeName, searchKey).or()
.like(YbCommonConstants.FieldName.UniqueRecordId, searchKey);
return R.ok(iCatalogZySyndromeService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 中医疾病目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1314Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogZyDiseaseDiagnosis> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.DiseaseCategoryName,
// YBCommonConstants.FieldName.DiseaseCategoryCode, YBCommonConstants.FieldName.UniqueRecordId)),
// request);
//
// return R.ok(catalogMapper.get1314Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogZyDiseaseDiagnosis> queryWrapper = new QueryWrapper<>();
queryWrapper.like(YbCommonConstants.FieldName.DiseaseCategoryName, searchKey).or()
.like(YbCommonConstants.FieldName.DiseaseCategoryCode, searchKey).or()
.like(YbCommonConstants.FieldName.UniqueRecordId, searchKey);
return R.ok(iCatalogZyDiseaseDiagnosisService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 手术标准目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1308Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogSurgeryStandardDirectory> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.CategoryName,
// YBCommonConstants.FieldName.SubcategoryName, YBCommonConstants.FieldName.ItemName,
// YBCommonConstants.FieldName.ItemName, YBCommonConstants.FieldName.OperationName,
// YBCommonConstants.FieldName.OperationCode)),
// request);
//
// return R.ok(catalogMapper.get1308Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogSurgeryStandardDirectory> queryWrapper = new QueryWrapper<>();
queryWrapper.like(YbCommonConstants.FieldName.CategoryName, searchKey).or()
.like(YbCommonConstants.FieldName.SubcategoryName, searchKey).or()
.like(YbCommonConstants.FieldName.ItemName, searchKey).or()
.like(YbCommonConstants.FieldName.OperationName, searchKey).or()
.like(YbCommonConstants.FieldName.OperationCode, searchKey);
return R.ok(iCatalogSurgeryStandardDirectoryService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 疾病与诊断目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1307Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogWesternDisease> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.CategoryName,
// YBCommonConstants.FieldName.SubcategoryName, YBCommonConstants.FieldName.ItemName,
// YBCommonConstants.FieldName.ItemName, YBCommonConstants.FieldName.OperationName,
// YBCommonConstants.FieldName.OperationCode)),
// request);
//
// return R.ok(catalogMapper.get1307Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogWesternDisease> queryWrapper = new QueryWrapper<>();
queryWrapper.like(YbCommonConstants.FieldName.CategoryName, searchKey).or()
.like(YbCommonConstants.FieldName.SubcategoryName, searchKey).or()
.like(YbCommonConstants.FieldName.ChapterName, searchKey).or()
.like(YbCommonConstants.FieldName.SectionName, searchKey);
return R.ok(iCatalogWesternDiseaseService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 医用耗材目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1306Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogMedicalConsumables> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.MedicalCatalogCode,
// YBCommonConstants.FieldName.ConsumableCategory, YBCommonConstants.FieldName.MaterialType,
// YBCommonConstants.FieldName.Specification)),
// request);
//
// return R.ok(catalogMapper.get1306Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogMedicalConsumables> queryWrapper = new QueryWrapper<>();
queryWrapper.like(YbCommonConstants.FieldName.MedicalCatalogCode, searchKey).or()
.like(YbCommonConstants.FieldName.ConsumableName, searchKey).or()
.like(YbCommonConstants.FieldName.ConsumableCategory, searchKey).or()
.like(YbCommonConstants.FieldName.MaterialType, searchKey).or()
.like(YbCommonConstants.FieldName.Specification, searchKey);
return R.ok(iCatalogMedicalConsumablesService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 医疗服务目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1305Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<CatalogMedicalService> queryWrapper =
HisQueryUtils.buildQueryWrapper(null, searchKey,
new HashSet<>(Arrays.asList(YbCommonConstants.FieldName.MedicalCatalogCode,
YbCommonConstants.FieldName.MedicalServiceName, YbCommonConstants.FieldName.UniqueRecordId)),
request);
// 只保留每组中 version_number 最大的记录
queryWrapper.eq(YbCommonConstants.FieldName.RowNumMax, 1);
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
return R.ok(catalogMapper.get1305Page(new Page(pageNo, pageSize), queryWrapper, tenantId));
// QueryWrapper<CatalogMedicalService> queryWrapper = new QueryWrapper<>();
// queryWrapper.like(YbCommonConstants.FieldName.MedicalServiceName, searchKey).or()
// .like(YbCommonConstants.FieldName.UniqueRecordId, searchKey);
// return R.ok(iCatalogMedicalServiceService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 中药饮片目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1302Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
// QueryWrapper<CatalogMedicalHerbInfo> queryWrapper = HisQueryUtils.buildQueryWrapper(
// null, searchKey, new HashSet<>(Arrays.asList(YBCommonConstants.FieldName.MedicalServiceName,
// YBCommonConstants.FieldName.UniqueRecordId)),
// request);
//
// return R.ok(catalogMapper.get1302Page(new Page(pageNo, pageSize), queryWrapper));
QueryWrapper<CatalogMedicalHerbInfo> queryWrapper = new QueryWrapper<>();
// queryWrapper.like(YBCommonConstants.FieldName.MedicalServiceName, searchKey).or()
// .like(YBCommonConstants.FieldName.UniqueRecordId, searchKey);
return R.ok(iCatalogMedicalHerbInfoService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
/**
* 西药中成药目录
*
* @param searchKey 模糊条件
* @param pageNo 分页参数
* @param pageSize 分页参数
* @param request 请求参数
* @return 分页内容
*/
private R<?> get1301Page(String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<CatalogDrugInfo> queryWrapper = HisQueryUtils.buildQueryWrapper(null, searchKey,
new HashSet<>(Arrays.asList(YbCommonConstants.FieldName.MedicalCatalogCode,
YbCommonConstants.FieldName.RegisteredName, YbCommonConstants.FieldName.ApprovalNo,
YbCommonConstants.FieldName.UniqueRecordId)),
request);
// 只保留每组中 version_number 最大的记录
queryWrapper.eq(YbCommonConstants.FieldName.RowNumMax, 1);
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
return R.ok(catalogMapper.get1301Page(new Page(pageNo, pageSize), queryWrapper, tenantId));
// QueryWrapper<CatalogDrugInfo> queryWrapper = new QueryWrapper<>();
// queryWrapper.like(YbCommonConstants.FieldName.MedicalCatalogCode, searchKey).or()
// .like(YbCommonConstants.FieldName.RegisteredName, searchKey).or()
// .like(YbCommonConstants.FieldName.ApprovalNo, searchKey).or()
// .like(YbCommonConstants.FieldName.UniqueRecordId, searchKey);
// return R.ok(iCatalogDrugInfoService.page(new Page<>(pageNo, pageSize), queryWrapper));
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.catalogmanage.controller;
import com.core.common.annotation.Anonymous;
import com.core.common.core.domain.R;
import com.openhis.web.catalogmanage.appservice.ICatalogService;
import com.openhis.web.patientmanage.appservice.IPatientInformationService;
import com.openhis.web.patientmanage.dto.PatientInfoSearchParam;
import com.openhis.web.ybmanage.config.YbServiceConfig;
import io.swagger.models.auth.In;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
/**
* 医保目录
*
* @author SunJQ
* @date 2025-04-09
*/
@RestController
@RequestMapping("/catalog")
@Slf4j
@AllArgsConstructor
public class CatalogController {
@Autowired
ICatalogService iCatalogService;
@Autowired
YbServiceConfig ybServiceConfig;
/**
* 分页查询医保目录信息,可选条件
*
* @param catalogType 查询参数
* @param searchKey 查询条件-模糊查询
* @param pageNo 页码默认为1
* @param pageSize 每页大小默认为10
*/
@Anonymous
@GetMapping("/page")
public R<?> getPage(Integer catalogType,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
System.out.println(ybServiceConfig.getUrl());
return R.ok(iCatalogService.getPage(catalogType, searchKey, pageNo, pageSize,request));
}
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.catalogmanage.mapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.ybcatalog.domain.*;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
/**
* 医保目录Mapper
*
* @author SunJQ
* @date 2025-04-09
*/
@Repository
public interface CatalogMapper {
IPage<CatalogZySyndrome> get1315Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogZySyndrome> queryWrapper);
IPage<CatalogZyDiseaseDiagnosis> get1314Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogZyDiseaseDiagnosis> queryWrapper);
IPage<CatalogSurgeryStandardDirectory> get1308Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogSurgeryStandardDirectory> queryWrapper);
IPage<CatalogWesternDisease> get1307Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogWesternDisease> queryWrapper);
IPage<CatalogMedicalConsumables> get1306Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogMedicalConsumables> queryWrapper);
IPage<CatalogMedicalService> get1305Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogMedicalService> queryWrapper,@Param("tenantId") Integer tenantId);
IPage<CatalogMedicalHerbInfo> get1302Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogMedicalHerbInfo> queryWrapper);
IPage<CatalogDrugInfo> get1301Page(@Param("page")Page page, @Param(Constants.WRAPPER)QueryWrapper<CatalogDrugInfo> queryWrapper,@Param("tenantId") Integer tenantId);
}

View File

@@ -0,0 +1,46 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.appservice;
import javax.servlet.http.HttpServletRequest;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
/**
* 门诊划价 service
*
* @author yangmo
* @date 2025-04-14
*/
public interface IOutpatientPricingAppService {
/**
* 查询就诊患者信息
*
* @param patientInfoDto 查询条件 (前端可传 statusEnum 区分就诊状态tab)
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 就诊患者信息
*/
IPage<PatientInfoDto> getPatientInfo(PatientInfoDto patientInfoDto, String searchKey, Integer pageNo,
Integer pageSize, HttpServletRequest request);
/**
* 查询医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 医嘱信息
*/
IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
Long organizationId, Integer pageNo, Integer pageSize);
}

View File

@@ -0,0 +1,72 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.appservice.impl;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.openhis.common.enums.Whether;
import com.openhis.web.chargemanage.appservice.IOutpatientPricingAppService;
import com.openhis.web.chargemanage.mapper.OutpatientPricingAppMapper;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import com.openhis.web.doctorstation.appservice.IDoctorStationMainAppService;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
/**
* 门诊划价 impl
*
* @author yangmo
* @date 2025-04-14
*/
@Service
public class OutpatientPricingAppServiceImpl implements IOutpatientPricingAppService {
@Resource
OutpatientPricingAppMapper outpatientPricingAppMapper;
@Resource
IDoctorStationMainAppService iDoctorStationMainAppService;
@Resource
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
/**
* 查询就诊患者信息
*
* @param patientInfoDto 查询条件 (前端传 statusEnum 区分就诊状态tab)
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 就诊患者信息
*/
@Override
public IPage<PatientInfoDto> getPatientInfo(PatientInfoDto patientInfoDto, String searchKey, Integer pageNo,
Integer pageSize, HttpServletRequest request) {
return iDoctorStationMainAppService.getPatientInfo(patientInfoDto, searchKey, pageNo, pageSize, request,
Whether.YES.getValue());
}
/**
* 查询医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 医嘱信息
*/
@Override
public IPage<AdviceBaseDto> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
Long organizationId, Integer pageNo, Integer pageSize) {
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, null,
organizationId, pageNo, pageSize, Whether.YES.getValue());
}
}

View File

@@ -0,0 +1,71 @@
package com.openhis.web.chargemanage.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.core.common.core.domain.R;
import com.openhis.web.chargemanage.appservice.IOutpatientPricingAppService;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.PatientInfoDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 门诊划价 controller
*
* @author yangmo
* @date 2025-04-14
*/
@RestController
@RequestMapping("/charge-manage/pricing")
@Slf4j
@AllArgsConstructor
public class OutpatientPricingController {
private final IOutpatientPricingAppService iOutpatientPricingAppService;
/**
* 查询就诊患者信息
*
* @param patientInfoDto 查询条件 (前端可传 statusEnum 区分就诊状态tab)
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 就诊患者信息
*/
@GetMapping(value = "/patient-info")
public R<?> getPatientInfo(PatientInfoDto patientInfoDto,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return R.ok(iOutpatientPricingAppService.getPatientInfo(patientInfoDto, searchKey, pageNo, pageSize, request));
}
/**
* 查询医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 医嘱信息
*/
@GetMapping(value = "/advice-base-info")
public R<?> getAdviceBaseInfo(AdviceBaseDto adviceBaseDto,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "locationId", required = false) Long locationId,
@RequestParam(value = "organizationId") Long organizationId,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return R.ok(iOutpatientPricingAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId, organizationId,
pageNo, pageSize));
}
}

View File

@@ -0,0 +1,105 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import com.openhis.web.paymentmanage.dto.PaymentDetailDto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 患者退款信息列表
*
* @author zwh
* @date 2025-05-05
*/
@Data
@Accessors(chain = true)
public class EncounterPatientRefundDto {
/** 支付ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long paymentId;
/** 收款人ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long entererId;
/** 就诊ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long encounterId;
/** 支付的患者ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 处方号 */
private String prescriptionNo;
/** 收费项目编号 */
private String busNo;
/** 合同编号 */
private String contractNo;
/** 项目名 */
private String itemName;
/** 项目名 */
private String orgName;
/** 收费项目ids */
private String chargeItemIds;
/** 收款人 */
private String entererName;
/** 收费状态 */
private Integer chargeStatus;
private String chargeStatus_enumText;
/** 支付状态 */
private Integer paymentStatus;
private String paymentStatus_enumText;
/** 发放状态 */
private Integer dispenseStatus;
private String dispenseStatus_enumText;
/** 执行状态 */
private Integer serviceStatus;
private String serviceStatus_enumText;
/** 数量 */
private Integer quantityValue;
/** 已发药数量 */
private Integer dispenseQuantity;
/** 单位 */
@Dict(dictCode = "unit_code")
private String quantityUnit;
private String quantityUnit_dictText;
/** 单价 */
private BigDecimal unitPrice;
/** 总价 */
private BigDecimal totalPrice;
/** 结算时间 */
private Date billDate;
/**
* 支付明细列表
*/
private List<PaymentDetailDto> paymentDetailList;
}

View File

@@ -0,0 +1,27 @@
package com.openhis.web.chargemanage.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 门诊科室信息 元数据
*/
@Data
@Accessors(chain = true)
public class OrgMetadata {
/**
* ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 科室名称
*/
private String name;
}

View File

@@ -0,0 +1,53 @@
package com.openhis.web.chargemanage.dto;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 门诊划价库存 dto
*/
@Data
@Accessors(chain = true)
public class OutpatientPricingInventoryDto {
/** 物理表名 */
private String itemTable;
/** 实例id */
@JsonSerialize(using = ToStringSerializer.class)
private Long itemId;
/** 当前库存数量 ,对应小单位*/
private BigDecimal quantity;
/** 单位 , 对应小单位*/
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
/** 产品批号 */
private String lotNumber;
/** 库位 */
@JsonSerialize(using = ToStringSerializer.class)
private Long locationStoreId;
/** 库房id */
@JsonSerialize(using = ToStringSerializer.class)
private Long locationId;
/**
* 库房名称
*/
private String locationName;
/** 采购单价(进价) */
private BigDecimal price;
}

View File

@@ -0,0 +1,46 @@
package com.openhis.web.chargemanage.dto;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 门诊划价价格 dto
*/
@Data
@Accessors(chain = true)
public class OutpatientPricingPriceDto {
/**
* 费用定价名称
*/
private String chargeName;
/** 费用定价主表ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long definitionId;
/** 费用定价子表ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long definitionDetailId;
/** 命中条件 */
private String conditionCode;
/** 命中值 */
private String conditionValue;
/** 价格 */
private BigDecimal price;
/** 单位 */
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
}

View File

@@ -0,0 +1,22 @@
package com.openhis.web.chargemanage.dto;
import com.openhis.web.paymentmanage.dto.PaymentDetailDto;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.Valid;
import java.util.List;
@Data
@Accessors(chain = true)
public class OutpatientRegistrationSettleParam {
OutpatientRegistrationAddParam outpatientRegistrationAddParam;
String chrgBchno;//收费批次号 付款时必传
String busNo;//挂号no
List<PaymentDetailDto> paymentDetails;//支付渠道 付款时必传
}

View File

@@ -0,0 +1,150 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.dto;
import com.core.common.utils.SecurityUtils;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.enums.EncounterClass;
import com.openhis.common.enums.RequestStatus;
import com.openhis.common.enums.TherapyTimeType;
import lombok.Data;
import lombok.experimental.Accessors;
import java.math.BigDecimal;
/**
* 划价项目 dto
*
* @author zwh
* @date 2025-04-10
*/
@Data
@Accessors(chain = true)
public class PricingProjectDto {
/** 医嘱类型 */
private Integer adviceType; // 1:药品 , 2: 耗材 , 3:项目
/**
* 医嘱详细分类
*/
private String categoryCode;
/** 拆零比 */
private BigDecimal partPercent;
/** 执行次数 */
private Integer executeNum; // 当医嘱类型为药品时,选填
/** 请求数量 */
private Integer quantity;
/** 请求单位编码 */
private String unitCode;
/** 单价 */
private BigDecimal unitPrice;
/** 总价 */
private BigDecimal totalPrice;
/** 费用定价主表ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long definitionId;
/** 费用定价子表ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long definitionDetailId;
/** 产品批号 */
private String lotNumber;
/**
* 请求状态
*/
private Integer statusEnum;
/** 请求类型 */
private Integer categoryEnum;
/** 耗材ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long deviceId;
/**
* 医嘱对应表名
*/
private String adviceTableName;
/** 患者 */
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/** 开方医生 */
@JsonSerialize(using = ToStringSerializer.class)
private Long practitionerId;
/** 请求发起的位置 */
@JsonSerialize(using = ToStringSerializer.class)
private Long locationId;
/** 发放位置 */
@JsonSerialize(using = ToStringSerializer.class)
private Long performLocation;
/** 所属科室 */
@JsonSerialize(using = ToStringSerializer.class)
private Long orgId;
/** 就诊id */
@JsonSerialize(using = ToStringSerializer.class)
private Long encounterId;
/**
* 账户id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/**
* 诊断ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long conditionId;
/** 治疗类型 */
private Integer therapyEnum;
/** 用法 */
private String methodCode;
/** 用药频次 */
private String rateCode;
/** 单次剂量 */
private BigDecimal dose;
/** 剂量单位 */
private String doseUnitCode;
/** 组套id */
@JsonSerialize(using = ToStringSerializer.class)
private Long packageId;
/** 活动(项目)定义id */
@JsonSerialize(using = ToStringSerializer.class)
private Long activityId;
/**
* 设置默认值
*/
public PricingProjectDto() {
this.statusEnum = RequestStatus.ACTIVE.getValue();
this.categoryEnum = EncounterClass.AMB.getValue();
this.therapyEnum = TherapyTimeType.TEMPORARY.getValue();
this.practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
this.orgId = SecurityUtils.getLoginUser().getOrgId(); // 开方人科室
}
}

View File

@@ -0,0 +1,28 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 退费项目id列表 dto
*
* @author yangmo
* @date 2025-04-15
*/
@Data
@Accessors(chain = true)
public class RefundItemParam {
/** 付款ID */
private Long paymentId;
/** 收费项ID */
private Long chargeItemId;
/** 退费标志 */
private Boolean refundFlg;
}

View File

@@ -0,0 +1,17 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.chargemanage.mapper;
import org.springframework.stereotype.Repository;
/**
* 门诊划价 appMapper
*
* @author yangmo
* @date 2025-04-14
*/
@Repository
public interface OutpatientPricingAppMapper {
}

View File

@@ -0,0 +1,96 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.appservice;
import java.util.List;
import com.core.common.core.domain.R;
import com.openhis.web.common.dto.InventoryItemParam;
import com.openhis.web.common.dto.LocationDto;
/**
* app常用接口
*
* @author zwh
* @date 2025-04-01
*/
public interface ICommonService {
/**
* 药房列表
*
* @return 药房列表
*/
List<LocationDto> getPharmacyList();
/**
* 药房列表(库房用)
*
* @return 药房列表
*/
List<LocationDto> getInventoryPharmacyList();
/**
* 药库列表
*
* @return 药库列表
*/
List<LocationDto> getCabinetList();
/**
* 药库列表(库房用)
*
* @return 药库列表
*/
List<LocationDto> getInventoryCabinetList();
/**
* 药房药库列表
*
* @return 药房药库列表
*/
List<LocationDto> getPharmacyCabinetList();
/**
* 获取病区列表
*
* @return 药库列表
*/
List<LocationDto> getWardList();
/**
* 库存项目下拉列表(药库业务使用)
*
* @param inventoryItemParam 查询条件
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 库存项目信息
*/
R<?> getInventoryItemList(InventoryItemParam inventoryItemParam, String searchKey, Integer pageNo,
Integer pageSize);
/**
* 根据项目相关信息查询项目库存相关信息
*
* @param inventoryItemParam 项目id
* @return 项目库存相关信息
*/
R<?> getInventoryItemInfo(InventoryItemParam inventoryItemParam);
/**
* 科室列表
*
* @return 科室列表
*/
R<?> getDepartmentList();
/**
* 根据追溯码获取药品/耗材信息
*
* @param traceNoList 追溯码列表
* @return 项目信息
*/
R<?> getItemInfoByTraceNo(List<String> traceNoList);
}

View File

@@ -0,0 +1,294 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.appservice.impl;
import java.util.*;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.SecurityUtils;
import com.core.common.utils.StringUtils;
import com.core.common.utils.bean.BeanUtils;
import com.openhis.administration.domain.Location;
import com.openhis.administration.service.ILocationService;
import com.openhis.administration.service.IOrganizationService;
import com.openhis.administration.service.IPractitionerRoleService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.enums.ConditionCode;
import com.openhis.common.enums.ItemType;
import com.openhis.common.enums.OrganizationType;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.common.appservice.ICommonService;
import com.openhis.web.common.dto.*;
import com.openhis.web.common.mapper.CommonAppMapper;
import com.openhis.workflow.domain.InventoryItem;
import com.openhis.workflow.service.IInventoryItemService;
/**
* app常用接口
*
* @author zwh
* @date 2025-04-01
*/
@Service
public class CommonServiceImpl implements ICommonService {
@Resource
private CommonAppMapper commonAppMapper;
@Resource
private ILocationService locationService;
@Resource
private IPractitionerRoleService practitionerRoleService;
@Resource
private IOrganizationService organizationService;
@Resource
private IInventoryItemService iInventoryItemService;
/**
* 获取药房列表
*
* @return 药房列表
*/
@Override
public List<LocationDto> getPharmacyList() {
List<Location> pharmacyList = locationService.getPharmacyList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : pharmacyList) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
return locationDtoList;
}
/**
* 获取药房列表(库房用)
*
* @return 药房列表
*/
@Override
public List<LocationDto> getInventoryPharmacyList() {
// 用户id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 根据用户id获得管理库房信息
List<Long> locationIds = practitionerRoleService.getLocationIdsByPractitionerId(practitionerId);
List<Location> pharmacyList = locationService.getPharmacyList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : pharmacyList) {
for (Long locationId : locationIds) {
if (location.getId().equals(locationId)) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
}
}
return locationDtoList;
}
/**
* 获取药库列表
*
* @return 药库列表
*/
@Override
public List<LocationDto> getCabinetList() {
List<Location> pharmacyList = locationService.getCabinetList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : pharmacyList) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
return locationDtoList;
}
/**
* 获取药库列表(库房用)
*
* @return 药库列表
*/
@Override
public List<LocationDto> getInventoryCabinetList() {
// 用户id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
// 根据用户id获得管理库房信息
List<Long> locationIds = practitionerRoleService.getLocationIdsByPractitionerId(practitionerId);
List<Location> pharmacyList = locationService.getCabinetList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : pharmacyList) {
for (Long locationId : locationIds) {
if (location.getId().equals(locationId)) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
}
}
return locationDtoList;
}
/**
* 药房药库列表
*
* @return 药房药库列表
*/
@Override
public List<LocationDto> getPharmacyCabinetList() {
List<Location> pharmacyCabinetList = locationService.getPharmacyCabinetList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : pharmacyCabinetList) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
return locationDtoList;
}
/**
* 获取病区列表
*
* @return 病区列表
*/
@Override
public List<LocationDto> getWardList() {
List<Location> getWardList = locationService.getWardList();
List<LocationDto> locationDtoList = new ArrayList<>();
LocationDto locationDto;
for (Location location : getWardList) {
locationDto = new LocationDto();
BeanUtils.copyProperties(location, locationDto);
locationDtoList.add(locationDto);
}
return locationDtoList;
}
/**
* 库存项目下拉列表(药库业务使用)
*
* @param inventoryItemParam 查询条件
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 库存项目信息
*/
@Override
public R<?> getInventoryItemList(InventoryItemParam inventoryItemParam, String searchKey, Integer pageNo,
Integer pageSize) {
Integer purchaseFlag = inventoryItemParam.getPurchaseFlag();
inventoryItemParam.setPurchaseFlag(null);
// 构建查询条件
QueryWrapper<InventoryItemParam> queryWrapper = HisQueryUtils.buildQueryWrapper(inventoryItemParam, searchKey,
new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name, CommonConstants.FieldName.PyStr,
CommonConstants.FieldName.WbStr)),
null);
// 查询库存项目信息
IPage<InventoryItemDto> inventoryItems = commonAppMapper.selectInventoryItemList(new Page<>(pageNo, pageSize),
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue(), purchaseFlag, ConditionCode.PURCHASE.getCode(),
PublicationStatus.RETIRED.getValue(), queryWrapper);
List<InventoryItemDto> inventoryItemDtoList = inventoryItems.getRecords();
inventoryItemDtoList.forEach(e -> {
// 项目类型
e.setItemType_enumText(EnumUtils.getInfoByValue(ItemType.class, e.getItemType()));
});
for (InventoryItemDto inventoryItem : inventoryItemDtoList) {
List<UnitDto> unitList = new ArrayList<>();
UnitDto unitDto = new UnitDto();
// 单位列表
unitDto.setUnitCode(inventoryItem.getUnitCode()).setMinUnitCode(inventoryItem.getMinUnitCode());
unitList.add(unitDto);
inventoryItem.setUnitList(unitList);
}
return R.ok(inventoryItemDtoList);
}
/**
* 根据项目相关信息查询项目库存相关信息
*
* @param inventoryItemParam 项目id
* @return 项目库存相关信息
*/
@Override
public R<?> getInventoryItemInfo(InventoryItemParam inventoryItemParam) {
// 查询项目库存相关信息
List<LocationInventoryDto> locationInventoryDtoList = commonAppMapper.selectInventoryItemInfo(
inventoryItemParam.getOrgLocationId(), CommonConstants.TableName.MED_MEDICATION_DEFINITION,
CommonConstants.TableName.ADM_DEVICE_DEFINITION, inventoryItemParam.getObjLocationId(),
inventoryItemParam.getLotNumber(), inventoryItemParam.getItemId(), ConditionCode.PURCHASE.getCode());
// 医保编码和生产厂家校验
for (LocationInventoryDto dto : locationInventoryDtoList) {
if (StringUtils.isNotEmpty(dto.getYbNo()) && StringUtils.isEmpty(dto.getManufacturer())) {
return R.fail("生产厂家不能为空,请到药品目录维护");
}
}
return R.ok(locationInventoryDtoList);
}
/**
* 科室列表
*
* @return 科室列表
*/
@Override
public R<?> getDepartmentList() {
return R.ok(organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null));
}
/**
* 根据追溯码获取药品/耗材信息
*
* @param traceNoList 追溯码列表
* @return 项目信息
*/
@Override
public R<?> getItemInfoByTraceNo(List<String> traceNoList) {
Map<String, String> traceNoMap = new HashMap<>();
for (String traceNo : traceNoList) {
if (traceNo != null && !StringUtils.isEmpty(traceNo)) {
InventoryItem inventoryItem = iInventoryItemService.getOne(
new LambdaQueryWrapper<InventoryItem>().like(InventoryItem::getTraceNo, traceNo).last("LIMIT 1"));
if (inventoryItem != null) {
String itemId = inventoryItem.getItemId().toString();
// 如果map中已经存在该itemId拼接traceNo否则直接添加
if (traceNoMap.containsKey(itemId)) {
String existingTraceNos = traceNoMap.get(itemId);
traceNoMap.put(itemId, existingTraceNos + CommonConstants.Common.COMMA + traceNo);
} else {
traceNoMap.put(itemId, traceNo);
}
} else {
return R.ok(null);
}
}
}
return R.ok(traceNoMap);
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.controller;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.core.common.core.domain.R;
import com.openhis.web.common.appservice.ICommonService;
import com.openhis.web.common.dto.InventoryItemParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* app常用接口
*
* @author zwh
* @date 2025-04-01
*/
@RestController
@RequestMapping("/app-common")
@Slf4j
@AllArgsConstructor
public class CommonAppController {
@Resource
private ICommonService commonService;
/**
* 药房列表
*
* @return 药房列表
*/
@GetMapping(value = "/pharmacy-list")
public R<?> getPharmacyList() {
return R.ok(commonService.getPharmacyList());
}
/**
* 药房列表(库房用)
*
* @return 药房列表
*/
@GetMapping(value = "/inventory-pharmacy-list")
public R<?> getInventoryPharmacyList() {
return R.ok(commonService.getInventoryPharmacyList());
}
/**
* 药库列表
*
* @return 药库列表
*/
@GetMapping(value = "/cabinet-list")
public R<?> getCabinetList() {
return R.ok(commonService.getCabinetList());
}
/**
* 药库列表(库房用)
*
* @return 药库列表
*/
@GetMapping(value = "/inventory-cabinet-list")
public R<?> getInventoryCabinetList() {
return R.ok(commonService.getInventoryCabinetList());
}
/**
* 药房药库列表
*
* @return 药房药库列表
*/
@GetMapping(value = "/pharmacy-cabinet-list")
public R<?> getPharmacyCabinetList() {
return R.ok(commonService.getPharmacyCabinetList());
}
/**
* 病区列表
*
* @return 病区列表
*/
@GetMapping(value = "/ward-list")
public R<?> getWardList() {
return R.ok(commonService.getWardList());
}
/**
* 科室列表
*
* @return 科室列表
*/
@GetMapping(value = "/department-list")
public R<?> getDepartmentList() {
return commonService.getDepartmentList();
}
/**
* 库存项目下拉列表(药库业务使用)
*
* @param inventoryItemParam 查询条件
* @param searchKey 模糊查询关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 库存项目信息
*/
@GetMapping(value = "/inventory-item")
public R<?> getInventoryItemList(InventoryItemParam inventoryItemParam,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "50") Integer pageSize) {
return commonService.getInventoryItemList(inventoryItemParam, searchKey, pageNo, pageSize);
}
/**
* 根据项目相关信息查询项目库存相关信息
*
* @param inventoryItemParam 项目id
* @return 项目库存相关信息
*/
@GetMapping(value = "/inventory-item-info")
public R<?> getInventoryItemInfo(InventoryItemParam inventoryItemParam) {
return commonService.getInventoryItemInfo(inventoryItemParam);
}
/**
* 根据追溯码获取药品/耗材信息
*
* @param traceNoList 追溯码列表
* @return 项目信息
*/
@GetMapping(value = "/item-trace-no")
public R<?> getItemInfoByTraceNo(@RequestParam List<String> traceNoList) {
return commonService.getItemInfoByTraceNo(traceNoList);
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.dto;
import java.math.BigDecimal;
import java.util.List;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* 库存项目dto
*
* @author zwh
* @date 2025-04-01
*/
@Data
@Accessors(chain = true)
public class InventoryItemDto {
/** 项目类型 */
private Integer itemType; // 1:药品 , 2: 耗材 , 3:诊疗
private String itemType_enumText;
/**
* 药品/耗材类型
*/
private String categoryCode;
/** 拆零比 */
private BigDecimal partPercent;
/** 采购单价 */
private BigDecimal purchaseAmount;
/** 项目定义ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long definitionId;
/** 项目名称 */
private String name;
/**
* 项目名称
*/
private String itemBusNo;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 医保编码 */
private String ybNo;
/** 商品名称 */
private String productName;
/** 包装单位 */
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
/** 最小单位 */
@Dict(dictCode = "unit_code")
private String minUnitCode;
private String minUnitCode_dictText;
/**
* 规格
*/
private String volume;
/**
* 供应商名称
*/
private String supplier;
/**
* 生产厂家
*/
private String manufacturer;
/**
* 项目对应表名
*/
private String itemTableName;
/**
* 产品批号
*/
private String lotNumber;
/** 原仓库 */
@JsonSerialize(using = ToStringSerializer.class)
private Long orgLocation;
/**
* 单位列表
*/
private List<UnitDto> unitList;
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.dto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 库存项目筛选条件
*
* @author zwh
* @date 2025-04-19
*/
@Data
@Accessors(chain = true)
public class InventoryItemParam {
/** 项目类型 */
private Integer itemType; // 1:药品 , 2: 耗材 , 3:诊疗
/** 项目id */
private Long itemId;
/** 项目名称 */
private String name;
/** 拼音码 */
private String pyStr;
/** 五笔码 */
private String wbStr;
/** 源仓库 */
private Long orgLocationId;
/** 目的仓库 */
private Long objLocationId;
/** 采购标志 */
private Integer purchaseFlag;
/**
* 产品批号
*/
private String lotNumber;
}

View File

@@ -0,0 +1,80 @@
package com.openhis.web.common.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 位置 dto
*
* @author system
* @date 2025-02-20
*/
@Data
@Accessors(chain = true)
public class LocationDto {
/**
* ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 编码
*/
private String busNo;
/**
* 名称
*/
private String name;
/**
* 状态编码
*/
private Integer statusEnum;
/**
* 操作状态
*/
private Integer operationalEnum;
/**
* 模式编码
*/
private Integer modeEnum;
/**
* 功能编码
*/
private String typeJson;
/**
* 拼音码
*/
private String pyStr;
/**
* 五笔码
*/
private String wbStr;
/**
* 物理形式枚举
*/
private Integer formEnum;
/**
* 机构编码
*/
private Long organizationId;
/**
* 显示顺序
*/
private Integer displayOrder;
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.dto;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 库存项目所在对应库房信息
*
* @author zwh
* @date 2025-04-01
*/
@Data
@Accessors(chain = true)
public class LocationInventoryDto {
/** 物理表名 */
private String itemTable;
/** 实例id */
@JsonSerialize(using = ToStringSerializer.class)
private Long itemId;
/** 采购单价 */
private BigDecimal price;
/** 产品批号 */
private String lotNumber;
/** 生产日期 */
private Date productionDate;
/** 失效日期 */
private Date expirationDate;
/** 仓库类型 */
private String formEnum;
/** 库位 */
@JsonSerialize(using = ToStringSerializer.class)
private Long locationStoreId;
/** 仓库 */
@JsonSerialize(using = ToStringSerializer.class)
private Long locationId;
/** 库房名称 */
private String locationName;
/** 货位名称 */
private String locationStoreName;
/** 原仓库数量(最小单位) */
private BigDecimal orgQuantity;
/** 目的仓库数量(最小单位) */
private BigDecimal objQuantity;
/** 供应商id */
@JsonSerialize(using = ToStringSerializer.class)
private Long supplierId;
/** 供应商名称 */
private String supplierName;
/** 医保编码 */
private String ybNo;
/** 生产厂家 */
private String manufacturer;
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.dto;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 单位列表
*
* @author zwh
* @date 2025-04-01
*/
@Data
@Accessors(chain = true)
public class UnitDto {
/** 包装单位 */
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
/** 最小单位 */
@Dict(dictCode = "unit_code")
private String minUnitCode;
private String minUnitCode_dictText;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.dto;
import java.math.BigDecimal;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 单位数量列表
*
* @author zwh
* @date 2025-04-01
*/
@Data
@Accessors(chain = true)
public class UnitQuantityDto {
/** 当前库存数量(最小单位) */
private BigDecimal minQuantity;
/** 当前库存数量(包装单位) */
private BigDecimal maxQuantity;
}

View File

@@ -0,0 +1,60 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.common.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.common.dto.InventoryItemDto;
import com.openhis.web.common.dto.InventoryItemParam;
import com.openhis.web.common.dto.LocationInventoryDto;
/**
* app常用接口 mapper
*
* @author zwh
* @date 2025-04-01
*/
@Repository
public interface CommonAppMapper {
/**
* 查询库存项目信息
*
* @param page 分页
* @param medicationTableName 药品表名
* @param deviceTableName 耗材表名
* @param purchaseFlag 是否入库
* @param purchase 命中条件:采购
* @param retired 停用
* @param queryWrapper 查询条件
* @return 库存项目信息
*/
IPage<InventoryItemDto> selectInventoryItemList(@Param("page") Page<InventoryItemDto> page,
@Param("medicationTableName") String medicationTableName, @Param("deviceTableName") String deviceTableName,
@Param("medicine") Integer medicine, @Param("device") Integer device,
@Param("purchaseFlag") Integer purchaseFlag, @Param("purchase") String purchase,
@Param("retired") Integer retired, @Param(Constants.WRAPPER) QueryWrapper<InventoryItemParam> queryWrapper);
/**
* 查询项目库存相关信息
*
* @param itemId 项目id
* @param lotNumber 批号
* @param orgLocationId 源仓库
* @param objLocationId 目的仓库
* @param purchase 价格命中条件:采购
* @return 项目库存相关信息
*/
List<LocationInventoryDto> selectInventoryItemInfo(@Param("orgLocationId") Long orgLocationId,
@Param("medicationTableName") String medicationTableName, @Param("deviceTableName") String deviceTableName,
@Param("objLocationId") Long objLocationId, @Param("lotNumber") String lotNumber, @Param("itemId") Long itemId,
@Param("purchase") String purchase);
}

View File

@@ -0,0 +1,78 @@
package com.openhis.web.datadictionary.appservice;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.core.common.core.domain.R;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentSelParam;
import com.openhis.web.datadictionary.dto.DiagnosisTreatmentUpDto;
/**
* 诊疗目录
*
* @author liuhr
* @date 2025/3/28
*/
public interface IDiagTreatMAppService {
/**
* 诊疗目录初期查询
*
* @return
*/
R<?> getDiseaseTreatmentInit();
/**
* 查询诊疗目录分页列表
*
* @param DiagnosisTreatmentSelParam 查询条件
* @param searchKey 查询条件-模糊查询
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return
*/
R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 根据id查询诊疗详情
*
* @param id 诊疗ID
* @return
*/
R<?> getDiseaseTreatmentOne(Long id);
/**
* 诊疗目录编辑
*
* @param diagnosisTreatmentUpDto 诊疗目录列表
* @return
*/
R<?> editDiseaseTreatment(DiagnosisTreatmentUpDto diagnosisTreatmentUpDto);
/**
* 诊疗目录停用
*
* @param ids 诊疗目录ID列表
* @return
*/
R<?> editDiseaseTreatmentStop(List<Long> ids);
/**
* 诊疗目录启用
*
* @param ids 诊疗目录ID列表
* @return
*/
R<?> editDiseaseTreatmentStart(List<Long> ids);
/**
* 新增外来诊疗目录
*
* @param diagnosisTreatmentUpDto 诊疗目录
* @return
*/
R<?> addDiseaseTreatment(DiagnosisTreatmentUpDto diagnosisTreatmentUpDto);
}

View File

@@ -0,0 +1,46 @@
package com.openhis.web.datadictionary.appservice;
import java.math.BigDecimal;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.core.domain.R;
import com.openhis.web.datadictionary.dto.ItemDefinitionDetailDto;
import com.openhis.web.datadictionary.dto.ItemDefinitionDto;
/**
* 项目定价 应用Service
*/
public interface ItemDefinitionAppService {
/**
* 项目定价 分页
*
* @param itemDefinitionDto dto
* @param searchKey 模糊查询关键字
* @param chargeItemContext 收费项目类型
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 项目定价
*/
IPage<ItemDefinitionDto> getChargeItemInfo(ItemDefinitionDto itemDefinitionDto, Integer chargeItemContext,
String searchKey, Integer pageNo, Integer pageSize);
/**
* 项目定价详细
*
* @param id id
* @return 项目定价详细
*/
List<ItemDefinitionDetailDto> getChargeItemInfoDetail(Long id);
/**
* 改价
*
* @param id id
* @param price 价格
* @return 结果
*/
R<?> updateChargeItemInfo(Long id, BigDecimal price);
}

View File

@@ -0,0 +1,390 @@
package com.openhis.web.datadictionary.appservice.impl;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import com.openhis.yb.service.YbManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.core.domain.entity.SysDictData;
import com.core.common.utils.*;
import com.core.common.utils.bean.BeanUtils;
import com.core.system.service.ISysDictTypeService;
import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.domain.Organization;
import com.openhis.administration.service.IOrganizationService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.sys.service.IOperationRecordService;
import com.openhis.web.common.appservice.ICommonService;
import com.openhis.web.datadictionary.appservice.IDiagTreatMAppService;
import com.openhis.web.datadictionary.appservice.IItemDefinitionService;
import com.openhis.web.datadictionary.dto.*;
import com.openhis.web.datadictionary.mapper.ActivityDefinitionManageMapper;
import com.openhis.workflow.domain.ActivityDefinition;
import com.openhis.workflow.mapper.ActivityDefinitionMapper;
import com.openhis.workflow.service.IActivityDefinitionService;
/**
* 诊疗实现类
*
* @author Wuser
* @date 2025/3/28
*/
@Service
public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
@Autowired
private IActivityDefinitionService iActivityDefinitionService;
@Autowired
private ActivityDefinitionMapper activityDefinitionMapper;
@Autowired
private IOrganizationService iOrganizationService;
@Autowired
private ISysDictTypeService iSysDictTypeService;
@Resource
private ActivityDefinitionManageMapper activityDefinitionManageMapper;
@Autowired
private IItemDefinitionService itemDefinitionServic;
@Autowired
private ISysDictTypeService sysDictTypeService;
@Autowired
private ICommonService commonService;
@Autowired(required = false)
AssignSeqUtil assignSeqUtil;
@Autowired
YbManager ybService;
@Autowired
IOperationRecordService iOperationRecordService;
/**
* 诊疗目录初期查询
*
* @return
*/
@Override
public R<?> getDiseaseTreatmentInit() {
DiagnosisTreatmentInitDto diagnosisTreatmentInitDto = new DiagnosisTreatmentInitDto();
// 获取状态
List<DiagnosisTreatmentInitDto.statusEnumOption> statusEnumOptions = Stream.of(PublicationStatus.values())
.map(status -> new DiagnosisTreatmentInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setStatusFlagOptions(statusEnumOptions);
// 获取执行科室
LambdaQueryWrapper<Organization> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Organization::getTypeEnum, OrganizationType.DEPARTMENT);
List<Organization> organizations = iOrganizationService.list(queryWrapper);
List<DiagnosisTreatmentInitDto.exeOrganization> exeOrganizations = organizations.stream()
.map(exeOrg -> new DiagnosisTreatmentInitDto.exeOrganization(exeOrg.getId(), exeOrg.getName()))
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setExeOrganizations(exeOrganizations);
// 获取诊目录疗分类
List<SysDictData> diagnosisList =
sysDictTypeService.selectDictDataByType(CommonConstants.DictName.DIAGNOSIS_CATEGORY_CODE);
// 获取诊疗录疗分类
List<DiagnosisTreatmentInitDto.dictCategoryCode> diagnosisCategories = diagnosisList.stream()
.map(category -> new DiagnosisTreatmentInitDto.dictCategoryCode(category.getDictValue(),
category.getDictLabel()))
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setDiagnosisCategoryOptions(diagnosisCategories);
// 查询医疗服务项类型
List<SysDictData> medical_service_items =
iSysDictTypeService.selectDictDataByType(ActivityDefCategory.MEDICAL_SERVICE_ITEM.getCode());
// 获取医疗服务项List
List<DiagnosisTreatmentInitDto.diseaseTreatmentType> diseaseTreatmentCategoryList = medical_service_items
.stream().map(status -> new DiagnosisTreatmentInitDto.diseaseTreatmentType(status.getDictValue(),
status.getDictLabel()))
.collect(Collectors.toList());
List<DiagnosisTreatmentInitDto.diseaseTreatmentCategory> diseaseTreatmentCategories = new ArrayList<>();
//
// //获取目录分类
// DiagnosisTreatmentInitDto.diseaseTreatmentCategory diseaseTreatmentCategory =
// new DiagnosisTreatmentInitDto.diseaseTreatmentCategory(ActivityDefCategory.MEDICAL_SERVICE_ITEM.getValue(),
// ActivityDefCategory.MEDICAL_SERVICE_ITEM.getInfo());
// diseaseTreatmentCategory.setChildren(diseaseTreatmentCategoryList);
// diseaseTreatmentCategories.add(diseaseTreatmentCategory);
// diagnosisTreatmentInitDto.setDiseaseTreatmentCategoryList(diseaseTreatmentCategories);
//
// // 查询手术与治疗类型
// List<SysDictData> medical_service_items2 =
// iSysDictTypeService.selectDictDataByType(ActivityDefCategory.TREATMENT_SURGERY.getCode());
// // 获取手术与治疗List
// List<DiagnosisTreatmentInitDto.diseaseTreatmentType> diseaseTreatmentCategoryList2 = medical_service_items2
// .stream().map(status -> new DiagnosisTreatmentInitDto.diseaseTreatmentType(status.getDictValue(),
// status.getDictLabel()))
// .collect(Collectors.toList());
//
// DiagnosisTreatmentInitDto.diseaseTreatmentCategory diseaseTreatmentCategory2 =
// new DiagnosisTreatmentInitDto.diseaseTreatmentCategory(ActivityDefCategory.TREATMENT_SURGERY.getValue(),
// ActivityDefCategory.TREATMENT_SURGERY.getInfo());
// diseaseTreatmentCategory2.setChildren(diseaseTreatmentCategoryList2);
// diseaseTreatmentCategories.add(diseaseTreatmentCategory2);
//
// diagnosisTreatmentInitDto.setDiseaseTreatmentCategoryList(diseaseTreatmentCategories);
// 获取类型
List<DiagnosisTreatmentInitDto.statusEnumOption> typeEnumOptions = Stream.of(ActivityType.values())
.map(status -> new DiagnosisTreatmentInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setTypeEnumOptions(typeEnumOptions);
// 获取是/否 列表
// 获取状态
List<DiagnosisTreatmentInitDto.statusEnumOption> statusWeatherOption = Stream.of(Whether.values())
.map(status -> new DiagnosisTreatmentInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
diagnosisTreatmentInitDto.setStatusWeatherOption(statusWeatherOption);
return R.ok(diagnosisTreatmentInitDto);
}
/**
* 查询诊疗目录分页列表
*
* @param DiagnosisTreatmentSelParam 查询条件
* @param searchKey 查询条件-模糊查询
* @param pageNo 当前页码
* @param pageSize 查询条数
* @return
*/
@Override
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 构建查询条件
QueryWrapper<DiagnosisTreatmentDto> queryWrapper = HisQueryUtils.buildQueryWrapper(DiagnosisTreatmentSelParam,
searchKey, new HashSet<>(Arrays.asList("bus_no", "name", "py_str", "wb_str")), request);
// 分页查询
IPage<DiagnosisTreatmentDto> diseaseTreatmentPage =
activityDefinitionManageMapper.getDiseaseTreatmentPage(new Page<>(pageNo, pageSize), queryWrapper);
diseaseTreatmentPage.getRecords().forEach(e -> {
// 医保标记枚举类回显赋值
e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag()));
// 医保对码标记枚举类回显赋值
e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag()));
// 类型举类回显赋值
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(ActivityType.class, e.getTypeEnum()));
// 状态举类回显赋值
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, e.getStatusEnum()));
// 划价标记
e.setPricingFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getPricingFlag()));
});
// 返回【诊疗目录列表DTO】分页
return R.ok(diseaseTreatmentPage);
}
/**
* 根据id查询诊疗详情
*
* @param id 诊疗ID
* @return
*/
@Override
public R<?> getDiseaseTreatmentOne(Long id) {
// 获取租户ID
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
// 根据ID查询【诊疗目录】
return R.ok(activityDefinitionManageMapper.getDiseaseTreatmentOne(id, tenantId));
}
/**
* 诊疗目录编辑
*
* @param diagnosisTreatmentUpDto 诊疗目录列表
* @return
*/
@Override
public R<?> editDiseaseTreatment(DiagnosisTreatmentUpDto diagnosisTreatmentUpDto) {
ActivityDefinition activityDefinition = new ActivityDefinition();
BeanUtils.copyProperties(diagnosisTreatmentUpDto, activityDefinition);
// 拼音码
activityDefinition.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(activityDefinition.getName()));
// 五笔码
activityDefinition.setWbStr(ChineseConvertUtils.toWBFirstLetter(activityDefinition.getName()));
// 更新诊疗信息
if (iActivityDefinitionService.updateById(activityDefinition)) {
// 调用医保目录对照接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo()) ) {
R<?> r = ybService.directoryCheck(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
activityDefinition.getId());
if (200 != r.getCode()) {
throw new RuntimeException("医保目录对照接口异常");
}
}
ChargeItemDefinition chargeItemDefinition = new ChargeItemDefinition();
chargeItemDefinition.setYbType(diagnosisTreatmentUpDto.getYbType())
.setTypeCode(diagnosisTreatmentUpDto.getItemTypeCode())
.setInstanceTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION)
.setInstanceId(diagnosisTreatmentUpDto.getId()).setPrice(diagnosisTreatmentUpDto.getRetailPrice())
.setChargeName(diagnosisTreatmentUpDto.getName());
// 插入操作记录
iOperationRecordService.addEntityOperationRecord(DbOpType.UPDATE.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, activityDefinition);
// 更新价格表
boolean upItemDef = itemDefinitionServic.updateItem(chargeItemDefinition);
// 更新子表,修改零售价,条件:单位
boolean upItemDetail1 = itemDefinitionServic.updateItemDetail(chargeItemDefinition,
diagnosisTreatmentUpDto.getRetailPrice(), ConditionCode.UNIT.getCode());
// 更新子表,修改最高零售价,条件:限制
boolean upItemDetail2 = itemDefinitionServic.updateItemDetail(chargeItemDefinition,
diagnosisTreatmentUpDto.getMaximumRetailPrice(), ConditionCode.LIMIT.getCode());
// 更新价格表
return upItemDef && upItemDetail1 && upItemDetail2
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
return R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 诊疗目录停用
*
* @param ids 诊疗目录ID列表
* @return
*/
@Override
public R<?> editDiseaseTreatmentStop(List<Long> ids) {
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
// 取得更新值
for (Long detail : ids) {
ActivityDefinition ActivityDefinition = new ActivityDefinition();
ActivityDefinition.setId(detail);
ActivityDefinition.setStatusEnum(PublicationStatus.RETIRED.getValue());
ActivityDefinitionList.add(ActivityDefinition);
}
// 插入操作记录
iOperationRecordService.addIdsOperationRecord(DbOpType.STOP.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
// 更新诊疗信息
return iActivityDefinitionService.updateBatchById(ActivityDefinitionList)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 诊疗目录启用
*
* @param ids 诊疗目录ID列表
* @return
*/
@Override
public R<?> editDiseaseTreatmentStart(List<Long> ids) {
List<ActivityDefinition> ActivityDefinitionList = new CopyOnWriteArrayList<>();
// 取得更新值
for (Long detail : ids) {
ActivityDefinition ActivityDefinition = new ActivityDefinition();
ActivityDefinition.setId(detail);
ActivityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
ActivityDefinitionList.add(ActivityDefinition);
}
// 插入操作记录
iOperationRecordService.addIdsOperationRecord(DbOpType.START.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, ids);
// 更新诊疗信息
return iActivityDefinitionService.updateBatchById(ActivityDefinitionList)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 新增外来诊疗目录
*
* @param diagnosisTreatmentUpDto 诊疗目录
* @return
*/
@Override
public R<?> addDiseaseTreatment(DiagnosisTreatmentUpDto diagnosisTreatmentUpDto) {
if (diagnosisTreatmentUpDto.getOrgId() == null) {
// 如果为空,设置当前登录所在的医院
Long orgId = SecurityUtils.getLoginUser().getHospitalId();
diagnosisTreatmentUpDto.setOrgId(orgId);
}
ActivityDefinition activityDefinition = new ActivityDefinition();
BeanUtils.copyProperties(diagnosisTreatmentUpDto, activityDefinition);
// 使用10位数基础采番
String code = assignSeqUtil.getSeq(AssignSeqEnum.ACTIVITY_DEFINITION_NUM.getPrefix(), 10);
activityDefinition.setBusNo(code);
// 拼音码
activityDefinition.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(activityDefinition.getName()));
// 五笔码
activityDefinition.setWbStr(ChineseConvertUtils.toWBFirstLetter(activityDefinition.getName()));
// 新增外来诊疗目录
activityDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
if (iActivityDefinitionService.addDiagnosisTreatment(activityDefinition)) {
// 调用医保目录对照接口
String ybSwitch = SecurityUtils.getLoginUser().getOptionJson().getString(CommonConstants.Option.YB_SWITCH); // 医保开关
if (Whether.YES.getCode().equals(ybSwitch) && StringUtils.isNotEmpty(activityDefinition.getYbNo()) ) {
R<?> r = ybService.directoryCheck(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
activityDefinition.getId());
if (200 != r.getCode()) {
throw new RuntimeException("医保目录对照接口异常");
}
}
// 插入操作记录
iOperationRecordService.addEntityOperationRecord(DbOpType.INSERT.getCode(),
CommonConstants.TableName.WOR_ACTIVITY_DEFINITION, activityDefinition);
ItemUpFromDirectoryDto itemUpFromDirectoryDto = new ItemUpFromDirectoryDto();
BeanUtils.copyProperties(diagnosisTreatmentUpDto, itemUpFromDirectoryDto);
itemUpFromDirectoryDto.setTypeCode(diagnosisTreatmentUpDto.getItemTypeCode())
.setUnitCode(diagnosisTreatmentUpDto.getPermittedUnitCode())
.setInstanceTable(CommonConstants.TableName.WOR_ACTIVITY_DEFINITION)
.setEffectiveStart(DateUtils.getNowDate()).setStatusEnum(PublicationStatus.ACTIVE.getValue())
.setConditionFlag(Whether.YES.getValue()).setChargeName(diagnosisTreatmentUpDto.getName())
.setInstanceId(activityDefinition.getId()).setPrice(diagnosisTreatmentUpDto.getRetailPrice());
return itemDefinitionServic.addItem(itemUpFromDirectoryDto)
? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"诊疗目录"}))
: R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00008, null));
}
return R.fail(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00008, null));
}
}

View File

@@ -0,0 +1,106 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.datadictionary.appservice.impl;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.MessageUtils;
import com.openhis.administration.domain.ChargeItemDefinition;
import com.openhis.administration.service.IChargeItemDefinitionService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.ConditionCode;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.datadictionary.appservice.ItemDefinitionAppService;
import com.openhis.web.datadictionary.dto.ItemDefinitionDetailDto;
import com.openhis.web.datadictionary.dto.ItemDefinitionDto;
import com.openhis.web.datadictionary.mapper.ItemDefinitionAppMapper;
/**
* 项目定价 应用impl
*/
@Service
public class ItemDefinitionAppServiceImpl implements ItemDefinitionAppService {
@Resource
ItemDefinitionAppMapper itemDefinitionAppMapper;
@Resource
IChargeItemDefinitionService iChargeItemDefinitionService;
/**
* 项目定价 分页
*
* @param itemDefinitionDto dto
* @param searchKey 模糊查询关键字
* @param chargeItemContext 收费项目类型
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 项目定价
*/
@Override
public IPage<ItemDefinitionDto> getChargeItemInfo(ItemDefinitionDto itemDefinitionDto, Integer chargeItemContext,
String searchKey, Integer pageNo, Integer pageSize) {
// 构建查询条件
QueryWrapper<ItemDefinitionDto> queryWrapper = HisQueryUtils.buildQueryWrapper(itemDefinitionDto, searchKey,
new HashSet<>(Arrays.asList("charge_name")), null);
IPage<ItemDefinitionDto> chargeItemInfo = itemDefinitionAppMapper.getChargeItemInfo(
new Page<>(pageNo, pageSize), chargeItemContext, CommonConstants.TableName.MED_MEDICATION_DEFINITION,
CommonConstants.TableName.ADM_DEVICE_DEFINITION, CommonConstants.TableName.WOR_ACTIVITY_DEFINITION,
CommonConstants.TableName.ADM_HEALTHCARE_SERVICE, queryWrapper);
List<ItemDefinitionDto> records = chargeItemInfo.getRecords();
for (ItemDefinitionDto record : records) {
// 状态
record.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, record.getStatusEnum()));
}
return chargeItemInfo;
}
/**
* 项目定价详细
*
* @param id id
* @return 项目定价详细
*/
@Override
public List<ItemDefinitionDetailDto> getChargeItemInfoDetail(Long id) {
List<ItemDefinitionDetailDto> chargeItemInfoDetail = itemDefinitionAppMapper.getChargeItemInfoDetail(id);
for (ItemDefinitionDetailDto itemDefinitionDetailDto : chargeItemInfoDetail) {
// 条件
itemDefinitionDetailDto.setConditionCode_enumText(
EnumUtils.getInfoByValue(ConditionCode.class, itemDefinitionDetailDto.getConditionCode()));
}
return chargeItemInfoDetail;
}
/**
* 改价
*
* @param id id
* @param price 价格
* @return 结果
*/
@Override
public R<?> updateChargeItemInfo(Long id, BigDecimal price) {
ChargeItemDefinition chargeItemDefinition = new ChargeItemDefinition();
chargeItemDefinition.setId(id);
chargeItemDefinition.setPrice(price);
iChargeItemDefinitionService.updateById(chargeItemDefinition);
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"项目定价"}));
}
}

View File

@@ -0,0 +1,25 @@
package com.openhis.web.datadictionary.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 诊疗子项JSON
*/
@Data
@Accessors(chain = true)
public class ActivityChildJsonDto {
/** 诊疗医嘱定义ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long adviceDefinitionId;
/**
* 子项请求数量
*/
private Integer childrenRequestNum;
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.datadictionary.dto;
import java.math.BigDecimal;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 收费项目详情 dto
*
* @author zxy
* @date 2025-02-21
*/
@Data
@Accessors(chain = true)
public class ItemDefinitionDetailDto {
/** 条件 */
private Integer conditionCode;
private String conditionCode_enumText;
/** 价格 */
private BigDecimal amount;
}

View File

@@ -0,0 +1,46 @@
package com.openhis.web.datadictionary.dto;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 项目定价 init基础数据
*/
@Data
@Accessors(chain = true)
public class ItemDefinitionInitDto {
private List<PublicationStatusOption> publicationStatusOptions;
private List<ChargeItemContextOption> chargeItemContextOptions;
/**
* 状态
*/
@Data
public static class PublicationStatusOption {
private Integer value;
private String label;
public PublicationStatusOption(Integer value, String label) {
this.value = value;
this.label = label;
}
}
/**
* 收费项目类型
*/
@Data
public static class ChargeItemContextOption {
private Integer value;
private String label;
public ChargeItemContextOption(Integer value, String label) {
this.value = value;
this.label = label;
}
}
}

View File

@@ -0,0 +1,49 @@
package com.openhis.web.datadictionary.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.web.datadictionary.dto.ItemDefinitionDetailDto;
import com.openhis.web.datadictionary.dto.ItemDefinitionDto;
/**
* 项目定价 应用Mapper
*/
@Repository
public interface ItemDefinitionAppMapper {
/**
* 查询项目定价信息
*
* @param page 分页参数
* @param chargeItemContext 收费项目类型
* @param MED_MEDICATION_DEFINITION 药品定义
* @param ADM_DEVICE_DEFINITION 器材定义
* @param WOR_ACTIVITY_DEFINITION 活动定义
* @param ADM_HEALTHCARE_SERVICE 服务管理
* @param queryWrapper 查询条件
* @return 项目定价信息
*/
IPage<ItemDefinitionDto> getChargeItemInfo(@Param("page") Page<ItemDefinitionDto> page,
@Param("chargeItemContext") Integer chargeItemContext,
@Param("MED_MEDICATION_DEFINITION") String MED_MEDICATION_DEFINITION,
@Param("ADM_DEVICE_DEFINITION") String ADM_DEVICE_DEFINITION,
@Param("WOR_ACTIVITY_DEFINITION") String WOR_ACTIVITY_DEFINITION,
@Param("ADM_HEALTHCARE_SERVICE") String ADM_HEALTHCARE_SERVICE,
@Param(Constants.WRAPPER) QueryWrapper<ItemDefinitionDto> queryWrapper);
/**
* 项目定价详细
*
* @param id id
* @return 项目定价详细
*/
List<ItemDefinitionDetailDto> getChargeItemInfoDetail(@Param("id") Long id);
}

View File

@@ -0,0 +1,52 @@
package com.openhis.web.doctorstation.appservice;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.GetMapping;
import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.dto.AllergyIntoInfoDto;
/**
* 医生站-患者过敏与不耐受管理的应用类
*
* @author liuhr
* @date 2025/4/10
*/
public interface IDoctorStationAllergyIntolAppService {
/**
* 患者过敏与不耐受数据初始化
*
* @return 基础数据
*/
@GetMapping(value = "/init")
R<?> init();
/**
* 查询患者过敏与不耐受信息
*
* @param patientId 患者Id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 患者过敏与不耐受信息
*/
R<?> getAllergyIntoleranceInfo(Long patientId, Integer pageNo, Integer pageSize, HttpServletRequest request);
/**
* 作废当条患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
R<?> invalidateAllergyIntolerance(AllergyIntoInfoDto allergyIntoInfoDto);
/**
* 新增患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
R<?> addAllergyIntoleranceInfo(AllergyIntoInfoDto allergyIntoInfoDto);
}

View File

@@ -0,0 +1,80 @@
package com.openhis.web.doctorstation.appservice;
import java.util.List;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.AdviceSaveParam;
import com.openhis.web.doctorstation.dto.ConditionDefinitionMetadata;
import com.openhis.web.doctorstation.dto.SaveDiagnosisParam;
/**
* 医生站-中医 应用Service
*/
public interface IDoctorStationChineseMedicalAppService {
/**
* 查询中医诊断数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医诊断数据
*/
Page<ConditionDefinitionMetadata> getConditionInfo(String searchKey, Integer pageNo, Integer pageSize);
/**
* 查询中医证候数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医证候数据
*/
Page<ConditionDefinitionMetadata> getSyndromeInfo(String searchKey, Integer pageNo, Integer pageSize);
/**
* 保存中医诊断
*
* @param saveDiagnosisParam 诊断信息
* @return 结果
*/
R<?> saveTcmDiagnosis(SaveDiagnosisParam saveDiagnosisParam);
/**
* 查询中医就诊诊断信息
*
* @param encounterId 就诊id
* @return 中医就诊诊断信息
*/
R<?> getTcmEncounterDiagnosis(Long encounterId);
/**
* 查询中医医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param adviceDefinitionIdParamList 医嘱定义id参数集合
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @param pricingFlag 划价标记
* @return 中医医嘱信息
*/
IPage<AdviceBaseDto> getTcmAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
Integer pricingFlag);
/**
* 门诊保存(签发)中医医嘱
*
* @param adviceSaveParam 医嘱表单信息
* @param adviceOpType 保存或签发
* @return 结果
*/
R<?> saveOrSignTcmAdvice(AdviceSaveParam adviceSaveParam, String adviceOpType);
}

View File

@@ -0,0 +1,94 @@
package com.openhis.web.doctorstation.appservice;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.core.common.core.domain.R;
import com.openhis.common.enums.AssignSeqEnum;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.AdviceSaveParam;
import com.openhis.web.doctorstation.dto.DeletePrescriptionInfoParam;
import com.openhis.web.doctorstation.dto.ElepPrescriptionInfoParam;
import java.util.List;
/**
* 医生站-电子处方 应用Service
*/
public interface IDoctorStationElepPrescriptionService {
/**
* 电子处方下拉框
*
* @return 下拉框信息
*/
R<?> elepPrescriptionInit();
/**
* 获取全部药品信息
*
* @param pageNo 当前页
* @param pageSize 每页多少条
* @param searchKey 模糊查询关键字
* @return 药品信息
*/
R<?> getAllMedicationInfo(String searchKey, Integer pageNo, Integer pageSize);
/**
* 获取处方信息
*
* @param patientId 患者id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品信息
*/
R<?> getPrescriptionInfo(Long patientId, Integer pageNo, Integer pageSize);
/**
* 获取药品信息
*
* @param prescriptionNo 处方号
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品详细信息
*/
R<?> getMedicationInfo(String prescriptionNo, Integer pageNo, Integer pageSize);
/**
* 获取处方编号
*
* @return 初始化信息
*/
R<?> prescriptionNoInit();
/**
* 保存处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
R<?> savePrescriptionInfo(ElepPrescriptionInfoParam prescriptionInfo);
/**
* 修改处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
R<?> updatePrescriptionInfo(ElepPrescriptionInfoParam prescriptionInfo);
/**
* 删除处方
*
* @param deletePrescriptionInfoParam 处方信息
* @return 执行结果
*/
R<?> deletePrescriptionInfo(DeletePrescriptionInfoParam deletePrescriptionInfoParam);
/**
* 签发处方
*
* @param prescriptionNoList 处方号
* @return 药品详细信息
*/
R<?> issuancePrescription(List<String> prescriptionNoList);
}

View File

@@ -0,0 +1,21 @@
package com.openhis.web.doctorstation.appservice;
import com.core.common.core.domain.R;
/**
* 医生站-患者详情应用类
*
* @author liuhr
* @date 2025/4/10
*/
public interface IDoctorStationPtDetailsAppService {
/**
* 查询患者详情
*
* @param encounterId 就诊Id
* @return 患者详情
*/
R<?> getPtDetails(Long encounterId);
}

View File

@@ -0,0 +1,195 @@
package com.openhis.web.doctorstation.appservice.impl;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.DateUtils;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.clinical.domain.AllergyIntolerance;
import com.openhis.clinical.mapper.AllergyIntoleranceMapper;
import com.openhis.clinical.service.IAllergyIntoleranceService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.ClinicalStatus;
import com.openhis.common.enums.Criticality;
import com.openhis.common.enums.Severity;
import com.openhis.common.enums.VerificationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.doctorstation.appservice.IDoctorStationAllergyIntolAppService;
import com.openhis.web.doctorstation.dto.AllergyIntoInfoDto;
import com.openhis.web.doctorstation.dto.AllergyIntoInitDto;
/**
* 医生站-患者过敏与不耐受管理的实现
*
* @author liuhr
* @date 2025/4/10
*/
@Service
public class DoctorStationAllergyIntolAppServiceImpl implements IDoctorStationAllergyIntolAppService {
@Autowired
private IAllergyIntoleranceService allergyIntoleranceService;
@Autowired
private AllergyIntoleranceMapper allergyIntoleranceMapper;
/**
* 患者过敏与不耐受数据初始化
*
* @return 基础数据
*/
@Override
public R<?> init() {
AllergyIntoInitDto initDto = new AllergyIntoInitDto();
// 获取临床状况列表
List<AllergyIntoInitDto.statusEnumOption> statusEnumOption1 = Stream.of(ClinicalStatus.values())
.map(status -> new AllergyIntoInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setClinicalStatusOptions(statusEnumOption1);
// 获取临床状况列表
List<AllergyIntoInitDto.statusEnumOption> statusEnumOption2 = Stream.of(VerificationStatus.values())
.map(status -> new AllergyIntoInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setVerificationStatusOptions(statusEnumOption2);
// 获取危险程度列表
List<AllergyIntoInitDto.statusEnumOption> statusEnumOption3 = Stream.of(Criticality.values())
.map(status -> new AllergyIntoInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setCriticalityOptions(statusEnumOption3);
// 获取严重程度列表
List<AllergyIntoInitDto.statusEnumOption> statusEnumOption4 = Stream.of(Severity.values())
.map(status -> new AllergyIntoInitDto.statusEnumOption(status.getValue(), status.getInfo()))
.collect(Collectors.toList());
initDto.setSeverityOptions(statusEnumOption4);
return R.ok(initDto);
}
/**
* 查询患者过敏与不耐受信息
*
* @param patientId 患者Id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 患者过敏与不耐受信息
*/
@Override
public R<?> getAllergyIntoleranceInfo(Long patientId, Integer pageNo, Integer pageSize,
HttpServletRequest request) {
// 构建查询条件
QueryWrapper<AllergyIntolerance> queryWrapper = HisQueryUtils.buildQueryWrapper(null, null, null, request);
// 根据患者ID查询过敏与不耐受记录
queryWrapper.eq(CommonConstants.FieldName.PatientId, patientId);
// 设置排序
queryWrapper.orderByAsc(CommonConstants.FieldName.CreateTime);
// 分页查询
Page<AllergyIntoInfoDto> allergyIntolerancePage =
HisPageUtils.selectPage(allergyIntoleranceMapper, queryWrapper, pageNo, pageSize, AllergyIntoInfoDto.class);
allergyIntolerancePage.getRecords().forEach(e -> {
// 临床状况回显赋值
e.setClinicalStatusEnum_enumText(EnumUtils.getInfoByValue(ClinicalStatus.class, e.getClinicalStatusEnum()));
// 验证状态回显赋值
e.setVerificationStatusEnum_enumText(
EnumUtils.getInfoByValue(VerificationStatus.class, e.getVerificationStatusEnum()));
// 危险程度回显赋值
e.setCriticalityEnum_enumText(EnumUtils.getInfoByValue(Criticality.class, e.getCriticalityEnum()));
// 严重程度回显赋值
e.setSeverityEnum_enumText(EnumUtils.getInfoByValue(Severity.class, e.getSeverityEnum()));
});
// 返回【患者过敏与不耐受信息】分页
return R.ok(allergyIntolerancePage);
}
/**
* 作废当条患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
@Override
public R<?> invalidateAllergyIntolerance(AllergyIntoInfoDto allergyIntoInfoDto) {
AllergyIntolerance allergyIntolerance = new AllergyIntolerance();
// 获取当前登录账号的参与者id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
allergyIntolerance.setId(allergyIntoInfoDto.getId()).setClinicalStatusEnum(ClinicalStatus.RESOLVED.getValue())
.setVerificationStatusEnum(VerificationStatus.REFUTED.getValue())
.setTypeEnum(allergyIntoInfoDto.getTypeEnum()).setCategoryCode(allergyIntoInfoDto.getCategoryCode())
.setCriticalityEnum(allergyIntoInfoDto.getCriticalityEnum()).setCode(allergyIntoInfoDto.getCode())
.setPatientId(allergyIntoInfoDto.getPatientId()).setDescription(allergyIntoInfoDto.getDescription())
.setSeverityEnum(allergyIntoInfoDto.getSeverityEnum())
.setOnsetDateTime(allergyIntoInfoDto.getOnsetDateTime()).setCheckPractitionerId(practitionerId)
.setLastReactionOccurrence(allergyIntoInfoDto.getLastReactionOccurrence())
.setNote(allergyIntoInfoDto.getNote());
boolean result = allergyIntoleranceService.saveOrUpdateAllergyIntolerance(allergyIntolerance);
if (result) {
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"过敏与不耐受"}));
} else {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}
/**
* 新增患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
@Override
public R<?> addAllergyIntoleranceInfo(AllergyIntoInfoDto allergyIntoInfoDto) {
AllergyIntolerance allergyIntolerance = new AllergyIntolerance();
// 获取当前登录账号的参与者id
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
allergyIntolerance.setId(allergyIntoInfoDto.getId()).setClinicalStatusEnum(ClinicalStatus.ACTIVE.getValue())
.setVerificationStatusEnum(VerificationStatus.CONFIRMED.getValue())
.setTypeEnum(allergyIntoInfoDto.getTypeEnum()).setCategoryCode(allergyIntoInfoDto.getCategoryCode())
.setCriticalityEnum(allergyIntoInfoDto.getCriticalityEnum()).setCode(allergyIntoInfoDto.getCode())
.setPatientId(allergyIntoInfoDto.getPatientId()).setDescription(allergyIntoInfoDto.getDescription())
.setSeverityEnum(allergyIntoInfoDto.getSeverityEnum())
.setOnsetDateTime(allergyIntoInfoDto.getOnsetDateTime()).setPractitionerId(practitionerId)
.setRecordedDate(DateUtils.getNowDate())
.setLastReactionOccurrence(allergyIntoInfoDto.getLastReactionOccurrence())
.setNote(allergyIntoInfoDto.getNote());
boolean result = allergyIntoleranceService.saveOrUpdateAllergyIntolerance(allergyIntolerance);
if (result) {
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00001, new Object[] {"过敏与不耐受"}));
} else {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
}
}

View File

@@ -0,0 +1,290 @@
package com.openhis.web.doctorstation.appservice.impl;
import java.util.*;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.MessageUtils;
import com.openhis.administration.domain.ChargeItem;
import com.openhis.administration.domain.EncounterDiagnosis;
import com.openhis.administration.service.IEncounterDiagnosisService;
import com.openhis.clinical.domain.Condition;
import com.openhis.clinical.domain.ConditionDefinition;
import com.openhis.clinical.mapper.ConditionDefinitionMapper;
import com.openhis.clinical.service.IConditionService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisPageUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.medication.domain.MedicationRequest;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import com.openhis.web.doctorstation.appservice.IDoctorStationChineseMedicalAppService;
import com.openhis.web.doctorstation.dto.*;
import com.openhis.web.doctorstation.mapper.DoctorStationChineseMedicalAppMapper;
import com.openhis.web.doctorstation.utils.AdviceUtils;
/**
* 医生站-中医 应用实现类
*/
@Service
public class DoctorStationChineseMedicalAppServiceImpl implements IDoctorStationChineseMedicalAppService {
@Resource
DoctorStationChineseMedicalAppMapper doctorStationChineseMedicalAppMapper;
@Resource
ConditionDefinitionMapper conditionDefinitionMapper;
@Resource
IConditionService iConditionService;
@Resource
IEncounterDiagnosisService iEncounterDiagnosisService;
@Resource
IDoctorStationAdviceAppService iDoctorStationAdviceAppService;
@Resource
AssignSeqUtil assignSeqUtil;
@Resource
AdviceUtils adviceUtils;
/**
* 查询中医诊断数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医诊断数据
*/
@Override
public Page<ConditionDefinitionMetadata> getConditionInfo(String searchKey, Integer pageNo, Integer pageSize) {
// 构建查询条件
ConditionDefinition conditionDefinition = new ConditionDefinition();
// 查询状态是有效的
conditionDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
// 中医诊断
conditionDefinition.setSourceEnum(ConditionDefinitionSource.TRADITIONAL_CHINESE_MEDICINE_DIAGNOSIS.getValue());
QueryWrapper<ConditionDefinition> queryWrapper = HisQueryUtils.buildQueryWrapper(conditionDefinition, searchKey,
new HashSet<>(Arrays.asList("name", "py_str", "wb_str")), null);
// 设置排序
queryWrapper.orderByDesc("update_time");
// 诊断信息
Page<ConditionDefinitionMetadata> conditionDefinitionMetadataPage = HisPageUtils
.selectPage(conditionDefinitionMapper, queryWrapper, pageNo, pageSize, ConditionDefinitionMetadata.class);
conditionDefinitionMetadataPage.getRecords().forEach(e -> {
// 所属分类
e.setSourceEnum_enumText(EnumUtils.getInfoByValue(ConditionDefinitionSource.class, e.getSourceEnum()));
// 中医诊断
e.setTypeName(CommonConstants.BusinessName.TCM_DIAGNOSIS);
// 医保标记
e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag()));
// 医保对码标记
e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag()));
});
return conditionDefinitionMetadataPage;
}
/**
* 查询中医证候数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医证候数据
*/
@Override
public Page<ConditionDefinitionMetadata> getSyndromeInfo(String searchKey, Integer pageNo, Integer pageSize) {
// 构建查询条件
ConditionDefinition conditionDefinition = new ConditionDefinition();
// 查询状态是有效的
conditionDefinition.setStatusEnum(PublicationStatus.ACTIVE.getValue());
// 中医证候
conditionDefinition
.setSourceEnum(ConditionDefinitionSource.TRADITIONAL_CHINESE_MEDICINE_SYNDROME_CATALOG.getValue());
QueryWrapper<ConditionDefinition> queryWrapper = HisQueryUtils.buildQueryWrapper(conditionDefinition, searchKey,
new HashSet<>(Arrays.asList("name", "py_str", "wb_str")), null);
// 设置排序
queryWrapper.orderByDesc("update_time");
// 诊断信息
Page<ConditionDefinitionMetadata> conditionDefinitionMetadataPage = HisPageUtils
.selectPage(conditionDefinitionMapper, queryWrapper, pageNo, pageSize, ConditionDefinitionMetadata.class);
conditionDefinitionMetadataPage.getRecords().forEach(e -> {
// 所属分类
e.setSourceEnum_enumText(EnumUtils.getInfoByValue(ConditionDefinitionSource.class, e.getSourceEnum()));
// 中医证候
e.setTypeName(CommonConstants.BusinessName.TCM_SYNDROME_CATALOG);
// 医保标记
e.setYbFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbFlag()));
// 医保对码标记
e.setYbMatchFlag_enumText(EnumUtils.getInfoByValue(Whether.class, e.getYbMatchFlag()));
});
return conditionDefinitionMetadataPage;
}
/**
* 保存中医诊断
*
* @param saveDiagnosisParam 诊断信息
* @return 结果
*/
@Override
public R<?> saveTcmDiagnosis(SaveDiagnosisParam saveDiagnosisParam) {
// 患者id
Long patientId = saveDiagnosisParam.getPatientId();
// 就诊ID
Long encounterId = saveDiagnosisParam.getEncounterId();
// 诊断定义集合
List<SaveDiagnosisChildParam> diagnosisChildList = saveDiagnosisParam.getDiagnosisChildList();
// 先删除再保存 (中医)
iEncounterDiagnosisService.deleteEncounterDiagnosisInfos(encounterId);
// 保存诊断管理
Condition condition;
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
condition = new Condition();
condition.setVerificationStatusEnum(saveDiagnosisChildParam.getVerificationStatusEnum());
condition.setPatientId(patientId);
condition.setDefinitionId(saveDiagnosisChildParam.getDefinitionId());
condition.setYbNo(saveDiagnosisChildParam.getYbNo());
condition.setTcmFlag(Whether.YES.getValue());// 中医标识
// 返回诊断id
Long conditionId = iConditionService.saveConditionByDoctor(condition);
saveDiagnosisChildParam.setConditionId(conditionId);
}
// 保存就诊诊断
EncounterDiagnosis encounterDiagnosis;
for (SaveDiagnosisChildParam saveDiagnosisChildParam : diagnosisChildList) {
encounterDiagnosis = new EncounterDiagnosis();
encounterDiagnosis.setEncounterId(encounterId);
encounterDiagnosis.setConditionId(saveDiagnosisChildParam.getConditionId());
encounterDiagnosis.setMaindiseFlag(saveDiagnosisChildParam.getMaindiseFlag());
encounterDiagnosis.setDiagSrtNo(saveDiagnosisChildParam.getDiagSrtNo()); // 排序号
encounterDiagnosis.setMedTypeCode(saveDiagnosisChildParam.getMedTypeCode());// 医疗类型
encounterDiagnosis.setTcmFlag(Whether.YES.getValue());// 中医标识
encounterDiagnosis.setSyndromeGroupNo(saveDiagnosisChildParam.getSyndromeGroupNo());// 中医证候组号
iEncounterDiagnosisService.save(encounterDiagnosis);
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"中医诊断"}));
}
/**
* 查询中医就诊诊断信息
*
* @param encounterId 就诊id
* @return 中医就诊诊断信息
*/
@Override
public R<?> getTcmEncounterDiagnosis(Long encounterId) {
HashMap<String, Object> resultMap = new HashMap<>();
// 中医就诊诊断信息
List<DiagnosisQueryDto> tcmEncounterDiagnosis =
doctorStationChineseMedicalAppMapper.getTcmEncounterDiagnosis(encounterId);
// 病
List<DiagnosisQueryDto> illness = tcmEncounterDiagnosis.stream().filter(
e -> ConditionDefinitionSource.TRADITIONAL_CHINESE_MEDICINE_DIAGNOSIS.getValue().equals(e.getSourceEnum()))
.collect(Collectors.toList());
// 症
List<DiagnosisQueryDto> symptom = tcmEncounterDiagnosis.stream()
.filter(e -> ConditionDefinitionSource.TRADITIONAL_CHINESE_MEDICINE_SYNDROME_CATALOG.getValue()
.equals(e.getSourceEnum()))
.collect(Collectors.toList());
resultMap.put("illness", illness);
resultMap.put("symptom", symptom);
return R.ok(resultMap);
}
/**
* 查询中医医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param adviceDefinitionIdParamList 医嘱定义id参数集合
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @param pricingFlag 划价标记
* @return 中医医嘱信息
*/
@Override
public IPage<AdviceBaseDto> getTcmAdviceBaseInfo(AdviceBaseDto adviceBaseDto, String searchKey, Long locationId,
List<Long> adviceDefinitionIdParamList, Long organizationId, Integer pageNo, Integer pageSize,
Integer pricingFlag) {
adviceBaseDto.setAdviceType(1); // 医嘱类型为药品
adviceBaseDto.setCategoryCode(medCategoryCode.CHINESE_HERBAL_MEDICINE.getValue());// 中草药
return iDoctorStationAdviceAppService.getAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, pricingFlag);
}
/**
* 门诊保存(签发)中医医嘱
*
* @param adviceSaveParam 医嘱表单信息
* @param adviceOpType 保存或签发
* @return 结果
*/
@Override
public R<?> saveOrSignTcmAdvice(AdviceSaveParam adviceSaveParam, String adviceOpType) {
// 医嘱分类信息 (中草药)
List<AdviceSaveDto> medicineList = adviceSaveParam.getAdviceSaveList();
// 保存操作
boolean is_save = AdviceOpType.SAVE_ADVICE.getCode().equals(adviceOpType);
// 签发操作
boolean is_sign = AdviceOpType.SIGN_ADVICE.getCode().equals(adviceOpType);
// 当前时间
Date curDate = new Date();
// 患者挂号对应的科室id
Long organizationId = adviceSaveParam.getOrganizationId();
// 保存时,校验库存
if (is_save) {
List<AdviceSaveDto> needCheckList = medicineList.stream()
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType())).collect(Collectors.toList());
// 校验库存
String tipRes = adviceUtils.checkInventory(needCheckList);
if (tipRes != null) {
return R.fail(null, tipRes);
}
}
// 药品请求
MedicationRequest medicationRequest;
// 费用项
ChargeItem chargeItem;
// 是否代煎
Integer sufferingFlag = adviceSaveParam.getSufferingFlag();
for (AdviceSaveDto adviceSaveDto : medicineList) {
// 中药付数
Integer chineseHerbsDoseQuantity = adviceSaveDto.getChineseHerbsDoseQuantity();
medicationRequest = new MedicationRequest();
medicationRequest.setTcmFlag(Whether.YES.getValue());// 中医标识
medicationRequest.setId(adviceSaveDto.getRequestId()); // 主键id
medicationRequest.setStatusEnum(is_save ? RequestStatus.DRAFT.getValue() : RequestStatus.ACTIVE.getValue()); // 请求状态
// 只有保存时才处理的字段属性
if (is_save) {
medicationRequest.setBusNo(assignSeqUtil.getSeq(AssignSeqEnum.MEDICATION_RES_NO.getPrefix(), 10));
medicationRequest.setChineseHerbsDoseQuantity(chineseHerbsDoseQuantity); // 中药付数
medicationRequest.setSufferingFlag(sufferingFlag); // 代煎标识
medicationRequest.setQuantity(adviceSaveDto.getQuantity() * chineseHerbsDoseQuantity); // 请求数量
}
// 代煎,生成中药代煎的request,及对应的账单
if (Whether.YES.getValue().equals(sufferingFlag)) {
}
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"门诊中医医嘱"}));
}
}

View File

@@ -0,0 +1,407 @@
package com.openhis.web.doctorstation.appservice.impl;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Resource;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.common.core.domain.model.LoginUser;
import com.core.common.utils.DateUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.administration.domain.Practitioner;
import com.openhis.administration.service.IPractitionerService;
import com.openhis.common.enums.ybenums.YbRxItemTypeCode;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.doctorstation.appservice.IDoctorStationElepPrescriptionService;
import com.openhis.web.doctorstation.mapper.DoctorStationElepPrescriptionMapper;
import com.openhis.workflow.domain.ElepMedicationRequest;
import com.openhis.workflow.domain.SupplyRequest;
import com.openhis.workflow.service.IElepMedicationRequestService;
import com.openhis.ybcatalog.domain.CatalogDrugInfo;
import com.openhis.ybcatalog.service.ICatalogDrugInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.MessageUtils;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.web.doctorstation.dto.*;
/**
* 医生站-电子处方 应用实现类
*/
@Service
public class DoctorStationElepPrescriptionServiceImpl implements IDoctorStationElepPrescriptionService {
@Autowired
ICatalogDrugInfoService catalogDrugInfoService;
@Autowired
DoctorStationElepPrescriptionMapper elepPrescriptionMapper;
@Autowired
IElepMedicationRequestService elepMedicationRequestService;
@Resource
IPractitionerService practitionerService;
@Resource
private AssignSeqUtil assignSeqUtil;
/**
* 电子处方下拉框
*
* @return 下拉框信息
*/
@Override
public R<?> elepPrescriptionInit() {
ElepPrescriptionInitDto initDto = new ElepPrescriptionInitDto();
// 处方类别
List<ElepPrescriptionInitDto.commonStatusOption> rxTypeCodeListOptions = Stream.of(YbRxItemTypeCode.values())
.map(prescriptionType -> new ElepPrescriptionInitDto.commonStatusOption(prescriptionType.getValue(),
prescriptionType.getDescription()))
.collect(Collectors.toList());
initDto.setRxTypeCodeListOptions(rxTypeCodeListOptions);
return R.ok(initDto);
}
/**
* 获取药品信息
*
* @param pageNo 当前页
* @param pageSize 每页多少条
* @param searchKey 模糊查询关键字
* @return 药品信息
*/
@Override
public R<?> getAllMedicationInfo(String searchKey, Integer pageNo, Integer pageSize) {
IPage<CatalogDrugInfo> medicationInfo = catalogDrugInfoService.selectCatalogDrugInfo(pageNo, pageSize, searchKey);
return R.ok(medicationInfo);
}
/**
* 获取处方信息
*
* @param patientId 患者id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品信息
*/
@Override
public R<?> getPrescriptionInfo(Long patientId, Integer pageNo, Integer pageSize) {
// 处方信息查询
IPage<ElepPrescriptionInfoDto> prescriptionInfo =
elepPrescriptionMapper.selectElepPrescriptionInfo(new Page<>(pageNo, pageSize), patientId);
// 状态转换
prescriptionInfo.getRecords().forEach(infoDto -> {
infoDto.setStatusEnum_enumText(EnumUtils.getInfoByValue(RequestStatus.class, infoDto.getStatusEnum()));
infoDto.setRxTypeCode_enumText(EnumUtils.getInfoByValue(PrescriptionType.class, infoDto.getRxTypeCode()));
});
return R.ok(prescriptionInfo);
}
/**
* 获取药品信息
*
* @param prescriptionNo 处方号
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品详细信息
*/
@Override
public R<?> getMedicationInfo(String prescriptionNo, Integer pageNo, Integer pageSize) {
// 药品详细查询
IPage<ElepMedicationInfoDto> medicationInfo =
elepPrescriptionMapper.selectMedicationInfo(new Page<>(pageNo, pageSize), prescriptionNo);
return R.ok(medicationInfo);
}
/**
* 获取处方编号
*
* @return 初始化信息
*/
@Override
public R<?> prescriptionNoInit() {
// 单据号
String prescriptionNo = assignSeqUtil.getSeqByDay(AssignSeqEnum.ELEP_MEDICATION_NO.getPrefix(), 10);
return R.ok(prescriptionNo);
}
/**
* 保存处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
@Override
public R<?> savePrescriptionInfo(ElepPrescriptionInfoParam prescriptionInfo) {
// 获取当前登陆用户信息
LoginUser loginUser = SecurityUtils.getLoginUser();
Practitioner user = practitionerService.getPractitionerByUserId(loginUser.getUserId());
// 获取当前时间
Date now = DateUtils.getNowDate();
// 根据处方号查询处方信息
List<ElepMedicationRequest> requestList = elepMedicationRequestService.selectElepMedicationRequestByPrescriptionNo(prescriptionInfo.getPrescriptionNo());
if (!requestList.isEmpty()) {
List<Integer> idList = requestList.stream().map(ElepMedicationRequest::getId).collect(Collectors.toList());
// 处方信息删除
elepMedicationRequestService.removeByIds(idList);
}
// 搜索更表需要信息
ElepPrescriptionInfoParam info = elepPrescriptionMapper.selectSaveInfo(prescriptionInfo.getEncounterId());
if(info.getConditionId() == null){
return R.fail("请先新增主诊断");
}
// 设置处方信息
List<ElepMedicationRequest> elepMedicationRequestList = new ArrayList<>();
ElepMedicationRequest elepMedicationRequest;
for (ElepMedicationInfoDto item : prescriptionInfo.getMedicationInfoList()) {
elepMedicationRequest = new ElepMedicationRequest();
elepMedicationRequest
// ID
.setId(null)
// 医院内部处方编号
.setPrescriptionNo(prescriptionInfo.getPrescriptionNo())
// 医院id
.setOrganizationId(info.getOrganizationId())
// 门诊/住院病历号
.setIptOtpNo(info.getIptOtpNo())
// 科室病区
.setDepartmentWard(info.getDepartmentWard())
// 医保类型
.setInsuranceEnum(info.getInsuranceEnum())
// 开具日期
.setIssueTime(now)
// 开具科室
.setOrgId(user.getOrgId())
// 患者
.setPatientId(prescriptionInfo.getPatientId())
// 就诊id
.setEncounterId(prescriptionInfo.getEncounterId())
// 诊断id
.setConditionId(info.getConditionId())
// 有效天数
.setValidityDays(prescriptionInfo.getValidityDays())
// 药品定义id
.setMedicationId(item.getMedicationId())
// 药品剂量
.setMedDosage(item.getMedDosage())
// 药品剂量单位
.setMedDosageUnitCode(item.getMedDosageUnitCode())
// 药品频率
.setMedFrequency(item.getMedFrequency())
// 药品途径
.setMedRoute(item.getMedRoute())
// 请求数量
.setQuantity(item.getQuantity())
// 请求单位
.setUnitCode(item.getUnitCode())
// 开方医师
.setPrescribingDrId(user.getId())
// 处方状态
.setStatusEnum(RequestStatus.DRAFT.getValue())
// 延长原因
.setExtensionReason(prescriptionInfo.getExtensionReason())
// 处方类别
.setRxTypeCode(item.getRxTypeCode())
// 支持用药信息
.setSupportInfo(item.getSupportInfo())
// 服药时间(开始)
.setEffectiveDoseStart(item.getEffectiveDoseStart())
// 服药时间(结束)
.setEffectiveDoseEnd(item.getEffectiveDoseEnd())
// 给药间隔
.setDispenseInterval(item.getDispenseInterval())
// 单次发药数
.setDispensePerQuantity(item.getDispensePerQuantity())
// 每次发药供应天数
.setDispensePerDuration(item.getDispensePerDuration());
elepMedicationRequestList.add(elepMedicationRequest);
}
// 保存处方
boolean flg = elepMedicationRequestService.saveBatch(elepMedicationRequestList);
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"电子处方"}));
}
/**
* 修改处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
@Override
public R<?> updatePrescriptionInfo(ElepPrescriptionInfoParam prescriptionInfo) {
// 获取当前登陆用户信息
LoginUser loginUser = SecurityUtils.getLoginUser();
Practitioner user = practitionerService.getPractitionerByUserId(loginUser.getUserId());
// 获取当前时间
Date now = DateUtils.getNowDate();
// 设置处方信息
ElepMedicationRequest elepMedicationRequest;
List<ElepMedicationRequest> elepMedicationRequestList;
// 修改处方信息
if (prescriptionInfo.getId() == null) {
elepMedicationRequestList = elepMedicationRequestService
.selectElepMedicationRequestByPrescriptionNo(prescriptionInfo.getPrescriptionNo());
// 判断信息是否存在
if (elepMedicationRequestList == null) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
for (ElepMedicationRequest item : elepMedicationRequestList) {
item
// 开具日期
.setIssueTime(now)
// 开具科室
.setOrgId(user.getOrgId())
// 开方医师
.setPrescribingDrId(user.getId())
// 有效天数
.setValidityDays(prescriptionInfo.getValidityDays())
// 延长原因
.setExtensionReason(prescriptionInfo.getExtensionReason())
// 处方类别
.setRxTypeCode(prescriptionInfo.getRxTypeCode());
}
// 修改处方
boolean flg = elepMedicationRequestService.updateBatchById(elepMedicationRequestList);
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
}
// 修改药品信息
else {
elepMedicationRequest = elepMedicationRequestService.getById(prescriptionInfo.getId());
// 判断信息是否存在
if (elepMedicationRequest == null) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
elepMedicationRequest
// 开具日期
.setIssueTime(now)
// 开具科室
.setOrgId(user.getOrgId())
// 开方医师
.setPrescribingDrId(user.getId())
// 药品定义id
.setMedicationId(prescriptionInfo.getMedicationId())
// 药品剂量
.setMedDosage(prescriptionInfo.getMedDosage())
// 药品剂量单位
.setMedDosageUnitCode(prescriptionInfo.getMedDosageUnitCode())
// 药品频率
.setMedFrequency(prescriptionInfo.getMedFrequency())
// 药品途径
.setMedRoute(prescriptionInfo.getMedRoute())
// 请求数量
.setQuantity(prescriptionInfo.getQuantity())
// 请求单位
.setUnitCode(prescriptionInfo.getUnitCode())
// 支持用药信息
.setSupportInfo(prescriptionInfo.getSupportInfo())
// 服药时间(开始)
.setEffectiveDoseStart(prescriptionInfo.getEffectiveDoseStart())
// 服药时间(结束)
.setEffectiveDoseEnd(prescriptionInfo.getEffectiveDoseEnd())
// 给药间隔
.setDispenseInterval(prescriptionInfo.getDispenseInterval())
// 单次发药数
.setDispensePerQuantity(prescriptionInfo.getDispensePerQuantity())
// 每次发药供应天数
.setDispensePerDuration(prescriptionInfo.getDispensePerDuration());
// 修改处方
boolean flg = elepMedicationRequestService.updateById(elepMedicationRequest);
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"电子处方"}));
}
/**
* 删除处方
*
* @param deletePrescriptionInfoParam 删除处方信息
* @return 执行结果
*/
@Override
public R<?> deletePrescriptionInfo(DeletePrescriptionInfoParam deletePrescriptionInfoParam) {
// 设置处方信息
List<ElepMedicationRequest> elepMedicationRequestList;
if (deletePrescriptionInfoParam.getIdList().isEmpty()) {
elepMedicationRequestList = elepMedicationRequestService
.selectElepMedicationRequestByPrescriptionNoList(deletePrescriptionInfoParam.getPrescriptionNoList());
// 判断信息是否存在
if (elepMedicationRequestList == null) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
// 删除处方
boolean flg = elepMedicationRequestService
.deleteElepMedicationRequestByPrescriptionNo(deletePrescriptionInfoParam.getPrescriptionNoList());
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
} else {
elepMedicationRequestList =
elepMedicationRequestService.selectElepMedicationRequestById(deletePrescriptionInfoParam.getIdList());
// 判断信息是否存在
if (elepMedicationRequestList == null) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
// 删除处方
boolean flg = elepMedicationRequestService.removeBatchByIds(elepMedicationRequestList);
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[] {"电子处方"}));
}
/**
* 签发处方
*
* @param prescriptionNoList 处方号
* @return 药品详细信息
*/
@Override
public R<?> issuancePrescription(List<String> prescriptionNoList) {
// 搜索处方信息
List<ElepMedicationRequest> elepMedicationRequestList =
elepMedicationRequestService.selectElepMedicationRequestByPrescriptionNoList(prescriptionNoList);
// 判断处方是否存在
if (elepMedicationRequestList == null) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
for (ElepMedicationRequest item : elepMedicationRequestList) {
// 处方状态
item.setStatusEnum(RequestStatus.ACTIVE.getValue());
}
// 签发处方
boolean flg = elepMedicationRequestService.updateBatchById(elepMedicationRequestList);
if (!flg) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
}
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"电子处方"}));
}
}

View File

@@ -0,0 +1,83 @@
package com.openhis.web.doctorstation.appservice.impl;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.core.common.core.domain.R;
import com.core.common.utils.DateUtils;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.web.doctorstation.appservice.IDoctorStationPtDetailsAppService;
import com.openhis.web.doctorstation.dto.PatientDetailsDto;
import com.openhis.web.doctorstation.mapper.DoctorStationPtDetailsAppMapper;
/**
* 医生站-患者详情应用实现类
*
* @author liuhr
* @date 2025/4/10
*/
@Service
public class DoctorStationPtDetailsAppServiceImpl implements IDoctorStationPtDetailsAppService {
@Autowired
DoctorStationPtDetailsAppMapper doctorStationPtDetailsAppMapper;
/**
* 查询患者详情
*
* @param encounterId 就诊Id
* @return 患者详情
*/
@Override
public R<?> getPtDetails(Long encounterId) {
// 收费状态List(1:待收费,2:待结算,5:已结算)
List<Integer> statusList = new ArrayList<>();
// 向列表中添加元素,1:待收费
statusList.add(ChargeItemStatus.PLANNED.getValue());
// 向列表中添加元素,2:待结算
statusList.add(ChargeItemStatus.BILLABLE.getValue());
// 向列表中添加元素,5:已结算
statusList.add(ChargeItemStatus.BILLED.getValue());
PatientDetailsDto patientDetailsDto = doctorStationPtDetailsAppMapper.getPtDetailsList(encounterId,
ChargeItemContext.MEDICATION.getValue(), ChargeItemContext.DEVICE.getValue(),
ChargeItemContext.ACTIVITY.getValue(), ClinicalStatus.ACTIVE.getValue(), LocationForm.BED.getValue(),
ParticipantType.ADMITTER.getCode(), statusList);
// 住院的场合,获取现在时间,计算住院天数
if (patientDetailsDto.getClassEnum() == EncounterClass.IMP.getValue()) {
// 截至时间,用于计算当前时刻下显示的住院天数
Date endTime;
if (patientDetailsDto.getEndTime() == null) {
endTime = DateUtils.getNowDate();
} else {
endTime = patientDetailsDto.getEndTime();
}
int days = DateUtils.differentDaysByMillisecond(patientDetailsDto.getStartTime(), endTime);
patientDetailsDto.setAdmissionDays(days);
}
// 性别枚举类回显赋值
patientDetailsDto.setGenderEnum_enumText(
EnumUtils.getInfoByValue(AdministrativeGender.class, patientDetailsDto.getGenderEnum()));
// 婚姻状态枚举类回显赋值
patientDetailsDto.setMaritalStatusEnum_enumText(
EnumUtils.getInfoByValue(MaritalStatus.class, patientDetailsDto.getMaritalStatusEnum()));
// 职业编码枚举类回显赋值
patientDetailsDto
.setPrfsEnum_enumText(EnumUtils.getInfoByValue(OccupationType.class, patientDetailsDto.getPrfsEnum()));
// 家庭关系枚举类回显赋值
patientDetailsDto.setLinkRelationCode_enumText(
EnumUtils.getInfoByValue(FamilyRelationshipType.class, patientDetailsDto.getLinkRelationCode()));
return R.ok(patientDetailsDto);
}
}

View File

@@ -0,0 +1,81 @@
package com.openhis.web.doctorstation.controller;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.web.doctorstation.appservice.IDoctorStationAllergyIntolAppService;
import com.openhis.web.doctorstation.dto.AllergyIntoInfoDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 医生站-患者过敏与不耐受管理
*
* @author liuhr
* @date 2025/4/10
*/
@RestController
@RequestMapping("/doctor-station/allergy-intolerance")
@Slf4j
@AllArgsConstructor
public class DoctorStationAllergyIntolController {
@Autowired
private IDoctorStationAllergyIntolAppService doctorStationAllergyIntolAppService;
/**
* 患者过敏与不耐受数据初始化
*
* @return 基础数据
*/
@GetMapping(value = "/init")
public R<?> init() {
return doctorStationAllergyIntolAppService.init();
}
/**
* 查询患者过敏与不耐受信息
*
* @param patientId 患者Id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 患者过敏与不耐受信息
*/
@GetMapping(value = "/allergy-intolerance-info")
public R<?> getAllergyIntolerance(@RequestParam Long patientId,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
return doctorStationAllergyIntolAppService.getAllergyIntoleranceInfo(patientId, pageNo, pageSize, request);
}
/**
* 作废当条患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
@PutMapping(value = "/allergy-intolerance-info")
public R<?> invalidateAllergyIntolerance(@RequestBody AllergyIntoInfoDto allergyIntoInfoDto) {
return doctorStationAllergyIntolAppService.invalidateAllergyIntolerance(allergyIntoInfoDto);
}
/**
* 新增患者过敏与不耐受信息
*
* @param allergyIntoInfoDto 患者过敏与不耐受信息
* @return
*/
@PostMapping(value = "/allergy-intolerance-info")
public R<?> addAllergyIntoleranceInfo(@Validated @RequestBody AllergyIntoInfoDto allergyIntoInfoDto) {
return doctorStationAllergyIntolAppService.addAllergyIntoleranceInfo(allergyIntoInfoDto);
}
}

View File

@@ -0,0 +1,120 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.doctorstation.controller;
import java.util.List;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.common.enums.AdviceOpType;
import com.openhis.common.enums.Whether;
import com.openhis.web.doctorstation.appservice.IDoctorStationChineseMedicalAppService;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.doctorstation.dto.AdviceSaveParam;
import com.openhis.web.doctorstation.dto.SaveDiagnosisParam;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 医生站-中医 controller
*/
@RestController
@RequestMapping("/doctor-station/chinese-medical")
@Slf4j
@AllArgsConstructor
public class DoctorStationChineseMedicalController {
private final IDoctorStationChineseMedicalAppService iDoctorStationChineseMedicalAppService;
/**
* 查询中医诊断数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医诊断数据
*/
@GetMapping(value = "/condition-info")
public R<?> getConditionInfo(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return R.ok(iDoctorStationChineseMedicalAppService.getConditionInfo(searchKey, pageNo, pageSize));
}
/**
* 查询中医证候数据
*
* @param searchKey 关键字
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医证候数据
*/
@GetMapping(value = "/syndrome-info")
public R<?> getSyndromeInfo(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return R.ok(iDoctorStationChineseMedicalAppService.getSyndromeInfo(searchKey, pageNo, pageSize));
}
/**
* 保存中医诊断
*
* @param saveDiagnosisParam 诊断信息
* @return 结果
*/
@PostMapping(value = "/save-tcm-diagnosis")
public R<?> saveTcmDiagnosis(@RequestBody SaveDiagnosisParam saveDiagnosisParam) {
return iDoctorStationChineseMedicalAppService.saveTcmDiagnosis(saveDiagnosisParam);
}
/**
* 查询中医就诊诊断信息
*
* @param encounterId 就诊id
* @return 中医就诊诊断信息
*/
@GetMapping(value = "/get-tcm-encounter-diagnosis")
public R<?> getTcmEncounterDiagnosis(@RequestParam Long encounterId) {
return iDoctorStationChineseMedicalAppService.getTcmEncounterDiagnosis(encounterId);
}
/**
* 查询中医医嘱信息
*
* @param adviceBaseDto 查询条件
* @param searchKey 模糊查询关键字
* @param locationId 药房id
* @param adviceDefinitionIdParamList 医嘱定义id参数集合
* @param organizationId 患者挂号对应的科室id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 中医医嘱信息
*/
@GetMapping(value = "/tcm-advice-base-info")
public R<?> getTcmAdviceBaseInfo(AdviceBaseDto adviceBaseDto,
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "locationId", required = false) Long locationId,
@RequestParam(value = "adviceDefinitionIdParamList", required = false) List<Long> adviceDefinitionIdParamList,
@RequestParam(value = "organizationId") Long organizationId,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return R.ok(iDoctorStationChineseMedicalAppService.getTcmAdviceBaseInfo(adviceBaseDto, searchKey, locationId,
adviceDefinitionIdParamList, organizationId, pageNo, pageSize, Whether.NO.getValue()));
}
/**
* 门诊保存中医医嘱
*
* @param adviceSaveParam 医嘱表单信息
* @return 结果
*/
@PostMapping(value = "/save-tcm-advice")
public R<?> saveTcmAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
return iDoctorStationChineseMedicalAppService.saveOrSignTcmAdvice(adviceSaveParam,
AdviceOpType.SAVE_ADVICE.getCode());
}
}

View File

@@ -0,0 +1,142 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.doctorstation.controller;
import com.openhis.web.doctorstation.appservice.IDoctorStationElepPrescriptionService;
import com.openhis.web.doctorstation.dto.*;
import com.openhis.web.ybmanage.service.IYbEleHttpService;
import org.apache.ibatis.annotations.Param;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.core.common.core.domain.R;
import com.openhis.common.enums.AdviceOpType;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import java.util.List;
/**
* 医生站-电子处方 controller
*/
@RestController
@RequestMapping("/doctor-station/elep")
@Slf4j
@AllArgsConstructor
public class DoctorStationElepPrescriptionController {
@Autowired
IDoctorStationElepPrescriptionService doctorStationElepService;
/**
* 电子处方下拉框
*
* @return 下拉框信息
*/
@GetMapping("/init")
public R<?> elepPrescriptionInit() {
return doctorStationElepService.elepPrescriptionInit();
}
/**
* 获取全部药品信息
*
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品信息
*/
@GetMapping("/get-allMedicationInfo")
public R<?> getAllMedicationInfo(@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return doctorStationElepService.getAllMedicationInfo(searchKey, pageNo, pageSize);
}
/**
* 获取处方信息
*
* @param patientId 患者id
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品信息
*/
@GetMapping("/get-prescriptionInfo")
public R<?> getPrescriptionInfo(@RequestParam Long patientId,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return doctorStationElepService.getPrescriptionInfo(patientId, pageNo, pageSize);
}
/**
* 获取药品信息
*
* @param prescriptionNo 处方号
* @param pageNo 当前页
* @param pageSize 每页多少条
* @return 药品详细信息
*/
@GetMapping("/get-medicationInfo")
public R<?> getMedicationInfo(@RequestParam String prescriptionNo,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
return doctorStationElepService.getMedicationInfo(prescriptionNo, pageNo, pageSize);
}
/**
* 获取单据号
*
* @return 初始化信息
*/
@GetMapping("/prescriptionNoInit")
public R<?> prescriptionNoInit() {
return doctorStationElepService.prescriptionNoInit();
}
/**
* 保存处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
@PostMapping("/save-prescriptionInfo")
public R<?> savePrescriptionInfo(@RequestBody ElepPrescriptionInfoParam prescriptionInfo) {
return doctorStationElepService.savePrescriptionInfo(prescriptionInfo);
}
/**
* 修改处方
*
* @param prescriptionInfo 处方信息
* @return 执行结果
*/
@PostMapping("/update-prescriptionInfo")
public R<?> updatePrescriptionInfo(@RequestBody ElepPrescriptionInfoParam prescriptionInfo) {
return doctorStationElepService.updatePrescriptionInfo(prescriptionInfo);
}
/**
* 删除处方
*
* @param deletePrescriptionInfoParam 处方信息
* @return 执行结果
*/
@PostMapping("/delete-prescriptionInfo")
public R<?> deletePrescriptionInfo(@RequestBody DeletePrescriptionInfoParam deletePrescriptionInfoParam) {
return doctorStationElepService.deletePrescriptionInfo(deletePrescriptionInfoParam);
}
/**
* 签发处方
*
* @param prescriptionNoList 处方号
* @return 执行结果
*/
@PostMapping("/issuance-prescription")
public R<?> issuancePrescription(@RequestBody List<String> prescriptionNoList) {
return doctorStationElepService.issuancePrescription(prescriptionNoList);
}
}

View File

@@ -0,0 +1,45 @@
package com.openhis.web.doctorstation.controller;
import com.openhis.web.doctorstation.appservice.IDoctorStationPtDetailsAppService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.core.common.core.domain.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
/**
* 医生站-患者详情
*
* @author liuhr
* @date 2025/4/10
*/
@RestController
@RequestMapping("/doctor-station/patient-details")
@Slf4j
@AllArgsConstructor
public class DoctorStationPtDetailsController {
@Autowired
private IDoctorStationPtDetailsAppService doctorStationPtDetailsAppService;
/**
* 查询患者详情
*
* @param encounterId 就诊Id
* @return 患者详情
*/
@GetMapping(value = "/patient-details")
public R<?> getPtDetails(@RequestParam Long encounterId) {
return doctorStationPtDetailsAppService.getPtDetails(encounterId);
}
}

View File

@@ -0,0 +1,91 @@
package com.openhis.web.doctorstation.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 患者过敏不耐受Dto
*
* @author liuhr
* @date 2025/4/10
*/
@Data
@Accessors(chain = true)
public class AllergyIntoInfoDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 临床状况 */
private Integer clinicalStatusEnum;
private String clinicalStatusEnum_enumText;
/** 验证状态 */
private Integer verificationStatusEnum;
private String verificationStatusEnum_enumText;
/** 类型 */
private Integer typeEnum;
/** 过敏原类别 */
@Dict(dictCode = "allergy_category")
private String categoryCode;
private String categoryCode_dictText;
/** 危险程度 */
private Integer criticalityEnum;
private String criticalityEnum_enumText;
/** 过敏物质编码 */
@Dict(dictCode = "allergy_code")
private String code;
private String code_dictText;
/** 患者ID */
@Dict(dictTable = "adm_patient", dictCode = "id", dictText = "name")
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
private String patientId_dictText;
/** 反应描述 */
private String description;
/** 严重程度 */
private Integer severityEnum;
private String severityEnum_enumText;
/** 过敏发生开始日期 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date onsetDateTime;
/** 记录者 */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_practitioner", dictCode = "id", dictText = "name")
private Long practitionerId;
private String practitionerId_dictText;
/** 断言者 */
@JsonSerialize(using = ToStringSerializer.class)
private Long checkPractitionerId;
/** 记录日期 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date recordedDate;
/** 最后反应发生日期 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date lastReactionOccurrence ;
/** 备注 */
private String note;
}

View File

@@ -0,0 +1,41 @@
package com.openhis.web.doctorstation.dto;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 患者过敏不耐受初期数据Dto
*
* @author liuhr
* @date 2025/4/10
*/
@Data
@Accessors(chain = true)
public class AllergyIntoInitDto {
//临床状况列表
private List<statusEnumOption> clinicalStatusOptions;
//验证状态列表
private List<statusEnumOption> verificationStatusOptions;
//危险程度列表
private List<statusEnumOption> criticalityOptions;
//严重程度列表
private List<statusEnumOption> severityOptions;
/**
* 状态
*/
@Data
public static class statusEnumOption {
private Integer value;
private String info;
public statusEnumOption(Integer value, String info) {
this.value = value;
this.info = info;
}
}
}

View File

@@ -0,0 +1,23 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 电子处方 dto
*/
@Data
@Accessors(chain = true)
public class DeletePrescriptionInfoParam {
/** ID */
private List<Integer> idList;
/** 医院内部处方编号*/
private List<String> prescriptionNoList;
}

View File

@@ -0,0 +1,63 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 药品信息 dto
*/
@Data
@Accessors(chain = true)
public class ElepMedicationInfoDto {
private Long id;
/** 药品定义id */
private String medicationId;
/** 药品名 */
private String medicationName;
/** 药品规格 */
private String drugSpecification;
/** 生产厂家 */
private String manufacturerName;
/** 药品剂量 */
private BigDecimal medDosage;
/** 药品剂量单位 */
private String medDosageUnitCode;
/** 使用频次 */
@Dict(dictCode = "elep_rate_code")
private String medFrequency;
private String medFrequency_dictText;
/** 途径 */
@Dict(dictCode = "method_code")
private String medRoute;
private String medRoute_dictText;
/** 请求数量 */
private Integer quantity;
/** 请求单位 */
private String unitCode;
/** 支持用药信息 */
private String supportInfo;
/** 服药时间(开始) */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date effectiveDoseStart;
/** 服药时间(结束) */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date effectiveDoseEnd;
/** 给药间隔 */
private String dispenseInterval;
/** 单次发药数 */
private Integer dispensePerQuantity;
/** 每次发药供应天数 */
private Integer dispensePerDuration;
/** 处方类别 */
private Integer rxTypeCode;
}

View File

@@ -0,0 +1,52 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 电子处方 dto
*/
@Data
@Accessors(chain = true)
public class ElepPrescriptionInfoDto {
/** 租户ID */
private Integer tenantId;
/** 处方号 */
private String prescriptionNo;
/** 门诊号 */
private String iptOtpNo;
/** 科室病区 */
private String departmentWard;
/** 有效天数 */
private Integer validityDays;
/** 状态 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 开方医生名 */
private String practitionerName;
/** 开单科室 */
private String prscDeptName;
/** 处方开立日期 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date prscTime;
/** 取药状态 */
private String medStatus;
/** 延长原因 */
private String extensionReason;
/** 撤销原因 */
private String quashReason;
/** 诊断名 */
private String conditionName;
/** 处方类别 */
private Integer rxTypeCode;
private String rxTypeCode_enumText;
}

View File

@@ -0,0 +1,112 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Positive;
/**
* 电子处方 dto
*/
@Data
@Accessors(chain = true)
public class ElepPrescriptionInfoParam {
/** ID */
private Integer id;
/** 医院内部处方编号 */
private String prescriptionNo;
/** 医院id (前台不传) */
private Long organizationId;
/** 门诊/住院病历号 (前台不传) */
private String iptOtpNo;
/** 科室病区 (前台不传) */
private String departmentWard;
/** 医保类型 (前台不传) */
private Integer insuranceEnum;
/** 开具日期 (前台不传) */
private Date issueTime;
/** 开具科室 (前台不传) */
private Long orgId;
/** 患者 */
private Long patientId;
/** 就诊id */
private Long encounterId;
/** 诊断id (前台不传) */
private Long conditionId;
/** 有效天数 */
private Integer validityDays;
/** 药品定义id */
private String medicationId;
/** 药品剂量 */
private BigDecimal medDosage;
/** 药品剂量单位 */
private String medDosageUnitCode;
/** 药品频率 */
private String medFrequency;
/** 药品途径 */
private String medRoute;
/** 开方医师 (前台不传) */
private Long prescribingDrId;
/** 延长原因 */
private String extensionReason;
/** 处方状态 (前台不传) */
private Integer statusEnum;
/** 请求数量 */
private Integer quantity;
/** 请求单位 */
private String unitCode;
/** 处方类别 */
private Integer rxTypeCode;
/** 支持用药信息 */
private String supportInfo;
/** 服药时间(开始) */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date effectiveDoseStart;
/** 服药时间(结束) */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date effectiveDoseEnd;
/** 给药间隔 */
private String dispenseInterval;
/** 单次发药数 */
private Integer dispensePerQuantity;
/** 每次发药供应天数 */
private Integer dispensePerDuration;
/** 药品信息 */
List<ElepMedicationInfoDto> medicationInfoList;
}

View File

@@ -0,0 +1,36 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import com.openhis.web.basedatamanage.dto.LocationDto;
import com.openhis.web.inventorymanage.dto.ProductStocktakingInitDto;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 电子处方下拉框
*/
@Data
@Accessors(chain = true)
public class ElepPrescriptionInitDto {
/**
* 处方类别
*/
private List<ElepPrescriptionInitDto.commonStatusOption> rxTypeCodeListOptions;
@Data
public static class commonStatusOption {
private String value;
private String label;
public commonStatusOption(String value, String label) {
this.value = value;
this.label = label;
}
}
}

View File

@@ -0,0 +1,28 @@
package com.openhis.web.doctorstation.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 就诊费用性质 dto
*
* @author system
* @date 2025-02-20
*/
@Data
@Accessors(chain = true)
public class EncounterContractDto {
/** 关联账户ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long accountId;
/** 合同名称 */
private String contractName;
/** 合同编码 */
private String busNo;
}

View File

@@ -0,0 +1,168 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 患者详情Dto
*
* @author liuhr
* @date 2025/4/10
*/
@Data
@Accessors(chain = true)
public class PatientDetailsDto {
/**
* 就诊id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 患者id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long patientId;
/**
* 患者名字
*/
private String name;
/**
* 性别
*/
private Integer genderEnum;
private String genderEnum_enumText;
/**
* 生日
*/
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date birthDate;
/**
* 病人年龄
*/
private String ageString;
/**
* 联系电话
*/
private String phone;
/**
* 详细地址
*/
private String address;
/**
* 工作单位
*/
private String workCompany;
/**
* 民族
*/
private String nationalityCode;
/**
* 婚姻状态
*/
private Integer maritalStatusEnum;
private String maritalStatusEnum_enumText;
/**
* 身份证ID
*/
private String idCard;
/**
* 国家编码
*/
private String countryCode;
/**
* 职业
*/
private Integer prfsEnum;
private String prfsEnum_enumText;
/**
* 联系人
*/
private String linkName;
/**
* 联系人关系
*/
private Integer linkRelationCode;
private String linkRelationCode_enumText;
/**
* 联系人电话
*/
private String linkTelcom;
/** 就诊类别 */
private Integer classEnum;
/** 就诊编号 */
private String busNo;
/** 挂号医生 */
private String doctorName;
/** 账户余额 */
private BigDecimal balanceAmount;
/** 账户类型编码 */
@Dict(dictCode = "")
private String typeCode;
private String typeCode_dictText;
/** 费用总计 */
private BigDecimal totalPrice;
/** 费用:药品 */
private BigDecimal totalMedicationPrice;
/** 费用:耗材 */
private BigDecimal totalDevicePrice;
/** 费用:项目 */
private BigDecimal totalActivityPrice;
/** 床位号 */
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_location", dictCode = "id", dictText = "name")
private Long bedLocationId;
private String bedLocationId_dictText;
/** 入院时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date startTime;
/** 出院时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date endTime;
/** 挂号时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
/** 入院天数 */
private Integer admissionDays;
/** 过敏史 */
private Integer allergyHistoryFlag;
}

View File

@@ -0,0 +1,155 @@
package com.openhis.web.doctorstation.dto;
import java.math.BigDecimal;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 医嘱请求基础 dto
*/
@Data
@Accessors(chain = true)
public class RequestBaseDto {
/** 医嘱类型 */
private Integer adviceType; // 1:药品 , 2: 耗材 , 3:项目
/**
* 唯一标识
*/
private String uniqueKey; // requestId拼接adviceType
/**
* 请求人id
*/
@JsonSerialize(using = ToStringSerializer.class)
@Dict(dictTable = "adm_practitioner", dictCode = "id", dictText = "name")
private Long requesterId;
private String requesterId_dictText;
/** 请求时间 */
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
private Date requestTime;
/**
* 当前登录账号请求标记 | 1:是,0:否
*/
private String bizRequestFlag;
/**
* 请求内容json
*/
private String contentJson;
/**
* 诊断定义名称
*/
private String conditionDefinitionName;
/**
* 分组id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long groupId;
/**
* 请求id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long requestId;
/**
* 费用项id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long chargeItemId;
/** 医嘱名称 */
private String adviceName;
/**
* 规格
*/
private String volume;
/** 产品批号 */
private String lotNumber;
/** 请求数量 */
private Integer quantity;
/** 请求单位编码 */
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
/** 请求状态 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 收费状态 */
private Integer chargeStatus;
private String chargeStatus_enumText;
/** 是否皮试 */
private Integer skinTestFlag;
private String skinTestFlag_enumText;
/** 是否为注射药物 */
private Integer injectFlag;
private String injectFlag_enumText;
/**
* 用法
*/
@Dict(dictCode = "method_code")
private String methodCode;
private String methodCode_dictText;
/**
* 使用频次
*/
@Dict(dictCode = "rate_code")
private String rateCode;
private String rateCode_dictText;
/**
* 单次剂量
*/
private BigDecimal dose;
/** 剂量单位 */
@Dict(dictCode = "unit_code")
private String doseUnitCode;
private String doseUnitCode_dictText;
/**
* 总价
*/
private BigDecimal totalPrice;
/**
* 物理位置id | 可能是 发药药房id,耗材房id,执行科室id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long positionId;
/**
* 物理位置| 可能是 发药药房,耗材房,执行科室
*/
private String positionName;
/** 用药天数 */
private Integer dispensePerDuration;
/** 拆零比 */
private BigDecimal partPercent;
}

View File

@@ -0,0 +1,28 @@
package com.openhis.web.doctorstation.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 更新组号 dto
*/
@Data
@Accessors(chain = true)
public class UpdateGroupDto {
/**
* 请求id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long requestId;
/**
* 分组id
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long groupId;
}

View File

@@ -0,0 +1,20 @@
package com.openhis.web.doctorstation.dto;
import java.util.List;
import lombok.Data;
import lombok.experimental.Accessors;
/**
* 更新组号参数类
*/
@Data
@Accessors(chain = true)
public class UpdateGroupIdParam {
/**
* 保存医嘱 dto
*/
private List<UpdateGroupDto> groupList;
}

Some files were not shown because too many files have changed in this diff Show More