| | |
| | | package com.smartor.service.impl; |
| | | |
| | | import com.alibaba.fastjson2.JSON; |
| | | import com.alibaba.fastjson2.JSONArray; |
| | | import com.alibaba.fastjson2.JSONObject; |
| | | import com.google.gson.Gson; |
| | | import com.ruoyi.common.utils.DateUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.http.HttpUtils; |
| | | import com.smartor.domain.Icd10; |
| | | import com.smartor.mapper.Icd10Mapper; |
| | | import com.smartor.service.IIcd10Service; |
| | | import lombok.extern.slf4j.Slf4j; |
| | | import org.springframework.beans.factory.annotation.Autowired; |
| | | import org.springframework.beans.factory.annotation.Value; |
| | | import org.springframework.stereotype.Service; |
| | | |
| | | import java.util.List; |
| | | import java.util.*; |
| | | import java.util.stream.Collectors; |
| | | |
| | | /** |
| | | * 疾病Service业务层处理 |
| | |
| | | * @author ruoyi |
| | | * @date 2023-12-21 |
| | | */ |
| | | @Slf4j |
| | | @Service |
| | | public class Icd10ServiceImpl implements IIcd10Service |
| | | { |
| | | public class Icd10ServiceImpl implements IIcd10Service { |
| | | |
| | | @Autowired |
| | | private Icd10Mapper icd10Mapper; |
| | | |
| | | @Value("${sltd_pub_path}") |
| | | private String sltdPubPath; |
| | | |
| | | @Value("${lwl_app_key}") |
| | | private String APP_KEY; |
| | | |
| | | /** |
| | | * 固定 orgId |
| | | */ |
| | | private static final long ORG_ID = 20001001L; |
| | | /** |
| | | * 每页拉取条数(接口最大允许 1000) |
| | | */ |
| | | private static final int PAGE_SIZE = 1000; |
| | | /** |
| | | * 批量写入单批最大条数 |
| | | */ |
| | | private static final int BATCH_SIZE = 500; |
| | | |
| | | /** |
| | | * 查询疾病 |
| | |
| | | * @return 疾病 |
| | | */ |
| | | @Override |
| | | public Icd10 selectIcd10ByIcdid(Long icdid) |
| | | { |
| | | public Icd10 selectIcd10ByIcdid(Long icdid) { |
| | | return icd10Mapper.selectIcd10ByIcdid(icdid); |
| | | } |
| | | |
| | |
| | | * @return 疾病 |
| | | */ |
| | | @Override |
| | | public List<Icd10> selectIcd10List(Icd10 icd10) |
| | | { |
| | | public List<Icd10> selectIcd10List(Icd10 icd10) { |
| | | return icd10Mapper.selectIcd10List(icd10); |
| | | } |
| | | |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int insertIcd10(Icd10 icd10) |
| | | { |
| | | public int insertIcd10(Icd10 icd10) { |
| | | icd10.setCreateTime(DateUtils.getNowDate()); |
| | | return icd10Mapper.insertIcd10(icd10); |
| | | } |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int updateIcd10(Icd10 icd10) |
| | | { |
| | | public int updateIcd10(Icd10 icd10) { |
| | | icd10.setUpdateTime(DateUtils.getNowDate()); |
| | | return icd10Mapper.updateIcd10(icd10); |
| | | } |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int deleteIcd10ByIcdids(Long[] icdids) |
| | | { |
| | | public int deleteIcd10ByIcdids(Long[] icdids) { |
| | | return icd10Mapper.deleteIcd10ByIcdids(icdids); |
| | | } |
| | | |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int deleteIcd10ByIcdid(Long icdid) |
| | | { |
| | | public int deleteIcd10ByIcdid(Long icdid) { |
| | | return icd10Mapper.deleteIcd10ByIcdid(icdid); |
| | | } |
| | | |
| | | /** |
| | | * 从远程接口(来未来)分页拉取并增量写入 icd10 表。 |
| | | * <p> |
| | | * 优化要点: |
| | | * 1. 每页最大拉取 1000 条,减少请求次数。 |
| | | * 2. 每页把当前页所有 icdcode 用一条 IN SQL 一次批量查库,避免循环 N 次单条查询。 |
| | | * 3. 将不存在的记录收集后分批(每批 500 条)批量插入。 |
| | | * </p> |
| | | * |
| | | * @return 本次运行新增总条数 |
| | | */ |
| | | @Override |
| | | public int queryAddIcd10() { |
| | | int totalInserted = 0; |
| | | long current = 1; |
| | | long totalPages = 1; // 首次循环前先执行一次 |
| | | |
| | | log.info("[开始] 从来未来拉取 ICD10 增量数据,orgId={}", ORG_ID); |
| | | |
| | | do { |
| | | // 构建请求体 |
| | | Map<String, Object> requestBody = new HashMap<>(); |
| | | requestBody.put("orgId", ORG_ID); |
| | | requestBody.put("searchText", ""); |
| | | requestBody.put("size", PAGE_SIZE); |
| | | requestBody.put("current", current); |
| | | |
| | | String responseStr; |
| | | try { |
| | | Map<String, String> headers = buildRequestHeaders(); |
| | | responseStr = HttpUtils.sendPostByHeader(sltdPubPath + "/hbos-thirdparty-integration/standard/base/dtc/pageDiagnosisDict", new Gson().toJson(requestBody), headers); |
| | | |
| | | } catch (Exception e) { |
| | | log.error("[第{}页] 请求来未来接口失败", current, e); |
| | | break; |
| | | } |
| | | |
| | | if (responseStr == null || responseStr.isEmpty()) { |
| | | log.warn("[第{}页] 接口返回空,停止采集", current); |
| | | break; |
| | | } |
| | | |
| | | JSONObject resp = JSON.parseObject(responseStr); |
| | | if (resp == null || !Boolean.TRUE.equals(resp.getBoolean("success"))) { |
| | | log.error("[第{}页] 接口返回失败:{}", current, responseStr); |
| | | break; |
| | | } |
| | | |
| | | JSONObject data = resp.getJSONObject("data"); |
| | | if (data == null) { |
| | | break; |
| | | } |
| | | |
| | | // 计算总页数 |
| | | long total = data.getLongValue("total"); |
| | | long pageSize = data.getLongValue("size"); |
| | | if (pageSize <= 0) { |
| | | break; |
| | | } |
| | | totalPages = (total + pageSize - 1) / pageSize; |
| | | |
| | | JSONArray records = data.getJSONArray("records"); |
| | | if (records == null || records.isEmpty()) { |
| | | break; |
| | | } |
| | | |
| | | log.info("[第{}/{}页] 获取 {} 条记录,总{}条", current, totalPages, records.size(), total); |
| | | |
| | | // 解析当前页数据 |
| | | List<String> pageNames = new ArrayList<>(); |
| | | List<Icd10> pageList = new ArrayList<>(); |
| | | for (int i = 0; i < records.size(); i++) { |
| | | JSONObject rec = records.getJSONObject(i); |
| | | String icdCode = rec.getString("icdCode"); |
| | | if (icdCode == null || icdCode.isEmpty()) { |
| | | continue; |
| | | } |
| | | String icdName = StringUtils.isEmpty(rec.getString("name")) ? null : rec.getString("name").trim(); |
| | | if (icdName == null || icdName.isEmpty()) { |
| | | continue; |
| | | } |
| | | pageNames.add(icdName); |
| | | |
| | | Icd10 icd10 = new Icd10(); |
| | | icd10.setIcdcode(icdCode); |
| | | icd10.setIcdname(icdName); |
| | | icd10.setIcdpym(rec.getString("pinyin")); |
| | | icd10.setHisIcdid(rec.getString("his_icdid")); |
| | | icd10.setOrgid(String.valueOf(ORG_ID)); |
| | | icd10.setDelFlag("0"); |
| | | icd10.setCreateTime(DateUtils.getNowDate()); |
| | | pageList.add(icd10); |
| | | } |
| | | |
| | | if (pageNames.isEmpty()) { |
| | | current++; |
| | | continue; |
| | | } |
| | | |
| | | // 一次 IN 查库,获取已存在的 icdname(核心去重优化点)南华附一的icdname不会重复,icd10code会重复 |
| | | Set<String> existingNames = new HashSet<>(icd10Mapper.selectExistingIcdcodes(pageNames)); |
| | | |
| | | // 过滤出不存在的记录 |
| | | List<Icd10> newList = pageList.stream().filter(item -> !existingNames.contains(item.getIcdname())).collect(Collectors.toList()); |
| | | |
| | | log.info("[第{}/{}页] 当前页共 {} 条,已存在 {} 条,需新入库 {} 条", current, totalPages, pageList.size(), existingNames.size(), newList.size()); |
| | | |
| | | // 分批批量插入 |
| | | int inserted = batchInsert(newList); |
| | | totalInserted += inserted; |
| | | |
| | | current++; |
| | | } while (current <= totalPages); |
| | | |
| | | log.info("[完成] ICD10 增量采集结束,本次共新增 {} 条", totalInserted); |
| | | return totalInserted; |
| | | } |
| | | |
| | | /** |
| | | * 分批批量插入,每批最大 BATCH_SIZE 条 |
| | | */ |
| | | private int batchInsert(List<Icd10> list) { |
| | | if (list == null || list.isEmpty()) { |
| | | return 0; |
| | | } |
| | | int total = 0; |
| | | int size = list.size(); |
| | | for (int start = 0; start < size; start += BATCH_SIZE) { |
| | | int end = Math.min(start + BATCH_SIZE, size); |
| | | total += icd10Mapper.batchIcd10(list.subList(start, end)); |
| | | } |
| | | return total; |
| | | } |
| | | |
| | | private Map<String, String> buildRequestHeaders() { |
| | | Map<String, String> headers = new HashMap<>(); |
| | | headers.put("Content-Type", "application/json"); |
| | | headers.put("app-key", APP_KEY); |
| | | return headers; |
| | | } |
| | | } |