super_institution接口说明.md 17 KB

super/institution 接口说明

接口概述

接口路径: POST super/institution

功能: 获取当前医生所在机构可访问的上级医院列表(用于远程诊断申请)

业务场景:

  • 下级医院申请远程诊断时,需要选择上级医院
  • 返回两类机构:普通远程合作机构 + 特殊远程机构(如专家会诊平台)

调用链路

Route (route.php)
  ↓
SuperController::institution_list()
  ↓
SuperService::getParentInstitution($institution_id)
  ↓
SuperDao (wrapper层)
  ↓
InstitutionModel (实际SQL查询)

核心逻辑流程

1. Controller 层

文件: controller/super/SuperController.php

public function institution_list(SuperService $service)
{
    // 1. 从token获取当前医生信息
    $doctor = $service->getUser($this->getToken());

    // 2. 根据医生所在机构ID查询可访问的上级机构
    $info = $service->getParentInstitution($doctor['institution_id']);

    // 3. 返回结果
    return $this->success($info);
}

2. Service 层

文件: services/super/SuperService.php

public function getParentInstitution($institution)
{
    // 1. 获取该机构配置的远程合作医院ID列表
    $hospitanInfo = $this->super->getRemoteIns($institution);
    $ids = $hospitanInfo;
    $parent = [];

    // 2. 获取特殊远程机构(专家会诊平台等,所有机构都可访问)
    $special = $this->super->getSpecialIns();

    // 3. 添加特殊机构到返回列表
    foreach ($special as $k => $v) {
        $s = [];
        $s['id'] = $v['id'];
        $s['name'] = $v['hospital_name'];
        $s['is_special'] = $v['is_special'];  // 标记为特殊机构
        $parent[] = $s;
    }

    // 4. 添加普通远程合作机构(并获取支付类型配置)
    foreach($ids as $k => $v) {
        // 查询当前机构与上级机构的支付方式配置
        $pay = $this->super->getPayType($institution, $v);
        if($pay == null) {
            $pay = '0';  // 默认患者支付
        }

        // 构造查询字段
        $pField = [
            'id',
            'name',
            '2 as is_special',    // 普通远程机构标记为2
            'id as hid',
            "$pay as pay_type"    // 支付类型
        ];

        // 获取机构详细信息
        $parent[] = $this->super->getInstitutionInfo($v, $pField);
    }

    return $parent;
}

返回数据结构:

[
    {
        "id": "机构ID",
        "name": "机构名称",
        "is_special": "1=特殊机构, 2=普通远程机构",
        "hid": "机构ID(普通远程机构才有)",
        "pay_type": "支付类型(普通远程机构才有, 0=患者支付, 1=医院挂账)"
    }
]

3. Model 层 - SQL 查询

文件: model/institution/InstitutionModel.php

3.1 获取远程合作机构列表

public function getRemoteIns($id)
{
    // 查询 remote_contact 表,获取该机构配置的所有上级机构ID
    $info = RcontactModel::where('hospital_id', $id)
                         ->column('super_hospital_id');
    return $info;
}

等价SQL:

SELECT super_hospital_id
FROM remote_contact
WHERE hospital_id = :id

涉及表: remote_contact (远程诊断关系表)


3.2 获取特殊远程机构

public function getSpecialIns()
{
    // 查询 special_remote 表,获取所有启用的特殊机构(按排序)
    $info = SremoteModel::where('status', 1)
                        ->order('sort asc')
                        ->field('id, name as hospital_name, 1 as is_special')
                        ->select();
    return $info;
}

等价SQL:

SELECT id,
       name as hospital_name,
       1 as is_special
FROM special_remote
WHERE status = 1
ORDER BY sort ASC

涉及表: special_remote (特殊远程机构表)


3.3 获取支付类型配置

public function getPayType($local, $super)
{
    // 查询下级机构与上级机构的支付方式配置
    $type = RcontactModel::where('hospital_id', $local)
                         ->where('super_hospital_id', $super)
                         ->value('pay_type');
    return $type;
}

等价SQL:

SELECT pay_type
FROM remote_contact
WHERE hospital_id = :local
  AND super_hospital_id = :super

支付类型说明:

  • 0 = 患者支付(患者直接支付远程诊断费用)
  • 1 = 医院挂账(下级医院与上级医院结算,患者不直接支付)

3.4 获取机构详细信息

public function getInfo($id, $field)
{
    // 根据ID和指定字段查询机构信息
    $info = $this->where('id', $id)
                 ->field($field)
                 ->find();
    return $info;
}

等价SQL:

SELECT {field}
FROM institution
WHERE id = :id

涉及表: institution (机构表)


数据库表结构

1. remote_contact (远程诊断关系表)

字段名 类型 说明
id int 主键
hospital_id varchar(32) 下级医院ID
hospital_name varchar(100) 下级医院名称
super_hospital_id varchar(32) 上级医院ID
super_hospital_name varchar(100) 上级医院名称
pay_type int 支付类型: 0=患者支付, 1=医院挂账
lower_ratio int 下级医院分成比例 (默认35%)
super_ratio int 上级医院分成比例 (默认50%)
zskk_ratio int 平台分成比例 (默认15%)
status int 状态: 1=正常, 0=禁用
sort int 排序号
create_time datetime 创建时间
update_time datetime 更新时间

索引:

  • hospital_id_index (hospital_id)
  • super_hospital_id_index (super_hospital_id)

2. special_remote (特殊远程机构表)

说明: 该表在新项目中尚未创建,需要补充。

预期字段:

CREATE TABLE `special_remote` (
  `id` varchar(32) NOT NULL COMMENT '机构ID',
  `name` varchar(100) NOT NULL COMMENT '机构名称',
  `status` int DEFAULT 1 COMMENT '状态: 1=启用, 0=禁用',
  `sort` int DEFAULT 0 COMMENT '排序号',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='特殊远程机构表(专家会诊平台等)';

特殊机构说明:

  • 所有机构都可以访问(不需要在 remote_contact 中配置关系)
  • 通常是专家会诊平台、知名医院专家团队等
  • 支持自定义排序(优先展示)

3. special_contact (特殊机构联系表)

说明: 用于配置特殊机构的医生联系方式和费用,该表在新项目中尚未创建

预期字段:

CREATE TABLE `special_contact` (
  `id` int NOT NULL AUTO_INCREMENT,
  `sid` varchar(32) COMMENT '特殊机构ID',
  `did` varchar(32) COMMENT '医生ID',
  `hid` varchar(32) COMMENT '机构ID',
  `cost` int DEFAULT 0 COMMENT '费用(分)',
  `describe` text COMMENT '医生介绍',
  `status` int DEFAULT 1 COMMENT '状态: 1=启用, 0=禁用',
  `sort` int DEFAULT 0 COMMENT '排序',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='特殊机构联系配置表';

业务规则总结

机构类型区分

类型 is_special 来源表 访问权限 支付配置
特殊机构 1 special_remote 所有机构 在 special_contact 中配置
普通远程机构 2 institution 需配置关系 在 remote_contact 中配置

支付类型说明

  • pay_type = 0 (患者支付):

    • 患者在申请远程诊断时直接支付费用
    • 费用分成按比例分配:下级(35%) + 上级(50%) + 平台(15%)
  • pay_type = 1 (医院挂账):

    • 患者不直接支付
    • 下级医院与上级医院按月或按单结算
    • 平台从医院结算中抽成

Java 实现建议

1. 实体类

RemoteContact.java

@Data
@TableName("remote_contact")
public class RemoteContact {
    @TableId(type = IdType.AUTO)
    private Integer id;

    @TableField("hospital_id")
    private String hospitalId;

    @TableField("hospital_name")
    private String hospitalName;

    @TableField("super_hospital_id")
    private String superHospitalId;

    @TableField("super_hospital_name")
    private String superHospitalName;

    @TableField("pay_type")
    private Integer payType;  // 0=患者支付, 1=医院挂账

    @TableField("lower_ratio")
    private Integer lowerRatio;

    @TableField("super_ratio")
    private Integer superRatio;

    @TableField("zskk_ratio")
    private Integer zskkRatio;

    @TableField("status")
    private Integer status;

    @TableField("sort")
    private Integer sort;

    @TableField("create_time")
    private Date createTime;

    @TableField("update_time")
    private Date updateTime;
}

SpecialRemote.java (待创建表)

@Data
@TableName("special_remote")
public class SpecialRemote {
    @TableId(type = IdType.ASSIGN_UUID)
    private String id;

    @TableField("name")
    private String name;

    @TableField("status")
    private Integer status;

    @TableField("sort")
    private Integer sort;

    @TableField("create_time")
    private Date createTime;

    @TableField("update_time")
    private Date updateTime;
}

2. DTO

InstitutionListDTO.java

@Data
@Schema(description = "上级机构列表项")
public class InstitutionListDTO {

    @Schema(description = "机构ID")
    private String id;

    @Schema(description = "机构名称")
    private String name;

    @Schema(description = "机构类型: 1=特殊机构, 2=普通远程机构")
    private Integer isSpecial;

    @Schema(description = "机构ID(普通远程机构)")
    private String hid;

    @Schema(description = "支付类型: 0=患者支付, 1=医院挂账")
    private Integer payType;
}

3. Service 实现

@Service
public class SuperServiceImpl implements SuperService {

    @Resource
    private RemoteContactMapper remoteContactMapper;

    @Resource
    private SpecialRemoteMapper specialRemoteMapper;

    @Resource
    private InstitutionMapper institutionMapper;

    @Override
    public List<InstitutionListDTO> getParentInstitution(String institutionId) {
        List<InstitutionListDTO> result = new ArrayList<>();

        // 1. 获取特殊远程机构(所有机构都可访问)
        List<SpecialRemote> specialList = getSpecialInstitutions();
        for (SpecialRemote special : specialList) {
            InstitutionListDTO dto = new InstitutionListDTO();
            dto.setId(special.getId());
            dto.setName(special.getName());
            dto.setIsSpecial(1);  // 特殊机构
            result.add(dto);
        }

        // 2. 获取该机构配置的远程合作机构
        List<String> remoteIds = getRemoteInstitutionIds(institutionId);
        for (String remoteId : remoteIds) {
            // 查询支付类型
            Integer payType = getPayType(institutionId, remoteId);
            if (payType == null) {
                payType = 0;  // 默认患者支付
            }

            // 查询机构信息
            Institution institution = institutionMapper.selectById(remoteId);
            if (institution != null) {
                InstitutionListDTO dto = new InstitutionListDTO();
                dto.setId(institution.getId());
                dto.setName(institution.getName());
                dto.setIsSpecial(2);  // 普通远程机构
                dto.setHid(institution.getId());
                dto.setPayType(payType);
                result.add(dto);
            }
        }

        return result;
    }

    /**
     * 获取特殊远程机构列表
     */
    private List<SpecialRemote> getSpecialInstitutions() {
        LambdaQueryWrapper<SpecialRemote> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SpecialRemote::getStatus, 1)
               .orderByAsc(SpecialRemote::getSort);
        return specialRemoteMapper.selectList(wrapper);
    }

    /**
     * 获取远程合作机构ID列表
     */
    private List<String> getRemoteInstitutionIds(String institutionId) {
        LambdaQueryWrapper<RemoteContact> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RemoteContact::getHospitalId, institutionId)
               .eq(RemoteContact::getStatus, 1);

        List<RemoteContact> contacts = remoteContactMapper.selectList(wrapper);
        return contacts.stream()
                      .map(RemoteContact::getSuperHospitalId)
                      .collect(Collectors.toList());
    }

    /**
     * 获取支付类型配置
     */
    private Integer getPayType(String localId, String superId) {
        LambdaQueryWrapper<RemoteContact> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(RemoteContact::getHospitalId, localId)
               .eq(RemoteContact::getSuperHospitalId, superId);

        RemoteContact contact = remoteContactMapper.selectOne(wrapper);
        return contact != null ? contact.getPayType() : null;
    }
}

4. Controller

@RestController
@RequestMapping("/api/super")
@Tag(name = "上级机构管理", description = "远程诊断相关接口")
public class SuperController {

    @Resource
    private SuperService superService;

    @Resource
    private JwtUtil jwtUtil;

    @Operation(
        summary = "获取上级机构列表",
        description = "获取当前机构可访问的上级医院列表," +
                      "包括特殊远程机构(所有人可见)和配置的远程合作机构"
    )
    @PostMapping("/institution")
    public RestResult<?> getInstitutionList(HttpServletRequest request) {
        try {
            // 1. 从token获取当前机构ID
            String token = getTokenFromRequest(request);
            String institutionId = jwtUtil.getCurrentOrgFromToken(token);

            if (StringUtils.isBlank(institutionId)) {
                return RestResult.error("无法获取机构信息");
            }

            // 2. 查询可访问的上级机构列表
            List<InstitutionListDTO> list = superService.getParentInstitution(institutionId);

            return RestResult.ok("查询成功", list);
        } catch (Exception e) {
            return RestResult.error("查询失败:" + e.getMessage());
        }
    }

    private String getTokenFromRequest(HttpServletRequest request) {
        String token = request.getHeader("Authorization");
        if (StringUtils.isBlank(token)) {
            token = request.getHeader("token");
        }
        return token;
    }
}

待办事项

1. 数据库表创建

需要创建以下表:

-- 特殊远程机构表
CREATE TABLE `special_remote` (
  `id` varchar(32) NOT NULL COMMENT '机构ID',
  `name` varchar(100) NOT NULL COMMENT '机构名称',
  `description` text COMMENT '机构描述',
  `status` int DEFAULT 1 COMMENT '状态: 1=启用, 0=禁用',
  `sort` int DEFAULT 0 COMMENT '排序号',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB COMMENT='特殊远程机构表';

-- 特殊机构联系表
CREATE TABLE `special_contact` (
  `id` int NOT NULL AUTO_INCREMENT,
  `sid` varchar(32) COMMENT '特殊机构ID',
  `did` varchar(32) COMMENT '医生ID',
  `hid` varchar(32) COMMENT '机构ID',
  `cost` int DEFAULT 0 COMMENT '费用(分)',
  `describe` text COMMENT '医生介绍',
  `status` int DEFAULT 1 COMMENT '状态: 1=启用, 0=禁用',
  `sort` int DEFAULT 0 COMMENT '排序',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP,
  `update_time` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  KEY `idx_sid` (`sid`),
  KEY `idx_did` (`did`)
) ENGINE=InnoDB COMMENT='特殊机构联系配置表';

2. Java 代码生成

  • 生成 RemoteContact 相关代码(Entity/Mapper/Service)
  • 生成 SpecialRemote 相关代码(Entity/Mapper/Service)
  • 生成 SpecialContact 相关代码(Entity/Mapper/Service)
  • 创建 SuperController 和 SuperService
  • 编写单元测试

3. 功能扩展

  • 支持机构搜索/过滤
  • 支持按检查类型过滤可用机构
  • 添加机构详情查询接口
  • 添加费用试算接口

注意事项

  1. 权限控制: 该接口应该限制只有下级医院的医生可以调用
  2. 缓存优化: 机构列表变化不频繁,可以添加缓存(5-10分钟)
  3. 数据一致性: remote_contact 表的 status=1 才是有效关系
  4. 支付类型: 务必正确配置 pay_type,影响费用结算流程
  5. 特殊机构: 特殊机构的排序需要由管理员在后台配置