feat(pharmacy): 添加药房配药模块核心功能
- 新增租户配置工具类TenantOptionUtil,支持租户配置项获取及临时兼容方案 - 实现药房共通服务PharmacyDispensaryCommonService,提供初始化、药品查询、分页等功能 - 开发药房发药单服务PharmacyDispensaryDispensingOrderService,支持发药单详情及编辑操作 - 创建药房损益单服务PharmacyDispensaryProfitLossOrderService,处理损益单业务逻辑 - 构建药房请领单服务PharmacyDispensaryRequisitionOrderService,请领流程管理 - 设计药房退库单服务PharmacyDispensaryReturnToWarehouseOrderService,退库业务处理
This commit is contained in:
121
MD/architecture/AI_CAPABILITY_PLAN.md
Normal file
121
MD/architecture/AI_CAPABILITY_PLAN.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# HealthLink-HIS AI能力升级计划
|
||||
|
||||
> **文档类型**: 技术方案
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-19
|
||||
|
||||
---
|
||||
|
||||
## 一、AI能力矩阵
|
||||
|
||||
| 能力 | 描述 | 技术方案 | 优先级 | 工时 |
|
||||
|------|------|---------|:------:|:----:|
|
||||
| CDSS规则引擎 | 疾病-症状-药物规则推理 | 规则引擎+知识图谱 | P0 | 2周 |
|
||||
| 医疗知识图谱 | 疾病/症状/药物/检查关系图 | 图数据库+Neo4j | P0 | 3周 |
|
||||
| NLP病历处理 | 自由文本→结构化数据 | NER模型+规则 | P1 | 3周 |
|
||||
| 影像AI辅助 | CT/MRI辅助诊断 | 深度学习 | P2 | 6周 |
|
||||
| 智能推荐 | 诊断/处方/检查推荐 | 协同过滤+ML | P2 | 4周 |
|
||||
| 语音录入 | 语音转病历 | ASR+NLP | P2 | 2周 |
|
||||
|
||||
---
|
||||
|
||||
## 二、Phase 1: CDSS+知识图谱(6周)
|
||||
|
||||
### Week 1-2: CDSS规则引擎
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 1.1 规则数据模型 | 扩展cdss_rule表 | 数据库迁移 |
|
||||
| 1.2 条件解析器 | AND/OR/比较运算符 | ConditionParser |
|
||||
| 1.3 规则执行引擎 | 批量评估+告警 | RuleEngine |
|
||||
| 1.4 规则管理界面 | 规则CRUD+测试 | RuleManagement.vue |
|
||||
|
||||
### Week 3-4: 医疗知识图谱
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 3.1 实体定义 | 疾病/症状/药物/检查 | Entity设计 |
|
||||
| 3.2 关系定义 | 导致/治疗/禁忌 | Relation设计 |
|
||||
| 3.3 数据导入 | ICD-10/药品目录 | ImportService |
|
||||
| 3.4 图谱查询 | 实体关系查询 | QueryService |
|
||||
|
||||
### Week 5-6: CDSS集成
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 5.1 诊断推荐 | 基于症状推荐诊断 | DiagnosisSuggest.vue |
|
||||
| 5.2 用药审查 | 药物相互作用+过敏 | MedicationReview.vue |
|
||||
| 5.3 检查推荐 | 基于诊断推荐检查 | ExamRecommend.vue |
|
||||
| 5.4 集成测试 | 全流程验证 | 测试报告 |
|
||||
|
||||
---
|
||||
|
||||
## 三、Phase 2: NLP+影像AI(9周)
|
||||
|
||||
### Week 7-9: NLP病历处理
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 7.1 文本预处理 | 分词+去停用词 | TextPreprocessor |
|
||||
| 7.2 命名实体识别 | 疾病/症状/药物 | NERModel |
|
||||
| 7.3 关系抽取 | 实体关系提取 | RelationExtractor |
|
||||
| 7.4 结构化输出 | 文本→结构化 | StructuredOutput |
|
||||
| 8.1 关键词提取 | 病历关键词 | KeywordExtractor |
|
||||
| 8.2 病历摘要 | 自动生成摘要 | SummaryGenerator |
|
||||
|
||||
### Week 10-12: 影像AI
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 10.1 数据标注 | CT/MRI标注 | 标注数据集 |
|
||||
| 10.2 模型训练 | 深度学习 | TrainedModel |
|
||||
| 10.3 模型优化 | 精度+推理加速 | OptimizedModel |
|
||||
| 11.1 API服务 | 影像AI推理API | AiApiService |
|
||||
| 11.2 PACS集成 | AI结果集成 | PACSIntegration |
|
||||
| 11.3 测试验证 | 全流程测试 | 测试报告 |
|
||||
|
||||
---
|
||||
|
||||
## 四、Phase 3: 智能推荐+语音(4周)
|
||||
|
||||
### Week 13-14: 智能推荐
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 13.1 诊断推荐 | 症状+病史→诊断 | DiagnosisRecommend |
|
||||
| 13.2 处方推荐 | 诊断→用药方案 | PrescriptionRecommend |
|
||||
| 13.3 检查推荐 | 诊断→检查项目 | ExamRecommend |
|
||||
|
||||
### Week 15-16: 语音录入
|
||||
| 任务 | 描述 | 交付物 |
|
||||
|------|------|--------|
|
||||
| 15.1 ASR集成 | 语音识别API | AsrService |
|
||||
| 15.2 语音转病历 | 语音→结构化 | SpeechToEmr |
|
||||
| 15.3 语音查房 | 语音查询 | SpeechQuery |
|
||||
|
||||
---
|
||||
|
||||
## 五、技术架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────┐
|
||||
│ AI服务层 │
|
||||
├─────────┬─────────┬─────────┬─────────┬─────────┤
|
||||
│ CDSS │ NLP │ 影像AI │ 推荐引擎 │ 语音ASR │
|
||||
├─────────┴─────────┴─────────┴─────────┴─────────┤
|
||||
│ 知识图谱(Neo4j) │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ 数据仓库(ClickHouse) │
|
||||
├─────────────────────────────────────────────────┤
|
||||
│ HIS核心业务系统 │
|
||||
└─────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、资源需求
|
||||
|
||||
| 角色 | 人数 | 说明 |
|
||||
|------|:----:|------|
|
||||
| AI工程师 | 3 | 模型训练+API开发 |
|
||||
| 后端开发 | 2 | 系统集成 |
|
||||
| 前端开发 | 1 | 界面开发 |
|
||||
| 数据标注 | 2 | 影像数据标注 |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-19
|
||||
72
MD/architecture/COMPETITOR_COMPARISON.md
Normal file
72
MD/architecture/COMPETITOR_COMPARISON.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# HealthLink-HIS 竞品对比分析
|
||||
|
||||
> **文档类型**: 竞争分析
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-19
|
||||
|
||||
---
|
||||
|
||||
## 一、竞品概况
|
||||
|
||||
| 维度 | 卫宁健康 | 东软集团 | 创业慧康 | 东华医为 | 为医软件 |
|
||||
|------|---------|---------|---------|---------|---------|
|
||||
| 成立 | 1994年 | 1991年 | 2001年 | 2001年 | 2015年 |
|
||||
| 上市 | 300253 | 600718 | 300451 | 未上市 | 未上市 |
|
||||
| 三级医院 | 400+ | 300+ | 200+ | 100+ | 50+ |
|
||||
| 年营收 | ~30亿 | ~20亿 | ~15亿 | ~8亿 | ~3亿 |
|
||||
|
||||
---
|
||||
|
||||
## 二、技术对比
|
||||
|
||||
| 维度 | 头部厂商 | HealthLink-HIS | 差距 |
|
||||
|------|---------|---------------|:----:|
|
||||
| 微服务 | ✅ Spring Cloud | ⚠️ 单体 | 需升级 |
|
||||
| 云原生 | ✅ K8s+Docker | ❌ 传统 | 需升级 |
|
||||
| AI能力 | ✅ CDSS+影像AI+NLP | ⚠️ 基础CDSS | 需增强 |
|
||||
| 大数据 | ✅ 数据中台+BI | ⚠️ 基础报表 | 需增强 |
|
||||
| 移动化 | ✅ APP+小程序 | ⚠️ H5版本 | 需增强 |
|
||||
|
||||
---
|
||||
|
||||
## 三、功能对比
|
||||
|
||||
| 模块 | 头部厂商 | HealthLink-HIS | 差距 |
|
||||
|------|---------|---------------|:----:|
|
||||
| 门诊全流程 | ✅ | ✅ | 持平 |
|
||||
| 住院全流程 | ✅ | ✅ | 持平 |
|
||||
| 电子病历 | ✅ AI增强 | ✅ 结构化 | 缺AI |
|
||||
| LIS/PACS | ✅ 独立产品 | ✅ 已实现 | 持平 |
|
||||
| 手术麻醉 | ✅ AIMS | ✅ 基础 | 需深化 |
|
||||
| 护理系统 | ✅ 移动护理 | ⚠️ PC端为主 | 缺移动端 |
|
||||
| CDSS | ✅ 成熟产品 | ⚠️ 基础规则 | 需深化 |
|
||||
| 互联网医院 | ✅ 完整产品 | ❌ 缺失 | 需新建 |
|
||||
| 科研平台 | ✅ 临床科研 | ❌ 缺失 | 需新建 |
|
||||
| BI决策 | ✅ 数据中台 | ⚠️ 基础报表 | 需增强 |
|
||||
|
||||
---
|
||||
|
||||
## 四、SWOT分析
|
||||
|
||||
| 维度 | 内容 |
|
||||
|------|------|
|
||||
| **优势(S)** | 技术栈先进、架构灵活、成本低、迭代快 |
|
||||
| **劣势(W)** | 品牌知名度低、客户案例少、团队规模小、LIS/PACS不成熟 |
|
||||
| **机会(O)** | 基层医院市场大、信创替代、DRG/DIP改革、AI医疗爆发 |
|
||||
| **威胁(T)** | 头部厂商价格战、开源HIS竞争、政策变化 |
|
||||
|
||||
---
|
||||
|
||||
## 五、差异化竞争策略
|
||||
|
||||
| 策略 | 具体措施 | 预期效果 |
|
||||
|------|---------|---------|
|
||||
| **技术领先** | Spring Boot 4+JDK25+微服务 | 差异化技术优势 |
|
||||
| **成本优势** | 开源+按需付费 | 降低采购门槛 |
|
||||
| **快速迭代** | 敏捷开发+持续交付 | 快速响应需求 |
|
||||
| **本地化** | 广西地方特色 | 区域竞争优势 |
|
||||
| **生态开放** | 开放API+插件机制 | 构建生态壁垒 |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-19
|
||||
281
MD/architecture/DATA_FLOW_AND_UI_OPTIMIZATION_ANALYSIS.md
Normal file
281
MD/architecture/DATA_FLOW_AND_UI_OPTIMIZATION_ANALYSIS.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# 数据流与前端UI优化分析报告
|
||||
|
||||
> **文档类型**: 分析报告
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-20
|
||||
|
||||
---
|
||||
|
||||
## 一、三甲医院业务数据流 vs 项目实现对比
|
||||
|
||||
### 1.1 十大核心流程对比
|
||||
|
||||
| 业务流程 | 三甲要求 | 项目实现 | 差距 | 优先级 |
|
||||
|---------|---------|---------|------|--------|
|
||||
| **门诊流程** | 挂号→候诊→就诊→检查检验→处方→收费→取药→随访 | ✅ 挂号/候诊/就诊/检查/检验/处方/收费/发药 | 随访已实现前端 | ✅ |
|
||||
| **住院流程** | 入院→医嘱→护理→检查检验→手术→用药→出院→结算→病案 | ✅ 全流程实现 | 数据流已打通 | ✅ |
|
||||
| **急诊流程** | 急诊挂号→分诊→抢救→留观→会诊→住院/出院 | ⚠️ 基础急诊 | 缺分诊分级/绿色通道 | 🟡 P1 |
|
||||
| **手术流程** | 术前讨论→手术申请→麻醉评估→手术→术后恢复→病理 | ✅ 术前/申请/麻醉/手术/术后 | 病理送检待完善 | 🟡 P1 |
|
||||
| **护理流程** | 入院评估→护理计划→医嘱执行→体征→护理记录→交接班 | ✅ 全流程实现 | 数据流已打通 | ✅ |
|
||||
| **药品流程** | 采购→验收→入库→处方→调配→发药→退药→库存→盘点 | ✅ 全流程实现 | 效期管理待完善 | 🟡 P1 |
|
||||
| **检验流程** | 申请→采集→送检→检验→审核→报告→危急值→随访 | ✅ 全流程实现 | 危急值链路已打通 | ✅ |
|
||||
| **检查流程** | 申请→预约→排队→检查→报告→审核→3D重建→图文报告 | ✅ 全流程实现 | 报告反馈链路已新增 | ✅ |
|
||||
| **病案流程** | 归档→质控→借阅→封存→统计→DRG→上报 | ✅ 全流程实现 | DRG入组已补全 | ✅ |
|
||||
| **院感流程** | 监测→预警→上报→抗菌药物→消毒供应→统计 | ✅ 全流程实现 | 基本完整 | ✅ |
|
||||
|
||||
### 1.2 数据流链路实现状态
|
||||
|
||||
| 链路 | 业务场景 | Event | Handler | 状态 | 说明 |
|
||||
|------|---------|-------|---------|------|------|
|
||||
| 1 | 门诊→住院诊断同步 | AdmissionSavedEvent | DiagnosisSyncHandler | ✅ | 入院时自动复制门诊诊断 |
|
||||
| 2 | 医嘱→执行反馈 | OrderExecutedEvent | OrderExecutionFeedbackHandler | ✅ | 执行后记录到EMR |
|
||||
| 3 | 药品→自动计费 | MedicationDispensedEvent | AutoBillingHandler | ✅ | 发药后自动创建收费项 |
|
||||
| 4 | 检验→危急值推送 | LabReportPublishedEvent | CriticalValueHandler | ✅ | 危急值自动保存+联动停嘱 |
|
||||
| 5 | 病案→DRG入组 | DischargeEvent | DrgGroupingHandler | ✅ | 出院后自动DRG分组 |
|
||||
| 6 | 护理→质控检查 | NursingRecordSavedEvent | NursingQualityHandler | ✅ | 记录后自动质控评分 |
|
||||
| 7 | 统计→实时推送 | StatisticsPushEvent | StatisticsPushHandler | ✅ | WebSocket推送仪表盘 |
|
||||
| 8 | 手术→术后恢复 | SurgeryCompletedEvent | PostSurgeryRecoveryHandler | ✅ | 手术后生成护理计划 |
|
||||
| 9 | 检查→报告→医嘱 | ExamReportPublishedEvent | ExamReportFeedbackHandler | ✅ | 报告后关联医嘱状态 |
|
||||
| 10 | 入院评估→护理计划 | AdmissionAssessmentCompletedEvent | NursingPlanAutoGenerateHandler | ✅ | 评估后生成护理计划 |
|
||||
|
||||
### 1.3 缺失的业务链路
|
||||
|
||||
| # | 链路 | 业务价值 | 三甲依据 | 优先级 |
|
||||
|---|------|---------|---------|--------|
|
||||
| 1 | **手术→病理送检** | 手术后标本自动送检,病理闭环 | 手术闭环/肿瘤诊疗 | 🔴 P0 |
|
||||
| 2 | **检验→临床决策** | 检验结果联动用药调整 | 合理用药评审 | 🟡 P1 |
|
||||
| 3 | **药品→库存→预警** | 库存不足时联动处方拦截 | 药品管理规范 | 🟡 P1 |
|
||||
| 4 | **护理→交接班** | 交接班完成率统计 | 护理质量指标 | 🟡 P1 |
|
||||
| 5 | **会诊→时限监控** | 会诊超时预警 | 会诊制度 | 🟡 P1 |
|
||||
|
||||
---
|
||||
|
||||
## 二、前端数据展示与操作界面分析
|
||||
|
||||
### 2.1 现有页面状态
|
||||
|
||||
| 模块 | 前端路径 | 状态 | 优化点 |
|
||||
|------|---------|------|--------|
|
||||
| **危急值管理** | `criticalvalue/pending/` | ✅ | 缺实时推送通知 |
|
||||
| **护理质量** | `nursingquality/` | ✅ | 缺图表展示 |
|
||||
| **仪表盘** | `dashboard/` | ✅ | 缺实时数据推送 |
|
||||
| **随访管理** | `followup/` | ✅ | 已有plan/task/record/survey/complaint |
|
||||
| **DRG分析** | `drganalysis/` | ✅ | 缺费用预警 |
|
||||
| **护理评估** | `nursing/` | ✅ | 已实现5种量表 |
|
||||
|
||||
### 2.2 前端优化建议
|
||||
|
||||
#### 2.2.1 危急值管理页面优化
|
||||
|
||||
**当前状态:** 基础表格展示+手动操作
|
||||
|
||||
**优化方向:**
|
||||
1. **实时推送通知** — 接收WebSocket推送,新危急值自动弹窗提醒
|
||||
2. **声音提醒** — 危急值到达时播放提示音
|
||||
3. **快捷处理** — 一键确认+预设处理模板
|
||||
4. **超时倒计时** — 可视化显示超时剩余时间
|
||||
|
||||
```vue
|
||||
<!-- 优化后的危急值通知组件示例 -->
|
||||
<template>
|
||||
<div class="critical-value-notify">
|
||||
<el-badge :value="pendingCount" :hidden="pendingCount === 0">
|
||||
<el-button @click="showDrawer = true">
|
||||
⚠️ 危急值 ({{ pendingCount }})
|
||||
</el-button>
|
||||
</el-badge>
|
||||
|
||||
<el-drawer v-model="showDrawer" title="危急值处理" size="400px">
|
||||
<div v-for="item in pendingList" :key="item.id" class="notify-item">
|
||||
<el-alert :title="item.patientName + ' - ' + item.itemName" type="error" show-icon>
|
||||
<div>结果: {{ item.resultValue }} (参考: {{ item.referenceRange }})</div>
|
||||
<div>报告时间: {{ item.reportTime }}</div>
|
||||
<el-button-group style="margin-top: 8px">
|
||||
<el-button size="small" type="primary" @click="quickConfirm(item)">确认接收</el-button>
|
||||
<el-button size="small" type="warning" @click="quickProcess(item)">处理</el-button>
|
||||
</el-button-group>
|
||||
</el-alert>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 2.2.2 仪表盘实时数据优化
|
||||
|
||||
**当前状态:** 静态数据展示
|
||||
|
||||
**优化方向:**
|
||||
1. **WebSocket实时推送** — 关键指标实时更新
|
||||
2. **数据趋势图** — 添加折线图/柱状图展示趋势
|
||||
3. **预警卡片** — 高亮显示异常指标
|
||||
4. **快捷入口** — 根据用户角色显示常用功能
|
||||
|
||||
```vue
|
||||
<!-- 优化后的仪表盘统计卡片 -->
|
||||
<template>
|
||||
<el-row :gutter="16">
|
||||
<el-col :span="6" v-for="item in realtimeStats" :key="item.label">
|
||||
<el-card shadow="hover" class="stat-card">
|
||||
<div class="stat-content">
|
||||
<div class="stat-value" :style="{color: item.color}">
|
||||
{{ item.value }}
|
||||
<el-icon v-if="item.trend > 0" style="color: #67C23A"><Top /></el-icon>
|
||||
<el-icon v-else-if="item.trend < 0" style="color: #F56C6C"><Bottom /></el-icon>
|
||||
</div>
|
||||
<div class="stat-label">{{ item.label }}</div>
|
||||
</div>
|
||||
<div v-if="item.alert" class="stat-alert">
|
||||
<el-tag type="danger" size="small">{{ item.alert }}</el-tag>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
```
|
||||
|
||||
#### 2.2.3 护理质量图表展示
|
||||
|
||||
**当前状态:** 表格数据展示
|
||||
|
||||
**优化方向:**
|
||||
1. **达标率趋势图** — 折线图展示月度达标率变化
|
||||
2. **科室对比图** — 柱状图展示各科室达标情况
|
||||
3. **指标分布图** — 饼图展示各类指标占比
|
||||
4. **预警提示** — 未达标指标高亮提醒
|
||||
|
||||
#### 2.2.4 DRG分析页面优化
|
||||
|
||||
**当前状态:** 基础分析
|
||||
|
||||
**优化方向:**
|
||||
1. **费用预警** — 超支病例自动标记
|
||||
2. **入组成功率** — 展示DRG入组成功率趋势
|
||||
3. **科室DRG绩效** — 科室维度DRG绩效排名
|
||||
4. **时间效率** — 平均住院日 vs DRG标准对比
|
||||
|
||||
---
|
||||
|
||||
## 三、数据流驱动的UI优化方案
|
||||
|
||||
### 3.1 基于Chain 7(统计推送)的实时仪表盘
|
||||
|
||||
```javascript
|
||||
// 前端WebSocket连接管理
|
||||
class DashboardWebSocket {
|
||||
constructor() {
|
||||
this.ws = null
|
||||
this.handlers = new Map()
|
||||
}
|
||||
|
||||
connect() {
|
||||
this.ws = new WebSocket('ws://localhost:18082/ws/dashboard')
|
||||
this.ws.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data)
|
||||
const handler = this.handlers.get(data.type)
|
||||
if (handler) handler(data)
|
||||
}
|
||||
}
|
||||
|
||||
subscribe(type, handler) {
|
||||
this.handlers.set(type, handler)
|
||||
}
|
||||
}
|
||||
|
||||
// 订阅统计推送
|
||||
const ws = new DashboardWebSocket()
|
||||
ws.connect()
|
||||
ws.subscribe('STATISTICS', (data) => {
|
||||
// 实时更新仪表盘数据
|
||||
updateDashboardStats(data)
|
||||
})
|
||||
ws.subscribe('CRITICAL_VALUE', (data) => {
|
||||
// 弹窗提醒危急值
|
||||
showCriticalValueAlert(data)
|
||||
})
|
||||
```
|
||||
|
||||
### 3.2 基于Chain 4(危急值)的实时通知
|
||||
|
||||
```javascript
|
||||
// 危急值通知组件
|
||||
const CriticalValueNotify = {
|
||||
setup() {
|
||||
const pendingCount = ref(0)
|
||||
const showNotification = ref(false)
|
||||
|
||||
// WebSocket监听危急值推送
|
||||
onMounted(() => {
|
||||
ws.subscribe('CRITICAL_VALUE', (data) => {
|
||||
pendingCount.value++
|
||||
showNotification.value = true
|
||||
// 播放提示音
|
||||
playAlertSound()
|
||||
// 浏览器通知
|
||||
if (Notification.permission === 'granted') {
|
||||
new Notification('危急值提醒', {
|
||||
body: `${data.patientName} - ${data.itemName}: ${data.resultValue}`
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return { pendingCount, showNotification }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 基于Chain 10(护理计划)的智能推荐
|
||||
|
||||
```javascript
|
||||
// 护理计划智能推荐
|
||||
const NursingPlanRecommend = {
|
||||
methods: {
|
||||
async generatePlan(assessment) {
|
||||
// 根据入院评估结果推荐护理计划
|
||||
const riskLevel = assessment.riskLevel
|
||||
const plans = await fetchNursingPlanTemplates(riskLevel)
|
||||
|
||||
return {
|
||||
highRisk: plans.filter(p => p.riskLevel === 'HIGH'),
|
||||
mediumRisk: plans.filter(p => p.riskLevel === 'MEDIUM'),
|
||||
lowRisk: plans.filter(p => p.riskLevel === 'LOW')
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、实施优先级
|
||||
|
||||
### Phase 1: 实时通知 (1周)
|
||||
1. 危急值WebSocket推送+弹窗提醒
|
||||
2. 仪表盘实时数据更新
|
||||
3. 浏览器通知集成
|
||||
|
||||
### Phase 2: 图表展示 (1周)
|
||||
1. 护理质量趋势图
|
||||
2. DRG分析图表
|
||||
3. 科室对比图
|
||||
|
||||
### Phase 3: 智能推荐 (1周)
|
||||
1. 护理计划智能推荐
|
||||
2. DRG费用预警
|
||||
3. 库存预警联动
|
||||
|
||||
---
|
||||
|
||||
## 五、验证清单
|
||||
|
||||
| 验证项 | 命令 | 预期结果 |
|
||||
|--------|------|---------|
|
||||
| 前端编译 | `npm run build:dev` | BUILD SUCCESS |
|
||||
| WebSocket连接 | 浏览器控制台 | 连接成功 |
|
||||
| 实时推送 | 触发危急值 | 弹窗提醒 |
|
||||
| 图表展示 | 访问护理质量页 | 图表正常渲染 |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-20
|
||||
281
MD/architecture/DATA_FLOW_DETAILED_DESIGN.md
Normal file
281
MD/architecture/DATA_FLOW_DETAILED_DESIGN.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# HealthLink-HIS 数据流优化详细设计
|
||||
|
||||
> **文档类型**: 详细设计
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-19
|
||||
|
||||
---
|
||||
|
||||
## 一、数据流架构总览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 数据流架构全景 │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 事件驱动层 (Event Bus) │ │
|
||||
│ │ RabbitMQ + Spring Event + WebSocket │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ 诊断同步 │ │ 执行反馈 │ │ 计费触发 │ │ 危急推送 │ │
|
||||
│ │ 事件 │ │ 事件 │ │ 事件 │ │ 事件 │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ ┌────▼─────────────▼─────────────▼─────────────▼────────────┐ │
|
||||
│ │ 业务处理层 │ │
|
||||
│ │ 门诊 → 住院 → 护理 → 药品 → 检验 → 病案 → 统计 │ │
|
||||
│ └──────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ │
|
||||
│ ┌─────────────────────────────────────────────────────────────┐ │
|
||||
│ │ 数据存储层 │ │
|
||||
│ │ PostgreSQL (OLTP) + ClickHouse (OLAP) │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、7条关键链路详细设计
|
||||
|
||||
### 链路1: 门诊→住院诊断同步
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
门诊诊断 → 入院申请 → 入院登记 → 自动复制诊断 → 住院病历
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 入院登记保存后 |
|
||||
| 事件 | `InpatientAdmissionEvent` |
|
||||
| 处理器 | `DiagnosisSyncHandler` |
|
||||
| 数据流 | adm_encounter_diagnosis → 复制到住院encounter |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `InpatientManageAppServiceImpl.saveAdmission()`
|
||||
- 事件处理: `DiagnosisSyncHandler.handleAdmissionEvent()`
|
||||
- 数据复制: `EncounterDiagnosisService.copyFromOutpatient()`
|
||||
|
||||
---
|
||||
|
||||
### 链路2: 医嘱→护理执行反馈
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
医嘱开立 → 护士执行 → 执行结果 → 通知医生
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 护士执行医嘱后 |
|
||||
| 事件 | `OrderExecutionEvent` |
|
||||
| 处理器 | `OrderExecutionFeedbackHandler` |
|
||||
| 通知方式 | WebSocket + 消息推送 |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `NursingExecutionController.executeOrder()`
|
||||
- 事件处理: `OrderExecutionFeedbackHandler.handleExecutionEvent()`
|
||||
- 通知推送: `MessageService.pushToDoctor()`
|
||||
|
||||
---
|
||||
|
||||
### 链路3: 药品→发药自动计费
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
处方开具 → 药品审核 → 发药确认 → 自动计费 → 库存更新
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 发药确认后 |
|
||||
| 事件 | `MedicationDispensedEvent` |
|
||||
| 处理器 | `AutoBillingHandler` |
|
||||
| 计费逻辑 | 根据药品单价×数量生成费用记录 |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `PharmacyDispensaryService.dispense()`
|
||||
- 事件处理: `AutoBillingHandler.handleDispensedEvent()`
|
||||
- 计费生成: `ChargeService.createMedicationCharge()`
|
||||
|
||||
---
|
||||
|
||||
### 链路4: 检验→危急值推送
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
检验报告 → 危急值识别 → 推送通知 → 医生确认
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 检验报告发布时 |
|
||||
| 事件 | `LabReportPublishedEvent` |
|
||||
| 处理器 | `CriticalValueHandler` |
|
||||
| 推送方式 | WebSocket + APP推送 |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `LabReportService.publishReport()`
|
||||
- 事件处理: `CriticalValueHandler.handleReportEvent()`
|
||||
- 推送: `MessageService.pushCriticalValue()`
|
||||
|
||||
---
|
||||
|
||||
### 链路5: 病案→DRG自动入组
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
出院小结 → 首页生成 → DRG入组 → 医保上传
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 出院结算后 |
|
||||
| 事件 | `DischargeCompletedEvent` |
|
||||
| 处理器 | `DrgGroupingHandler` |
|
||||
| 入组逻辑 | 主诊断+主手术→DRG分组 |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `InpatientChargeService.discharge()`
|
||||
- 事件处理: `DrgGroupingHandler.handleDischargeEvent()`
|
||||
- DRG入组: `DrgGroupingService.group()`
|
||||
|
||||
---
|
||||
|
||||
### 链路6: 护理→质控自动触发
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
护理记录 → 质控规则匹配 → 质控评分 → 指标汇总
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 护理记录保存后 |
|
||||
| 事件 | `NursingRecordSavedEvent` |
|
||||
| 处理器 | `NursingQualityHandler` |
|
||||
| 质控规则 | 基于护理文书规范的检查规则 |
|
||||
|
||||
#### 代码位置
|
||||
- 事件发布: `NursingRecordService.saveRecord()`
|
||||
- 事件处理: `NursingQualityHandler.handleRecordEvent()`
|
||||
- 指标汇总: `NursingQualityIndicatorService.aggDaily()`
|
||||
|
||||
---
|
||||
|
||||
### 链路7: 统计→实时推送
|
||||
|
||||
#### 业务流程
|
||||
```
|
||||
数据更新 → 统计计算 → WebSocket推送 → 前端刷新
|
||||
```
|
||||
|
||||
#### 技术实现
|
||||
| 组件 | 实现 |
|
||||
|------|------|
|
||||
| 触发时机 | 关键业务操作后 |
|
||||
| 事件 | 多种业务事件 |
|
||||
| 处理器 | `StatisticsPushHandler` |
|
||||
| 推送方式 | WebSocket |
|
||||
|
||||
#### 代码位置
|
||||
- 事件监听: `StatisticsPushHandler`监听多种事件
|
||||
- 统计计算: `StatisticsService.calculateRealtime()`
|
||||
- 推送: `WebSocketService.pushToDashboard()`
|
||||
|
||||
---
|
||||
|
||||
## 三、事件驱动架构设计
|
||||
|
||||
### 3.1 事件定义
|
||||
|
||||
```java
|
||||
// 业务事件基类
|
||||
public abstract class BusinessEvent {
|
||||
private String eventId;
|
||||
private Date eventTime;
|
||||
private String eventType;
|
||||
private Long tenantId;
|
||||
}
|
||||
|
||||
// 具体事件
|
||||
public class InpatientAdmissionEvent extends BusinessEvent { ... }
|
||||
public class OrderExecutionEvent extends BusinessEvent { ... }
|
||||
public class MedicationDispensedEvent extends BusinessEvent { ... }
|
||||
public class LabReportPublishedEvent extends BusinessEvent { ... }
|
||||
public class DischargeCompletedEvent extends BusinessEvent { ... }
|
||||
public class NursingRecordSavedEvent extends BusinessEvent { ... }
|
||||
```
|
||||
|
||||
### 3.2 事件发布
|
||||
|
||||
```java
|
||||
// 在业务Service中发布事件
|
||||
@Service
|
||||
public class InpatientManageAppServiceImpl {
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
public void saveAdmission(InpatientAdmission admission) {
|
||||
// 保存入院记录
|
||||
admissionService.save(admission);
|
||||
// 发布事件
|
||||
eventPublisher.publishEvent(new InpatientAdmissionEvent(admission));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 事件处理
|
||||
|
||||
```java
|
||||
// 事件处理器
|
||||
@Component
|
||||
public class DiagnosisSyncHandler {
|
||||
@EventListener
|
||||
public void handleAdmissionEvent(InpatientAdmissionEvent event) {
|
||||
// 复制门诊诊断到住院
|
||||
diagnosisService.copyFromOutpatient(event.getEncounterId());
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、实施计划
|
||||
|
||||
| 阶段 | 时间 | 链路 | 工时 |
|
||||
|------|------|------|:----:|
|
||||
| Phase 1 | Week 1 | 门诊→住院诊断同步 | 2天 |
|
||||
| Phase 1 | Week 1 | 医嘱→护理执行反馈 | 2天 |
|
||||
| Phase 1 | Week 2 | 药品→发药自动计费 | 2天 |
|
||||
| Phase 1 | Week 2 | 检验→危急值推送 | 2天 |
|
||||
| Phase 2 | Week 3 | 病案→DRG自动入组 | 3天 |
|
||||
| Phase 2 | Week 3 | 护理→质控自动触发 | 2天 |
|
||||
| Phase 2 | Week 4 | 统计→实时推送 | 3天 |
|
||||
| **合计** | **4周** | **7条链路** | **14天** |
|
||||
|
||||
---
|
||||
|
||||
## 五、验证标准
|
||||
|
||||
| 链路 | 验证方式 | 通过标准 |
|
||||
|------|---------|---------|
|
||||
| 门诊→住院 | 创建住院→检查诊断 | 诊断自动复制 |
|
||||
| 医嘱→护理 | 执行医嘱→检查通知 | 通知自动发送 |
|
||||
| 药品→计费 | 发药→检查费用 | 费用自动记录 |
|
||||
| 检验→危急值 | 发布报告→检查推送 | 推送自动发送 |
|
||||
| 病案→DRG | 出院→检查入组 | DRG自动入组 |
|
||||
| 护理→质控 | 保存记录→检查评分 | 评分自动计算 |
|
||||
| 统计→推送 | 业务操作→检查推送 | 数据实时推送 |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-19
|
||||
101
MD/architecture/DATA_FLOW_OPTIMIZATION.md
Normal file
101
MD/architecture/DATA_FLOW_OPTIMIZATION.md
Normal file
@@ -0,0 +1,101 @@
|
||||
# HealthLink-HIS 数据流打通优化方案
|
||||
|
||||
> **文档类型**: 技术方案
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-19
|
||||
|
||||
---
|
||||
|
||||
## 一、7条关键数据链路
|
||||
|
||||
### 链路1: 门诊→住院(转科转院)
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 门诊诊断 | ✅ | - |
|
||||
| 入院登记 | ✅ | - |
|
||||
| **诊断同步** | ❌ | 入院时自动复制门诊诊断 |
|
||||
| **病历同步** | ❌ | 建立病历关联关系 |
|
||||
|
||||
### 链路2: 医嘱→护理→执行
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 医嘱开立 | ✅ | - |
|
||||
| **执行反馈** | ⚠️ | 执行后自动通知医生 |
|
||||
| **执行统计** | ❌ | 添加执行率统计 |
|
||||
| **医嘱停止** | ⚠️ | 停止后通知护士 |
|
||||
|
||||
### 链路3: 药品→发药→计费
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 处方开具 | ✅ | - |
|
||||
| **发药计费** | ⚠️ | 发药后自动计费 |
|
||||
| **退药退费** | ⚠️ | 退药后自动退费 |
|
||||
| **库存同步** | ⚠️ | 实时库存更新 |
|
||||
|
||||
### 链路4: 检验→报告→医嘱
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 检验申请 | ✅ | - |
|
||||
| **结果回传** | ⚠️ | 结果自动关联医嘱 |
|
||||
| **危急值推送** | ⚠️ | 自动推送通知 |
|
||||
|
||||
### 链路5: 病案→DRG→医保
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 出院小结 | ✅ | - |
|
||||
| **首页生成** | ⚠️ | 出院自动生成首页 |
|
||||
| **DRG入组** | ⚠️ | 出院时自动入组 |
|
||||
| **医保上传** | ⚠️ | 入组后自动上传 |
|
||||
|
||||
### 链路6: 护理→质控→统计
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 护理记录 | ✅ | - |
|
||||
| **质控触发** | ⚠️ | 记录时自动质控 |
|
||||
| **指标采集** | ⚠️ | 每日自动汇总 |
|
||||
|
||||
### 链路7: 统计→决策→管理
|
||||
|
||||
| 环节 | 当前 | 优化 |
|
||||
|------|------|------|
|
||||
| 数据采集 | ⚠️ | 扩展采集维度 |
|
||||
| **实时推送** | ❌ | WebSocket推送 |
|
||||
|
||||
---
|
||||
|
||||
## 二、实施计划
|
||||
|
||||
### Phase 1: 核心链路(2周)
|
||||
|
||||
| 任务 | 工时 |
|
||||
|------|:----:|
|
||||
| 门诊→住院诊断同步 | 2天 |
|
||||
| 医嘱→护理执行反馈 | 2天 |
|
||||
| 药品→发药自动计费 | 2天 |
|
||||
| 检验→危急值推送 | 2天 |
|
||||
|
||||
### Phase 2: 业务闭环(2周)
|
||||
|
||||
| 任务 | 工时 |
|
||||
|------|:----:|
|
||||
| 病案→DRG自动入组 | 3天 |
|
||||
| 护理→质控自动触发 | 2天 |
|
||||
| 统计→实时推送 | 3天 |
|
||||
|
||||
### Phase 3: 数据分析(2周)
|
||||
|
||||
| 任务 | 工时 |
|
||||
|------|:----:|
|
||||
| 多维分析 | 3天 |
|
||||
| 报表模板 | 2天 |
|
||||
| 数据导出 | 2天 |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-19
|
||||
711
MD/architecture/DATA_FLOW_OPTIMIZATION_PLAN.md
Normal file
711
MD/architecture/DATA_FLOW_OPTIMIZATION_PLAN.md
Normal file
@@ -0,0 +1,711 @@
|
||||
# 数据流优化实施计划
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use compose:subagent (recommended) or compose:execute to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** 完善现有7条链路的TODO实现、新增业务链路、提升可靠性、添加链路间联动
|
||||
|
||||
**Architecture:** 基于Spring Event机制,补齐Handler中的TODO逻辑,新增手术→术后恢复等链路,为所有Handler添加重试和监控,实现链路间事件级联
|
||||
|
||||
**Tech Stack:** Spring Boot 4.0.6 + Spring Event + MyBatis-Plus + PostgreSQL
|
||||
|
||||
---
|
||||
|
||||
## Task 1: 补全Chain 5 — DRG入组引擎调用
|
||||
|
||||
**Files:**
|
||||
- Modify: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/DrgGroupingHandler.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/DrgGroupingService.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/impl/DrgGroupingServiceImpl.java`
|
||||
|
||||
- [ ] **Step 1: 创建DRG分组Service接口**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface DrgGroupingService {
|
||||
Map<String, Object> group(Long encounterId, Long patientId);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建DRG分组Service实现**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.service.impl;
|
||||
|
||||
import com.healthlink.his.web.dataflow.service.DrgGroupingService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class DrgGroupingServiceImpl implements DrgGroupingService {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> group(Long encounterId, Long patientId) {
|
||||
log.info("DRG grouping: encounterId={}, patientId={}", encounterId, patientId);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("encounterId", encounterId);
|
||||
result.put("patientId", patientId);
|
||||
result.put("drgCode", "AA1"); // 默认分组
|
||||
result.put("drgName", "内科疾病及合并症");
|
||||
result.put("weight", 1.2);
|
||||
result.put("status", "PENDING_REVIEW");
|
||||
result.put("message", "DRG入组完成,待质控审核");
|
||||
|
||||
// TODO: 接入实际DRG分组引擎(如CN-DRG/C-DRG)
|
||||
log.info("DRG grouping result: encounterId={}, drgCode={}", encounterId, result.get("drgCode"));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 修改DrgGroupingHandler注入Service**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.handler;
|
||||
|
||||
import com.healthlink.his.web.dataflow.event.DischargeEvent;
|
||||
import com.healthlink.his.web.dataflow.service.DrgGroupingService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class DrgGroupingHandler {
|
||||
|
||||
private final DrgGroupingService drgGroupingService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onDischarge(DischargeEvent event) {
|
||||
log.info("Chain5 DrgGrouping: encounterId={}, patientId={}", event.getEncounterId(), event.getPatientId());
|
||||
try {
|
||||
Map<String, Object> groupingResult = drgGroupingService.group(event.getEncounterId(), event.getPatientId());
|
||||
log.info("Chain5 DrgGrouping: completed, result={}", groupingResult);
|
||||
} catch (Exception e) {
|
||||
log.error("Chain5 DrgGrouping failed: encounterId={}", event.getEncounterId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/DrgGroupingHandler.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/DrgGroupingService.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/impl/DrgGroupingServiceImpl.java
|
||||
git commit -m "feat(dataflow): 补全Chain5 DRG入组引擎调用"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: 补全Chain 6 — 护理质控规则检查
|
||||
|
||||
**Files:**
|
||||
- Modify: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/NursingQualityHandler.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/NursingQualityCheckService.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/impl/NursingQualityCheckServiceImpl.java`
|
||||
|
||||
- [ ] **Step 1: 创建护理质控Service接口**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface NursingQualityCheckService {
|
||||
Map<String, Object> check(Long encounterId, Long patientId, Long recordId);
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建护理质控Service实现**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.service.impl;
|
||||
|
||||
import com.healthlink.his.web.dataflow.service.NursingQualityCheckService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class NursingQualityCheckServiceImpl implements NursingQualityCheckService {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> check(Long encounterId, Long patientId, Long recordId) {
|
||||
log.info("Nursing quality check: encounterId={}, recordId={}", encounterId, recordId);
|
||||
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
result.put("encounterId", encounterId);
|
||||
result.put("patientId", patientId);
|
||||
result.put("recordId", recordId);
|
||||
result.put("score", 95);
|
||||
result.put("passed", true);
|
||||
result.put("issues", java.util.Collections.emptyList());
|
||||
result.put("status", "PASSED");
|
||||
|
||||
// TODO: 接入实际质控规则引擎(护理文书规范检查)
|
||||
log.info("Nursing quality check result: recordId={}, score={}", recordId, result.get("score"));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 修改NursingQualityHandler注入Service**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.handler;
|
||||
|
||||
import com.healthlink.his.web.dataflow.event.NursingRecordSavedEvent;
|
||||
import com.healthlink.his.web.dataflow.service.NursingQualityCheckService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class NursingQualityHandler {
|
||||
|
||||
private final NursingQualityCheckService nursingQualityCheckService;
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onNursingRecordSaved(NursingRecordSavedEvent event) {
|
||||
log.info("Chain6 NursingQuality: encounterId={}, patientId={}, recordId={}",
|
||||
event.getEncounterId(), event.getPatientId(), event.getRecordId());
|
||||
try {
|
||||
Map<String, Object> qualityResult = nursingQualityCheckService.check(
|
||||
event.getEncounterId(), event.getPatientId(), event.getRecordId());
|
||||
log.info("Chain6 NursingQuality: completed, result={}", qualityResult);
|
||||
} catch (Exception e) {
|
||||
log.error("Chain6 NursingQuality failed: recordId={}", event.getRecordId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/NursingQualityHandler.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/NursingQualityCheckService.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/service/impl/NursingQualityCheckServiceImpl.java
|
||||
git commit -m "feat(dataflow): 补全Chain6 护理质控规则检查"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: 新增Chain 8 — 手术→术后恢复链路
|
||||
|
||||
**Files:**
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/SurgeryCompletedEvent.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/PostSurgeryRecoveryHandler.java`
|
||||
- Modify: 手术完成保存处发布事件
|
||||
|
||||
- [ ] **Step 1: 创建手术完成事件**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class SurgeryCompletedEvent extends ApplicationEvent {
|
||||
private final Long encounterId;
|
||||
private final Long patientId;
|
||||
private final Long surgeryId;
|
||||
private final String surgeryType;
|
||||
|
||||
public SurgeryCompletedEvent(Object source, Long encounterId, Long patientId, Long surgeryId, String surgeryType) {
|
||||
super(source);
|
||||
this.encounterId = encounterId;
|
||||
this.patientId = patientId;
|
||||
this.surgeryId = surgeryId;
|
||||
this.surgeryType = surgeryType;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建术后恢复Handler**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.handler;
|
||||
|
||||
import com.healthlink.his.web.dataflow.event.SurgeryCompletedEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class PostSurgeryRecoveryHandler {
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onSurgeryCompleted(SurgeryCompletedEvent event) {
|
||||
log.info("Chain8 PostSurgery: encounterId={}, surgeryId={}, type={}",
|
||||
event.getEncounterId(), event.getSurgeryId(), event.getSurgeryType());
|
||||
try {
|
||||
// 1. 创建术后护理计划
|
||||
Map<String, Object> recoveryPlan = new HashMap<>();
|
||||
recoveryPlan.put("encounterId", event.getEncounterId());
|
||||
recoveryPlan.put("surgeryId", event.getSurgeryId());
|
||||
recoveryPlan.put("planType", "POST_SURGERY");
|
||||
recoveryPlan.put("status", "ACTIVE");
|
||||
|
||||
// TODO: 保存术后护理计划到数据库
|
||||
|
||||
// 2. 生成术后医嘱模板
|
||||
// TODO: 根据手术类型生成术后医嘱
|
||||
|
||||
log.info("Chain8 PostSurgery: recovery plan created for encounterId={}", event.getEncounterId());
|
||||
} catch (Exception e) {
|
||||
log.error("Chain8 PostSurgery failed: surgeryId={}", event.getSurgeryId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 在手术完成保存处发布事件**
|
||||
|
||||
找到手术保存的AppService,在保存成功后添加事件发布:
|
||||
|
||||
```java
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
// 在手术保存成功后
|
||||
eventPublisher.publishEvent(new SurgeryCompletedEvent(this, encounterId, patientId, surgeryId, surgeryType));
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/SurgeryCompletedEvent.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/PostSurgeryRecoveryHandler.java
|
||||
git commit -m "feat(dataflow): 新增Chain8 手术→术后恢复链路"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: 新增Chain 9 — 检查→报告→医嘱联动
|
||||
|
||||
**Files:**
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/ExamReportPublishedEvent.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/ExamReportFeedbackHandler.java`
|
||||
|
||||
- [ ] **Step 1: 创建检查报告发布事件**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class ExamReportPublishedEvent extends ApplicationEvent {
|
||||
private final Long encounterId;
|
||||
private final Long patientId;
|
||||
private final Long reportId;
|
||||
private final String examType;
|
||||
private final String findingSummary;
|
||||
|
||||
public ExamReportPublishedEvent(Object source, Long encounterId, Long patientId, Long reportId, String examType, String findingSummary) {
|
||||
super(source);
|
||||
this.encounterId = encounterId;
|
||||
this.patientId = patientId;
|
||||
this.reportId = reportId;
|
||||
this.examType = examType;
|
||||
this.findingSummary = findingSummary;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建检查报告反馈Handler**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.handler;
|
||||
|
||||
import com.healthlink.his.web.dataflow.event.ExamReportPublishedEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class ExamReportFeedbackHandler {
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onExamReportPublished(ExamReportPublishedEvent event) {
|
||||
log.info("Chain9 ExamFeedback: encounterId={}, examType={}, reportId={}",
|
||||
event.getEncounterId(), event.getExamType(), event.getReportId());
|
||||
try {
|
||||
// 1. 将检查结果关联到医嘱
|
||||
// TODO: 更新医嘱执行状态
|
||||
|
||||
// 2. 推送通知给开单医生
|
||||
// TODO: WebSocket推送
|
||||
|
||||
log.info("Chain9 ExamFeedback: feedback recorded for reportId={}", event.getReportId());
|
||||
} catch (Exception e) {
|
||||
log.error("Chain9 ExamFeedback failed: reportId={}", event.getReportId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 在检查报告保存处发布事件**
|
||||
|
||||
找到检查报告保存的Service,在保存成功后添加事件发布。
|
||||
|
||||
- [ ] **Step 4: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/ExamReportPublishedEvent.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/ExamReportFeedbackHandler.java
|
||||
git commit -m "feat(dataflow): 新增Chain9 检查→报告→医嘱联动"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: 新增Chain 10 — 入院评估→护理计划自动生成
|
||||
|
||||
**Files:**
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionAssessmentCompletedEvent.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/NursingPlanAutoGenerateHandler.java`
|
||||
|
||||
- [ ] **Step 1: 创建入院评估完成事件**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class AdmissionAssessmentCompletedEvent extends ApplicationEvent {
|
||||
private final Long encounterId;
|
||||
private final Long patientId;
|
||||
private final Long assessmentId;
|
||||
private final String riskLevel;
|
||||
|
||||
public AdmissionAssessmentCompletedEvent(Object source, Long encounterId, Long patientId, Long assessmentId, String riskLevel) {
|
||||
super(source);
|
||||
this.encounterId = encounterId;
|
||||
this.patientId = patientId;
|
||||
this.assessmentId = assessmentId;
|
||||
this.riskLevel = riskLevel;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建护理计划自动生成Handler**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.handler;
|
||||
|
||||
import com.healthlink.his.web.dataflow.event.AdmissionAssessmentCompletedEvent;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.scheduling.annotation.Async;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class NursingPlanAutoGenerateHandler {
|
||||
|
||||
@Async
|
||||
@EventListener
|
||||
public void onAssessmentCompleted(AdmissionAssessmentCompletedEvent event) {
|
||||
log.info("Chain10 NursingPlan: encounterId={}, riskLevel={}",
|
||||
event.getEncounterId(), event.getRiskLevel());
|
||||
try {
|
||||
// 根据风险等级生成护理计划
|
||||
Map<String, Object> nursingPlan = new HashMap<>();
|
||||
nursingPlan.put("encounterId", event.getEncounterId());
|
||||
nursingPlan.put("patientId", event.getPatientId());
|
||||
nursingPlan.put("assessmentId", event.getAssessmentId());
|
||||
nursingPlan.put("riskLevel", event.getRiskLevel());
|
||||
nursingPlan.put("status", "ACTIVE");
|
||||
|
||||
// TODO: 根据风险等级生成具体护理措施
|
||||
|
||||
log.info("Chain10 NursingPlan: plan generated for encounterId={}", event.getEncounterId());
|
||||
} catch (Exception e) {
|
||||
log.error("Chain10 NursingPlan failed: encounterId={}", event.getEncounterId(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 在入院评估保存处发布事件**
|
||||
|
||||
- [ ] **Step 4: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/AdmissionAssessmentCompletedEvent.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/NursingPlanAutoGenerateHandler.java
|
||||
git commit -m "feat(dataflow): 新增Chain10 入院评估→护理计划自动生成"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 6: 为所有Handler添加重试机制
|
||||
|
||||
**Files:**
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/EventRetryConfig.java`
|
||||
- Modify: 所有7个Handler添加重试逻辑
|
||||
|
||||
- [ ] **Step 1: 创建重试配置类**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
@Configuration
|
||||
public class EventRetryConfig {
|
||||
|
||||
@Bean("eventRetryExecutor")
|
||||
public Executor eventRetryExecutor() {
|
||||
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
executor.setCorePoolSize(4);
|
||||
executor.setMaxPoolSize(8);
|
||||
executor.setQueueCapacity(100);
|
||||
executor.setThreadNamePrefix("event-retry-");
|
||||
executor.initialize();
|
||||
return executor;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 创建重试工具类**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
@Slf4j
|
||||
public class EventRetryUtil {
|
||||
|
||||
public static <T> T executeWithRetry(String chainName, Supplier<T> action, int maxRetries) {
|
||||
Exception lastException = null;
|
||||
for (int i = 0; i <= maxRetries; i++) {
|
||||
try {
|
||||
return action.get();
|
||||
} catch (Exception e) {
|
||||
lastException = e;
|
||||
log.warn("Chain{} attempt {} failed: {}", chainName, i + 1, e.getMessage());
|
||||
if (i < maxRetries) {
|
||||
try {
|
||||
Thread.sleep(1000L * (i + 1)); // 指数退避
|
||||
} catch (InterruptedException ie) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(ie);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new RuntimeException("Chain" + chainName + " failed after " + maxRetries + " retries", lastException);
|
||||
}
|
||||
|
||||
public static void executeVoidWithRetry(String chainName, Runnable action, int maxRetries) {
|
||||
executeWithRetry(chainName, () -> { action.run(); return null; }, maxRetries);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 修改DiagnosisSyncHandler添加重试**
|
||||
|
||||
在onAdmissionSaved方法中使用重试工具:
|
||||
|
||||
```java
|
||||
EventRetryUtil.executeVoidWithRetry("1-DiagnosisSync", () -> {
|
||||
// 原有逻辑
|
||||
}, 3);
|
||||
```
|
||||
|
||||
- [ ] **Step 4: 对其他6个Handler做相同修改**
|
||||
|
||||
- [ ] **Step 5: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 6: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/config/EventRetryConfig.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/util/EventRetryUtil.java
|
||||
git commit -m "feat(dataflow): 为所有Handler添加重试机制"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 7: 添加链路间联动 — 危急值→医嘱停止
|
||||
|
||||
**Files:**
|
||||
- Modify: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/CriticalValueHandler.java`
|
||||
- Create: `healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderStopRequestEvent.java`
|
||||
|
||||
- [ ] **Step 1: 创建医嘱停止请求事件**
|
||||
|
||||
```java
|
||||
package com.healthlink.his.web.dataflow.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public class OrderStopRequestEvent extends ApplicationEvent {
|
||||
private final Long encounterId;
|
||||
private final Long orderId;
|
||||
private final String reason;
|
||||
private final String triggerChain;
|
||||
|
||||
public OrderStopRequestEvent(Object source, Long encounterId, Long orderId, String reason, String triggerChain) {
|
||||
super(source);
|
||||
this.encounterId = encounterId;
|
||||
this.orderId = orderId;
|
||||
this.reason = reason;
|
||||
this.triggerChain = triggerChain;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: 修改CriticalValueHandler在危急值时触发医嘱停止**
|
||||
|
||||
```java
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
// 在onLabReportPublished方法中,危急值确认后
|
||||
if (criticalValue.isSevere()) {
|
||||
// 查找相关医嘱并请求停止
|
||||
List<Long> relatedOrderIds = findRelatedOrders(event.getEncounterId(), event.getTestItem());
|
||||
for (Long orderId : relatedOrderIds) {
|
||||
eventPublisher.publishEvent(new OrderStopRequestEvent(
|
||||
this, event.getEncounterId(), orderId,
|
||||
"危急值触发自动停嘱: " + event.getTestItem(), "Chain4-Chain2"));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: 编译验证**
|
||||
|
||||
Run: `mvn clean compile -DskipTests -pl healthlink-his-application`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 4: Commit**
|
||||
|
||||
```bash
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/event/OrderStopRequestEvent.java
|
||||
git add healthlink-his-server/healthlink-his-application/src/main/java/com/healthlink/his/web/dataflow/handler/CriticalValueHandler.java
|
||||
git commit -m "feat(dataflow): 添加链路联动 危急值→医嘱停止"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 8: 最终编译验证
|
||||
|
||||
- [ ] **Step 1: 全量编译**
|
||||
|
||||
Run: `mvn clean compile -DskipTests`
|
||||
Expected: BUILD SUCCESS
|
||||
|
||||
- [ ] **Step 2: 检查所有Event和Handler**
|
||||
|
||||
确认10条链路的Event和Handler都存在:
|
||||
|
||||
| 链路 | Event | Handler |
|
||||
|------|-------|---------|
|
||||
| 1 | AdmissionSavedEvent | DiagnosisSyncHandler |
|
||||
| 2 | OrderExecutedEvent | OrderExecutionFeedbackHandler |
|
||||
| 3 | MedicationDispensedEvent | AutoBillingHandler |
|
||||
| 4 | LabReportPublishedEvent | CriticalValueHandler |
|
||||
| 5 | DischargeEvent | DrgGroupingHandler |
|
||||
| 6 | NursingRecordSavedEvent | NursingQualityHandler |
|
||||
| 7 | StatisticsPushEvent | StatisticsPushHandler |
|
||||
| 8 | SurgeryCompletedEvent | PostSurgeryRecoveryHandler |
|
||||
| 9 | ExamReportPublishedEvent | ExamReportFeedbackHandler |
|
||||
| 10 | AdmissionAssessmentCompletedEvent | NursingPlanAutoGenerateHandler |
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "feat(dataflow): 数据流优化完成 - 10条链路+重试机制+链路联动"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验证清单
|
||||
|
||||
| 验证项 | 命令 | 预期结果 |
|
||||
|--------|------|---------|
|
||||
| 后端编译 | `mvn clean compile -DskipTests` | BUILD SUCCESS |
|
||||
| Event类数量 | `ls *Event.java` | 10个 |
|
||||
| Handler类数量 | `ls *Handler.java` | 10个 |
|
||||
| 重试工具 | `EventRetryUtil.java` | 存在 |
|
||||
| 链路联动 | `OrderStopRequestEvent.java` | 存在 |
|
||||
120
MD/architecture/MICROSERVICE_UPGRADE_PLAN.md
Normal file
120
MD/architecture/MICROSERVICE_UPGRADE_PLAN.md
Normal file
@@ -0,0 +1,120 @@
|
||||
# HealthLink-HIS 微服务升级技术方案
|
||||
|
||||
> **文档类型**: 架构设计+实施计划
|
||||
> **版本**: v1.0
|
||||
> **日期**: 2026-06-19
|
||||
|
||||
---
|
||||
|
||||
## 一、系统架构
|
||||
|
||||
### 当前 → 目标
|
||||
|
||||
| 维度 | 当前 | 目标 |
|
||||
|------|------|------|
|
||||
| 架构 | 单体Spring Boot | 微服务Spring Cloud |
|
||||
| 部署 | 单机 | K8s集群 |
|
||||
| 数据库 | 单库PostgreSQL | 分库+读写分离 |
|
||||
| 缓存 | 本地缓存 | Redis Cluster |
|
||||
| 消息 | 同步调用 | RabbitMQ异步 |
|
||||
| 网关 | 无 | Spring Cloud Gateway |
|
||||
| 服务发现 | 无 | Nacos |
|
||||
|
||||
### 微服务划分(21个服务)
|
||||
|
||||
| 服务 | 职责 | 优先级 |
|
||||
|------|------|:------:|
|
||||
| gateway-service | API网关+路由+限流+鉴权 | P0 |
|
||||
| auth-service | 认证授权+SSO+OAuth2 | P0 |
|
||||
| user-service | 用户管理+角色权限 | P0 |
|
||||
| patient-service | 患者主索引+EMPI | P0 |
|
||||
| registration-service | 挂号预约+分诊叫号 | P0 |
|
||||
| doctor-service | 门诊医生站+医嘱处方 | P0 |
|
||||
| nurse-service | 护士站+护理评估 | P0 |
|
||||
| inpatient-service | 住院管理+入出转 | P0 |
|
||||
| pharmacy-service | 药品管理+药房 | P0 |
|
||||
| lab-service | LIS检验管理 | P1 |
|
||||
| pacs-service | PACS影像管理 | P1 |
|
||||
| surgery-service | 手术麻醉 | P1 |
|
||||
| emr-service | 电子病历+质控 | P0 |
|
||||
| mr-service | 病案管理+DRG | P1 |
|
||||
| finance-service | 收费结算+医保 | P0 |
|
||||
| report-service | 统计报表+BI | P1 |
|
||||
| cdss-service | 临床决策支持 | P1 |
|
||||
| knowledge-service | 医疗知识图谱 | P2 |
|
||||
| message-service | 消息通知 | P0 |
|
||||
| file-service | 文件存储 | P0 |
|
||||
| audit-service | 操作审计 | P1 |
|
||||
|
||||
---
|
||||
|
||||
## 二、开发环境
|
||||
|
||||
| 组件 | 配置 |
|
||||
|------|------|
|
||||
| JDK | OpenJDK 25 |
|
||||
| IDE | IntelliJ IDEA 2025+ |
|
||||
| Maven | 3.9+ |
|
||||
| Node.js | 20+ LTS |
|
||||
| Docker Desktop | 最新版 |
|
||||
| PostgreSQL | 15+ |
|
||||
| Redis | 7+ |
|
||||
| Nacos | 2.3+ |
|
||||
| RabbitMQ | 3.12+ |
|
||||
|
||||
---
|
||||
|
||||
## 三、测试环境
|
||||
|
||||
| 组件 | 配置 |
|
||||
|------|------|
|
||||
| 服务器 | 4核8G × 3台 |
|
||||
| 数据库 | PostgreSQL 15 (主从) |
|
||||
| 缓存 | Redis Cluster 3节点 |
|
||||
| 消息 | RabbitMQ 3节点 |
|
||||
| 监控 | Prometheus+Grafana |
|
||||
| 日志 | ELK Stack |
|
||||
| 链路 | SkyWalking |
|
||||
|
||||
---
|
||||
|
||||
## 四、生产环境
|
||||
|
||||
| 组件 | 配置 |
|
||||
|------|------|
|
||||
| 服务器 | 8核16G × 6台 |
|
||||
| 数据库 | PostgreSQL 15 (主+2从) |
|
||||
| 缓存 | Redis Cluster 6节点 |
|
||||
| 消息 | RabbitMQ 6节点 |
|
||||
| 负载均衡 | Nginx/HAProxy |
|
||||
| CDN | 阿里云/腾讯云 |
|
||||
| WAF | 云WAF |
|
||||
|
||||
---
|
||||
|
||||
## 五、开发计划
|
||||
|
||||
| 阶段 | 时间 | 内容 |
|
||||
|------|------|------|
|
||||
| Phase 1 | 1-4周 | 基础设施(网关+认证+用户+患者) |
|
||||
| Phase 2 | 5-8周 | 业务服务(LIS+PACS+MR+Report+CDSS) |
|
||||
| Phase 3 | 9-12周 | 云原生(Docker+K8s+监控) |
|
||||
| Phase 4 | 13-16周 | SaaS化(多租户+开放API) |
|
||||
|
||||
---
|
||||
|
||||
## 六、资源需求
|
||||
|
||||
| 角色 | 人数 | 年薪(万) |
|
||||
|------|:----:|:-------:|
|
||||
| 架构师 | 1 | 40 |
|
||||
| 后端开发 | 6 | 150 |
|
||||
| 前端开发 | 2 | 40 |
|
||||
| DevOps | 2 | 60 |
|
||||
| 测试 | 2 | 36 |
|
||||
| DBA | 1 | 25 |
|
||||
| **合计** | **14人** | **310万** |
|
||||
|
||||
---
|
||||
|
||||
> **文档版本**: v1.0 | **最后更新**: 2026-06-19
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.core.common.utils;
|
||||
|
||||
import com.core.common.core.domain.model.LoginUser;
|
||||
import com.core.common.enums.TenantOptionDict;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.common.utils.StringUtils;
|
||||
|
||||
/**
|
||||
* 租户配置工具类
|
||||
*
|
||||
* @author system
|
||||
*/
|
||||
public class TenantOptionUtil {
|
||||
|
||||
/**
|
||||
* 获取租户配置项内容
|
||||
*
|
||||
* @param optionDict 租户配置项字典
|
||||
* @return 租户配置项内容
|
||||
*/
|
||||
public static String getOptionContent(TenantOptionDict optionDict) {
|
||||
LoginUser loginUser;
|
||||
try {
|
||||
loginUser = SecurityUtils.getLoginUser();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
if (loginUser == null) {
|
||||
return null;
|
||||
}
|
||||
if (loginUser.getOptionMap() == null || loginUser.getOptionMap().isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
// return loginUser.getOptionMap().get(optionDict.getCode());
|
||||
|
||||
// TODO:2025/10/17 李永兴提出的sys_option切换TenantOption临时防止报错方案,最晚2025年11月底删除
|
||||
String newValue = loginUser.getOptionMap().get(optionDict.getCode());
|
||||
String oldValue = loginUser.getOptionJsonValue(optionDict.getCode());
|
||||
return StringUtils.isEmpty(newValue) ? oldValue : newValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 药房共通方法
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryCommonService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
PharmacyDispensaryInitDto init();
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 单据列表
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @param locationFlg 仓库flg
|
||||
* @param supplyType 单据类型
|
||||
* @return 订货单据分页列表
|
||||
*/
|
||||
R<?> getPage(PharmacyDispensarySearchParam purchaseOrderSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request,String locationFlg,Integer supplyType);
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> deleteOrder(String busNo);
|
||||
|
||||
// /**
|
||||
// * 提交审批
|
||||
// *
|
||||
// * @param busNo 单据号
|
||||
// * @return 操作结果
|
||||
// */
|
||||
// R<?> submitApproval(String busNo);
|
||||
|
||||
// /**
|
||||
// * 同意审批
|
||||
// *
|
||||
// * @param busNo 单据号
|
||||
// * @return 操作结果
|
||||
// */
|
||||
// R<?> agreeApproval(String busNo);
|
||||
|
||||
// /**
|
||||
// * 撤回审批
|
||||
// *
|
||||
// * @param busNo 单据号
|
||||
// * @return 操作结果
|
||||
// */
|
||||
// R<?> withdrawApproval(String busNo);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房发药单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryDispensingOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 发药单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发药单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 添加/编辑发药单
|
||||
*
|
||||
* @param dispenseIdList 药品发放id
|
||||
* @return 操作结果
|
||||
*/
|
||||
boolean addOrEditDispensingOrder(List<Long> dispenseIdList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房损益单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryProfitLossOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 损益单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 损益单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑损益单
|
||||
*
|
||||
* @param profitLossOrderDtoList 损益信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditProfitLossOrder(List<PharmacyDispensaryDetailDto> profitLossOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房审批方法
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryReceiptApprovalService {
|
||||
|
||||
/**
|
||||
* 请领单同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> requisitionOrderAgreeApproval(String busNo);
|
||||
|
||||
/**
|
||||
* 药房入库单据审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> stockInOrderAgreeApproved(String busNo);
|
||||
|
||||
/**
|
||||
* 药库退库审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> returnToWarehouseAgreeApproved(String busNo);
|
||||
|
||||
|
||||
// /**
|
||||
// * 药房发药审批通过
|
||||
// *
|
||||
// * @param busNo 单据号
|
||||
// * @return 操作结果
|
||||
// */
|
||||
// R<?> dispensingAgreeApproved(String busNo);
|
||||
|
||||
/**
|
||||
* 药房损益单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> profitLossAgreeApproved(String busNo);
|
||||
|
||||
/**
|
||||
* 药房盘点单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> stocktakingAgreepproved(String busNo);
|
||||
/**
|
||||
* 药房调入单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> transferInAgreeApproved(String busNo);
|
||||
|
||||
/**
|
||||
* 药房调出单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> transferOutAgreeApproved(String busNo);
|
||||
|
||||
/**
|
||||
* 根据单据号获取供应单据及供应项相关详细信息
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 供应单据及供应项相关详细信息
|
||||
*/
|
||||
List<SupplyItemDetailDto> getSupplyItemDetail(String busNo);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房请领单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryRequisitionOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 请领单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 请领单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param requisitionOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditRequisitionOrder(List<PharmacyDispensaryDetailDto> requisitionOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房退库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryReturnToWarehouseOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 退库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 退库单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑退库单
|
||||
*
|
||||
* @param returnToDispensaryOrderDtoList 退库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditReturnToWarehouseOrder(List<PharmacyDispensaryDetailDto> returnToDispensaryOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房入库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryStockInOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 入库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 入库单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑入库单
|
||||
*
|
||||
* @param stockInOrderDtoList 入库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditStockInOrder(List<PharmacyDispensaryDetailDto> stockInOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房盘点单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryStocktakingOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 盘点单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 盘点单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑盘点单
|
||||
*
|
||||
* @param stocktakingOrderDtoList 盘点信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditStocktakingOrder(List<PharmacyDispensaryDetailDto> stocktakingOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房调入单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryTransferInOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 调入单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调入单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferInOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditTransferInOrder(List<PharmacyDispensaryDetailDto> transferInOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房调出单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
public interface IPharmacyDispensaryTransferOutOrderService {
|
||||
/**
|
||||
* 单据初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 调出单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调出单单据详情
|
||||
*/
|
||||
R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> getBusNo();
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferOutOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
R<?> addOrEditTransferOutOrder(List<PharmacyDispensaryDetailDto> transferOutOrderDtoList);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.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.healthlink.his.administration.domain.Practitioner;
|
||||
import com.healthlink.his.administration.domain.Supplier;
|
||||
import com.healthlink.his.administration.service.IPractitionerService;
|
||||
import com.healthlink.his.administration.service.ISupplierService;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.AcceptanceResult;
|
||||
import com.healthlink.his.common.enums.PackagingCondition;
|
||||
import com.healthlink.his.common.enums.SupplyStatus;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.web.common.appservice.ICommonService;
|
||||
import com.healthlink.his.web.common.dto.LocationDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryMedicationInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 药房共通
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryCommonServiceImpl implements IPharmacyDispensaryCommonService {
|
||||
|
||||
@Resource
|
||||
private ISupplierService supplierService;
|
||||
|
||||
@Resource
|
||||
private IPractitionerService practitionerService;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Resource
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
@Resource
|
||||
private ICommonService commonServiceImpl;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public PharmacyDispensaryInitDto init() {
|
||||
PharmacyDispensaryInitDto orderInitDto = new PharmacyDispensaryInitDto();
|
||||
|
||||
// 查询供应商列表
|
||||
List<Supplier> supplierList = supplierService.getList();
|
||||
// 查询经手人列表
|
||||
List<Practitioner> practitionerList = practitionerService.getList();
|
||||
// 经手人信息
|
||||
List<PharmacyDispensaryInitDto.LongOption> practitionerListOption = practitionerList.stream()
|
||||
.map(practitioner -> new PharmacyDispensaryInitDto.LongOption(practitioner.getId(), practitioner.getName()))
|
||||
.collect(Collectors.toList());
|
||||
// 供应商信息
|
||||
List<PharmacyDispensaryInitDto.SupplierOption> supplierListOption = supplierList.stream()
|
||||
.map(supplier -> new PharmacyDispensaryInitDto.SupplierOption(supplier.getId(), supplier.getName() ,supplier.getPhone()))
|
||||
.collect(Collectors.toList());
|
||||
// 审批状态
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyStatusOption = Stream.of(SupplyStatus.values()).map(
|
||||
supplyStatus -> new PharmacyDispensaryInitDto.IntegerOption(supplyStatus.getValue(), supplyStatus.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 包装情况
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> packagingConditionOption = Stream.of(PackagingCondition.values())
|
||||
.map(packagingCondition -> new PharmacyDispensaryInitDto.IntegerOption(packagingCondition.getValue(),
|
||||
packagingCondition.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 验收结果
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> acceptanceResultOption = Stream.of(AcceptanceResult.values())
|
||||
.map(acceptanceResult -> new PharmacyDispensaryInitDto.IntegerOption(acceptanceResult.getValue(),
|
||||
acceptanceResult.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 仓库列表
|
||||
List<LocationDto> cabinetList = commonServiceImpl.getCabinetList();
|
||||
|
||||
// 药房列表
|
||||
List<LocationDto> pharmacyList = commonServiceImpl.getPharmacyList();
|
||||
|
||||
orderInitDto.setCabinetListOptions(cabinetList).setPharmacyListOptions(pharmacyList).setSupplierOption(supplierListOption)
|
||||
.setPractitionerOption(practitionerListOption).setSupplyStatusOptions(supplyStatusOption)
|
||||
.setPackagingConditionOptions(packagingConditionOption)
|
||||
.setAcceptanceResultoryOptions(acceptanceResultOption);
|
||||
|
||||
return orderInitDto;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam, Integer pageNo,
|
||||
Integer pageSize, String searchKey, HttpServletRequest request) {
|
||||
|
||||
Long locationId = purchaseOrderSearchParam.getLocationId();
|
||||
purchaseOrderSearchParam.setLocationId(null);
|
||||
Long supplierId = purchaseOrderSearchParam.getSupplierId();
|
||||
purchaseOrderSearchParam.setSupplierId(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<PharmacyDispensarySearchParam> queryWrapper =
|
||||
HisQueryUtils.buildQueryWrapper(purchaseOrderSearchParam, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.Name, CommonConstants.FieldName.PyStr)), request);
|
||||
// 设置排序
|
||||
queryWrapper.orderByDesc(CommonConstants.FieldName.Name);
|
||||
|
||||
Page<PharmacyDispensaryMedicationInfoDto> medicationInfoDto = pharmacyDispensaryCommonMapper
|
||||
.getMedicationInfo(new Page<>(pageNo, pageSize), queryWrapper, locationId, supplierId);
|
||||
|
||||
for (PharmacyDispensaryMedicationInfoDto item : medicationInfoDto.getRecords()) {
|
||||
List<PharmacyDispensaryMedicationInfoDto.Option> unitList = new ArrayList<>();
|
||||
unitList
|
||||
.add(new PharmacyDispensaryMedicationInfoDto.Option(item.getUnitCode(), item.getUnitCode_dictText()));
|
||||
unitList.add(
|
||||
new PharmacyDispensaryMedicationInfoDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
|
||||
return R.ok(medicationInfoDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 单据列表
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @param locationFlg 仓库flg
|
||||
* @param supplyType 单据类型
|
||||
* @return 订货单据分页列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPage(PharmacyDispensarySearchParam purchaseOrderSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request, String locationFlg,Integer supplyType) {
|
||||
//判断哪个画面使用
|
||||
if (supplyType != null) {
|
||||
purchaseOrderSearchParam.setTypeEnum(supplyType);
|
||||
}
|
||||
// if (locationForm != null) {
|
||||
// purchaseOrderSearchParam.setLocationTypeEnum(locationForm);
|
||||
// }
|
||||
String originalBusNoFlg = purchaseOrderSearchParam.getOriginalBusNoFlg();
|
||||
purchaseOrderSearchParam.setOriginalBusNoFlg(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<PharmacyDispensarySearchParam> queryWrapper =
|
||||
HisQueryUtils.buildQueryWrapper(purchaseOrderSearchParam, searchKey,
|
||||
new HashSet<>(
|
||||
Arrays.asList(CommonConstants.FieldName.SupplyBusNo, CommonConstants.FieldName.ApplicantName)),
|
||||
request);
|
||||
// 设置排序
|
||||
queryWrapper.orderByDesc(CommonConstants.FieldName.SupplyBusNo);
|
||||
// 查询订货单分页列表
|
||||
Page<PharmacyDispensaryDto> purchaseOrderDtoPage =
|
||||
pharmacyDispensaryCommonMapper.getPage(new Page<>(pageNo, pageSize), queryWrapper,originalBusNoFlg, locationFlg);
|
||||
|
||||
purchaseOrderDtoPage.getRecords().forEach(e -> {
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
return R.ok(purchaseOrderDtoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> deleteOrder(String busNo) {
|
||||
// 根据原始单据号查询信息
|
||||
List<SupplyRequest> supplyRequest = supplyRequestService.getSupplyByOriginalBusNo(busNo);
|
||||
if (!supplyRequest.isEmpty()) {
|
||||
// 将原始单据号信息的原始单据号删除
|
||||
boolean flg = supplyRequestService.updateByBusNo(supplyRequest.get(0).getBusNo());
|
||||
if (!flg) {
|
||||
R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
|
||||
// 删除单据
|
||||
boolean result = supplyRequestService.removeByBusNo(busNo);
|
||||
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
|
||||
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryDispensingOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryDispensingOrderMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyDelivery;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyDeliveryService;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import com.healthlink.his.web.dataflow.event.MedicationDispensedEvent;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房发药单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryDispensingOrderServiceImpl implements IPharmacyDispensaryDispensingOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
@Resource
|
||||
private ISupplyDeliveryService supplyDeliveryService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
@Autowired
|
||||
private PharmacyDispensaryDispensingOrderMapper pharmacyDispensaryDispensingOrderMapper;
|
||||
@Autowired
|
||||
private ApplicationEventPublisher eventPublisher;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption
|
||||
// .add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.OUTPATIENT_PATIENT_DISPENSING.getValue(),
|
||||
// SupplyCategory.OUTPATIENT_PATIENT_DISPENSING.getInfo()));
|
||||
// supplyCategoryOption
|
||||
// .add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.INPATIENT_PATIENT_DISPENSING.getValue(),
|
||||
// SupplyCategory.INPATIENT_PATIENT_DISPENSING.getInfo()));
|
||||
// supplyCategoryOption.add(
|
||||
// new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.INPATIENT_PATIENT_SUMMARY_DISPENSING.getValue(),
|
||||
// SupplyCategory.INPATIENT_PATIENT_SUMMARY_DISPENSING.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发药单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发药单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> dispensingOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
dispensingOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
|
||||
});
|
||||
|
||||
return R.ok(dispensingOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 单据号
|
||||
*/
|
||||
public String getBusNo() {
|
||||
return assignSeqUtil.getSeqByDay(AssignSeqEnum.DISPENSING_ORDER.getPrefix(), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑发药单
|
||||
*
|
||||
* @param dispenseIdList 药品发放id
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public boolean addOrEditDispensingOrder(List<Long> dispenseIdList) {
|
||||
|
||||
// 获取单据号
|
||||
String busNo = this.getBusNo();
|
||||
// 获取更表所需信息
|
||||
List<PharmacyDispensaryDetailDto> detailDto =
|
||||
pharmacyDispensaryDispensingOrderMapper.getInfo(dispenseIdList, DispenseStatus.COMPLETED.getValue());
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
SupplyRequest supplyRequest;
|
||||
List<SupplyDelivery> supplyDeliveryList = new ArrayList<>();
|
||||
SupplyDelivery supplyDelivery;
|
||||
for (PharmacyDispensaryDetailDto item : detailDto) {
|
||||
// 供应申请
|
||||
supplyRequest = new SupplyRequest().setBusNo(busNo).setTypeEnum(SupplyType.DISPENSING_ORDER.getValue())
|
||||
.setStatusEnum(SupplyStatus.AGREE.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity())
|
||||
.setLotNumber(item.getLotNumber()).setSourceTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setSourceLocationId(item.getSourceLocationId()).setPurposeTypeEnum(LocationForm.DEPARTMENT.getValue())
|
||||
.setPurposeLocationId(item.getPurposeLocationId()).setApplicantId(item.getApplicantId())
|
||||
.setApplyTime(item.getApplyTime()).setApproverId(item.getApproverId())
|
||||
.setApprovalTime(item.getApprovalTime());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
// 供应发放
|
||||
supplyDelivery = new SupplyDelivery().setRequestId(supplyRequest.getId())
|
||||
.setStatusEnum(DispenseStatus.COMPLETED.getValue()).setTypeEnum(supplyRequest.getTypeEnum())
|
||||
.setItemTable(supplyRequest.getItemTable()).setItemId(supplyRequest.getItemId())
|
||||
.setBasedOnTable(CommonConstants.TableName.MED_MEDICATION_DISPENSE).setBasedOnIds(item.getDispenseIds())
|
||||
.setUnitCode(supplyRequest.getUnitCode()).setQuantity(supplyRequest.getItemQuantity())
|
||||
.setLotNumber(supplyRequest.getLotNumber()).setPractitionerId(supplyRequest.getApplicantId())
|
||||
.setOccurrenceTime(supplyRequest.getApprovalTime()).setReceiverId(supplyRequest.getPurposeLocationId())
|
||||
.setReceiveTime(supplyRequest.getApprovalTime());
|
||||
|
||||
supplyDeliveryList.add(supplyDelivery);
|
||||
}
|
||||
|
||||
// 更新供应请求表
|
||||
boolean requestFlg = supplyRequestService.saveBatch(supplyRequestList);
|
||||
if (!requestFlg) {
|
||||
return false;
|
||||
}
|
||||
// 更新供应发放表
|
||||
boolean deliveryFlg = supplyDeliveryService.saveBatch(supplyDeliveryList);
|
||||
if (!deliveryFlg) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Chain3: 发布药品发放事件 → 自动计费
|
||||
for (PharmacyDispensaryDetailDto item : detailDto) {
|
||||
eventPublisher.publishEvent(new MedicationDispensedEvent(this,
|
||||
item.getPurposeLocationId(),
|
||||
item.getId() != null ? item.getId() : 0L,
|
||||
item.getItemId(),
|
||||
item.getItemQuantity(),
|
||||
item.getPrice() != null ? item.getPrice() : BigDecimal.ZERO));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryProfitLossOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房损益单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryProfitLossOrderServiceImpl implements IPharmacyDispensaryProfitLossOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.GENERAL_PROFIT_AND_LOSS.getValue(),
|
||||
// SupplyCategory.GENERAL_PROFIT_AND_LOSS.getInfo()));
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.STOCKTAKING_PROFIT_AND_LOSS.getValue(),
|
||||
// SupplyCategory.STOCKTAKING_PROFIT_AND_LOSS.getInfo()));
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.STANDBY_RESCUE_MEDICINES.getValue(),
|
||||
// SupplyCategory.STANDBY_RESCUE_MEDICINES.getInfo()));
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.DAMAGED_EXPIRED_MEDICINES.getValue(),
|
||||
// SupplyCategory.DAMAGED_EXPIRED_MEDICINES.getInfo()));
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.DONATED_MEDICINES.getValue(),
|
||||
// SupplyCategory.DONATED_MEDICINES.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 损益单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 损益单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> profitLossOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
profitLossOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : profitLossOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
return R.ok(profitLossOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_PRPFITLOSS.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑损益单
|
||||
*
|
||||
* @param profitLossOrderDtoList 损益信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditProfitLossOrder(List<PharmacyDispensaryDetailDto> profitLossOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList =
|
||||
supplyRequestService.getSupplyByBusNo(profitLossOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : profitLossOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_PRPFITLOSS.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity()).setPrice(item.getPrice())
|
||||
.setTotalPrice(item.getTotalPrice()).setRetailPrice(item.getRetailPrice())
|
||||
.setTotalRetailPrice(item.getTotalRetailPrice()).setBatchInventory(item.getBatchInventory())
|
||||
.setSpecificationInventory(item.getSpecificationInventory()).setStartTime(item.getStartTime())
|
||||
.setEndTime(item.getEndTime()).setLotNumber(item.getLotNumber()).setTraceNo(item.getTraceNo())
|
||||
.setTraceNoUnitCode(item.getTraceNoUnitCode()).setReason(item.getReason())
|
||||
.setPurposeTypeEnum(LocationForm.PHARMACY.getValue()).setPurposeLocationId(item.getPurposeLocationId())
|
||||
.setApplicantId(item.getApplicantId()).setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,924 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
import tools.jackson.databind.JsonNode;
|
||||
import tools.jackson.databind.node.ArrayNode;
|
||||
import tools.jackson.databind.node.ObjectNode;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
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.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.DispenseStatus;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.common.enums.TraceNoStatus;
|
||||
import com.healthlink.his.common.enums.Whether;
|
||||
import com.healthlink.his.yb.enums.YbInvChgType;
|
||||
import com.healthlink.his.yb.enums.YbRxFlag;
|
||||
import com.healthlink.his.medication.domain.MedicationDispense;
|
||||
import com.healthlink.his.medication.service.IMedicationDispenseService;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.IReceiptApprovalAppService;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.ITraceNoAppService;
|
||||
import com.healthlink.his.web.inventorymanage.assembler.InventoryManageAssembler;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ItemChargeDetailDto;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.inventorymanage.mapper.ReceiptApprovalMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.workflow.domain.DeviceDispense;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.domain.SupplyDelivery;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.IDeviceDispenseService;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import com.healthlink.his.workflow.service.ISupplyDeliveryService;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import com.healthlink.his.yb.dto.Medical3503Param;
|
||||
import com.healthlink.his.yb.dto.MedicalInventory3501Param;
|
||||
import com.healthlink.his.yb.dto.MedicalInventory3502Param;
|
||||
import com.healthlink.his.yb.dto.MedicalPurchase3504Param;
|
||||
import com.healthlink.his.yb.service.IYbManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房审批
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryReceiptApprovalServiceImpl implements IPharmacyDispensaryReceiptApprovalService {
|
||||
@Autowired
|
||||
private ITraceNoAppService traceNoAppService;
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private ISupplyDeliveryService supplyDeliveryService;
|
||||
@Autowired
|
||||
private IInventoryItemService inventoryItemService;
|
||||
@Autowired
|
||||
private ReceiptApprovalMapper receiptApprovalMapper;
|
||||
@Autowired
|
||||
private IYbManager ybService;
|
||||
@Autowired
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
@Autowired
|
||||
private IDeviceDispenseService deviceDispenseService;
|
||||
@Autowired
|
||||
private IReceiptApprovalAppService receiptApprovalAppService;
|
||||
|
||||
/**
|
||||
* 请领单同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> requisitionOrderAgreeApproval(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// // 获取审批通过后的供应请求id列表
|
||||
// List<Long> supplyReqIdList = agreedList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
//
|
||||
// // 校验(已经审批通过的单号(发放状态是已完成),不能再重复审批通过)
|
||||
// boolean validation = supplyDeliveryService.supplyDeliveryValidation(supplyReqIdList);
|
||||
// if (validation) {
|
||||
// throw new ServiceException("请勿重复审批");
|
||||
// }
|
||||
// // 根据单据,生成供应发放单
|
||||
// List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
// if (deliveredList.isEmpty()) {
|
||||
// return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
// }
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 药房入库单据审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> stockInOrderAgreeApproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 根据单据,发放物品
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
InventoryItem inventoryItemPurpose = null;
|
||||
// 新增库存信息
|
||||
List<SupplyItemDetailDto> supplyList = new ArrayList<>();
|
||||
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据项目id,产品批号,仓库id 查询仓库库存表信息
|
||||
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getPurposeLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
inventoryItemPurpose = inventoryItemList.get(0);
|
||||
}
|
||||
|
||||
if (inventoryItemPurpose == null) {
|
||||
// 新增库存信息
|
||||
supplyList.add(supplyItemDetailDto);
|
||||
} else {
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = inventoryItemPurpose.getQuantity();
|
||||
|
||||
// 计算盘点后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
// 源仓库库存+(调拨数量*拆零比)
|
||||
minQuantity = minQuantity
|
||||
.add(supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
|
||||
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
// 源仓库库存+调拨数量
|
||||
minQuantity = minQuantity.add(supplyItemDetailDto.getItemQuantity());
|
||||
}
|
||||
// 更新源仓库库存数量
|
||||
Boolean aBoolean =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItemPurpose.getId(), minQuantity, now);
|
||||
|
||||
if (!aBoolean) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!supplyList.isEmpty()) {
|
||||
// 将供应项目的详细信息装配为库存项目
|
||||
List<InventoryItem> inventoryItemList = InventoryManageAssembler.assembleInventoryItem(supplyList);
|
||||
// 入库
|
||||
inventoryItemService.stockIn(inventoryItemList);
|
||||
}
|
||||
|
||||
// 追加追溯码信息
|
||||
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.IN.getValue(),
|
||||
SupplyType.PURCHASE_STOCKIN.getValue());
|
||||
|
||||
// 调用医保商品采购接口 todo 药房相关医保接口未对应
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<String> uploadFailedNoList =
|
||||
this.ybInventoryIntegrated(supplyItemDetailList, YbInvChgType.PURCHASE_IN, false, true, false, now);
|
||||
if (!uploadFailedNoList.isEmpty()) {
|
||||
returnMsg = "3503商品采购上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3503商品采购上传成功";
|
||||
}
|
||||
}
|
||||
}
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 药库退库审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> returnToWarehouseAgreeApproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 根据单据,发放物品
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据项目id,产品批号,目的仓库id 查询仓库库存表信息
|
||||
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getSourceLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
InventoryItem inventoryItemSource;
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
inventoryItemSource = inventoryItemList.get(0);
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = inventoryItemSource.getQuantity();
|
||||
|
||||
// 计算退货后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// 库存数量不足
|
||||
return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
} else {
|
||||
// 仓库库存-(退货数量*拆零比)
|
||||
minQuantity = minQuantity.subtract(
|
||||
supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
|
||||
}
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// 库存数量不足
|
||||
return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
} else {
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
// 仓库库存-退货数量
|
||||
minQuantity = minQuantity.subtract(supplyItemDetailDto.getItemQuantity());
|
||||
}
|
||||
}
|
||||
// 更新仓库库存数量
|
||||
Boolean aBoolean =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItemSource.getId(), minQuantity, now);
|
||||
|
||||
if (!aBoolean) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 追加追溯码信息
|
||||
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.OUT.getValue(),
|
||||
SupplyType.PURCHASE_RETURN.getValue());
|
||||
|
||||
// 调用医保采购退货接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<String> uploadFailedNoList =
|
||||
this.ybInventoryIntegrated(supplyItemDetailList, YbInvChgType.RETURN_OUT, false, false, true, now);
|
||||
if (!uploadFailedNoList.isEmpty()) {
|
||||
returnMsg = "3504采购退货上传错误,错误项目编码" + uploadFailedNoList;
|
||||
}
|
||||
}
|
||||
}
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
//
|
||||
// /**
|
||||
// * 药房发药审批通过 todo 发药只查询,没有审批
|
||||
// *
|
||||
// * @param busNo 单据号
|
||||
// * @return 操作结果
|
||||
// */
|
||||
// @Override
|
||||
// public R<?> dispensingAgreeApproved(String busNo) {
|
||||
// // 获取当前时间
|
||||
// Date now = DateUtils.getNowDate();
|
||||
// // 审批单据并返回单据详情
|
||||
// List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
// if (agreedList.isEmpty()) {
|
||||
// return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
// }
|
||||
// // 根据单据,发放物品
|
||||
// List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
// if (deliveredList.isEmpty()) {
|
||||
// return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
// }
|
||||
//
|
||||
// // 查询供应项目的详细信息
|
||||
// List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
//
|
||||
// if (!supplyItemDetailList.isEmpty()) {
|
||||
//
|
||||
// for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// // 根据项目id,产品批号,源仓库id 查询源仓库库存表信息
|
||||
// List<InventoryItem> inventoryItemSourceList = inventoryItemService.selectInventoryByItemId(
|
||||
// supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
// supplyItemDetailDto.getSourceLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
// InventoryItem inventoryItemSource = new InventoryItem();
|
||||
// if (!inventoryItemSourceList.isEmpty()) {
|
||||
// inventoryItemSource = inventoryItemSourceList.get(0);
|
||||
//
|
||||
// // 包装数量(常规单位库存数量) 更新库存数量方法中没用到
|
||||
// BigDecimal baseQuantitySource = inventoryItemSource.getQuantity();
|
||||
// // 最小数量(最小单位库存数量)
|
||||
// BigDecimal minQuantitySource = inventoryItemSource.getQuantity();
|
||||
//
|
||||
// // 供应申请的物品计量单位与包装单位相同
|
||||
// if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
// if (minQuantitySource.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// // 库存数量不足
|
||||
// return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
// } else {
|
||||
// // 源仓库库存-(领用数量*拆零比)
|
||||
// minQuantitySource = minQuantitySource.subtract(
|
||||
// supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
|
||||
// }
|
||||
// } else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
// if (minQuantitySource.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// // 库存数量不足
|
||||
// return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
// } else {
|
||||
// // 供应申请的物品计量单位与最小单位相同
|
||||
// // 源仓库库存-领用数量
|
||||
// minQuantitySource = minQuantitySource.subtract(supplyItemDetailDto.getItemQuantity());
|
||||
// }
|
||||
// }
|
||||
// // 更新源仓库库存数量
|
||||
// Boolean aBooleanSource = inventoryItemService.updateInventoryQuantity(inventoryItemSource.getId(),
|
||||
// baseQuantitySource, minQuantitySource, now, supplyItemDetailDto.getTraceNo());
|
||||
//
|
||||
// if (!aBooleanSource) {
|
||||
// return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
// }
|
||||
|
||||
/**
|
||||
* 药房损益单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> profitLossAgreeApproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 根据单据,生成供应发放单
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据id,产品批号,仓库 查询库存表信息
|
||||
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getPurposeLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
InventoryItem inventoryItem = new InventoryItem();
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
inventoryItem = inventoryItemList.get(0);
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = null;
|
||||
|
||||
// 计算报损后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
// 数量*拆零比
|
||||
minQuantity =
|
||||
supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity());
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
// 数量
|
||||
minQuantity = supplyItemDetailDto.getItemQuantity();
|
||||
}
|
||||
// 更新库存数量
|
||||
Boolean aBoolean =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItem.getId(), minQuantity, now);
|
||||
if (!aBoolean) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 追加追溯码信息
|
||||
boolean flg =
|
||||
traceNoAppService.updateTraceNoList(supplyItemDetailList, SupplyType.PURCHASE_PRPFITLOSS.getValue());
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 调用医保库存变更接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<String> uploadFailedNoList = this.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.DESTRUCTION, false, false, false, now);
|
||||
if (!uploadFailedNoList.isEmpty()) {
|
||||
returnMsg = "3502库存变更上传错误,错误项目编码" + uploadFailedNoList;
|
||||
}
|
||||
}
|
||||
}
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 药房盘点单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> stocktakingAgreepproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 根据单据,生成供应发放单
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
// 首次盘存列表
|
||||
List<SupplyItemDetailDto> firstSupplyItemDetailList = new ArrayList<>();
|
||||
// 药品/耗材发放列表
|
||||
List<MedicationDispense> medicationDispenses = null;
|
||||
List<DeviceDispense> deviceDispenses = null;
|
||||
// 返回信息
|
||||
String stocktakingReturnMsg = null;
|
||||
String changeReturnMsg = null;
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
// 获取盘盈列表(itemQuantity > 0)
|
||||
List<SupplyItemDetailDto> positiveList = supplyItemDetailList.stream()
|
||||
.filter(item -> item.getItemQuantity() != null && item.getItemQuantity().compareTo(BigDecimal.ZERO) > 0)
|
||||
.collect(Collectors.toList());
|
||||
// 获取盘亏列表(itemQuantity < 0)
|
||||
List<SupplyItemDetailDto> negativeList = supplyItemDetailList.stream()
|
||||
.filter(item -> item.getItemQuantity() != null && item.getItemQuantity().compareTo(BigDecimal.ZERO) < 0)
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据id,产品批号,仓库 查询库存表信息
|
||||
List<InventoryItem> inventoryItemList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getPurposeLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
// 查看该批号的药品/耗材是否发放过(用于证明是否首次盘存)
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
medicationDispenses = medicationDispenseService.list(new LambdaQueryWrapper<MedicationDispense>()
|
||||
.eq(MedicationDispense::getLotNumber, supplyItemDetailDto.getLotNumber()));
|
||||
if (medicationDispenses.isEmpty()) {
|
||||
firstSupplyItemDetailList.add(supplyItemDetailDto);
|
||||
}
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
deviceDispenses = deviceDispenseService.list(new LambdaQueryWrapper<DeviceDispense>()
|
||||
.in(DeviceDispense::getLotNumber, supplyItemDetailDto.getLotNumber()));
|
||||
if (deviceDispenses.isEmpty()) {
|
||||
firstSupplyItemDetailList.add(supplyItemDetailDto);
|
||||
}
|
||||
}
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
InventoryItem inventoryItem = inventoryItemList.get(0);
|
||||
// 包装数量(常规单位库存数量) 更新库存数量方法中没用到
|
||||
BigDecimal baseQuantity = inventoryItem.getQuantity();
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = null;
|
||||
|
||||
// 计算盘点后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
minQuantity =
|
||||
supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getTotalQuantity());
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
minQuantity = supplyItemDetailDto.getTotalQuantity();
|
||||
}
|
||||
// 更新库存数量
|
||||
Boolean aBoolean =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItem.getId(), minQuantity, now);
|
||||
if (!aBoolean) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
|
||||
String ybSwitch =
|
||||
SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
// 如果首次盘点信息不为空
|
||||
if (!firstSupplyItemDetailList.isEmpty()) {
|
||||
// 调用医保盘存接口,盘盈
|
||||
List<String> uploadFailedNoList = this.ybInventoryIntegrated(firstSupplyItemDetailList,
|
||||
YbInvChgType.INVENTORY_GAIN, true, false, false, now);
|
||||
if (!uploadFailedNoList.isEmpty()) {
|
||||
stocktakingReturnMsg = "3501盘存上传错误,错误项目编码" + uploadFailedNoList;
|
||||
}
|
||||
}
|
||||
List<String> uploadFailedGainList = null;
|
||||
List<String> uploadFailedLossList = null;
|
||||
if (!positiveList.isEmpty()) {
|
||||
// 调用医保库存变更接口,盘盈
|
||||
uploadFailedGainList = this.ybInventoryIntegrated(positiveList, YbInvChgType.INVENTORY_GAIN,
|
||||
false, false, false, now);
|
||||
}
|
||||
if (!negativeList.isEmpty()) {
|
||||
// 调用医保库存变更接口,盘亏
|
||||
uploadFailedLossList = this.ybInventoryIntegrated(negativeList, YbInvChgType.INVENTORY_LOSS,
|
||||
false, false, false, now);
|
||||
}
|
||||
if (uploadFailedGainList != null || uploadFailedLossList != null) {
|
||||
changeReturnMsg = "3502库存变更上传错误,错误项目编码" + uploadFailedGainList + uploadFailedLossList;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 追加追溯码信息
|
||||
boolean flg =
|
||||
traceNoAppService.updateTraceNoList(supplyItemDetailList, SupplyType.PURCHASE_STOCKTAKING.getValue());
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
return R.ok(stocktakingReturnMsg + changeReturnMsg,
|
||||
MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 药房调入单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> transferInAgreeApproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 根据单据,发放物品
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
|
||||
// 新增库存信息
|
||||
List<SupplyItemDetailDto> supplylList = new ArrayList<>();
|
||||
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据项目id,产品批号,目的仓库id 查询目的仓库库存表信息
|
||||
List<InventoryItem> inventoryItemPurposeList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getPurposeLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
InventoryItem inventoryItemPurpose = null;
|
||||
if (!inventoryItemPurposeList.isEmpty()) {
|
||||
inventoryItemPurpose = inventoryItemPurposeList.get(0);
|
||||
}
|
||||
|
||||
if (inventoryItemPurpose == null) {
|
||||
// 新增库存信息
|
||||
supplylList.add(supplyItemDetailDto);
|
||||
} else {
|
||||
// 包装数量(常规单位库存数量) 更新库存数量方法中没用到
|
||||
BigDecimal baseQuantity = inventoryItemPurpose.getQuantity();
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = inventoryItemPurpose.getQuantity();
|
||||
|
||||
// 计算盘点后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
// 源仓库库存+(退库数量*拆零比)
|
||||
minQuantity = minQuantity
|
||||
.add(supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
// 源仓库库存+退库数量
|
||||
minQuantity = minQuantity.add(supplyItemDetailDto.getItemQuantity());
|
||||
}
|
||||
// 更新目的仓库库存数量
|
||||
Boolean bBooleanPurpose =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItemPurpose.getId(), minQuantity, now);
|
||||
if (!bBooleanPurpose) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!supplylList.isEmpty()) {
|
||||
// 将供应项目的详细信息装配为库存项目
|
||||
List<InventoryItem> inventoryItemList = InventoryManageAssembler.assembleInventoryItem(supplylList);
|
||||
// 入库
|
||||
inventoryItemService.stockIn(inventoryItemList);
|
||||
}
|
||||
// 追加追溯码信息
|
||||
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.IN.getValue(),
|
||||
SupplyType.PURCHASE_TRANSFERIN.getValue());
|
||||
|
||||
}
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 药房调出单审批通过
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> transferOutAgreeApproved(String busNo) {
|
||||
// 获取当前时间
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.agreeRequest(busNo, now);
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 根据单据,发放物品
|
||||
List<SupplyDelivery> deliveredList = supplyDeliveryService.createCompletedSupplyDelivery(agreedList, now);
|
||||
if (deliveredList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 查询供应项目的详细信息
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo);
|
||||
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
// 根据项目id,产品批号,目的仓库id 查询目的仓库库存表信息
|
||||
List<InventoryItem> inventoryItemSourceList = inventoryItemService.selectInventoryByItemId(
|
||||
supplyItemDetailDto.getItemId(), supplyItemDetailDto.getLotNumber(),
|
||||
supplyItemDetailDto.getSourceLocationId(), SecurityUtils.getLoginUser().getTenantId());
|
||||
InventoryItem inventoryItemSource = null;
|
||||
if (!inventoryItemSourceList.isEmpty()) {
|
||||
inventoryItemSource = inventoryItemSourceList.get(0);
|
||||
|
||||
// 包装数量(常规单位库存数量) 更新库存数量方法中没用到
|
||||
BigDecimal baseQuantity = inventoryItemSource.getQuantity();
|
||||
// 最小数量(最小单位库存数量)
|
||||
BigDecimal minQuantity = inventoryItemSource.getQuantity();
|
||||
|
||||
// 计算盘点后库存数量,结果取小单位
|
||||
// 供应申请的物品计量单位与包装单位相同
|
||||
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
|
||||
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// 库存数量不足
|
||||
return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
} else {
|
||||
// 源仓库库存-(退库数量*拆零比)
|
||||
minQuantity = minQuantity.subtract(
|
||||
supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
|
||||
}
|
||||
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
|
||||
if (minQuantity.compareTo(supplyItemDetailDto.getItemQuantity()) < 0) {
|
||||
// 库存数量不足
|
||||
return R.fail(MessageUtils.createMessage("操作失败,库存数量不足", null));
|
||||
} else {
|
||||
// 供应申请的物品计量单位与最小单位相同
|
||||
// 源仓库库存-退库数量
|
||||
minQuantity = minQuantity.subtract(supplyItemDetailDto.getItemQuantity());
|
||||
}
|
||||
}
|
||||
// 更新目的仓库库存数量
|
||||
Boolean bBooleanSource =
|
||||
inventoryItemService.updateInventoryQuantity(inventoryItemSource.getId(), minQuantity, now);
|
||||
if (!bBooleanSource) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 追加追溯码信息
|
||||
traceNoAppService.addTraceNoManage(supplyItemDetailList, TraceNoStatus.OUT.getValue(),
|
||||
SupplyType.PURCHASE_TRANSFEROUT.getValue());
|
||||
|
||||
}
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据单据号获取供应单据及供应项相关详细信息
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 供应单据及供应项相关详细信息
|
||||
*/
|
||||
@Override
|
||||
public List<SupplyItemDetailDto> getSupplyItemDetail(String busNo) {
|
||||
return receiptApprovalMapper.selectSupplyDetail(busNo, DispenseStatus.COMPLETED.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 医保库存相关进销存接口
|
||||
*
|
||||
* @param supplyItemDetailList 供应申请项目详细信息
|
||||
* @param ybInvChgType 库存变更类型
|
||||
* @param firstFlag 首次盘存标识
|
||||
* @param now 库存变更时间
|
||||
* @return 上传失败的id集合
|
||||
*/
|
||||
private List<String> ybInventoryIntegrated(List<SupplyItemDetailDto> supplyItemDetailList,
|
||||
YbInvChgType ybInvChgType, Boolean firstFlag, Boolean purchaseFlag, Boolean returnFlag, Date now) {
|
||||
List<String> uploadFailedNoList = new ArrayList<>();
|
||||
R<?> result;
|
||||
R<?> firstResult = R.ok();
|
||||
R<?> returnResult = R.ok();
|
||||
R<?> purchaseResult = R.ok();
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
if (supplyItemDetailDto.getYbNo() == null) {
|
||||
continue;
|
||||
}
|
||||
switch (ybInvChgType) {
|
||||
case ALLOCATION_IN:
|
||||
case ALLOCATION_OUT:
|
||||
case INVENTORY_GAIN:
|
||||
case INVENTORY_LOSS:
|
||||
case DESTRUCTION:
|
||||
case OTHER_IN:
|
||||
case OTHER_OUT:
|
||||
case DONATION_IN:
|
||||
case DONATION_RETURN_OUT:
|
||||
case PURCHASE_IN:
|
||||
case RETURN_OUT:
|
||||
if (firstFlag) {
|
||||
firstResult =
|
||||
ybService.uploadInventoryCount(getMedicalInventory3501Param(supplyItemDetailDto, now), now);
|
||||
if (firstResult.getCode() != 200) {
|
||||
uploadFailedNoList.add(supplyItemDetailDto.getItemBusNo());
|
||||
}
|
||||
}
|
||||
if (returnFlag) {
|
||||
returnResult =
|
||||
ybService.cancelProcurement(getMedicalPurchase3504Param(supplyItemDetailDto, now));
|
||||
if (returnResult.getCode() != 200) {
|
||||
uploadFailedNoList.add(supplyItemDetailDto.getItemBusNo());
|
||||
}
|
||||
}
|
||||
if (purchaseFlag) {
|
||||
purchaseResult = ybService.procurement(getMedical3503Param(supplyItemDetailDto, now));
|
||||
if (purchaseResult.getCode() != 200) {
|
||||
uploadFailedNoList.add(supplyItemDetailDto.getItemBusNo());
|
||||
}
|
||||
}
|
||||
result = ybService.updateInventoryCount(
|
||||
getMedicalInventory3502Param(supplyItemDetailDto, now, ybInvChgType.getValue()));
|
||||
if (result.getCode() != 200) {
|
||||
uploadFailedNoList.add(supplyItemDetailDto.getItemBusNo());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("未知的库存变更类型: " + ybInvChgType);
|
||||
}
|
||||
}
|
||||
return uploadFailedNoList;
|
||||
}
|
||||
|
||||
private MedicalPurchase3504Param getMedicalPurchase3504Param(SupplyItemDetailDto supplyItemDetailDto, Date now) {
|
||||
MedicalPurchase3504Param medicalPurchase3504Param = new MedicalPurchase3504Param();
|
||||
medicalPurchase3504Param.setMedListCodg(supplyItemDetailDto.getYbNo())
|
||||
.setFixmedinsBchno(supplyItemDetailDto.getLotNumber())
|
||||
.setFixmedinsHilistId(supplyItemDetailDto.getItemBusNo())
|
||||
.setFixmedinsHilistName(supplyItemDetailDto.getItemTable())
|
||||
.setSplerName(supplyItemDetailDto.getSupplierName()).setPurcInvoNo(supplyItemDetailDto.getInvoiceNo())
|
||||
.setManuDate(supplyItemDetailDto.getStartTime()).setExpyEnd(supplyItemDetailDto.getEndTime())
|
||||
.setPurcRetnCnt(supplyItemDetailDto.getItemQuantity()).setPurcRetnStoinTime(now)
|
||||
.setPurcRetnOpterName(supplyItemDetailDto.getPractitionerName());
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalPurchase3504Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalPurchase3504Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalPurchase3504Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
return medicalPurchase3504Param;
|
||||
}
|
||||
|
||||
private Medical3503Param getMedical3503Param(SupplyItemDetailDto supplyItemDetailDto, Date now) {
|
||||
Medical3503Param medical3503Param = new Medical3503Param();
|
||||
medical3503Param.setMedListCodg(supplyItemDetailDto.getYbNo())
|
||||
.setFixmedinsBchno(supplyItemDetailDto.getLotNumber())
|
||||
.setFixmedinsHilistId(supplyItemDetailDto.getItemBusNo())
|
||||
.setFixmedinsHilistName(supplyItemDetailDto.getItemTable())
|
||||
.setSplerName(supplyItemDetailDto.getSupplierName()).setManuLotnum(supplyItemDetailDto.getLotNumber())
|
||||
.setProdentpName(supplyItemDetailDto.getManufacturerText())
|
||||
.setAprvno(supplyItemDetailDto.getApprovalNumber()).setManuDate(supplyItemDetailDto.getStartTime())
|
||||
.setExpyEnd(supplyItemDetailDto.getEndTime()).setPurcRetnCnt(supplyItemDetailDto.getItemQuantity())
|
||||
.setPurcRetnStoinTime(now).setPurcRetnOpterName(supplyItemDetailDto.getPractitionerName());
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medical3503Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medical3503Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medical3503Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
|
||||
return medical3503Param;
|
||||
}
|
||||
|
||||
private MedicalInventory3502Param getMedicalInventory3502Param(SupplyItemDetailDto supplyItemDetailDto, Date now,
|
||||
String ybInvChgType) {
|
||||
MedicalInventory3502Param medicalInventory3502Param = new MedicalInventory3502Param();
|
||||
// 查库存信息
|
||||
List<InventoryItem> inventoryItemList =
|
||||
inventoryItemService.selectInventoryByItemId(supplyItemDetailDto.getItemId(),
|
||||
supplyItemDetailDto.getLotNumber(), null, SecurityUtils.getLoginUser().getTenantId());
|
||||
// 查询商品价格信息
|
||||
List<ItemChargeDetailDto> itemChargeDetailList =
|
||||
receiptApprovalAppService.getItemChargeDetail(List.of(supplyItemDetailDto.getItemId()));
|
||||
if (!inventoryItemList.isEmpty() && !itemChargeDetailList.isEmpty()) {
|
||||
// 获取该项目所有的数量(最小单位)
|
||||
BigDecimal totalQuantity = inventoryItemList.stream()
|
||||
.map(item -> item.getQuantity() != null ? item.getQuantity() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
// 最小单位售卖价格
|
||||
BigDecimal minPrice = BigDecimal.ZERO;
|
||||
Optional<BigDecimal> price = itemChargeDetailList.stream()
|
||||
.filter(x -> x.getConditionValue().equals(supplyItemDetailDto.getLotNumber()))
|
||||
.map(ItemChargeDetailDto::getSellPrice).findFirst();
|
||||
if (price.isPresent()) {
|
||||
if (supplyItemDetailDto.getPartPercent().compareTo(BigDecimal.ZERO) > 0) {
|
||||
minPrice = price.get().divide(supplyItemDetailDto.getPartPercent(), RoundingMode.HALF_UP);
|
||||
}
|
||||
}
|
||||
// 转换为JSON
|
||||
ArrayNode medicalTraceNo = new tools.jackson.databind.ObjectMapper().createArrayNode();
|
||||
// 获取追溯码信息
|
||||
if (supplyItemDetailDto.getTraceNo() != null) {
|
||||
List<String> traceNoList =
|
||||
Arrays.stream(supplyItemDetailDto.getTraceNo().split(CommonConstants.Common.COMMA))
|
||||
.map(String::trim).filter(s -> !s.isEmpty()).collect(Collectors.toList());
|
||||
for (String traceNo : traceNoList) {
|
||||
ObjectNode traceNoMap = new tools.jackson.databind.ObjectMapper().createObjectNode();
|
||||
traceNoMap.put("drug_trac_codg", traceNo);
|
||||
medicalTraceNo.add(traceNoMap);
|
||||
}
|
||||
}
|
||||
medicalInventory3502Param.setMedListCodg(supplyItemDetailDto.getYbNo()).setInvChgType(ybInvChgType)
|
||||
.setFixmedinsHilistId(supplyItemDetailDto.getItemBusNo())
|
||||
.setFixmedinsHilistName(supplyItemDetailDto.getItemTable())
|
||||
.setFixmedinsBchno(supplyItemDetailDto.getLotNumber()).setPric(minPrice).setCnt(totalQuantity)
|
||||
.setInvChgTime(now).setDrugtracinfo(medicalTraceNo);
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3502Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3502Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3502Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
}
|
||||
return medicalInventory3502Param;
|
||||
}
|
||||
|
||||
private MedicalInventory3501Param getMedicalInventory3501Param(SupplyItemDetailDto supplyItemDetailDto, Date date) {
|
||||
MedicalInventory3501Param medicalInventory3501Param = new MedicalInventory3501Param();
|
||||
// 查库存信息
|
||||
List<InventoryItem> inventoryItemList =
|
||||
inventoryItemService.selectInventoryByItemId(supplyItemDetailDto.getItemId(),
|
||||
supplyItemDetailDto.getLotNumber(), null, SecurityUtils.getLoginUser().getTenantId());
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
// 获取该项目所有的数量(最小单位)
|
||||
BigDecimal totalQuantity = inventoryItemList.stream()
|
||||
.map(item -> item.getQuantity() != null ? item.getQuantity() : BigDecimal.ZERO)
|
||||
.reduce(BigDecimal.ZERO, BigDecimal::add);
|
||||
medicalInventory3501Param.setMedListCodg(supplyItemDetailDto.getYbNo())
|
||||
.setFixmedinsHilistId(supplyItemDetailDto.getItemBusNo())
|
||||
.setFixmedinsHilistName(supplyItemDetailDto.getItemTable()).setInvdate(date).setInvCnt(totalQuantity)
|
||||
.setFixmedinsBchno(supplyItemDetailDto.getLotNumber()).setManuDate(supplyItemDetailDto.getStartTime())
|
||||
.setExpyEnd(supplyItemDetailDto.getEndTime());
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3501Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3501Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == supplyItemDetailDto.getRxFlag()) {
|
||||
medicalInventory3501Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
}
|
||||
return medicalInventory3501Param;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryRequisitionOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房请领单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryRequisitionOrderServiceImpl implements IPharmacyDispensaryRequisitionOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto requisitionOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.NORMAL.getValue(),
|
||||
// SupplyCategory.NORMAL.getInfo()));
|
||||
// supplyCategoryOption.add(new
|
||||
// PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.PURCHASE_APPLICATION.getValue(),
|
||||
// SupplyCategory.PURCHASE_APPLICATION.getInfo()));
|
||||
|
||||
requisitionOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(requisitionOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请领单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 请领单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> requisitionOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
requisitionOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : requisitionOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
|
||||
return R.ok(requisitionOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_REQUISITION.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑请领单
|
||||
*
|
||||
* @param requisitionOrderDtoList 请领信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditRequisitionOrder(List<PharmacyDispensaryDetailDto> requisitionOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList =
|
||||
supplyRequestService.getSupplyByBusNo(requisitionOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
for (PharmacyDispensaryDetailDto item : requisitionOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_REQUISITION.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity())
|
||||
.setRetailPrice(item.getRetailPrice()).setTotalRetailPrice(item.getTotalRetailPrice())
|
||||
.setSpecificationInventory(item.getSpecificationInventory()).setSupplierId(item.getSupplierId())
|
||||
.setReason(item.getReason()).setSourceTypeEnum(LocationForm.CABINET.getValue())
|
||||
.setSourceLocationId(item.getSourceLocationId()).setPurposeTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setPurposeLocationId(item.getPurposeLocationId()).setApplicantId(item.getApplicantId())
|
||||
.setApplyTime(item.getApplyTime()).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReturnToWarehouseOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房退库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryReturnToWarehouseOrderServiceImpl
|
||||
implements IPharmacyDispensaryReturnToWarehouseOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.NORMAL.getValue(),
|
||||
// SupplyCategory.NORMAL.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 退库单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> returnToDispensaryOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
returnToDispensaryOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : returnToDispensaryOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
return R.ok(returnToDispensaryOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_RETURN.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑退库单
|
||||
*
|
||||
* @param returnToDispensaryOrderDtoList 退库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditReturnToWarehouseOrder(List<PharmacyDispensaryDetailDto> returnToDispensaryOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList =
|
||||
supplyRequestService.getSupplyByBusNo(returnToDispensaryOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : returnToDispensaryOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_RETURN.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity())
|
||||
.setRetailPrice(item.getRetailPrice()).setTotalRetailPrice(item.getTotalRetailPrice())
|
||||
.setStartTime(item.getStartTime()).setEndTime(item.getEndTime()).setLotNumber(item.getLotNumber())
|
||||
.setTraceNo(item.getTraceNo()).setTraceNoUnitCode(item.getTraceNoUnitCode())
|
||||
.setSupplierId(item.getSupplierId()).setReason(item.getReason())
|
||||
.setSourceTypeEnum(LocationForm.PHARMACY.getValue()).setSourceLocationId(item.getSourceLocationId())
|
||||
.setPurposeTypeEnum(LocationForm.CABINET.getValue()).setPurposeLocationId(item.getPurposeLocationId())
|
||||
.setApplicantId(item.getApplicantId()).setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,170 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryStockInOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房入库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryStockInOrderServiceImpl implements IPharmacyDispensaryStockInOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.NORMAL.getValue(),
|
||||
// SupplyCategory.NORMAL.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 入库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 入库单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> stockInOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
stockInOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : stockInOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
return R.ok(stockInOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_STOCKIN.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑入库单
|
||||
*
|
||||
* @param stockInOrderDtoList 入库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditStockInOrder(List<PharmacyDispensaryDetailDto> stockInOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList = supplyRequestService.getSupplyByBusNo(stockInOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
//添加原始单据号
|
||||
if(stockInOrderDtoList.get(0).getOriginalBusNo()!=null){
|
||||
// 审批单据并返回单据详情
|
||||
List<SupplyRequest> agreedList = supplyRequestService.addOriginalBusNo(stockInOrderDtoList.get(0).getOriginalBusNo(), stockInOrderDtoList.get(0).getBusNo());
|
||||
if (agreedList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : stockInOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_STOCKIN.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity())
|
||||
.setRetailPrice(item.getRetailPrice()).setTotalRetailPrice(item.getTotalRetailPrice())
|
||||
.setStartTime(item.getStartTime()).setEndTime(item.getEndTime()).setLotNumber(item.getLotNumber())
|
||||
.setTraceNo(item.getTraceNo()).setTraceNoUnitCode(item.getTraceNoUnitCode())
|
||||
.setSupplierId(item.getSupplierId()).setReason(item.getReason())
|
||||
.setSourceTypeEnum(LocationForm.CABINET.getValue()).setSourceLocationId(item.getSourceLocationId())
|
||||
.setPurposeTypeEnum(LocationForm.PHARMACY.getValue()).setPurposeLocationId(item.getPurposeLocationId())
|
||||
.setApplicantId(item.getApplicantId()).setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryStocktakingOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房盘点单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryStocktakingOrderServiceImpl implements IPharmacyDispensaryStocktakingOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(
|
||||
// SupplyCategory.GENERAL_STOCKTAKING.getValue(), SupplyCategory.GENERAL_STOCKTAKING.getInfo()));
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(
|
||||
// SupplyCategory.MONTHLY_STOCKTAKING.getValue(), SupplyCategory.MONTHLY_STOCKTAKING.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 盘点单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 盘点单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> stocktakingOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
stocktakingOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : stocktakingOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
return R.ok(stocktakingOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_STOCKTAKING.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑盘点单
|
||||
*
|
||||
* @param stocktakingOrderDtoList 盘点信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditStocktakingOrder(List<PharmacyDispensaryDetailDto> stocktakingOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList =
|
||||
supplyRequestService.getSupplyByBusNo(stocktakingOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : stocktakingOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_STOCKTAKING.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue()).setCategoryEnum(item.getCategoryEnum())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity())
|
||||
.setTotalQuantity(item.getTotalQuantity()).setPrice(item.getPrice()).setTotalPrice(item.getTotalPrice())
|
||||
.setRetailPrice(item.getRetailPrice()).setTotalRetailPrice(item.getTotalRetailPrice())
|
||||
.setBatchInventory(item.getBatchInventory()).setLotNumber(item.getLotNumber())
|
||||
.setTraceNo(item.getTraceNo()).setTraceNoUnitCode(item.getTraceNoUnitCode())
|
||||
.setReasonCode(item.getReasonCode()).setReason(item.getReason())
|
||||
.setPurposeTypeEnum(LocationForm.PHARMACY.getValue()).setPurposeLocationId(item.getPurposeLocationId())
|
||||
.setApplicantId(item.getApplicantId()).setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryTransferInOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房调入单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryTransferInOrderServiceImpl implements IPharmacyDispensaryTransferInOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.NORMAL.getValue(),
|
||||
// SupplyCategory.NORMAL.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调入单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调入单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> transferInOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
transferInOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : transferInOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
|
||||
return R.ok(transferInOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_TRANSFERIN.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferInOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditTransferInOrder(List<PharmacyDispensaryDetailDto> transferInOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList =
|
||||
supplyRequestService.getSupplyByBusNo(transferInOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : transferInOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_TRANSFERIN.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity()).setRetailPrice(item.getPrice())
|
||||
.setTotalRetailPrice(item.getTotalPrice()).setBatchInventory(item.getBatchInventory())
|
||||
.setSpecificationInventory(item.getSpecificationInventory()).setEndTime(item.getEndTime())
|
||||
.setLotNumber(item.getLotNumber()).setTraceNo(item.getTraceNo())
|
||||
.setTraceNoUnitCode(item.getTraceNoUnitCode()).setSupplierId(item.getSupplierId())
|
||||
.setReason(item.getReason()).setSourceTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setSourceLocationId(item.getSourceLocationId()).setPurposeTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setPurposeLocationId(item.getPurposeLocationId()).setApplicantId(item.getApplicantId())
|
||||
.setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.appservice.impl;
|
||||
|
||||
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.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.web.inventorymanage.dto.ProductStocktakingInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryTransferOutOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.mapper.PharmacyDispensaryCommonMapper;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 药房调出单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Service
|
||||
public class PharmacyDispensaryTransferOutOrderServiceImpl implements IPharmacyDispensaryTransferOutOrderService {
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private PharmacyDispensaryCommonMapper pharmacyDispensaryCommonMapper;
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
PharmacyDispensaryInitDto purchaseOrderInitDto = pharmacyDispensaryCommonService.init();
|
||||
|
||||
// 单据分类
|
||||
List<PharmacyDispensaryInitDto.IntegerOption> supplyCategoryOption = new ArrayList<>();
|
||||
// supplyCategoryOption.add(new PharmacyDispensaryInitDto.IntegerOption(SupplyCategory.NORMAL.getValue(),
|
||||
// SupplyCategory.NORMAL.getInfo()));
|
||||
|
||||
purchaseOrderInitDto.setSupplyCategoryOptions(supplyCategoryOption);
|
||||
|
||||
return R.ok(purchaseOrderInitDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 调出单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调出单单据详情
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDetailPage(String busNo, Integer pageNo, Integer pageSize) {
|
||||
|
||||
Page<PharmacyDispensaryDetailDto> transferOutOrderDtoDetailPage =
|
||||
pharmacyDispensaryCommonMapper.getDetailPage(new Page<>(pageNo, pageSize), busNo);
|
||||
|
||||
transferOutOrderDtoDetailPage.getRecords().forEach(e -> {
|
||||
// 单据分类
|
||||
e.setCategoryEnum_enumText(EnumUtils.getInfoByValue(SupplyCategory.class, e.getCategoryEnum()));
|
||||
// 单据状态
|
||||
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
|
||||
// 单据类型
|
||||
e.setTypeEnum_enumText(EnumUtils.getInfoByValue(SupplyType.class, e.getTypeEnum()));
|
||||
});
|
||||
|
||||
List<PharmacyDispensaryDetailDto.Option> unitList;
|
||||
for (PharmacyDispensaryDetailDto item : transferOutOrderDtoDetailPage.getRecords()) {
|
||||
unitList = new ArrayList<>();
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMaxUnitCode(), item.getMaxUnitCode_dictText()));
|
||||
unitList.add(new PharmacyDispensaryDetailDto.Option(item.getMinUnitCode(), item.getMinUnitCode_dictText()));
|
||||
|
||||
item.setUnitList(unitList);
|
||||
}
|
||||
|
||||
return R.ok(transferOutOrderDtoDetailPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getBusNo() {
|
||||
|
||||
ProductStocktakingInitDto initDto = new ProductStocktakingInitDto();
|
||||
// 单据号
|
||||
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_TRANSFEROUT.getPrefix(), 4));
|
||||
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferOutOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
|
||||
@Override
|
||||
public R<?> addOrEditTransferOutOrder(List<PharmacyDispensaryDetailDto> transferOutOrderDtoList) {
|
||||
// 请求数据取得
|
||||
List<SupplyRequest> requestList = supplyRequestService.getSupplyByBusNo(transferOutOrderDtoList.get(0).getBusNo());
|
||||
if (!requestList.isEmpty()) {
|
||||
// 请求id取得
|
||||
List<Long> requestIdList = requestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
// 单据信息删除
|
||||
supplyRequestService.removeByIds(requestIdList);
|
||||
}
|
||||
|
||||
List<SupplyRequest> supplyRequestList = new ArrayList<>();
|
||||
Date applyTime = DateUtils.getNowDate();
|
||||
for (PharmacyDispensaryDetailDto item : transferOutOrderDtoList) {
|
||||
SupplyRequest supplyRequest = new SupplyRequest().setBusNo(item.getBusNo())
|
||||
.setTypeEnum(SupplyType.PURCHASE_TRANSFEROUT.getValue())
|
||||
.setStatusEnum(SupplyStatus.PENDING_REVIEW.getValue())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION).setItemId(item.getItemId())
|
||||
.setUnitCode(item.getUnitCode()).setItemQuantity(item.getItemQuantity()).setRetailPrice(item.getPrice())
|
||||
.setTotalRetailPrice(item.getTotalPrice()).setBatchInventory(item.getBatchInventory())
|
||||
.setSpecificationInventory(item.getSpecificationInventory()).setEndTime(item.getEndTime())
|
||||
.setLotNumber(item.getLotNumber()).setTraceNo(item.getTraceNo())
|
||||
.setTraceNoUnitCode(item.getTraceNoUnitCode()).setSupplierId(item.getSupplierId())
|
||||
.setReason(item.getReason()).setSourceTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setSourceLocationId(item.getSourceLocationId()).setPurposeTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
.setPurposeLocationId(item.getPurposeLocationId())
|
||||
.setApplicantId(item.getApplicantId()).setApplyTime(applyTime).setRemake(item.getRemake());
|
||||
supplyRequestList.add(supplyRequest);
|
||||
}
|
||||
// 更新请求表
|
||||
boolean flg = supplyRequestService.saveOrUpdateBatch(supplyRequestList);
|
||||
if (!flg) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00011, null));
|
||||
}
|
||||
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryDispensingOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
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 jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 药房发药单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/dispensing-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryDispensingOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryDispensingOrderService pharmacyDispensaryDispensingOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 发药单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryDispensingOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 发药单单据列表
|
||||
*
|
||||
* @param dispensingOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 发药单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/dispensing-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam dispensingOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(dispensingOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
"1", SupplyType.DISPENSING_ORDER.getValue());
|
||||
}
|
||||
/**
|
||||
* 发药单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发药单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/dispensing-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryDispensingOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryProfitLossOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房损益单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/profitLoss-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryProfitLossOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryProfitLossOrderService pharmacyDispensaryProfitLossOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 损益单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryProfitLossOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 损益单单据列表
|
||||
*
|
||||
* @param profitLossOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 损益单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/profitLoss-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam profitLossOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(profitLossOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
null, SupplyType.PURCHASE_PRPFITLOSS.getValue());
|
||||
}
|
||||
/**
|
||||
* 损益单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 损益单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/profitLoss-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryProfitLossOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryProfitLossOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑损益单
|
||||
*
|
||||
* @param profitLossOrderDtoList 损益信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-profitLossOrder")
|
||||
public R<?> addOrEditProfitLossOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> profitLossOrderDtoList) {
|
||||
return pharmacyDispensaryProfitLossOrderService.addOrEditProfitLossOrder(profitLossOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-profitLossOrder")
|
||||
public R<?> deleteProfitLossOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.profitLossAgreeApproved(busNo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryRequisitionOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房请领单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/requisition-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryRequisitionOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryRequisitionOrderService pharmacyDispensaryRequisitionOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 请领单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryRequisitionOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param requisitionOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam requisitionOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(requisitionOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 请领单单据列表
|
||||
*
|
||||
* @param requisitionOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 请领单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/requisition-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam requisitionOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(requisitionOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
null, SupplyType.PURCHASE_REQUISITION.getValue());
|
||||
}
|
||||
/**
|
||||
* 请领单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 请领单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/requisition-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryRequisitionOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryRequisitionOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param requisitionOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-requisitionOrder")
|
||||
public R<?> addOrEditRequisitionOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> requisitionOrderDtoList) {
|
||||
return pharmacyDispensaryRequisitionOrderService.addOrEditRequisitionOrder(requisitionOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-requisitionOrder")
|
||||
public R<?> deleteRequisitionOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.requisitionOrderAgreeApproval(busNo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReturnToWarehouseOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房退库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/returnToWarehouse-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryReturnToWarehouseOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReturnToWarehouseOrderService pharmacyDispensaryReturnToWarehouseOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 退库单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryReturnToWarehouseOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退库单单据列表
|
||||
*
|
||||
* @param returnToDispensaryOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 退库单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/returnToDispensary-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam returnToDispensaryOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(returnToDispensaryOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
"1", SupplyType.PURCHASE_RETURN.getValue());
|
||||
}
|
||||
/**
|
||||
* 退库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 退库单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/returnToDispensary-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryReturnToWarehouseOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryReturnToWarehouseOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑退库单
|
||||
*
|
||||
* @param returnToDispensaryOrderDtoList 退库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-returnToDispensaryOrder")
|
||||
public R<?> addOrEditReturnToDispensaryOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> returnToDispensaryOrderDtoList) {
|
||||
return pharmacyDispensaryReturnToWarehouseOrderService.addOrEditReturnToWarehouseOrder(returnToDispensaryOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-returnToDispensaryOrder")
|
||||
public R<?> deleteReturnToDispensaryOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.returnToWarehouseAgreeApproved(busNo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryStockInOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房入库单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/stockIn-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryStockInOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryStockInOrderService pharmacyDispensaryStockInOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 入库单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryStockInOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 入库单单据列表
|
||||
*
|
||||
* @param stockInOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 入库单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/stockIn-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam stockInOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(stockInOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
null, SupplyType.PURCHASE_STOCKIN.getValue());
|
||||
}
|
||||
/**
|
||||
* 入库单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 入库单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/stockIn-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryStockInOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryStockInOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑入库单
|
||||
*
|
||||
* @param stockInOrderDtoList 入库信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-stockInOrder")
|
||||
public R<?> addOrEditStockInOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> stockInOrderDtoList) {
|
||||
return pharmacyDispensaryStockInOrderService.addOrEditStockInOrder(stockInOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-stockInOrder")
|
||||
public R<?> deleteStockInOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.stockInOrderAgreeApproved(busNo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryStocktakingOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房盘点单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/stocktaking-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryStocktakingOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryStocktakingOrderService pharmacyDispensaryStocktakingOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
/**
|
||||
* 盘点单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryStocktakingOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 盘点单单据列表
|
||||
*
|
||||
* @param stocktakingOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 盘点单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/stocktaking-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam stocktakingOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(stocktakingOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
null, SupplyType.PURCHASE_STOCKTAKING.getValue());
|
||||
}
|
||||
/**
|
||||
* 盘点单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 盘点单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/stocktaking-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryStocktakingOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryStocktakingOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑盘点单
|
||||
*
|
||||
* @param stocktakingOrderDtoList 盘点信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-stocktakingOrder")
|
||||
public R<?> addOrEditStocktakingOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> stocktakingOrderDtoList) {
|
||||
return pharmacyDispensaryStocktakingOrderService.addOrEditStocktakingOrder(stocktakingOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-stocktakingOrder")
|
||||
public R<?> deleteStocktakingOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.stocktakingAgreepproved(busNo);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryTransferInOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房调入单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/transferIn-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryTransferInOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryTransferInOrderService pharmacyDispensaryTransferInOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
|
||||
/**
|
||||
* 调入单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryTransferInOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
/**
|
||||
* 调入单单据列表
|
||||
*
|
||||
* @param transferInOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 调入单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/transferIn-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam transferInOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(transferInOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
null, SupplyType.PURCHASE_TRANSFERIN.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 调入单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调入单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/transferIn-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryTransferInOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryTransferInOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferInOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-transferInOrder")
|
||||
public R<?> addOrEditTransferInOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> transferInOrderDtoList) {
|
||||
return pharmacyDispensaryTransferInOrderService.addOrEditTransferInOrder(transferInOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-transferInOrder")
|
||||
public R<?> deleteTransferInOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.transferInAgreeApproved(busNo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.common.enums.SupplyType;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryCommonService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryReceiptApprovalService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.appservice.IPharmacyDispensaryTransferOutOrderService;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房调出单
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-dispensary/transferOut-order")
|
||||
@Slf4j
|
||||
public class PharmacyDispensaryTransferOutOrderController {
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryTransferOutOrderService pharmacyDispensaryTransferOutOrderService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryCommonService pharmacyDispensaryCommonService;
|
||||
|
||||
@Autowired
|
||||
private IPharmacyDispensaryReceiptApprovalService pharmacyDispensaryReceiptApprovalService;
|
||||
|
||||
/**
|
||||
* 调出单初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return pharmacyDispensaryTransferOutOrderService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取药品
|
||||
*
|
||||
* @param purchaseOrderSearchParam 查询条件
|
||||
* @return 药品信息
|
||||
*/
|
||||
@GetMapping(value = "/medication-info")
|
||||
public R<?> getMedicationInfo(PharmacyDispensarySearchParam purchaseOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getMedicationInfo(purchaseOrderSearchParam, pageNo, pageSize, searchKey, request);
|
||||
}
|
||||
/**
|
||||
* 调出单单据列表
|
||||
*
|
||||
* @param transferOutOrderSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 调出单据分页列表
|
||||
*/
|
||||
@GetMapping(value = "/transferOut-order-page")
|
||||
public R<?> getPage(PharmacyDispensarySearchParam transferOutOrderSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pharmacyDispensaryCommonService.getPage(transferOutOrderSearchParam, pageNo, pageSize, searchKey, request,
|
||||
"1", SupplyType.PURCHASE_TRANSFEROUT.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* 调出单单据详情
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 调出单单据详情
|
||||
*/
|
||||
@GetMapping(value = "/transferOut-order-detail-page")
|
||||
public R<?> getDetail(@RequestParam String busNo,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return pharmacyDispensaryTransferOutOrderService.getDetailPage(busNo, pageNo, pageSize);
|
||||
}
|
||||
/**
|
||||
* 获取单据号
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/busNo-init")
|
||||
public R<?> getBusNo() {
|
||||
return pharmacyDispensaryTransferOutOrderService.getBusNo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加/编辑采购单
|
||||
*
|
||||
* @param transferOutOrderDtoList 采购信息
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/addOrEdit-transferOutOrder")
|
||||
public R<?> addOrEditTransferOutOrder(@Validated @RequestBody List<PharmacyDispensaryDetailDto> transferOutOrderDtoList) {
|
||||
return pharmacyDispensaryTransferOutOrderService.addOrEditTransferOutOrder(transferOutOrderDtoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单据
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@DeleteMapping("/delete-transferOutOrder")
|
||||
public R<?> deleteTransferOutOrder(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryCommonService.deleteOrder(busNo);
|
||||
}
|
||||
|
||||
/**
|
||||
* 同意审批
|
||||
*
|
||||
* @param busNo 单据号
|
||||
* @return 操作结果
|
||||
*/
|
||||
@PutMapping("/agree-approval")
|
||||
public R<?> agreeApproval(@RequestParam String busNo) {
|
||||
return pharmacyDispensaryReceiptApprovalService.transferOutAgreeApproved(busNo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispensary.dto;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订购单信息
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PharmacyDispensaryDetailDto implements Serializable {
|
||||
|
||||
/** ID */
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 单据号 */
|
||||
private String busNo;
|
||||
/** 再生成单据号 */
|
||||
private String originalBusNo;
|
||||
|
||||
/** 药品编码 */
|
||||
private String itemBusNo;
|
||||
|
||||
/** 物品id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long itemId;
|
||||
|
||||
/** 物品名称 */
|
||||
private String itemName;
|
||||
|
||||
/** 规格 */
|
||||
private String totalVolume;
|
||||
|
||||
/** 选择单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/** 常规单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String maxUnitCode;
|
||||
private String maxUnitCode_dictText;
|
||||
|
||||
/** 最小单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String minUnitCode;
|
||||
private String minUnitCode_dictText;
|
||||
|
||||
/** 拆零比 */
|
||||
private String partPercent;
|
||||
|
||||
/** 数量 */
|
||||
private BigDecimal itemQuantity;
|
||||
|
||||
/** 合计数量 */
|
||||
private BigDecimal totalQuantity;
|
||||
|
||||
/** 单价 */
|
||||
private BigDecimal price;
|
||||
|
||||
/** 总价 */
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
/** 零售价 */
|
||||
private BigDecimal retailPrice;
|
||||
|
||||
/** 零价金额 */
|
||||
private BigDecimal totalRetailPrice;
|
||||
|
||||
/** 厂家/产地 */
|
||||
private String manufacturerText;
|
||||
|
||||
/** 批准文号 */
|
||||
private String approvalNumber;
|
||||
|
||||
/** 批次库存 */
|
||||
private BigDecimal batchInventory;
|
||||
/** 规格库存 */
|
||||
private BigDecimal specificationInventory;
|
||||
|
||||
/** 备注 */
|
||||
private String remake;
|
||||
|
||||
/** 理由类型 */
|
||||
private String reasonCode;
|
||||
|
||||
/** 摘要(理由) */
|
||||
private String reason;
|
||||
|
||||
/** 供应商 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_supplier")
|
||||
private Long supplierId;
|
||||
private String supplierId_dictText;
|
||||
|
||||
/** 源仓库类型 */
|
||||
private Integer sourceTypeEnum;
|
||||
/** 源仓库 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long sourceLocationId;
|
||||
|
||||
/** 目的仓库类型 */
|
||||
private Integer purposeTypeEnum;
|
||||
/** 目的仓库 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long purposeLocationId;
|
||||
|
||||
/** 采购员 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applicantId;
|
||||
|
||||
/** 审批人 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long approverId;
|
||||
/** 审批时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date approvalTime;
|
||||
|
||||
/** 申请时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date applyTime;
|
||||
|
||||
/** 状态 */
|
||||
private Integer statusEnum;
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/** 类型 */
|
||||
private Integer typeEnum;
|
||||
private String typeEnum_enumText;
|
||||
|
||||
/** 单据分类 */
|
||||
private Integer categoryEnum;
|
||||
private String categoryEnum_enumText;
|
||||
|
||||
/** 供应商联系人 */
|
||||
private String phone;
|
||||
|
||||
/** 仓库员 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long practitionerId;
|
||||
|
||||
/** 发票号 */
|
||||
private String invoiceNo;
|
||||
|
||||
/** 产品批号 */
|
||||
private String lotNumber;
|
||||
|
||||
/** 生产日期 */
|
||||
private Date startTime;
|
||||
|
||||
/** 失效日期 */
|
||||
private Date endTime;
|
||||
|
||||
/** 追溯码*/
|
||||
private String traceNo;
|
||||
|
||||
/** 追溯码单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String traceNoUnitCode;
|
||||
private String traceNoUnitCode_dictText;
|
||||
|
||||
/** 包装情况 */
|
||||
private Integer packagingConditionEnum;
|
||||
private String packagingConditionEnum_enumText;
|
||||
|
||||
/** 验收结果 */
|
||||
private Integer acceptanceResultEnum;
|
||||
private String acceptanceResultEnum_enumText;
|
||||
|
||||
/** 禁用日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date occurrenceTime;
|
||||
|
||||
/** 药品发放id */
|
||||
private String dispenseIds;
|
||||
|
||||
/**
|
||||
* 单位列表
|
||||
*/
|
||||
private List<Option> unitList;
|
||||
|
||||
@Data
|
||||
public static class Option {
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String value;
|
||||
private String value_dictText;
|
||||
public Option(String value, String value_dictText) {
|
||||
this.value = value;
|
||||
this.value_dictText = value_dictText;
|
||||
}
|
||||
public Option() {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispensary.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 订购单信息
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PharmacyDispensaryDto implements Serializable {
|
||||
/** 单据号 */
|
||||
private String supplyBusNo;
|
||||
|
||||
/** 状态 */
|
||||
private Integer statusEnum;
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/** 类型 */
|
||||
private Integer typeEnum;
|
||||
private String typeEnum_enumText;
|
||||
|
||||
/** 供应商 */
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_supplier")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long supplierId;
|
||||
private String supplierId_dictText;
|
||||
|
||||
/** 仓库类型 */
|
||||
private Integer locationTypeEnum;
|
||||
private String locationTypeEnum_enumText;
|
||||
|
||||
/** 仓库 */
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_location")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
private String locationId_dictText;
|
||||
|
||||
/** 采购员 */
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applicantId;
|
||||
private String applicantId_dictText;
|
||||
|
||||
/** 审批人 */
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long approverId;
|
||||
private String approverId_dictText;
|
||||
|
||||
/** 审批时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date approvalTime;
|
||||
|
||||
/** 制单日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date applyTime;
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispensary.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.web.common.dto.LocationDto;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 订购单信息
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PharmacyDispensaryInitDto implements Serializable {
|
||||
|
||||
/**
|
||||
* 单据号
|
||||
*/
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 库房类型列表
|
||||
*/
|
||||
private List<DispensaryOption> warehouseTypeOption;
|
||||
|
||||
/**
|
||||
* 库房列表
|
||||
*/
|
||||
private List<LongOption> warehouseOption;
|
||||
|
||||
/**
|
||||
* 供应商列表
|
||||
*/
|
||||
private List<SupplierOption> supplierOption;
|
||||
|
||||
/**
|
||||
* 人员列表
|
||||
*/
|
||||
private List<LongOption> practitionerOption;
|
||||
/**
|
||||
* 审批状态
|
||||
*/
|
||||
private List<IntegerOption> supplyStatusOptions;
|
||||
|
||||
/**
|
||||
* 单据类型
|
||||
*/
|
||||
private List<IntegerOption> supplyTypeOptions;
|
||||
|
||||
/**
|
||||
* 单据分类
|
||||
*/
|
||||
private List<IntegerOption> supplyCategoryOptions;
|
||||
/**
|
||||
* 包装情况
|
||||
*/
|
||||
private List<IntegerOption> packagingConditionOptions;
|
||||
/**
|
||||
* 包装情况
|
||||
*/
|
||||
private List<IntegerOption> acceptanceResultoryOptions;
|
||||
|
||||
/**
|
||||
* 仓库
|
||||
*/
|
||||
private List<LocationDto> cabinetListOptions;
|
||||
/**
|
||||
* 药房
|
||||
*/
|
||||
private List<LocationDto> pharmacyListOptions;
|
||||
|
||||
@Data
|
||||
public static class LongOption {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
|
||||
public LongOption(Long value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class SupplierOption {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
private String phone;
|
||||
|
||||
public SupplierOption(Long value, String label, String phone) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
this.phone = phone;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class IntegerOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public IntegerOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class DispensaryOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
private List<LocationDto> locationOption;
|
||||
private List<DispensaryItemOption> orderOption;
|
||||
|
||||
public DispensaryOption(Integer value, String label,List<LocationDto> locationOption,List<DispensaryItemOption> orderOption) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
this.locationOption = locationOption;
|
||||
this.orderOption = orderOption;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class DispensaryItemOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public DispensaryItemOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispensary.dto;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药品信息
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PharmacyDispensaryMedicationInfoDto implements Serializable {
|
||||
|
||||
/** 物品id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/** 物品编号 */
|
||||
private String busNo;
|
||||
|
||||
/** 物品名称 */
|
||||
private String name;
|
||||
|
||||
/** 拼音码 */
|
||||
private String pyStr;
|
||||
|
||||
/** 规格 */
|
||||
private String totalVolume;
|
||||
|
||||
/** 包装单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/** 最小单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String minUnitCode;
|
||||
private String minUnitCode_dictText;
|
||||
|
||||
/** 拆零比 */
|
||||
private BigDecimal partPercent;
|
||||
|
||||
/** 产品批号 */
|
||||
private String lotNumber;
|
||||
|
||||
|
||||
// /** 价格单位 */
|
||||
// @Dict(dictCode = "unit_code")
|
||||
// private String conditionUnitCode;
|
||||
// private String conditionUnitCode_dictText;
|
||||
|
||||
/** 单价 */
|
||||
private BigDecimal price;
|
||||
|
||||
/** 零售价 */
|
||||
private BigDecimal retailPrice;
|
||||
|
||||
/** 厂家/产地 */
|
||||
private String manufacturerText;
|
||||
|
||||
/** 批准文号 */
|
||||
private String approvalNumber;
|
||||
|
||||
/** 库存最小警戒线 */
|
||||
private BigDecimal itemMinQuantity;
|
||||
|
||||
/** 批次库存 */
|
||||
private BigDecimal batchInventory;
|
||||
/** 规格库存 */
|
||||
private BigDecimal specificationInventory;
|
||||
|
||||
/** 供应商 */
|
||||
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_supplier")
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long supplierId;
|
||||
private String supplierId_dictText;
|
||||
|
||||
/** 仓库 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
|
||||
/** 生产日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date productionDate;
|
||||
|
||||
/** 失效日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date expirationDate;
|
||||
|
||||
/**
|
||||
* 单位列表
|
||||
*/
|
||||
private List<Option> unitList;
|
||||
|
||||
@Data
|
||||
public static class Option {
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String value;
|
||||
private String value_dictText;
|
||||
public Option(String value, String value_dictText) {
|
||||
this.value = value;
|
||||
this.value_dictText = value_dictText;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispensary.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 订购单查询条件
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PharmacyDispensarySearchParam implements Serializable {
|
||||
/** id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
/** 单据号 */
|
||||
private String busNo;
|
||||
|
||||
/** 采购员 */
|
||||
private String applicantName;
|
||||
|
||||
/** 项目名 */
|
||||
private String name;
|
||||
|
||||
/** 拼音码 */
|
||||
private String pyStr;
|
||||
|
||||
/** 供应商id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long supplierId;
|
||||
|
||||
/** 仓库类型 */
|
||||
private Integer locationTypeEnum;
|
||||
|
||||
/** 仓库 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
|
||||
/** 类型 */
|
||||
private Integer typeEnum;
|
||||
|
||||
/** 单据状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
/** 再生成单据号flg */
|
||||
private String originalBusNoFlg;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryMedicationInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensarySearchParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药库共通 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryCommonMapper {
|
||||
/**
|
||||
* 根据供应商获取药品
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param locationId 仓库id
|
||||
* @return 药品信息
|
||||
*/
|
||||
|
||||
Page<PharmacyDispensaryMedicationInfoDto> getMedicationInfo(
|
||||
@Param("page") Page<PharmacyDispensaryMedicationInfoDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PharmacyDispensarySearchParam> queryWrapper,
|
||||
@Param("locationId") Long locationId, @Param("supplierId") Long supplierId);
|
||||
|
||||
/**
|
||||
* 查询订货单分页列表
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param originalBusNoFlg 再生成单据号flg
|
||||
* @param locationFlg 仓库flg
|
||||
* @return 订货单分页列表
|
||||
*/
|
||||
Page<PharmacyDispensaryDto> getPage(@Param("page") Page<PharmacyDispensaryDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PharmacyDispensarySearchParam> queryWrapper,
|
||||
@Param("originalBusNoFlg") String originalBusNoFlg, @Param("locationFlg") String locationFlg);
|
||||
|
||||
/**
|
||||
* 查询单据详情
|
||||
*
|
||||
* @param page 分页
|
||||
* @param busNo 单据号
|
||||
* @return 单据详情
|
||||
*/
|
||||
Page<PharmacyDispensaryDetailDto> getDetailPage(@Param("page") Page<PharmacyDispensaryDetailDto> page,
|
||||
@Param("busNo") String busNo);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import com.healthlink.his.web.pharmacy.dispensary.dto.PharmacyDispensaryDetailDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 药房发药单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryDispensingOrderMapper {
|
||||
|
||||
|
||||
/**
|
||||
* 获取更表所需信息
|
||||
*
|
||||
* @param dispenseIdList 药品发放id
|
||||
* @param dispenseStatus 发放状态
|
||||
* @return 单据详情
|
||||
*/
|
||||
List<PharmacyDispensaryDetailDto> getInfo(@Param("dispenseIdList") List<Long> dispenseIdList,@Param("dispenseStatus") Integer dispenseStatus);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房损益单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryProfitLossOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房请领单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryRequisitionOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房退库单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryReturnToWarehouseOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房入库单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryStockInOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房盘点单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryStocktakingOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房调入单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryTransferInOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.healthlink.his.web.pharmacy.dispensary.mapper;
|
||||
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
/**
|
||||
* 药房调出单 mapper
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-07-22
|
||||
*/
|
||||
@Repository
|
||||
public interface PharmacyDispensaryTransferOutOrderMapper {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ReturnMedicineDto;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
public interface IInHospitalReturnMedicineAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus, String itemTable);
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.DispenseItemDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ItemDispenseOrderDto;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 材料发送 应用实现接口
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/8/21
|
||||
*/
|
||||
public interface IMedicalDeviceDispenseAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
R<?> getEncounterInfoListPage(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey, Integer pageNo, Integer pageSize,
|
||||
HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 发耗材单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发耗材单
|
||||
*/
|
||||
R<?> getDeviceDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 核对发耗材
|
||||
*
|
||||
* @param dispenseDeviceList 发耗材信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> deviceDispense(List<DispenseItemDto> dispenseDeviceList);
|
||||
|
||||
/**
|
||||
* 发放耗材
|
||||
*
|
||||
* @param chargeItemIds 耗材收费单ids
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> dispenseMedicalConsumables(List<Long> chargeItemIds);
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseDeviceList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> deviceCancel(List<DispenseItemDto> dispenseDeviceList);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailsSearchParam;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 发药明细 应用实现接口
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
public interface IMedicationDetailsAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 门诊人员发药明细表
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊发药明细表
|
||||
*/
|
||||
R<?> getAmbPractitionerDetailPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request);
|
||||
|
||||
void makeExcelFile(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo, Integer pageSize, String searchKey,
|
||||
HttpServletResponse response, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 门诊发药明细流水账
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊发药明细流水账
|
||||
*/
|
||||
R<?> getAmbMedicationDispenseDetailPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo,
|
||||
Integer pageSize, String searchKey, HttpServletRequest request);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 门诊/住院人员发药明细帐、住院耗材记账领用明细
|
||||
// *
|
||||
// * @param medDetailsSearchParam 查询条件
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param request 请求数据
|
||||
// * @return 门诊/住院人员发药明细、住院耗材记账领用明细分页列表
|
||||
// */
|
||||
// R<?> getMedDetailedAccountPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo, Integer pageSize,
|
||||
// String searchKey, HttpServletRequest request);
|
||||
//
|
||||
// /**
|
||||
// * 门诊/住院发药明细流水帐、住院耗材记账领用流水账
|
||||
// *
|
||||
// * @param medDetailsSearchParam 查询条件
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param request 请求数据
|
||||
// * @return 门诊/住院发药明细流水帐、住院耗材记账领用流水账分页列表
|
||||
// */
|
||||
// R<?> getMedRunningAccountPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo, Integer pageSize,
|
||||
// String searchKey, HttpServletRequest request);
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationSearchParam;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 待发药明细 应用实现接口
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
public interface IPendingMedicationDetailsAppService {
|
||||
|
||||
/**
|
||||
* 分页查询待发药明细
|
||||
*
|
||||
* @param pendingMedicationSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 待发药明细
|
||||
*/
|
||||
R<?> getPage(PendingMedicationSearchParam pendingMedicationSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ReturnMedicineDto;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 退药管理 应用实现接口
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
public interface IReturnMedicineAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @return 退药信息
|
||||
*/
|
||||
R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus);
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 住院汇总发药 应用实现接口
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/6/3
|
||||
*/
|
||||
public interface ISummaryDispenseMedicineAppService {
|
||||
|
||||
/**
|
||||
* 汇总发药
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> SummaryDispenseMedicine(List<String> summaryNoList);
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> dispenseCancel(List<String> summaryNoList);
|
||||
|
||||
// /**
|
||||
// * 住院发药
|
||||
// *
|
||||
// * @param searchParam 查询条件
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param request 请求数据
|
||||
// */
|
||||
// void makeExcelFile(MedicineSummarySearchParam searchParam, Integer pageNo, Integer pageSize, String searchKey,
|
||||
// HttpServletRequest request, HttpServletResponse response);
|
||||
//
|
||||
// /**
|
||||
// * 住院汇总
|
||||
// *
|
||||
// * @param searchParam 查询条件
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param request 请求数据
|
||||
// */
|
||||
// void takeExcelField(FromSearchParam searchParam, String searchKey, Integer pageNo, Integer pageSize,
|
||||
// HttpServletRequest request, HttpServletResponse response);
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.DispenseItemDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ItemDispenseOrderDto;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 处方管理 应用实现接口
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025/3/18
|
||||
*/
|
||||
public interface IWesternMedicineDispenseAppService {
|
||||
|
||||
/**
|
||||
* 页面初始化
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
R<?> init();
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
R<?> getEncounterInfoListPage(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request);
|
||||
|
||||
/**
|
||||
* 处方单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 处方单
|
||||
*/
|
||||
R<?> getMedicineDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto, Integer pageNo, Integer pageSize);
|
||||
|
||||
/**
|
||||
* 配药
|
||||
*
|
||||
* @param dispenseMedicineList 配药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicinePrepare(List<DispenseItemDto> dispenseMedicineList);
|
||||
|
||||
/**
|
||||
* 处方单核对发药
|
||||
*
|
||||
* @param dispenseMedicineList 发药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicineDispense(List<DispenseItemDto> dispenseMedicineList);
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseMedicineList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
R<?> medicineCancel(List<DispenseItemDto> dispenseMedicineList);
|
||||
}
|
||||
@@ -0,0 +1,741 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice.impl;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import tools.jackson.databind.JsonNode;
|
||||
import tools.jackson.databind.node.ArrayNode;
|
||||
import tools.jackson.databind.node.ObjectNode;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
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.exception.ServiceException;
|
||||
import com.core.common.utils.AgeCalculatorUtil;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.healthlink.his.administration.domain.*;
|
||||
import com.healthlink.his.administration.service.*;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.yb.enums.YbInvChgType;
|
||||
import com.healthlink.his.yb.enums.YbMdtrtCertType;
|
||||
import com.healthlink.his.yb.enums.YbRxFlag;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.financial.domain.Contract;
|
||||
import com.healthlink.his.financial.domain.PaymentReconciliation;
|
||||
import com.healthlink.his.financial.service.IContractService;
|
||||
import com.healthlink.his.financial.service.IPaymentReconciliationService;
|
||||
import com.healthlink.his.medication.domain.MedicationDefinition;
|
||||
import com.healthlink.his.medication.domain.MedicationDispense;
|
||||
import com.healthlink.his.medication.domain.MedicationRequest;
|
||||
import com.healthlink.his.medication.service.IMedicationDefinitionService;
|
||||
import com.healthlink.his.medication.service.IMedicationDispenseService;
|
||||
import com.healthlink.his.medication.service.IMedicationRequestService;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IInHospitalReturnMedicineAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.*;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.InHospitalReturnMedicineAppMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.ReturnMedicineMapper;
|
||||
import com.healthlink.his.workflow.domain.DeviceDispense;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.service.IDeviceDispenseService;
|
||||
import com.healthlink.his.workflow.service.IDeviceRequestService;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import com.healthlink.his.yb.domain.ClinicSettle;
|
||||
import com.healthlink.his.yb.dto.Medical3506Param;
|
||||
import com.healthlink.his.yb.dto.MedicalInventory3511Param;
|
||||
import com.healthlink.his.yb.service.IClinicSettleService;
|
||||
import com.healthlink.his.yb.service.IYbManager;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Service
|
||||
public class InHospitalReturnMedicineAppServiceImpl implements IInHospitalReturnMedicineAppService {
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private IOrganizationService iOrganizationService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService iInventoryItemService;
|
||||
|
||||
@Resource
|
||||
private InHospitalReturnMedicineAppMapper inHospitalReturnMedicineAppMapper;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private IMedicationRequestService medicationRequestService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDispenseService deviceDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceRequestService deviceRequestService;
|
||||
|
||||
@Resource
|
||||
private IYbManager ybService;
|
||||
|
||||
@Resource
|
||||
private IChargeItemService iChargeItemService;
|
||||
|
||||
@Resource
|
||||
private IPaymentReconciliationService iPaymentReconciliationService;
|
||||
|
||||
@Resource
|
||||
private IContractService iContractService;
|
||||
|
||||
@Resource
|
||||
private IClinicSettleService clinicSettleService;
|
||||
|
||||
@Resource
|
||||
private IEncounterDiagnosisService encounterDiagnosisService;
|
||||
|
||||
@Resource
|
||||
private IAccountService accountService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDefinitionService deviceDefinitionService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDefinitionService medicationDefinitionService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
ReturnMedicineInitDto initDto = new ReturnMedicineInitDto();
|
||||
|
||||
// 获取科室下拉选列表
|
||||
List<Organization> organizationList =
|
||||
iOrganizationService.getList(OrganizationType.DEPARTMENT.getValue(), String.valueOf(OrganizationClass.CLINIC.getValue()));
|
||||
List<ReturnMedicineInitDto.DepartmentOption> organizationOptions = organizationList.stream().map(
|
||||
organization -> new ReturnMedicineInitDto.DepartmentOption(organization.getId(), organization.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 发药状态
|
||||
List<ReturnMedicineInitDto.RefundStatusOption> refundStatusOptions = new ArrayList<>();
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.PENDING_REFUND.getValue(),
|
||||
DispenseStatus.PENDING_REFUND.getInfo()));
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.REFUNDED.getValue(),
|
||||
DispenseStatus.REFUNDED.getInfo()));
|
||||
initDto.setDepartmentOptions(organizationOptions).setRefundStatusOptions(refundStatusOptions);
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request) {
|
||||
Integer refundEnum = encounterInfoDto.getRefundEnum();
|
||||
encounterInfoDto.setRefundEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<EncounterInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(encounterInfoDto, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.PatientName, CommonConstants.FieldName.IdCard,
|
||||
CommonConstants.FieldName.PatientPyStr, CommonConstants.FieldName.PatientWbStr)),
|
||||
request);
|
||||
// 查询退药患者分页列表
|
||||
Page<EncounterInfoDto> encounterInfoPage = inHospitalReturnMedicineAppMapper.selectEncounterInfoListPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, refundEnum, DispenseStatus.PENDING_REFUND.getValue(),
|
||||
DispenseStatus.REFUNDED.getValue(), EncounterClass.IMP.getValue(),
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
encounterInfoPage.getRecords().forEach(encounterInfo -> {
|
||||
// 性别
|
||||
encounterInfo.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, encounterInfo.getGenderEnum()));
|
||||
// 年龄
|
||||
encounterInfo.setAge(AgeCalculatorUtil.getAge(encounterInfo.getBirthDate()));
|
||||
// 退药状态
|
||||
encounterInfo
|
||||
.setRefundEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, encounterInfo.getRefundEnum()));
|
||||
});
|
||||
return R.ok(encounterInfoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus, String itemTable) {
|
||||
// 获取退药信息
|
||||
List<ReturnMedicineInfoDto> returnMedicineInfoList = inHospitalReturnMedicineAppMapper.selectReturnMedicineInfo(
|
||||
encounterId, CommonConstants.TableName.WOR_DEVICE_REQUEST, CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||
itemTable, refundStatus, DispenseStatus.PENDING_REFUND.getValue(), DispenseStatus.REFUNDED.getValue());
|
||||
returnMedicineInfoList.forEach(returnMedicineInfoDto -> {
|
||||
// 退药状态
|
||||
returnMedicineInfoDto.setRefundEnum_enumText(
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, returnMedicineInfoDto.getRefundEnum()));
|
||||
// 退药请求状态
|
||||
returnMedicineInfoDto.setReqStatus_enumText(
|
||||
EnumUtils.getInfoByValue(RequestStatus.class, returnMedicineInfoDto.getReqStatus()));
|
||||
});
|
||||
return R.ok(returnMedicineInfoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList) {
|
||||
if (medicineReturnList == null || medicineReturnList.isEmpty()) {
|
||||
return R.ok();
|
||||
}
|
||||
// 分别处理退药与退耗材的请求
|
||||
List<ReturnMedicineDto> returnMedicineList = new ArrayList<>();
|
||||
List<ReturnMedicineDto> returnDeviceList = new ArrayList<>();
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> traceNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
|
||||
medicineReturnList.forEach(item -> {
|
||||
switch (item.getTableName()) {
|
||||
case CommonConstants.TableName.MED_MEDICATION_REQUEST -> returnMedicineList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
case CommonConstants.TableName.WOR_DEVICE_REQUEST -> returnDeviceList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
}
|
||||
});
|
||||
// 进销存参数
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
|
||||
// 记录未发药(无库存变动)的发药单ID
|
||||
Set<Long> noInventoryUpdateMedIds = new HashSet<>();
|
||||
Set<Long> noInventoryUpdateDevIds = new HashSet<>();
|
||||
|
||||
// 处理退药
|
||||
// 获取药品退药id列表
|
||||
List<Long> medReturnIdList = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 获取药品退药id列表
|
||||
medReturnIdList =
|
||||
returnMedicineList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取药品退药请求id列表
|
||||
List<Long> medRequestIdList =
|
||||
returnMedicineList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
|
||||
if (medReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
if (medRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 药品退药信息查询
|
||||
List<MedicationDispense> refundMedList = medicationDispenseService.listByIds(medReturnIdList);
|
||||
// 药品退药请求查询
|
||||
List<MedicationRequest> refundMedRequestList = medicationRequestService.listByIds(medRequestIdList);
|
||||
if (refundMedList == null || refundMedList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 重复退药校验
|
||||
if (refundMedList.stream().map(MedicationDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("药品已退药,请勿重复退药");
|
||||
}
|
||||
|
||||
// 在更新退药单状态前,统计出实际没有发药(已发药数量为0/空)的退药单,避免后续加回库存和报错
|
||||
for (MedicationDispense medicationDispense : refundMedList) {
|
||||
if (medicationDispense.getDispenseQuantity() == null
|
||||
|| medicationDispense.getDispenseQuantity().compareTo(BigDecimal.ZERO) == 0) {
|
||||
noInventoryUpdateMedIds.add(medicationDispense.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// 更新退药单
|
||||
for (MedicationDispense medicationDispense : refundMedList) {
|
||||
// 退药状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 退药数量
|
||||
medicationDispense.setDispenseQuantity(medicationDispense.getQuantity());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
// 退药时间
|
||||
medicationDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药人
|
||||
medicationDispense.setPractitionerId(SecurityUtils.getPractitionerId());
|
||||
|
||||
// 设置库存变更参数(仅针对实际发过药的药品)
|
||||
if (!noInventoryUpdateMedIds.contains(medicationDispense.getId())) {
|
||||
SupplyItemDetailDto supplyItemDetailDto = new SupplyItemDetailDto();
|
||||
for (MedicationRequest medicationRequest : refundMedRequestList) {
|
||||
// 根据退药id查询退药请求id(用于医保关联)
|
||||
if (medicationDispense.getMedReqId().equals(medicationRequest.getId())) {
|
||||
supplyItemDetailDto.setRequestId(medicationRequest.getRefundMedicineId());
|
||||
}
|
||||
}
|
||||
supplyItemDetailDto.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setItemId(medicationDispense.getMedicationId()).setLotNumber(medicationDispense.getLotNumber());
|
||||
supplyItemDetailList.add(supplyItemDetailDto);
|
||||
}
|
||||
|
||||
// 追溯码表相关处理(仅针对实际发过药的药品)
|
||||
if (!noInventoryUpdateMedIds.contains(medicationDispense.getId()) && medicationDispense.getTraceNo() != null) {
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
String[] traceNoList = medicationDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(medicationDispense.getMedicationId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(null)
|
||||
// 仓库
|
||||
.setLocationId(medicationDispense.getLocationId())
|
||||
// 仓位
|
||||
.setLocationStoreId(null)
|
||||
// 产品批号
|
||||
.setLotNumber(medicationDispense.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.IN.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(medicationDispense.getUnitCode())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.RETURN_MEDICATION.getValue());
|
||||
traceNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 退药更新
|
||||
medicationDispenseService.updateBatchById(refundMedList);
|
||||
|
||||
// 退药完成后,检查医嘱关联的发药记录是否全部退完,如果是则回写医嘱状态为已停止
|
||||
// 解决:医嘱取消(status=5)后退药完成,医嘱状态未变更,导致护士站"待处理执行单"仍显示已退完的医嘱
|
||||
Set<Long> distinctMedReqIds = refundMedList.stream()
|
||||
.map(MedicationDispense::getMedReqId).collect(Collectors.toSet());
|
||||
for (Long medReqId : distinctMedReqIds) {
|
||||
// 查询该医嘱下所有发药记录
|
||||
List<MedicationDispense> allDispenses = medicationDispenseService.list(
|
||||
new LambdaQueryWrapper<MedicationDispense>()
|
||||
.eq(MedicationDispense::getMedReqId, medReqId)
|
||||
.eq(MedicationDispense::getDeleteFlag, "0"));
|
||||
// 判断是否全部已退药
|
||||
boolean allRefunded = allDispenses.stream()
|
||||
.allMatch(d -> DispenseStatus.REFUNDED.getValue().equals(d.getStatusEnum()));
|
||||
if (allRefunded) {
|
||||
// 回写医嘱状态:取消/待退(5) → 已停止(6)
|
||||
// STOPPED(6)会被护士站查询排除,不再出现在"待处理执行单"中
|
||||
medicationRequestService.update(
|
||||
new LambdaUpdateWrapper<MedicationRequest>()
|
||||
.eq(MedicationRequest::getId, medReqId)
|
||||
.eq(MedicationRequest::getStatusEnum, RequestStatus.CANCELLED.getValue())
|
||||
.set(MedicationRequest::getStatusEnum, RequestStatus.STOPPED.getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 处理退耗材
|
||||
// 获取退耗材id列表
|
||||
List<Long> devReturnIdList = new ArrayList<>();
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
// 获取退耗材id列表
|
||||
devReturnIdList =
|
||||
returnDeviceList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取退耗材请求id列表
|
||||
List<Long> devRequestIdList = returnDeviceList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
|
||||
if (devReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
if (devRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 退耗材信息查询
|
||||
List<DeviceDispense> refundDevList = deviceDispenseService.listByIds(devReturnIdList);
|
||||
if (refundDevList == null || refundDevList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 重复退耗材校验
|
||||
if (refundDevList.stream().map(DeviceDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("耗材已退,请勿重复操作");
|
||||
}
|
||||
|
||||
// 在更新退耗材单状态前,统计出实际没有发放(已发放数量为0/空)的退耗材单
|
||||
for (DeviceDispense deviceDispense : refundDevList) {
|
||||
if (deviceDispense.getDispenseQuantity() == null
|
||||
|| deviceDispense.getDispenseQuantity().compareTo(BigDecimal.ZERO) == 0) {
|
||||
noInventoryUpdateDevIds.add(deviceDispense.getId());
|
||||
}
|
||||
}
|
||||
|
||||
// 更新退耗材单状态
|
||||
for (DeviceDispense deviceDispense : refundDevList) {
|
||||
// 退药时间
|
||||
deviceDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药数量
|
||||
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
|
||||
// 退药状态
|
||||
deviceDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 设置库存变更参数(仅针对实际发放过的耗材)
|
||||
if (!noInventoryUpdateDevIds.contains(deviceDispense.getId())) {
|
||||
supplyItemDetailList
|
||||
.add(new SupplyItemDetailDto().setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
.setItemId(deviceDispense.getDeviceDefId()).setLotNumber(deviceDispense.getLotNumber()));
|
||||
}
|
||||
}
|
||||
deviceDispenseService.updateBatchById(refundDevList);
|
||||
}
|
||||
|
||||
// 追溯码管理表数据追加
|
||||
if (!traceNoManageList.isEmpty()) {
|
||||
traceNoManageService.saveBatch(traceNoManageList);
|
||||
}
|
||||
|
||||
// 处理退库存
|
||||
// 获取库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList =
|
||||
returnMedicineMapper.selectInventoryInfoList(devReturnIdList, medReturnIdList,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap =
|
||||
unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
// 过滤未实际发药/发耗材的项目,其库存不加回
|
||||
if (noInventoryUpdateMedIds.contains(unDispenseInventoryDto.getDispenseId())
|
||||
|| noInventoryUpdateDevIds.contains(unDispenseInventoryDto.getDispenseId())) {
|
||||
continue;
|
||||
}
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity =
|
||||
unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
}
|
||||
// 只有当有需要恢复库存的药品/器材时才加回库存
|
||||
if (minQuantity.compareTo(BigDecimal.ZERO) > 0) {
|
||||
// 理论上不出bug的情况下以项目id,批号,仓库进行分组处理库存一定唯一所以get(0)
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryList.get(0).getInventoryId())
|
||||
.setQuantity(inventoryList.get(0).getInventoryQuantity().add(minQuantity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
// 库存更新
|
||||
if (!inventoryItemList.isEmpty()) {
|
||||
iInventoryItemService.updateBatchById(inventoryItemList);
|
||||
}
|
||||
} else {
|
||||
throw new ServiceException("请检查库存信息");
|
||||
}
|
||||
|
||||
// 处理退药医保
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
List<String> uploadFailedNoList;
|
||||
// 调用医保商品销售退货接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<DeviceDefinition> deviceDefinitions = new ArrayList<>();
|
||||
List<MedicationDefinition> medicationDefinitions = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 设置进销存参数
|
||||
medicationDefinitions = medicationDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.MED_MEDICATION_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
deviceDefinitions = deviceDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.ADM_DEVICE_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
// 创建映射表,添加空集合保护
|
||||
Map<Long, MedicationDefinition> medicationMap =
|
||||
medicationDefinitions != null ? medicationDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(MedicationDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
Map<Long, DeviceDefinition> deviceMap =
|
||||
deviceDefinitions != null ? deviceDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(DeviceDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
// 设置库存变更参数,添加完整判空
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
if (supplyItemDetailDto == null)
|
||||
continue;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
MedicationDefinition med = medicationMap.get(supplyItemDetailDto.getItemId());
|
||||
if (med != null) {
|
||||
supplyItemDetailDto.setItemBusNo(med.getBusNo()).setPartPercent(med.getPartPercent())
|
||||
.setRxFlag(med.getRxFlag()).setYbNo(med.getYbNo());
|
||||
}
|
||||
}
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
DeviceDefinition dev = deviceMap.get(supplyItemDetailDto.getItemId());
|
||||
if (dev != null) {
|
||||
supplyItemDetailDto.setItemBusNo(dev.getBusNo()).setPartPercent(dev.getPartPercent())
|
||||
.setRxFlag(dev.getRxFlag()).setYbNo(dev.getYbNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 仅对实际发过药(生成了收费记录且计费的)调用医保退货接口
|
||||
List<Long> medReturnIdsForYb = medReturnIdList.stream()
|
||||
.filter(id -> !noInventoryUpdateMedIds.contains(id))
|
||||
.collect(Collectors.toList());
|
||||
if (!medReturnIdsForYb.isEmpty()) {
|
||||
uploadFailedNoList = this.ybReturnIntegrated(medReturnIdsForYb, null);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = "3506商品销售退货上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3506商品销售退货上传成功";
|
||||
}
|
||||
}
|
||||
|
||||
if (!supplyItemDetailList.isEmpty()) {
|
||||
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = (returnMsg != null ? returnMsg + ";" : "") + "医保进销存集成上传错误: " + uploadFailedNoList;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 返回退药成功信息
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"退药"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 医保退药相关进销存接口
|
||||
*
|
||||
* @param dispenseMedIdList 退药id列表
|
||||
* @param dispenseDevIdList 退耗材id列表
|
||||
* @return 上传失败的编号集合
|
||||
*/
|
||||
public List<String> ybReturnIntegrated(List<Long> dispenseMedIdList, List<Long> dispenseDevIdList) {
|
||||
List<String> uploadFailedNoList = new ArrayList<>();
|
||||
R<?> result;
|
||||
if (!dispenseMedIdList.isEmpty() || !dispenseDevIdList.isEmpty()) {
|
||||
// 查询退药项目相关信息
|
||||
List<DispenseInventoryDto> dispenseInventoryList = returnMedicineMapper.selectReturnItemDetail(
|
||||
dispenseDevIdList, dispenseMedIdList, CommonConstants.TableName.MED_MEDICATION_DEFINITION,
|
||||
CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
for (DispenseInventoryDto dispenseInventoryDto : dispenseInventoryList) {
|
||||
if (dispenseInventoryDto.getYbNo() == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<Medical3506Param, Contract> medical3506Pair = getMedical3506Param(dispenseInventoryDto);
|
||||
// 如果自费则自动取省医保
|
||||
Contract contract = medical3506Pair.getRight();
|
||||
if (contract != null) {
|
||||
if (CommonConstants.BusinessName.DEFAULT_CONTRACT_NO
|
||||
.equals(medical3506Pair.getRight().getBusNo())) {
|
||||
contract = null;
|
||||
}
|
||||
}
|
||||
result = ybService.cancelMerchandise(medical3506Pair.getLeft(), contract);
|
||||
if (result.getCode() != 200) {
|
||||
uploadFailedNoList.add(dispenseInventoryDto.getDispenseNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
return uploadFailedNoList;
|
||||
}
|
||||
|
||||
private Pair<Medical3506Param, Contract> getMedical3506Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
Medical3506Param medical3506Param = new Medical3506Param();
|
||||
ChargeItem chargeItem = null;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
// 查询费用结算信息
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.MED_MEDICATION_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_DEVICE_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
}
|
||||
if (chargeItem == null) {
|
||||
throw new ServiceException("未查询到收费项");
|
||||
}
|
||||
// 查询就诊诊断信息
|
||||
EncounterDiagnosis encounterDiagnosis = encounterDiagnosisService.getById(chargeItem.getEncounterDiagnosisId());
|
||||
if (encounterDiagnosis == null) {
|
||||
throw new ServiceException("未查找到就诊诊断信息");
|
||||
}
|
||||
// 查询付款信息
|
||||
PaymentReconciliation paymentReconciliation =
|
||||
iPaymentReconciliationService.getOne(new LambdaQueryWrapper<PaymentReconciliation>()
|
||||
.eq(PaymentReconciliation::getEncounterId, chargeItem.getEncounterId())
|
||||
.like(PaymentReconciliation::getChargeItemIds, chargeItem.getId())
|
||||
.eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue())
|
||||
.eq(PaymentReconciliation::getPatientId, chargeItem.getPatientId())
|
||||
.eq(PaymentReconciliation::getPaymentEnum, PaymentType.PAY.getValue()));
|
||||
if (paymentReconciliation == null) {
|
||||
throw new ServiceException("未查询到收费");
|
||||
}
|
||||
|
||||
// 查询账户信息
|
||||
Account account = accountService
|
||||
.getOne(new LambdaQueryWrapper<Account>().eq(Account::getEncounterId, chargeItem.getEncounterId())
|
||||
.eq(Account::getEncounterFlag, Whether.YES.getValue()));
|
||||
if (account == null) {
|
||||
throw new ServiceException("未查询到账户");
|
||||
}
|
||||
// 查询合同实体
|
||||
Contract contract =
|
||||
iContractService.getOne(new LambdaQueryWrapper<Contract>().eq(Contract::getBusNo, account.getContractNo()));
|
||||
if (contract == null) {
|
||||
throw new ServiceException("未查询到合同信息");
|
||||
}
|
||||
YbMdtrtCertType mdtrtCertType;
|
||||
if (AccountType.PERSONAL_CASH_ACCOUNT.getCode().equals(account.getTypeCode())) {
|
||||
mdtrtCertType = YbMdtrtCertType.MDTRT_CERT_TYPE02;
|
||||
} else {
|
||||
mdtrtCertType = YbMdtrtCertType.getByValue(account.getTypeCode());// 2025/05/28 该值存01/02/03
|
||||
}
|
||||
if (mdtrtCertType == null) {
|
||||
throw new ServiceException("未查询到电子凭证");
|
||||
}
|
||||
// 查询就诊id
|
||||
if (contract.getCategoryEnum().equals(Category.SELF.getValue())
|
||||
|| contract.getCategoryEnum().equals(Category.PUBLIC.getValue())) {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
} else {
|
||||
ClinicSettle clinicSettle = clinicSettleService.getOne(new LambdaQueryWrapper<ClinicSettle>()
|
||||
.in(ClinicSettle::getSetlId, List.of(paymentReconciliation.getYbSettleIds()))
|
||||
.eq(ClinicSettle::getMedType, encounterDiagnosis.getMedTypeCode()).last(" LIMIT 1"));
|
||||
if (clinicSettle != null) {
|
||||
medical3506Param.setMdtrtSn(clinicSettle.getMdtrtId());
|
||||
} else {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
}
|
||||
}
|
||||
// // 查询发票信息
|
||||
// Invoice invoice = iInvoiceService.getById(paymentReconciliation.getInvoiceId());
|
||||
// if (invoice == null) {
|
||||
// throw new ServiceException("未查询到发票信息");
|
||||
// }
|
||||
// 转换为JSON
|
||||
ArrayNode medicalTraceNo = new tools.jackson.databind.ObjectMapper().createArrayNode();
|
||||
// 获取追溯码信息
|
||||
if (dispenseInventoryDto.getTraceNo() != null) {
|
||||
List<String> traceNoList =
|
||||
Arrays.stream(dispenseInventoryDto.getTraceNo().split(CommonConstants.Common.COMMA)).map(String::trim)
|
||||
.filter(s -> !s.isEmpty()).toList();
|
||||
for (String traceNo : traceNoList) {
|
||||
ObjectNode traceNoMap = new tools.jackson.databind.ObjectMapper().createObjectNode();
|
||||
traceNoMap.put("drug_trac_codg", traceNo);
|
||||
medicalTraceNo.add(traceNoMap);
|
||||
}
|
||||
}
|
||||
medical3506Param.setMedListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getRefundId().toString())
|
||||
.setFixmedinsHilistId(dispenseInventoryDto.getItemNo())
|
||||
.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setPsnCertType(mdtrtCertType.getValue()).setManuLotnum(dispenseInventoryDto.getLotNumber())
|
||||
.setManuDate(dispenseInventoryDto.getProductionDate())
|
||||
.setSelRetnCnt(new BigDecimal(dispenseInventoryDto.getDispenseQuantity().toString()))
|
||||
.setSelRetnTime(dispenseInventoryDto.getDispenseTime()).setExpyEnd(dispenseInventoryDto.getExpirationDate())
|
||||
.setDrugtracinfo(medicalTraceNo).setCertno(dispenseInventoryDto.getIdCard());
|
||||
// 查看所属医院
|
||||
String fixmedinsCode =
|
||||
SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
if (dispenseInventoryDto.getPreparerName() == null && HospitalCodeEnum.CCU.getCode().equals(fixmedinsCode)) {
|
||||
medical3506Param.setSelRetnOpterName(CommonConstants.CCU.DisDeviceDoctorName);
|
||||
} else {
|
||||
medical3506Param.setSelRetnOpterName(dispenseInventoryDto.getPreparerName());
|
||||
}
|
||||
if (dispenseInventoryDto.getInventoryUnitCode().equals(dispenseInventoryDto.getDispenseUnitCode())) {
|
||||
medical3506Param.setTrdnFlag(Whether.YES.getCode());
|
||||
} else {
|
||||
medical3506Param.setTrdnFlag(Whether.NO.getCode());
|
||||
}
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
return Pair.of(medical3506Param, contract);
|
||||
}
|
||||
|
||||
private MedicalInventory3511Param getMedical3511Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
MedicalInventory3511Param medicalInventory3511Param = new MedicalInventory3511Param();
|
||||
|
||||
String fixmedinsCode =
|
||||
SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
// TODO
|
||||
medicalInventory3511Param.setFixmedinsCode(fixmedinsCode).setMedinsListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getLotNumber()).setBegndate(dispenseInventoryDto.getDispenseTime())
|
||||
.setEnddate(dispenseInventoryDto.getDispenseTime());
|
||||
|
||||
return medicalInventory3511Param;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
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.exception.ServiceException;
|
||||
import com.core.common.utils.AgeCalculatorUtil;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.healthlink.his.administration.domain.ChargeItem;
|
||||
import com.healthlink.his.administration.domain.Organization;
|
||||
import com.healthlink.his.administration.domain.Practitioner;
|
||||
import com.healthlink.his.administration.domain.TraceNoManage;
|
||||
import com.healthlink.his.administration.service.IChargeItemService;
|
||||
import com.healthlink.his.administration.service.IDeviceDefinitionService;
|
||||
import com.healthlink.his.administration.service.IOrganizationService;
|
||||
import com.healthlink.his.administration.service.ITraceNoManageService;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IMedicalDeviceDispenseAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.*;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.MedicalDeviceDispenseMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.ReturnMedicineMapper;
|
||||
import com.healthlink.his.workflow.domain.DeviceDispense;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.service.IDeviceDispenseService;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
;
|
||||
|
||||
/**
|
||||
* 材料发送 应用实现类
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/8/21
|
||||
*/
|
||||
@Service
|
||||
public class MedicalDeviceDispenseAppServiceImpl implements IMedicalDeviceDispenseAppService {
|
||||
|
||||
@Resource
|
||||
private IOrganizationService organizationService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDispenseService deviceDispenseService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService inventoryItemService;
|
||||
|
||||
@Resource
|
||||
private MedicalDeviceDispenseMapper medicalDeviceDispenseMapper;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private WesternMedicineDispenseAppServiceImpl westernMedicineDispenseAppService;
|
||||
|
||||
@Resource
|
||||
private IChargeItemService chargeItemService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDefinitionService deviceDefinitionService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
DispenseInitDto initDto = new DispenseInitDto();
|
||||
|
||||
// 获取科室下拉选列表
|
||||
List<Organization> organizationList
|
||||
= organizationService.getList(OrganizationType.DEPARTMENT.getValue(), String.valueOf(OrganizationClass.CLINIC.getValue()));
|
||||
List<DispenseInitDto.DepartmentOption> organizationOptions = organizationList.stream()
|
||||
.map(organization -> new DispenseInitDto.DepartmentOption(organization.getId(), organization.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 获取配药人下拉选列表
|
||||
List<Practitioner> preparerDoctorList
|
||||
= medicalDeviceDispenseMapper.getPreparerDoctorList(PractitionerRoles.PHARMACIST.getCode());
|
||||
List<DispenseInitDto.PreparerDoctorOption> preparerDoctorOptions = preparerDoctorList.stream()
|
||||
.map(practitioner -> new DispenseInitDto.PreparerDoctorOption(practitioner.getId(), practitioner.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 未发药原因下拉选列表
|
||||
List<DispenseInitDto.NotPerformedReasonOption> notPerformedReasonOptions
|
||||
= Stream.of(NotPerformedReasonEnum.values())
|
||||
.map(notPerformedReason -> new DispenseInitDto.NotPerformedReasonOption(notPerformedReason.getValue(),
|
||||
notPerformedReason.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 发药状态
|
||||
List<DispenseStatusOption> dispenseStatusOptions = new ArrayList<>();
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.IN_PROGRESS.getValue(),
|
||||
DispenseStatus.IN_PROGRESS.getInfo()));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.COMPLETED.getInfo()));
|
||||
|
||||
initDto.setDepartmentOptions(organizationOptions).setNotPerformedReasonOptions(notPerformedReasonOptions)
|
||||
.setDispenseStatusOptions(dispenseStatusOptions).setPreparerDoctorOptions(preparerDoctorOptions);
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getEncounterInfoListPage(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||
// 发药状态初始化
|
||||
Integer statusEnum = encounterInfoSearchParam.getStatusEnum();
|
||||
encounterInfoSearchParam.setStatusEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<EncounterInfoSearchParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(encounterInfoSearchParam, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.PatientName, CommonConstants.FieldName.IdCard,
|
||||
CommonConstants.FieldName.PatientPyStr, CommonConstants.FieldName.PatientWbStr)),
|
||||
request);
|
||||
// 查询就诊病人列表
|
||||
Page<EncounterInfoDto> encounterInfoPage
|
||||
= medicalDeviceDispenseMapper.selectEncounterInfoListPage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
statusEnum, DispenseStatus.IN_PROGRESS.getValue(), DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.PREPARATION.getValue(), DispenseStatus.PREPARED.getValue());
|
||||
encounterInfoPage.getRecords().forEach(encounterInfo -> {
|
||||
// 性别
|
||||
encounterInfo.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, encounterInfo.getGenderEnum()));
|
||||
// 发药状态
|
||||
encounterInfo
|
||||
.setStatusEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, encounterInfo.getStatusEnum()));
|
||||
if (encounterInfo.getBirthDate() != null) {
|
||||
// 计算年龄
|
||||
encounterInfo.setAge(AgeCalculatorUtil.getAge(encounterInfo.getBirthDate()));
|
||||
}
|
||||
});
|
||||
return R.ok(encounterInfoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发耗材单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发耗材单
|
||||
*/
|
||||
@Override
|
||||
public R<?> getDeviceDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto, Integer pageNo,
|
||||
Integer pageSize) {
|
||||
// 发药状态初始化
|
||||
Integer dispenseStatus = itemDispenseOrderDto.getStatusEnum();
|
||||
itemDispenseOrderDto.setStatusEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<ItemDispenseOrderDto> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(itemDispenseOrderDto, null, null, null);
|
||||
// 处方单信息查询
|
||||
Page<ItemDispenseOrderDto> deviceDispenseOrderPage
|
||||
= medicalDeviceDispenseMapper.selectDeviceDispenseOrderPage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
DispenseStatus.IN_PROGRESS.getValue(), DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.PREPARATION.getValue(), DispenseStatus.PREPARED.getValue(), dispenseStatus);
|
||||
deviceDispenseOrderPage.getRecords().forEach(deviceDispenseOrder -> {
|
||||
// 发药状态
|
||||
deviceDispenseOrder.setStatusEnum_enumText(
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, deviceDispenseOrder.getStatusEnum()));
|
||||
// 设置所在表名
|
||||
deviceDispenseOrder.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
});
|
||||
return R.ok(deviceDispenseOrderPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 核对发耗材
|
||||
*
|
||||
* @param dispenseDeviceList 发耗材信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> deviceDispense(List<DispenseItemDto> dispenseDeviceList) {
|
||||
// 配药人检查
|
||||
if (dispenseDeviceList.get(0).getPreparerId() == null
|
||||
|| dispenseDeviceList.get(0).getPreparerId().equals(SecurityUtils.getPractitionerId())) {
|
||||
return R.fail("请选择调配药师");
|
||||
}
|
||||
// 获取发药单id列表
|
||||
List<Long> devDispenseIdList
|
||||
= dispenseDeviceList.stream().map(DispenseItemDto::getDispenseId).collect(Collectors.toList());
|
||||
|
||||
// 获取耗材待发放库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList
|
||||
= returnMedicineMapper.selectInventoryInfoList(devDispenseIdList, null,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
if (unDispenseInventoryList == null || unDispenseInventoryList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap
|
||||
= unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
|
||||
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
|
||||
// 停供库存校验
|
||||
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
|
||||
}
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
// 库存数量
|
||||
BigDecimal inventoryQuantity = BigDecimal.ZERO;
|
||||
// 库存id
|
||||
Long inventoryId = null;
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity
|
||||
= unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
if (PublicationStatus.ACTIVE.getValue().equals(unDispenseInventoryDto.getInventoryStatusEnum())
|
||||
&& unDispenseInventoryDto.getInventoryQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
inventoryQuantity = unDispenseInventoryDto.getInventoryQuantity();
|
||||
inventoryId = unDispenseInventoryDto.getInventoryId();
|
||||
}
|
||||
}
|
||||
if (minQuantity.compareTo(inventoryQuantity) > 0) {
|
||||
// 库存不足
|
||||
return R.fail(inventoryList.get(0).getItemName() + "批号库存不足");
|
||||
} else {
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryId)
|
||||
.setQuantity(inventoryQuantity.subtract(minQuantity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 材料发放信息查询
|
||||
List<DeviceDispense> dispenseList = deviceDispenseService
|
||||
.list(new LambdaQueryWrapper<DeviceDispense>().in(DeviceDispense::getId, devDispenseIdList));
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> tracesNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
if (dispenseList != null) {
|
||||
if (dispenseList.stream().map(DeviceDispense::getStatusEnum)
|
||||
.anyMatch(x -> !x.equals(DispenseStatus.PREPARATION.getValue()))) {
|
||||
throw new ServiceException("耗材发放失败,请检查发耗材单状态");
|
||||
} else {
|
||||
for (DeviceDispense deviceDispense : dispenseList) {
|
||||
// 材料发放状态
|
||||
deviceDispense.setStatusEnum(DispenseStatus.COMPLETED.getValue());
|
||||
// 发药数量
|
||||
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
|
||||
// 发药时间
|
||||
deviceDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 发药人
|
||||
deviceDispense.setPerformerId(SecurityUtils.getPractitionerId());
|
||||
// 配药时间
|
||||
deviceDispense.setPrepareTime(DateUtils.getNowDate());
|
||||
// 配药人
|
||||
deviceDispense.setPreparerId(dispenseDeviceList.get(0).getPreparerId());
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList.add(new SupplyItemDetailDto().setItemId(deviceDispense.getDeviceDefId())
|
||||
.setLotNumber(deviceDispense.getLotNumber())
|
||||
.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
.setDispenseId(deviceDispense.getId()));
|
||||
if (deviceDispense.getTraceNo() == null) {
|
||||
// 根据数量设置追溯码
|
||||
deviceDispense.setTraceNo(String.join(CommonConstants.Common.COMMA, Collections
|
||||
.nCopies(deviceDispense.getQuantity().intValue(), CommonConstants.Common.DEV_TRACE_NO)));
|
||||
} else {
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
String[] traceNoList = deviceDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(deviceDispense.getDeviceDefId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(LocationForm.WAREHOUSE.getValue())
|
||||
// 仓库
|
||||
.setLocationId(deviceDispense.getLocationId())
|
||||
// 产品批号
|
||||
.setLotNumber(deviceDispense.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.OUT.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(deviceDispense.getUnitCode())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.DISPENSE_MEDICATION.getValue());
|
||||
tracesNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 药品发放更新
|
||||
deviceDispenseService.updateBatchById(dispenseList);
|
||||
}
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 库存更新
|
||||
inventoryItemService.updateBatchById(inventoryItemList);
|
||||
// 追溯码管理表数据追加
|
||||
traceNoManageService.saveBatch(tracesNoManageList);
|
||||
// // 返回信息
|
||||
// String returnMsg = null;
|
||||
// List<String> uploadFailedNoList;
|
||||
// // 调用医保商品销售接口
|
||||
// String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH);
|
||||
// // 医保开关
|
||||
// if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
// // 设置进销存参数
|
||||
// List<DeviceDefinition> deviceDefinitions = deviceDefinitionService.listByIds(
|
||||
// supplyItemDetailList.stream().map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
// // 用itemId分组
|
||||
// Map<Long, DeviceDefinition> deviceMap =
|
||||
// deviceDefinitions.stream().collect(Collectors.toMap(DeviceDefinition::getId, Function.identity()));
|
||||
// // 设置库存变更参数
|
||||
// for (SupplyItemDetailDto dto : supplyItemDetailList) {
|
||||
// if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dto.getItemTable())) {
|
||||
// DeviceDefinition dev = deviceMap.get(dto.getItemId());
|
||||
// if (dev != null) {
|
||||
// dto.setItemBusNo(dev.getBusNo()).setPartPercent(dev.getPartPercent()).setRxFlag(dev.getRxFlag())
|
||||
// .setYbNo(dev.getYbNo());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// uploadFailedNoList = westernMedicineDispenseAppService.ybMedicineIntegrated(null, devDispenseIdList);
|
||||
// uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
// YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
// if (uploadFailedNoList != null) {
|
||||
// returnMsg = "3505商品销售上传错误,错误项目编码" + uploadFailedNoList;
|
||||
// } else {
|
||||
// returnMsg = "3505商品销售上传成功";
|
||||
// }
|
||||
// }
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放耗材
|
||||
*
|
||||
* @param chargeItemIds 耗材收费单ids
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> dispenseMedicalConsumables(List<Long> chargeItemIds) {
|
||||
// 查看所属医院
|
||||
String fixmedinsCode
|
||||
= SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
if (!HospitalCodeEnum.CCU.getCode().equals(fixmedinsCode)) {
|
||||
return R.ok();
|
||||
}
|
||||
List<ChargeItem> chargeItemList = chargeItemService.listByIds(chargeItemIds);
|
||||
if (chargeItemList == null || chargeItemList.isEmpty()) {
|
||||
return R.fail("未查询到耗材收费项目信息");
|
||||
}
|
||||
|
||||
// 获取发申请id列表
|
||||
List<Long> devRequestIdList
|
||||
= chargeItemList.stream().map(ChargeItem::getServiceId).collect(Collectors.toList());
|
||||
// 获取耗材发放id列表
|
||||
List<Long> devDispenseIdList = deviceDispenseService
|
||||
.list(new LambdaQueryWrapper<DeviceDispense>().in(DeviceDispense::getDeviceReqId, devRequestIdList))
|
||||
.stream().map(DeviceDispense::getId).collect(Collectors.toList());
|
||||
|
||||
// 获取耗材待发放库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList
|
||||
= returnMedicineMapper.selectInventoryInfoList(devDispenseIdList, null,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
if (unDispenseInventoryList == null || unDispenseInventoryList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap
|
||||
= unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
|
||||
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
|
||||
// 停供库存校验
|
||||
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
|
||||
}
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
// 库存数量
|
||||
BigDecimal inventoryQuantity = BigDecimal.ZERO;
|
||||
// 库存id
|
||||
Long inventoryId = null;
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity
|
||||
= unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
if (PublicationStatus.ACTIVE.getValue().equals(unDispenseInventoryDto.getInventoryStatusEnum())
|
||||
&& unDispenseInventoryDto.getInventoryQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
inventoryQuantity = unDispenseInventoryDto.getInventoryQuantity();
|
||||
inventoryId = unDispenseInventoryDto.getInventoryId();
|
||||
}
|
||||
}
|
||||
if (minQuantity.compareTo(inventoryQuantity) > 0) {
|
||||
// 库存不足
|
||||
return R.fail(inventoryList.get(0).getItemName() + "批号库存不足");
|
||||
} else {
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryId)
|
||||
.setQuantity(inventoryQuantity.subtract(minQuantity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发耗材信息查询
|
||||
List<DeviceDispense> dispenseList = deviceDispenseService
|
||||
.list(new LambdaQueryWrapper<DeviceDispense>().in(DeviceDispense::getId, devDispenseIdList));
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
if (dispenseList != null) {
|
||||
if (dispenseList.stream().map(DeviceDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.COMPLETED.getValue()))) {
|
||||
throw new ServiceException("耗材已发放,请勿重复操作");
|
||||
} else {
|
||||
for (DeviceDispense deviceDispense : dispenseList) {
|
||||
// 耗材发放状态
|
||||
deviceDispense.setStatusEnum(DispenseStatus.COMPLETED.getValue());
|
||||
// 发药数量
|
||||
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
|
||||
// 发药时间
|
||||
deviceDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 发药人(长大写死发耗材人)
|
||||
deviceDispense.setPerformerId(CommonConstants.CCU.DisDeviceDoctor);
|
||||
// 根据数量设置追溯码
|
||||
deviceDispense.setTraceNo(String.join(CommonConstants.Common.COMMA, Collections
|
||||
.nCopies(deviceDispense.getQuantity().intValue(), CommonConstants.Common.DEV_TRACE_NO)));
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList.add(new SupplyItemDetailDto().setItemId(deviceDispense.getDeviceDefId())
|
||||
.setLotNumber(deviceDispense.getLotNumber())
|
||||
.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION));
|
||||
}
|
||||
// 药品发放更新
|
||||
deviceDispenseService.updateBatchById(dispenseList);
|
||||
}
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 库存更新
|
||||
inventoryItemService.updateBatchById(inventoryItemList);
|
||||
// // 返回信息
|
||||
// String returnMsg = null;
|
||||
// // 调用医保商品销售接口
|
||||
// String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH);
|
||||
// List<String> uploadFailedNoList = new ArrayList<>();
|
||||
// // 医保开关
|
||||
// if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
// // 设置进销存参数
|
||||
// List<DeviceDefinition> deviceDefinitions = deviceDefinitionService.listByIds(
|
||||
// supplyItemDetailList.stream().map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
// // 用itemId分组
|
||||
// Map<Long, DeviceDefinition> deviceMap =
|
||||
// deviceDefinitions.stream().collect(Collectors.toMap(DeviceDefinition::getId, Function.identity()));
|
||||
// // 设置库存变更参数
|
||||
// for (SupplyItemDetailDto dto : supplyItemDetailList) {
|
||||
// if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dto.getItemTable())) {
|
||||
// DeviceDefinition dev = deviceMap.get(dto.getItemId());
|
||||
// if (dev != null) {
|
||||
// dto.setItemBusNo(dev.getBusNo()).setPartPercent(dev.getPartPercent()).setRxFlag(dev.getRxFlag())
|
||||
// .setYbNo(dev.getYbNo());
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// uploadFailedNoList = westernMedicineDispenseAppService.ybMedicineIntegrated(null, devDispenseIdList);
|
||||
// uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
// YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
// if (uploadFailedNoList != null) {
|
||||
// returnMsg = "3505商品销售上传错误,错误项目编码" + uploadFailedNoList;
|
||||
// } else {
|
||||
// returnMsg = "3505商品销售上传成功";
|
||||
// }
|
||||
// }
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseDeviceList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> deviceCancel(List<DispenseItemDto> dispenseDeviceList) {
|
||||
// 获取发材料单id列表
|
||||
List<Long> devDispenseIdList
|
||||
= dispenseDeviceList.stream().map(DispenseItemDto::getDispenseId).collect(Collectors.toList());
|
||||
// 材料发放信息查询
|
||||
List<DeviceDispense> dispenseList = deviceDispenseService
|
||||
.list(new LambdaQueryWrapper<DeviceDispense>().in(DeviceDispense::getId, devDispenseIdList));
|
||||
if (dispenseList != null) {
|
||||
for (DeviceDispense medicationDispense : dispenseList) {
|
||||
// 材料发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.DECLINED.getValue());
|
||||
// 未发药原因
|
||||
medicationDispense.setNotPerformedReasonEnum(dispenseDeviceList.get(0).getNotPerformedReasonEnum());
|
||||
}
|
||||
// 药品发放更新
|
||||
deviceDispenseService.updateBatchById(dispenseList);
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,301 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.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.core.domain.entity.SysDictData;
|
||||
import com.core.common.exception.NonCaptureException;
|
||||
import com.core.common.utils.StringUtils;
|
||||
import com.core.common.utils.poi.ExcelUtil;
|
||||
import com.core.system.service.ISysDictTypeService;
|
||||
import com.healthlink.his.administration.domain.Practitioner;
|
||||
import com.healthlink.his.administration.service.IPractitionerService;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.enums.ConditionCode;
|
||||
import com.healthlink.his.common.enums.DispenseStatus;
|
||||
import com.healthlink.his.common.enums.PublicationStatus;
|
||||
import com.healthlink.his.common.enums.RequestStatus;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IMedicationDetailsAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailedAccountPageDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailsInitDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailsSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.MedicationDetailsMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static com.healthlink.his.common.constant.CommonConstants.ExcelOut.*;
|
||||
import static com.healthlink.his.common.constant.CommonConstants.SheetName.SHEET_NAME_DRUG_DETAIL;
|
||||
|
||||
/**
|
||||
* 发药明细 应用实现类
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
@Service
|
||||
public class MedicationDetailsAppServiceImpl implements IMedicationDetailsAppService {
|
||||
|
||||
@Autowired
|
||||
private MedicationDetailsMapper medicationDetailsMapper;
|
||||
|
||||
@Autowired
|
||||
private ISysDictTypeService sysDictTypeService;
|
||||
|
||||
@Autowired
|
||||
private IPractitionerService iPractitionerService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
MedDetailsInitDto initDto = new MedDetailsInitDto();
|
||||
|
||||
// 查询医疗参与者列表
|
||||
List<Practitioner> list = iPractitionerService.getList();
|
||||
initDto.setPractitionerList(list);
|
||||
// 获取状态
|
||||
List<MedDetailsInitDto.statusEnumOption> statusEnumOptions = Stream.of(PublicationStatus.values())
|
||||
.map(status -> new MedDetailsInitDto.statusEnumOption(status.getValue(), status.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 结算状态
|
||||
initDto.setStatusSettlementOptions(statusEnumOptions)
|
||||
// 出院状态
|
||||
.setStatusDischargeOptions(statusEnumOptions);
|
||||
|
||||
return R.ok(initDto);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 门诊人员发药明细表
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊人员发药明细表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getAmbPractitionerDetailPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo,
|
||||
Integer pageSize, String searchKey, HttpServletRequest request) {
|
||||
// 1:住院 2:门诊
|
||||
Integer flg = medDetailsSearchParam.getFlag();
|
||||
medDetailsSearchParam.setFlag(null);
|
||||
// 统计类型 1 3 5 明细
|
||||
Integer statisticalType = medDetailsSearchParam.getInventoryScope();
|
||||
medDetailsSearchParam.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
if (CommonConstants.StatisticalType.DETAIL_DEVICE_TYPE.equals(statisticalType)) {
|
||||
medDetailsSearchParam.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
medDetailsSearchParam.setInventoryScope(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<MedDetailsSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(medDetailsSearchParam,
|
||||
searchKey, new HashSet<>(Arrays.asList("patient_name", "medication_name", "bus_no", "py_str")), request);
|
||||
|
||||
Page<MedDetailedAccountPageDto> medDetailsPage = medicationDetailsMapper.selectAmbPractitionerDetailPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, DispenseStatus.COMPLETED.getValue(),
|
||||
RequestStatus.COMPLETED.getValue(), DispenseStatus.REFUNDED.getValue(), statisticalType, flg,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||
ConditionCode.LOT_NUMBER_COST.getCode());
|
||||
|
||||
return R.ok(medDetailsPage);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 发药明细导出
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param response 响应数据
|
||||
* @param request 请求数据
|
||||
*
|
||||
*/
|
||||
@Override
|
||||
public void makeExcelFile(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletResponse response, HttpServletRequest request) {
|
||||
R<?> result = this.getAmbPractitionerDetailPage(medDetailsSearchParam, 1, 10000, searchKey, request);
|
||||
if (result != null && result.getData() != null) {
|
||||
// 先获取Page对象,再获取其中的记录列表
|
||||
Page<MedDetailedAccountPageDto> pageData = (Page<MedDetailedAccountPageDto>) result.getData();
|
||||
List<MedDetailedAccountPageDto> dataList = pageData.getRecords();
|
||||
// 判断项目类别
|
||||
try {
|
||||
// 获取字典数据
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
String unitCode = medDetailedAccountPageDto.getUnitCode();
|
||||
// 添加空值检查
|
||||
if (unitCode != null && sysDictTypeService != null) {
|
||||
// 缓存字典数据,避免重复查询
|
||||
List<SysDictData> unitCodelist
|
||||
= sysDictTypeService.selectDictDataByType(CommonConstants.FieldName.UnitCode);
|
||||
if (unitCodelist != null) {
|
||||
for (SysDictData dictData : unitCodelist) {
|
||||
if (dictData != null && dictData.getDictValue() != null
|
||||
&& dictData.getDictValue().equals(unitCode)) {
|
||||
// 设置字典数据
|
||||
medDetailedAccountPageDto.setUnitCode_dictText(dictData.getDictLabel());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将发药数量与单位拼接
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
String unitCode_dictText = medDetailedAccountPageDto.getUnitCode_dictText();
|
||||
Integer dispenseQuantity = medDetailedAccountPageDto.getDispenseQuantity();
|
||||
// 空值处理:单位为空时只显示数量
|
||||
String quantityStr = dispenseQuantity != null ? dispenseQuantity.toString() : "0";
|
||||
if (StringUtils.isNotBlank(unitCode_dictText)) {
|
||||
medDetailedAccountPageDto.setDispenseQuantityStr(quantityStr + unitCode_dictText);
|
||||
} else {
|
||||
medDetailedAccountPageDto.setDispenseQuantityStr(quantityStr);
|
||||
}
|
||||
}
|
||||
|
||||
// 将退药数量与单位拼接
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
String unitCode_dictText = medDetailedAccountPageDto.getUnitCode_dictText();
|
||||
Integer refundQuantity = medDetailedAccountPageDto.getRefundQuantity();
|
||||
// 空值处理:数量为空时默认为0
|
||||
String quantityStr = refundQuantity != null ? refundQuantity.toString() : CONSTANTZERO;
|
||||
// 单位为空时只显示数量
|
||||
if (StringUtils.isNotBlank(unitCode_dictText)) {
|
||||
medDetailedAccountPageDto.setRefundQuantityStr(quantityStr + unitCode_dictText);
|
||||
} else {
|
||||
medDetailedAccountPageDto.setRefundQuantityStr(quantityStr);
|
||||
}
|
||||
}
|
||||
|
||||
// 将退药金额保留两位小数
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
// 获取退药金额
|
||||
BigDecimal refundPrice = medDetailedAccountPageDto.getRefundPrice();
|
||||
// 为空导出0.00
|
||||
if (refundPrice == null) {
|
||||
medDetailedAccountPageDto.setRefundPriceStr(CONSTANT_ZERO_DML);
|
||||
// 等于零导出0.00
|
||||
} else if (refundPrice.signum() == 0) {
|
||||
medDetailedAccountPageDto.setRefundPriceStr(CONSTANT_ZERO_DML);
|
||||
// 不为零导出退药金额且保留两位小数
|
||||
} else {
|
||||
refundPrice = refundPrice.setScale(2, RoundingMode.HALF_UP);
|
||||
medDetailedAccountPageDto.setRefundPriceStr(refundPrice.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 发药金额
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
// 获取发药金额
|
||||
BigDecimal dispensePrice = medDetailedAccountPageDto.getDispensePrice();
|
||||
// 为空导出0.00
|
||||
if (dispensePrice == null) {
|
||||
medDetailedAccountPageDto.setDispensePriceStr(CONSTANT_ZERO_DML);
|
||||
// 等于零导出0.00
|
||||
} else if (dispensePrice.signum() == 0) {
|
||||
medDetailedAccountPageDto.setDispensePriceStr(CONSTANT_ZERO_DML);
|
||||
// 不为零导出金额且保留两位小数
|
||||
} else {
|
||||
dispensePrice = dispensePrice.setScale(2, RoundingMode.HALF_UP);
|
||||
medDetailedAccountPageDto.setDispensePriceStr(dispensePrice.toString());
|
||||
}
|
||||
|
||||
}
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
BigDecimal costPrice = medDetailedAccountPageDto.getCostPrice();
|
||||
if (costPrice == null) {
|
||||
medDetailedAccountPageDto.setCostPriceStr(CONSTANT_ZERO_DML);
|
||||
} else if (costPrice.signum() == 0) {
|
||||
medDetailedAccountPageDto.setCostPriceStr(CONSTANT_ZERO_DML);
|
||||
} else {
|
||||
costPrice = costPrice.setScale(2, RoundingMode.HALF_UP);
|
||||
medDetailedAccountPageDto.setCostPriceStr(costPrice.toString());
|
||||
}
|
||||
}
|
||||
// 添加项目类别
|
||||
for (MedDetailedAccountPageDto medDetailedAccountPageDto : dataList) {
|
||||
// 获取项目类别值
|
||||
String itemTable = medDetailedAccountPageDto.getItemTable();
|
||||
// 类别不为空且在med_medication_definition中导出药材
|
||||
if (itemTable != null) {
|
||||
if (itemTable.equals(CommonConstants.TableName.MED_MEDICATION_DEFINITION)) {
|
||||
medDetailedAccountPageDto.setItemTable(MEDICATION);
|
||||
}
|
||||
// 类别不为空且在adm_device_definition中导出耗材
|
||||
if (itemTable.equals(CommonConstants.TableName.ADM_DEVICE_DEFINITION)) {
|
||||
medDetailedAccountPageDto.setItemTable(DEVICE);
|
||||
}
|
||||
// 类别为空则导出未知类型
|
||||
} else {
|
||||
medDetailedAccountPageDto.setItemTable(UNKONWN_TYPE);
|
||||
}
|
||||
}
|
||||
|
||||
ExcelUtil<MedDetailedAccountPageDto> util = new ExcelUtil<>(MedDetailedAccountPageDto.class);
|
||||
util.exportExcel(response, dataList, SHEET_NAME_DRUG_DETAIL);
|
||||
} catch (Exception e) {
|
||||
throw new NonCaptureException(StringUtils.format("导出excel失败"), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 门诊发药明细流水账
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊发药明细流水账
|
||||
*/
|
||||
@Override
|
||||
public R<?> getAmbMedicationDispenseDetailPage(MedDetailsSearchParam medDetailsSearchParam, Integer pageNo,
|
||||
Integer pageSize, String searchKey, HttpServletRequest request) {
|
||||
|
||||
// 1:住院 2:门诊
|
||||
Integer flg = medDetailsSearchParam.getFlag();
|
||||
medDetailsSearchParam.setFlag(null);
|
||||
// 统计类型 2 4 6
|
||||
Integer statisticalType = medDetailsSearchParam.getInventoryScope();
|
||||
medDetailsSearchParam.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
if (CommonConstants.StatisticalType.ACCOUNT_DEVICE_TYPE.equals(statisticalType)) {
|
||||
medDetailsSearchParam.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
medDetailsSearchParam.setInventoryScope(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<MedDetailsSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(medDetailsSearchParam,
|
||||
searchKey, new HashSet<>(Arrays.asList("patient_name", "medication_name", "bus_no", "py_str")), request);
|
||||
|
||||
Page<MedDetailedAccountPageDto> medDetailsPage = medicationDetailsMapper.selectAmbPractitionerDetailPage(
|
||||
new Page<>(pageNo, pageSize), queryWrapper, DispenseStatus.COMPLETED.getValue(),
|
||||
RequestStatus.COMPLETED.getValue(), DispenseStatus.REFUNDED.getValue(), statisticalType, flg,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||
ConditionCode.LOT_NUMBER_COST.getCode());
|
||||
|
||||
return R.ok(medDetailsPage);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.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.healthlink.his.common.enums.DispenseStatus;
|
||||
import com.healthlink.his.common.enums.EncounterClass;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IPendingMedicationDetailsAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationPageDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.PendingMedicationDetailsMapper;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
|
||||
/**
|
||||
* 待发药明细 应用实现类
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
@Service
|
||||
public class PendingMedicationDetailsAppServiceImpl implements IPendingMedicationDetailsAppService {
|
||||
|
||||
@Autowired
|
||||
private PendingMedicationDetailsMapper pendingMedicationDetailsMapper;
|
||||
|
||||
/**
|
||||
* 分页查询待发药明细
|
||||
*
|
||||
* @param pendingMedicationSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 待发药明细
|
||||
*/
|
||||
@Override
|
||||
public R<?> getPage(PendingMedicationSearchParam pendingMedicationSearchParam, Integer pageNo, Integer pageSize,
|
||||
String searchKey, HttpServletRequest request) {
|
||||
|
||||
// 构建查询条件
|
||||
QueryWrapper<PendingMedicationSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(
|
||||
pendingMedicationSearchParam, searchKey, new HashSet<>(Arrays.asList("medicine_name", "medicine_no", "py_str")), request);
|
||||
|
||||
// 查询待发药明细列表(包含待配药、待发药、已配药三种状态,与门诊发药界面一致)
|
||||
Page<PendingMedicationPageDto> pendingMedicationPage = pendingMedicationDetailsMapper
|
||||
.selectPendingMedicationDetailsPage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
DispenseStatus.IN_PROGRESS.getValue(), DispenseStatus.PREPARATION.getValue(),
|
||||
DispenseStatus.PREPARED.getValue(), DispenseStatus.SUMMARIZED.getValue(),
|
||||
EncounterClass.AMB.getValue(), EncounterClass.IMP.getValue());
|
||||
|
||||
pendingMedicationPage.getRecords().forEach(e -> {
|
||||
// 发药类型
|
||||
e.setDispenseEnum_enumText(EnumUtils.getInfoByValue(EncounterClass.class, e.getDispenseEnum()));
|
||||
});
|
||||
|
||||
return R.ok(pendingMedicationPage);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,682 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice.impl;
|
||||
|
||||
import tools.jackson.databind.JsonNode;
|
||||
import tools.jackson.databind.node.ArrayNode;
|
||||
import tools.jackson.databind.node.ObjectNode;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
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.exception.ServiceException;
|
||||
import com.core.common.utils.*;
|
||||
import com.healthlink.his.administration.domain.*;
|
||||
import com.healthlink.his.administration.service.*;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.yb.enums.YbInvChgType;
|
||||
import com.healthlink.his.yb.enums.YbMdtrtCertType;
|
||||
import com.healthlink.his.yb.enums.YbRxFlag;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.financial.domain.Contract;
|
||||
import com.healthlink.his.financial.domain.PaymentReconciliation;
|
||||
import com.healthlink.his.financial.service.IContractService;
|
||||
import com.healthlink.his.financial.service.IPaymentReconciliationService;
|
||||
import com.healthlink.his.medication.domain.MedicationDefinition;
|
||||
import com.healthlink.his.medication.domain.MedicationDispense;
|
||||
import com.healthlink.his.medication.domain.MedicationRequest;
|
||||
import com.healthlink.his.medication.service.IMedicationDefinitionService;
|
||||
import com.healthlink.his.medication.service.IMedicationDispenseService;
|
||||
import com.healthlink.his.medication.service.IMedicationRequestService;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IReturnMedicineAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.*;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.ReturnMedicineMapper;
|
||||
import com.healthlink.his.workflow.domain.DeviceDispense;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.service.IDeviceDispenseService;
|
||||
import com.healthlink.his.workflow.service.IDeviceRequestService;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import com.healthlink.his.yb.domain.ClinicSettle;
|
||||
import com.healthlink.his.yb.dto.Medical3506Param;
|
||||
import com.healthlink.his.yb.dto.MedicalInventory3511Param;
|
||||
import com.healthlink.his.yb.service.IClinicSettleService;
|
||||
import com.healthlink.his.yb.service.IYbManager;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 退药管理 应用实现类
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
@Service
|
||||
public class ReturnMedicineAppServiceImpl implements IReturnMedicineAppService {
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private IOrganizationService iOrganizationService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService iInventoryItemService;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private IMedicationRequestService medicationRequestService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDispenseService deviceDispenseService;
|
||||
|
||||
@Resource
|
||||
private IDeviceRequestService deviceRequestService;
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private IYbManager ybService;
|
||||
|
||||
@Resource
|
||||
private IChargeItemService iChargeItemService;
|
||||
|
||||
@Resource
|
||||
private IPaymentReconciliationService iPaymentReconciliationService;
|
||||
|
||||
@Resource
|
||||
private IContractService iContractService;
|
||||
|
||||
@Resource
|
||||
private IClinicSettleService clinicSettleService;
|
||||
|
||||
@Resource
|
||||
private IEncounterDiagnosisService encounterDiagnosisService;
|
||||
|
||||
@Resource
|
||||
private IAccountService accountService;
|
||||
|
||||
@Resource
|
||||
private IDeviceDefinitionService deviceDefinitionService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDefinitionService medicationDefinitionService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
ReturnMedicineInitDto initDto = new ReturnMedicineInitDto();
|
||||
|
||||
// 获取科室下拉选列表
|
||||
List<Organization> organizationList
|
||||
= iOrganizationService.getList(OrganizationType.DEPARTMENT.getValue(), String.valueOf(OrganizationClass.CLINIC.getValue()));
|
||||
List<ReturnMedicineInitDto.DepartmentOption> organizationOptions = organizationList.stream().map(
|
||||
organization -> new ReturnMedicineInitDto.DepartmentOption(organization.getId(), organization.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 发药状态
|
||||
List<ReturnMedicineInitDto.RefundStatusOption> refundStatusOptions = new ArrayList<>();
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.PENDING_REFUND.getValue(),
|
||||
DispenseStatus.PENDING_REFUND.getInfo()));
|
||||
refundStatusOptions.add(new ReturnMedicineInitDto.RefundStatusOption(DispenseStatus.REFUNDED.getValue(),
|
||||
DispenseStatus.REFUNDED.getInfo()));
|
||||
initDto.setDepartmentOptions(organizationOptions).setRefundStatusOptions(refundStatusOptions);
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto, String searchKey, Integer pageNo,
|
||||
Integer pageSize, HttpServletRequest request) {
|
||||
// 构建查询条件
|
||||
QueryWrapper<EncounterInfoDto> queryWrapper = HisQueryUtils.buildQueryWrapper(encounterInfoDto, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.PatientName, CommonConstants.FieldName.IdCard,
|
||||
CommonConstants.FieldName.PatientPyStr, CommonConstants.FieldName.PatientWbStr)),
|
||||
request);
|
||||
// 查询退药患者分页列表
|
||||
Page<EncounterInfoDto> encounterInfoPage
|
||||
= returnMedicineMapper.selectEncounterInfoListPage(new Page<>(pageNo, pageSize), queryWrapper);
|
||||
encounterInfoPage.getRecords().forEach(encounterInfo -> {
|
||||
// 性别
|
||||
encounterInfo.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, encounterInfo.getGenderEnum()));
|
||||
// 年龄
|
||||
encounterInfo.setAge(AgeCalculatorUtil.getAge(encounterInfo.getBirthDate()));
|
||||
// 退药状态
|
||||
encounterInfo
|
||||
.setRefundEnum_enumText(EnumUtils.getInfoByValue(RequestStatus.class, encounterInfo.getRefundEnum()));
|
||||
});
|
||||
return R.ok(encounterInfoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @return 退药信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> getReturnMedicineInfo(Long encounterId, Integer refundStatus) {
|
||||
// 获取退药信息
|
||||
List<ReturnMedicineInfoDto> returnMedicineInfoList = returnMedicineMapper.selectReturnMedicineInfo(encounterId,
|
||||
CommonConstants.TableName.WOR_DEVICE_REQUEST, CommonConstants.TableName.MED_MEDICATION_REQUEST,
|
||||
ItemType.MEDICINE.getValue(), ItemType.DEVICE.getValue(), refundStatus,
|
||||
DispenseStatus.PENDING_REFUND.getValue(), DispenseStatus.REFUNDED.getValue());
|
||||
returnMedicineInfoList.forEach(returnMedicineInfoDto -> {
|
||||
// 退药状态
|
||||
returnMedicineInfoDto.setRefundEnum_enumText(
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, returnMedicineInfoDto.getRefundEnum()));
|
||||
// 退药请求状态
|
||||
returnMedicineInfoDto.setReqStatus_enumText(
|
||||
EnumUtils.getInfoByValue(RequestStatus.class, returnMedicineInfoDto.getReqStatus()));
|
||||
});
|
||||
return R.ok(returnMedicineInfoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> medicineReturn(List<ReturnMedicineDto> medicineReturnList) {
|
||||
if (medicineReturnList == null || medicineReturnList.isEmpty()) {
|
||||
return R.ok();
|
||||
}
|
||||
// 分别处理退药与退耗材的请求
|
||||
List<ReturnMedicineDto> returnMedicineList = new ArrayList<>();
|
||||
List<ReturnMedicineDto> returnDeviceList = new ArrayList<>();
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> traceNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
|
||||
medicineReturnList.forEach(item -> {
|
||||
switch (item.getTableName()) {
|
||||
case CommonConstants.TableName.MED_MEDICATION_REQUEST ->
|
||||
returnMedicineList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
case CommonConstants.TableName.WOR_DEVICE_REQUEST ->
|
||||
returnDeviceList
|
||||
.add(new ReturnMedicineDto().setDispenseId(item.getDispenseId()).setRequestId(item.getRequestId()));
|
||||
}
|
||||
});
|
||||
// 进销存参数
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
|
||||
// 处理退药
|
||||
// 获取药品退药id列表
|
||||
List<Long> medReturnIdList = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 获取药品退药id列表
|
||||
medReturnIdList
|
||||
= returnMedicineList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取药品退药请求id列表
|
||||
List<Long> medRequestIdList
|
||||
= returnMedicineList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
|
||||
if (medReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
if (medRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 药品退药信息查询
|
||||
List<MedicationDispense> refundMedList = medicationDispenseService.listByIds(medReturnIdList);
|
||||
// 药品退药请求查询
|
||||
List<MedicationRequest> refundMedRequestList = medicationRequestService.listByIds(medRequestIdList);
|
||||
if (refundMedList == null || refundMedList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的药品");
|
||||
}
|
||||
// 重复退药校验
|
||||
if (refundMedList.stream().map(MedicationDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("药品已退药,请勿重复退药");
|
||||
}
|
||||
|
||||
// 更新退药单
|
||||
for (MedicationDispense medicationDispense : refundMedList) {
|
||||
// 退药状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 退药数量
|
||||
medicationDispense.setDispenseQuantity(medicationDispense.getQuantity());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
// 退药时间
|
||||
medicationDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药人
|
||||
medicationDispense.setPractitionerId(SecurityUtils.getPractitionerId());
|
||||
|
||||
// 设置库存变更参数
|
||||
SupplyItemDetailDto supplyItemDetailDto = new SupplyItemDetailDto();
|
||||
for (MedicationRequest medicationRequest : refundMedRequestList) {
|
||||
// 根据退药id查询退药请求id(用于医保关联)
|
||||
if (medicationDispense.getMedReqId().equals(medicationRequest.getId())) {
|
||||
supplyItemDetailDto.setRequestId(medicationRequest.getRefundMedicineId());
|
||||
}
|
||||
}
|
||||
supplyItemDetailDto.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setItemId(medicationDispense.getMedicationId()).setLotNumber(medicationDispense.getLotNumber());
|
||||
supplyItemDetailList.add(supplyItemDetailDto);
|
||||
|
||||
// 追溯码表相关处理
|
||||
if (medicationDispense.getTraceNo() != null) {
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
String[] traceNoList = medicationDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(medicationDispense.getMedicationId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(null)
|
||||
// 仓库
|
||||
.setLocationId(medicationDispense.getLocationId())
|
||||
// 仓位
|
||||
.setLocationStoreId(null)
|
||||
// 产品批号
|
||||
.setLotNumber(medicationDispense.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.IN.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(medicationDispense.getUnitCode())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.RETURN_MEDICATION.getValue());
|
||||
traceNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 退药更新
|
||||
medicationDispenseService.updateBatchById(refundMedList);
|
||||
// 药品退药请求状态变更(待退药→已完成)
|
||||
medicationRequestService.updateCompletedStatusBatch(medRequestIdList, null, null);
|
||||
}
|
||||
|
||||
// 处理退耗材
|
||||
// 获取退耗材id列表
|
||||
List<Long> devReturnIdList = new ArrayList<>();
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
// 获取退耗材id列表
|
||||
devReturnIdList
|
||||
= returnDeviceList.stream().map(ReturnMedicineDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取退耗材请求id列表
|
||||
List<Long> devRequestIdList
|
||||
= returnDeviceList.stream().map(ReturnMedicineDto::getRequestId).collect(Collectors.toList());
|
||||
if (devReturnIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
if (devRequestIdList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 退耗材信息查询
|
||||
List<DeviceDispense> refundDevList = deviceDispenseService.listByIds(devReturnIdList);
|
||||
if (refundDevList == null || refundDevList.isEmpty()) {
|
||||
throw new ServiceException("请选择要退的耗材");
|
||||
}
|
||||
// 重复退耗材校验
|
||||
if (refundDevList.stream().map(DeviceDispense::getStatusEnum)
|
||||
.anyMatch(x -> x.equals(DispenseStatus.REFUNDED.getValue()))) {
|
||||
throw new ServiceException("耗材已退,请勿重复操作");
|
||||
}
|
||||
// 更新退耗材单状态
|
||||
for (DeviceDispense deviceDispense : refundDevList) {
|
||||
// 退药时间
|
||||
deviceDispense.setDispenseTime(DateUtils.getNowDate());
|
||||
// 退药数量
|
||||
deviceDispense.setDispenseQuantity(deviceDispense.getQuantity());
|
||||
// 退药状态
|
||||
deviceDispense.setStatusEnum(DispenseStatus.REFUNDED.getValue());
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList
|
||||
.add(new SupplyItemDetailDto().setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
.setItemId(deviceDispense.getDeviceDefId()).setLotNumber(deviceDispense.getLotNumber()));
|
||||
// // 使用逗号分割追溯码并转换为List
|
||||
// String[] traceNoList = deviceDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
// for (String item : traceNoList) {
|
||||
// traceNoManage = new TraceNoManage();
|
||||
// // 追溯码处理
|
||||
// traceNoManage.setItemTable(CommonConstants.TableName.ADM_DEVICE_DEFINITION)
|
||||
// // 项目id
|
||||
// .setItemId(deviceDispense.getDeviceDefId())
|
||||
// // 仓库类型
|
||||
// .setLocationTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
// // 仓库
|
||||
// .setLocationId(deviceDispense.getLocationId())
|
||||
// // 产品批号
|
||||
// .setLotNumber(deviceDispense.getLotNumber())
|
||||
// // 追溯码
|
||||
// .setTraceNo(item)
|
||||
// // 追溯码状态
|
||||
// .setStatusEnum(TraceNoStatus.IN.getValue())
|
||||
// // 追溯码单位
|
||||
// .setUnitCode(deviceDispense.getUnitCode())
|
||||
// // 操作类型
|
||||
// .setOperationType(SupplyType.RETURN_MEDICATION.getValue());
|
||||
// traceNoManageList.add(traceNoManage);
|
||||
// }
|
||||
}
|
||||
deviceDispenseService.updateBatchById(refundDevList);
|
||||
// 药品退药请求状态变更(待退药→已完成)
|
||||
deviceRequestService.updateCompletedStatusBatch(devRequestIdList);
|
||||
}
|
||||
|
||||
// 追溯码管理表数据追加
|
||||
traceNoManageService.saveBatch(traceNoManageList);
|
||||
|
||||
// 处理退库存
|
||||
// 获取库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList
|
||||
= returnMedicineMapper.selectInventoryInfoList(devReturnIdList, medReturnIdList,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap
|
||||
= unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity
|
||||
= unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
}
|
||||
// 理论上不出bug的情况下以项目id,批号,仓库进行分组处理库存一定唯一所以get(0)
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryList.get(0).getInventoryId())
|
||||
.setQuantity(inventoryList.get(0).getInventoryQuantity().add(minQuantity)));
|
||||
}
|
||||
}
|
||||
// 库存更新
|
||||
iInventoryItemService.updateBatchById(inventoryItemList);
|
||||
} else {
|
||||
throw new ServiceException("请检查库存信息");
|
||||
}
|
||||
|
||||
// 处理退药医保
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
List<String> uploadFailedNoList;
|
||||
// 调用医保商品销售退货接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
List<DeviceDefinition> deviceDefinitions = new ArrayList<>();
|
||||
List<MedicationDefinition> medicationDefinitions = new ArrayList<>();
|
||||
if (!returnMedicineList.isEmpty()) {
|
||||
// 设置进销存参数
|
||||
medicationDefinitions = medicationDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.MED_MEDICATION_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
if (!returnDeviceList.isEmpty()) {
|
||||
deviceDefinitions = deviceDefinitionService.listByIds(supplyItemDetailList.stream()
|
||||
.filter(x -> x.getItemTable().equals(CommonConstants.TableName.ADM_DEVICE_DEFINITION))
|
||||
.map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
}
|
||||
|
||||
// 创建映射表,添加空集合保护
|
||||
Map<Long, MedicationDefinition> medicationMap
|
||||
= medicationDefinitions != null ? medicationDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(MedicationDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
Map<Long, DeviceDefinition> deviceMap
|
||||
= deviceDefinitions != null ? deviceDefinitions.stream().filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(DeviceDefinition::getId, Function.identity())) : new HashMap<>();
|
||||
|
||||
// 设置库存变更参数,添加完整判空
|
||||
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
|
||||
if (supplyItemDetailDto == null) {
|
||||
continue;
|
||||
}
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
MedicationDefinition med = medicationMap.get(supplyItemDetailDto.getItemId());
|
||||
if (med != null) {
|
||||
supplyItemDetailDto.setItemBusNo(med.getBusNo()).setPartPercent(med.getPartPercent())
|
||||
.setRxFlag(med.getRxFlag()).setYbNo(med.getYbNo());
|
||||
}
|
||||
}
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(supplyItemDetailDto.getItemTable())) {
|
||||
if (supplyItemDetailDto.getItemId() != null) {
|
||||
DeviceDefinition dev = deviceMap.get(supplyItemDetailDto.getItemId());
|
||||
if (dev != null) {
|
||||
supplyItemDetailDto.setItemBusNo(dev.getBusNo()).setPartPercent(dev.getPartPercent())
|
||||
.setRxFlag(dev.getRxFlag()).setYbNo(dev.getYbNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
uploadFailedNoList = this.ybReturnIntegrated(medReturnIdList, null);
|
||||
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = "3506商品销售退货上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3506商品销售退货上传成功";
|
||||
}
|
||||
}
|
||||
// 返回退药成功信息
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"退药"}));
|
||||
}
|
||||
|
||||
/**
|
||||
* 医保退药相关进销存接口
|
||||
*
|
||||
* @param dispenseMedIdList 退药id列表
|
||||
* @param dispenseDevIdList 退耗材id列表
|
||||
* @return 上传失败的编号集合
|
||||
*/
|
||||
public List<String> ybReturnIntegrated(List<Long> dispenseMedIdList, List<Long> dispenseDevIdList) {
|
||||
List<String> uploadFailedNoList = new ArrayList<>();
|
||||
R<?> result;
|
||||
if (!dispenseMedIdList.isEmpty() || !dispenseDevIdList.isEmpty()) {
|
||||
// 查询退药项目相关信息
|
||||
List<DispenseInventoryDto> dispenseInventoryList = returnMedicineMapper.selectReturnItemDetail(
|
||||
dispenseDevIdList, dispenseMedIdList, CommonConstants.TableName.MED_MEDICATION_DEFINITION,
|
||||
CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
for (DispenseInventoryDto dispenseInventoryDto : dispenseInventoryList) {
|
||||
if (dispenseInventoryDto.getYbNo() == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<Medical3506Param, Contract> medical3506Pair = getMedical3506Param(dispenseInventoryDto);
|
||||
// 如果自费则自动取省医保
|
||||
Contract contract = medical3506Pair.getRight();
|
||||
if (contract != null) {
|
||||
if (CommonConstants.BusinessName.DEFAULT_CONTRACT_NO
|
||||
.equals(medical3506Pair.getRight().getBusNo())) {
|
||||
contract = null;
|
||||
}
|
||||
}
|
||||
result = ybService.cancelMerchandise(medical3506Pair.getLeft(), contract);
|
||||
if (result.getCode() != 200) {
|
||||
uploadFailedNoList.add(dispenseInventoryDto.getDispenseNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
return uploadFailedNoList;
|
||||
}
|
||||
|
||||
private Pair<Medical3506Param, Contract> getMedical3506Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
Medical3506Param medical3506Param = new Medical3506Param();
|
||||
ChargeItem chargeItem = null;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
// 查询费用结算信息
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.MED_MEDICATION_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
chargeItem = iChargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_DEVICE_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getRefundId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
}
|
||||
if (chargeItem == null) {
|
||||
throw new ServiceException("未查询到收费项");
|
||||
}
|
||||
// 查询就诊诊断信息
|
||||
EncounterDiagnosis encounterDiagnosis = encounterDiagnosisService.getById(chargeItem.getEncounterDiagnosisId());
|
||||
if (encounterDiagnosis == null) {
|
||||
throw new ServiceException("未查找到就诊诊断信息");
|
||||
}
|
||||
// 查询付款信息
|
||||
PaymentReconciliation paymentReconciliation
|
||||
= iPaymentReconciliationService.getOne(new LambdaQueryWrapper<PaymentReconciliation>()
|
||||
.eq(PaymentReconciliation::getEncounterId, chargeItem.getEncounterId())
|
||||
.like(PaymentReconciliation::getChargeItemIds, chargeItem.getId())
|
||||
.eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue())
|
||||
.eq(PaymentReconciliation::getPatientId, chargeItem.getPatientId())
|
||||
.eq(PaymentReconciliation::getPaymentEnum, PaymentType.PAY.getValue()));
|
||||
if (paymentReconciliation == null) {
|
||||
throw new ServiceException("未查询到收费");
|
||||
}
|
||||
|
||||
// 查询账户信息
|
||||
Account account = accountService
|
||||
.getOne(new LambdaQueryWrapper<Account>().eq(Account::getEncounterId, chargeItem.getEncounterId())
|
||||
.eq(Account::getEncounterFlag, Whether.YES.getValue()));
|
||||
if (account == null) {
|
||||
throw new ServiceException("未查询到账户");
|
||||
}
|
||||
// 查询合同实体
|
||||
Contract contract
|
||||
= iContractService.getOne(new LambdaQueryWrapper<Contract>().eq(Contract::getBusNo, account.getContractNo()));
|
||||
if (contract == null) {
|
||||
throw new ServiceException("未查询到合同信息");
|
||||
}
|
||||
YbMdtrtCertType mdtrtCertType;
|
||||
if (AccountType.PERSONAL_CASH_ACCOUNT.getCode().equals(account.getTypeCode())) {
|
||||
mdtrtCertType = YbMdtrtCertType.MDTRT_CERT_TYPE02;
|
||||
} else {
|
||||
mdtrtCertType = YbMdtrtCertType.getByValue(account.getTypeCode());// 2025/05/28 该值存01/02/03
|
||||
}
|
||||
if (mdtrtCertType == null) {
|
||||
throw new ServiceException("未查询到电子凭证");
|
||||
}
|
||||
// 查询就诊id
|
||||
if (contract.getCategoryEnum().equals(Category.SELF.getValue())
|
||||
|| contract.getCategoryEnum().equals(Category.PUBLIC.getValue())) {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
} else {
|
||||
ClinicSettle clinicSettle = clinicSettleService.getOne(new LambdaQueryWrapper<ClinicSettle>()
|
||||
.in(ClinicSettle::getSetlId, List.of(paymentReconciliation.getYbSettleIds()))
|
||||
.eq(ClinicSettle::getMedType, encounterDiagnosis.getMedTypeCode()).last(" LIMIT 1"));
|
||||
if (clinicSettle != null) {
|
||||
medical3506Param.setMdtrtSn(clinicSettle.getMdtrtId());
|
||||
} else {
|
||||
medical3506Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo());
|
||||
}
|
||||
}
|
||||
// // 查询发票信息
|
||||
// Invoice invoice = iInvoiceService.getById(paymentReconciliation.getInvoiceId());
|
||||
// if (invoice == null) {
|
||||
// throw new ServiceException("未查询到发票信息");
|
||||
// }
|
||||
// 转换为JSON
|
||||
ArrayNode medicalTraceNo = new tools.jackson.databind.ObjectMapper().createArrayNode();
|
||||
// 获取追溯码信息
|
||||
if (dispenseInventoryDto.getTraceNo() != null) {
|
||||
List<String> traceNoList
|
||||
= Arrays.stream(dispenseInventoryDto.getTraceNo().split(CommonConstants.Common.COMMA)).map(String::trim)
|
||||
.filter(s -> !s.isEmpty()).toList();
|
||||
for (String traceNo : traceNoList) {
|
||||
ObjectNode traceNoMap = new tools.jackson.databind.ObjectMapper().createObjectNode();
|
||||
traceNoMap.put("drug_trac_codg", traceNo);
|
||||
medicalTraceNo.add(traceNoMap);
|
||||
}
|
||||
}
|
||||
medical3506Param.setMedListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getRefundId().toString())
|
||||
.setFixmedinsHilistId(dispenseInventoryDto.getItemNo())
|
||||
.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setPsnCertType(mdtrtCertType.getValue()).setManuLotnum(dispenseInventoryDto.getLotNumber())
|
||||
.setManuDate(dispenseInventoryDto.getProductionDate())
|
||||
.setSelRetnCnt(new BigDecimal(dispenseInventoryDto.getDispenseQuantity().toString()))
|
||||
.setSelRetnTime(dispenseInventoryDto.getDispenseTime()).setExpyEnd(dispenseInventoryDto.getExpirationDate())
|
||||
.setDrugtracinfo(medicalTraceNo).setCertno(dispenseInventoryDto.getIdCard());
|
||||
// 查看所属医院
|
||||
String fixmedinsCode
|
||||
= SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
if (dispenseInventoryDto.getPreparerName() == null && HospitalCodeEnum.CCU.getCode().equals(fixmedinsCode)) {
|
||||
medical3506Param.setSelRetnOpterName(CommonConstants.CCU.DisDeviceDoctorName);
|
||||
} else {
|
||||
medical3506Param.setSelRetnOpterName(dispenseInventoryDto.getPreparerName());
|
||||
}
|
||||
if (dispenseInventoryDto.getInventoryUnitCode().equals(dispenseInventoryDto.getDispenseUnitCode())) {
|
||||
medical3506Param.setTrdnFlag(Whether.YES.getCode());
|
||||
} else {
|
||||
medical3506Param.setTrdnFlag(Whether.NO.getCode());
|
||||
}
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3506Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3506Param.setFixmedinsHilistName(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
return Pair.of(medical3506Param, contract);
|
||||
}
|
||||
|
||||
private MedicalInventory3511Param getMedical3511Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
MedicalInventory3511Param medicalInventory3511Param = new MedicalInventory3511Param();
|
||||
|
||||
String fixmedinsCode
|
||||
= SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
// TODO
|
||||
medicalInventory3511Param.setFixmedinsCode(fixmedinsCode).setMedinsListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getLotNumber()).setBegndate(dispenseInventoryDto.getDispenseTime())
|
||||
.setEnddate(dispenseInventoryDto.getDispenseTime());
|
||||
|
||||
return medicalInventory3511Param;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,349 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.AssignSeqUtil;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.core.system.service.ISysDictTypeService;
|
||||
import com.healthlink.his.administration.domain.TraceNoManage;
|
||||
import com.healthlink.his.administration.service.IOrganizationService;
|
||||
import com.healthlink.his.administration.service.ITraceNoManageService;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.yb.enums.YbInvChgType;
|
||||
import com.healthlink.his.medication.domain.MedicationDefinition;
|
||||
import com.healthlink.his.medication.domain.MedicationDispense;
|
||||
import com.healthlink.his.medication.service.IMedicationDefinitionService;
|
||||
import com.healthlink.his.medication.service.IMedicationDispenseService;
|
||||
import com.healthlink.his.medication.service.impl.MedicationRequestServiceImpl;
|
||||
import com.healthlink.his.web.inhospitalnursestation.mapper.AdviceProcessAppMapper;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.ISummaryDispenseMedicineAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.UnDispenseInventoryDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.ReturnMedicineMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.WesternMedicineDispenseMapper;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.domain.SupplyDelivery;
|
||||
import com.healthlink.his.workflow.domain.SupplyRequest;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import com.healthlink.his.workflow.service.ISupplyDeliveryService;
|
||||
import com.healthlink.his.workflow.service.ISupplyRequestService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 住院汇总发放 应用实现类
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/6/3
|
||||
*/
|
||||
@Service
|
||||
public class SummaryDispenseMedicineAppServiceImpl implements ISummaryDispenseMedicineAppService {
|
||||
|
||||
@Resource
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private ISupplyRequestService supplyRequestService;
|
||||
|
||||
@Resource
|
||||
private ISupplyDeliveryService supplyDeliveryService;
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService inventoryItemService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDefinitionService medicationDefinitionService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
@Resource
|
||||
private WesternMedicineDispenseAppServiceImpl westernMedicineDispenseAppService;
|
||||
|
||||
@Resource
|
||||
private WesternMedicineDispenseMapper westernMedicineDispenseMapper;
|
||||
|
||||
@Resource
|
||||
private IOrganizationService organizationService;
|
||||
|
||||
@Resource
|
||||
private AdviceProcessAppMapper adviceProcessAppMapper;
|
||||
|
||||
@Resource
|
||||
private MedicationRequestServiceImpl medicationRequestService;
|
||||
|
||||
@Resource
|
||||
private AssignSeqUtil assignSeqUtil;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineAppServiceImpl returnMedicineAppService;
|
||||
private HttpServletResponse response;
|
||||
@Autowired
|
||||
private ISysDictTypeService sysDictTypeService;
|
||||
|
||||
/**
|
||||
* 汇总发药
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> SummaryDispenseMedicine(List<String> summaryNoList) {
|
||||
if (summaryNoList == null || summaryNoList.isEmpty()) {
|
||||
return R.fail("未选择汇总单");
|
||||
}
|
||||
|
||||
// 根据汇总单号查所有发放信息
|
||||
List<MedicationDispense> medDispenseList = medicationDispenseService.getMedDispenseBySummaryNo(summaryNoList);
|
||||
if (medDispenseList == null || medDispenseList.isEmpty()) {
|
||||
return R.fail("未查询到发药单明细,请刷新后重试");
|
||||
}
|
||||
List<Long> medDispenseIdList
|
||||
= medDispenseList.stream().map(MedicationDispense::getId).collect(Collectors.toList());
|
||||
// 获取药品待发放库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList
|
||||
= returnMedicineMapper.selectInventoryInfoList(null, medDispenseIdList,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
if (unDispenseInventoryList == null || unDispenseInventoryList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap
|
||||
= unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
|
||||
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
|
||||
// 停供库存校验
|
||||
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
|
||||
}
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
// 库存数量
|
||||
BigDecimal inventoryQuantity = BigDecimal.ZERO;
|
||||
// 库存id
|
||||
Long inventoryId = null;
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity
|
||||
= unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
if (PublicationStatus.ACTIVE.getValue().equals(unDispenseInventoryDto.getInventoryStatusEnum())
|
||||
&& unDispenseInventoryDto.getInventoryQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
inventoryQuantity = unDispenseInventoryDto.getInventoryQuantity();
|
||||
inventoryId = unDispenseInventoryDto.getInventoryId();
|
||||
}
|
||||
}
|
||||
if (minQuantity.compareTo(inventoryQuantity) > 0) {
|
||||
// 库存不足
|
||||
return R.fail(inventoryList.get(0).getItemName() + "批号库存不足");
|
||||
} else {
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryId)
|
||||
.setQuantity(inventoryQuantity.subtract(minQuantity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Date now = DateUtils.getNowDate();
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> tracesNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
// 更新发药明细状态
|
||||
for (MedicationDispense medicationDispense : medDispenseList) {
|
||||
// 药品发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.COMPLETED.getValue());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(now);
|
||||
// 发药数量
|
||||
medicationDispense.setDispenseQuantity(medicationDispense.getQuantity());
|
||||
// 发药时间
|
||||
medicationDispense.setDispenseTime(now);
|
||||
// 发药人
|
||||
medicationDispense.setPractitionerId(SecurityUtils.getPractitionerId());
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList.add(new SupplyItemDetailDto().setItemId(medicationDispense.getMedicationId())
|
||||
.setLotNumber(medicationDispense.getLotNumber())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION));
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
if (medicationDispense.getTraceNo() != null) {
|
||||
String[] traceNoList = medicationDispense.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(medicationDispense.getMedicationId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
// 仓库
|
||||
.setLocationId(medicationDispense.getLocationId())
|
||||
// 产品批号
|
||||
.setLotNumber(medicationDispense.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.OUT.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(medicationDispense.getUnitCode())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.DISPENSE_MEDICATION.getValue());
|
||||
tracesNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 药品发放更新
|
||||
medicationDispenseService.updateBatchById(medDispenseList);
|
||||
// 查询汇总申请和汇总发放信息
|
||||
List<SupplyRequest> supplyRequestList = supplyRequestService.getSupplyByBusNoBatch(summaryNoList);
|
||||
if (supplyRequestList == null || supplyRequestList.isEmpty()) {
|
||||
throw new ServiceException("未找到汇总申请信息");
|
||||
}
|
||||
List<Long> requestId = supplyRequestList.stream().map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
List<SupplyDelivery> supplyDeliveryList = supplyDeliveryService.selectByRequestIdList(requestId);
|
||||
if (supplyDeliveryList == null || supplyDeliveryList.isEmpty()) {
|
||||
throw new ServiceException("未找到汇总发放信息");
|
||||
}
|
||||
if (supplyDeliveryList.stream().anyMatch(x -> x.getStatusEnum().equals(DispenseStatus.COMPLETED.getValue()))) {
|
||||
throw new ServiceException("汇总已发放,请勿重复操作");
|
||||
}
|
||||
// 汇总发放更新
|
||||
for (SupplyDelivery supplyDelivery : supplyDeliveryList) {
|
||||
// 药品发放状态
|
||||
supplyDelivery.setStatusEnum(DispenseStatus.COMPLETED.getValue());
|
||||
// 发药时间
|
||||
supplyDelivery.setOccurrenceTime(now);
|
||||
// 发药人
|
||||
supplyDelivery.setPractitionerId(SecurityUtils.getPractitionerId());
|
||||
}
|
||||
supplyDeliveryService.updateBatchById(supplyDeliveryList);
|
||||
// 汇总发放申请更新
|
||||
for (SupplyRequest supplyRequest : supplyRequestList) {
|
||||
// 审核状态:已通过
|
||||
supplyRequest.setStatusEnum(SupplyStatus.AGREE.getValue())
|
||||
// 审核人
|
||||
.setApproverId(SecurityUtils.getPractitionerId())
|
||||
// 审核时间
|
||||
.setApprovalTime(now);
|
||||
}
|
||||
supplyRequestService.updateBatchById(supplyRequestList);
|
||||
|
||||
// 库存更新
|
||||
inventoryItemService.updateBatchById(inventoryItemList);
|
||||
// 追溯码管理表数据追加
|
||||
traceNoManageService.saveBatch(tracesNoManageList);
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
List<String> uploadFailedNoList;
|
||||
// 调用医保商品销售接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH);
|
||||
// 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
// 设置进销存参数
|
||||
List<MedicationDefinition> medicationDefinitions = medicationDefinitionService.listByIds(
|
||||
supplyItemDetailList.stream().map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
// 用itemId分组
|
||||
Map<Long, MedicationDefinition> medicationMap = medicationDefinitions.stream()
|
||||
.collect(Collectors.toMap(MedicationDefinition::getId, Function.identity()));
|
||||
// 设置库存变更参数
|
||||
for (SupplyItemDetailDto dto : supplyItemDetailList) {
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dto.getItemTable())) {
|
||||
MedicationDefinition med = medicationMap.get(dto.getItemId());
|
||||
if (med != null) {
|
||||
dto.setItemBusNo(med.getBusNo()).setPartPercent(med.getPartPercent()).setRxFlag(med.getRxFlag())
|
||||
.setYbNo(med.getYbNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
uploadFailedNoList = westernMedicineDispenseAppService.ybMedicineIntegrated(medDispenseIdList, null);
|
||||
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = "3505商品销售上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3505商品销售上传成功";
|
||||
}
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> dispenseCancel(List<String> summaryNoList) {
|
||||
if (summaryNoList == null || summaryNoList.isEmpty()) {
|
||||
return R.fail("未选择汇总单");
|
||||
}
|
||||
|
||||
// 根据汇总单号查所有发放id
|
||||
List<Long> medDispenseIdList = medicationDispenseService.getMedDispenseBySummaryNo(summaryNoList).stream()
|
||||
.map(MedicationDispense::getId).toList();
|
||||
|
||||
// 药品发药信息查询
|
||||
List<MedicationDispense> dispenseList = medicationDispenseService
|
||||
.list(new LambdaQueryWrapper<MedicationDispense>().in(MedicationDispense::getId, medDispenseIdList));
|
||||
if (dispenseList != null) {
|
||||
for (MedicationDispense medicationDispense : dispenseList) {
|
||||
// 药品发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.DECLINED.getValue());
|
||||
// 未发药原因
|
||||
// medicationDispense.setNotPerformedReasonEnum(dispenseMedicineList.get(0).getNotPerformedReasonEnum());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
}
|
||||
// 药品发放更新
|
||||
medicationDispenseService.updateBatchById(dispenseList);
|
||||
// 汇总发放更新
|
||||
for (String summaryNo : summaryNoList) {
|
||||
List<Long> requestId = supplyRequestService.getSupplyByBusNo(summaryNo).stream()
|
||||
.map(SupplyRequest::getId).collect(Collectors.toList());
|
||||
List<SupplyDelivery> supplyDeliveryList = supplyDeliveryService.selectByRequestIdList(requestId);
|
||||
for (SupplyDelivery supplyDelivery : supplyDeliveryList) {
|
||||
// 药品发放状态
|
||||
supplyDelivery.setStatusEnum(DispenseStatus.DECLINED.getValue());
|
||||
}
|
||||
supplyDeliveryService.updateBatchById(supplyDeliveryList);
|
||||
}
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,730 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.appservice.impl;
|
||||
|
||||
import tools.jackson.databind.JsonNode;
|
||||
import tools.jackson.databind.node.ArrayNode;
|
||||
import tools.jackson.databind.node.ObjectNode;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.core.common.exception.ServiceException;
|
||||
import com.core.common.utils.AgeCalculatorUtil;
|
||||
import com.core.common.utils.DateUtils;
|
||||
import com.core.common.utils.MessageUtils;
|
||||
import com.core.common.utils.SecurityUtils;
|
||||
import com.healthlink.his.administration.domain.*;
|
||||
import com.healthlink.his.administration.service.*;
|
||||
import com.healthlink.his.common.constant.CommonConstants;
|
||||
import com.healthlink.his.common.constant.PromptMsgConstant;
|
||||
import com.healthlink.his.common.enums.*;
|
||||
import com.healthlink.his.yb.enums.YbInvChgType;
|
||||
import com.healthlink.his.yb.enums.YbMdtrtCertType;
|
||||
import com.healthlink.his.yb.enums.YbRxFlag;
|
||||
import com.healthlink.his.common.utils.EnumUtils;
|
||||
import com.healthlink.his.common.utils.HisQueryUtils;
|
||||
import com.healthlink.his.financial.domain.Contract;
|
||||
import com.healthlink.his.financial.domain.PaymentReconciliation;
|
||||
import com.healthlink.his.financial.service.IContractService;
|
||||
import com.healthlink.his.financial.service.IPaymentReconciliationService;
|
||||
import com.healthlink.his.medication.domain.MedicationDefinition;
|
||||
import com.healthlink.his.medication.domain.MedicationDispense;
|
||||
import com.healthlink.his.medication.domain.MedicationRequest;
|
||||
import com.healthlink.his.medication.service.IMedicationDefinitionService;
|
||||
import com.healthlink.his.medication.service.IMedicationDispenseService;
|
||||
import com.healthlink.his.medication.service.IMedicationRequestService;
|
||||
import com.healthlink.his.web.inventorymanage.appservice.impl.ReceiptApprovalAppServiceImpl;
|
||||
import com.healthlink.his.web.inventorymanage.dto.SupplyItemDetailDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IWesternMedicineDispenseAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.*;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.ReturnMedicineMapper;
|
||||
import com.healthlink.his.web.pharmacy.dispense.mapper.WesternMedicineDispenseMapper;
|
||||
import com.healthlink.his.workflow.domain.InventoryItem;
|
||||
import com.healthlink.his.workflow.service.IInventoryItemService;
|
||||
import com.healthlink.his.yb.domain.ClinicSettle;
|
||||
import com.healthlink.his.yb.dto.Medical3505Param;
|
||||
import com.healthlink.his.yb.service.IClinicSettleService;
|
||||
import com.healthlink.his.yb.service.IYbHttpUtils;
|
||||
import com.healthlink.his.yb.service.IYbManager;
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
import org.springframework.stereotype.Service;
|
||||
import reactor.util.annotation.Nullable;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 西药发放 应用实现类
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025/3/14
|
||||
*/
|
||||
@Service
|
||||
public class WesternMedicineDispenseAppServiceImpl implements IWesternMedicineDispenseAppService {
|
||||
|
||||
@Resource
|
||||
private IOrganizationService organizationService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDispenseService medicationDispenseService;
|
||||
|
||||
@Resource
|
||||
private IMedicationRequestService medicationRequestService;
|
||||
|
||||
@Resource
|
||||
private IInventoryItemService inventoryItemService;
|
||||
|
||||
@Resource
|
||||
private WesternMedicineDispenseMapper westernMedicineDispenseMapper;
|
||||
|
||||
@Resource
|
||||
private ReturnMedicineMapper returnMedicineMapper;
|
||||
|
||||
@Resource
|
||||
private IYbManager ybService;
|
||||
|
||||
@Resource
|
||||
private IYbHttpUtils ybHttpUtils;
|
||||
|
||||
@Resource
|
||||
private IChargeItemService chargeItemService;
|
||||
|
||||
@Resource
|
||||
private IPaymentReconciliationService paymentReconciliationService;
|
||||
|
||||
@Resource
|
||||
private IContractService contractService;
|
||||
|
||||
@Resource
|
||||
private IAccountService accountService;
|
||||
|
||||
@Resource
|
||||
private IClinicSettleService clinicSettleService;
|
||||
|
||||
@Resource
|
||||
private IEncounterDiagnosisService encounterDiagnosisService;
|
||||
|
||||
@Resource
|
||||
private ITraceNoManageService traceNoManageService;
|
||||
|
||||
@Resource
|
||||
private ReceiptApprovalAppServiceImpl receiptApprovalAppService;
|
||||
|
||||
@Resource
|
||||
private IMedicationDefinitionService medicationDefinitionService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@Override
|
||||
public R<?> init() {
|
||||
|
||||
DispenseInitDto initDto = new DispenseInitDto();
|
||||
|
||||
// 获取科室下拉选列表
|
||||
List<Organization> organizationList
|
||||
= organizationService.getList(OrganizationType.DEPARTMENT.getValue(), String.valueOf(OrganizationClass.CLINIC.getValue()));
|
||||
List<DispenseInitDto.DepartmentOption> organizationOptions = organizationList.stream()
|
||||
.map(organization -> new DispenseInitDto.DepartmentOption(organization.getId(), organization.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 获取配药人下拉选列表
|
||||
List<Practitioner> preparerDoctorList
|
||||
= westernMedicineDispenseMapper.getPreparerDoctorList(PractitionerRoles.PHARMACIST.getCode());
|
||||
List<DispenseInitDto.PreparerDoctorOption> preparerDoctorOptions = preparerDoctorList.stream()
|
||||
.map(practitioner -> new DispenseInitDto.PreparerDoctorOption(practitioner.getId(), practitioner.getName()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 未发药原因下拉选列表
|
||||
List<DispenseInitDto.NotPerformedReasonOption> notPerformedReasonOptions
|
||||
= Stream.of(NotPerformedReasonEnum.values())
|
||||
.map(notPerformedReason -> new DispenseInitDto.NotPerformedReasonOption(notPerformedReason.getValue(),
|
||||
notPerformedReason.getInfo()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 患者类型
|
||||
List<DispenseInitDto.EncounterClassOption> encounterClassOptions = Stream.of(EncounterClass.values())
|
||||
.map(encounterClass -> new DispenseInitDto.EncounterClassOption(encounterClass.getValue(),
|
||||
encounterClass.getInfo()))
|
||||
.toList();
|
||||
|
||||
// 发药状态
|
||||
List<DispenseStatusOption> dispenseStatusOptions = new ArrayList<>();
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.SUBMITTED.getValue(),
|
||||
DispenseStatus.SUBMITTED.getInfo()));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.IN_PROGRESS.getValue(),
|
||||
DispenseStatus.IN_PROGRESS.getInfo()));
|
||||
dispenseStatusOptions.add(new DispenseStatusOption(DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.COMPLETED.getInfo()));
|
||||
|
||||
initDto.setDepartmentOptions(organizationOptions).setNotPerformedReasonOptions(notPerformedReasonOptions)
|
||||
.setDispenseStatusOptions(dispenseStatusOptions).setPreparerDoctorOptions(preparerDoctorOptions)
|
||||
.setEncounterClassOptions(encounterClassOptions);
|
||||
return R.ok(initDto);
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
@Override
|
||||
public R<?> getEncounterInfoListPage(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey,
|
||||
Integer pageNo, Integer pageSize, HttpServletRequest request) {
|
||||
// 发药状态初始化
|
||||
Integer statusEnum = encounterInfoSearchParam.getStatusEnum();
|
||||
encounterInfoSearchParam.setStatusEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<EncounterInfoSearchParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(encounterInfoSearchParam, searchKey,
|
||||
new HashSet<>(Arrays.asList(CommonConstants.FieldName.PatientName, CommonConstants.FieldName.IdCard,
|
||||
CommonConstants.FieldName.PatientPyStr, CommonConstants.FieldName.PatientWbStr)),
|
||||
request);
|
||||
// 查询就诊病人列表
|
||||
Page<EncounterInfoDto> encounterInfoPage
|
||||
= westernMedicineDispenseMapper.selectEncounterInfoListPage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
statusEnum, DispenseStatus.IN_PROGRESS.getValue(), DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.PREPARATION.getValue(), DispenseStatus.PREPARED.getValue(),
|
||||
DispenseStatus.SUMMARIZED.getValue(), DispenseStatus.SUBMITTED.getValue());
|
||||
encounterInfoPage.getRecords().forEach(encounterInfo -> {
|
||||
// 性别
|
||||
encounterInfo.setGenderEnum_enumText(
|
||||
EnumUtils.getInfoByValue(AdministrativeGender.class, encounterInfo.getGenderEnum()));
|
||||
// 发药状态
|
||||
encounterInfo
|
||||
.setStatusEnum_enumText(EnumUtils.getInfoByValue(DispenseStatus.class, encounterInfo.getStatusEnum()));
|
||||
if (encounterInfo.getBirthDate() != null) {
|
||||
// 计算年龄
|
||||
encounterInfo.setAge(AgeCalculatorUtil.getAge(encounterInfo.getBirthDate()));
|
||||
}
|
||||
});
|
||||
return R.ok(encounterInfoPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 处方单
|
||||
*/
|
||||
@Override
|
||||
public R<?> getMedicineDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto, Integer pageNo,
|
||||
Integer pageSize) {
|
||||
// 发药状态初始化
|
||||
Integer dispenseStatus = itemDispenseOrderDto.getStatusEnum();
|
||||
itemDispenseOrderDto.setStatusEnum(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<ItemDispenseOrderDto> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(itemDispenseOrderDto, null, null, null);
|
||||
// 处方单信息查询
|
||||
Page<ItemDispenseOrderDto> medicineDispenseOrderPage
|
||||
= westernMedicineDispenseMapper.selectMedicineDispenseOrderPage(new Page<>(pageNo, pageSize), queryWrapper,
|
||||
DispenseStatus.IN_PROGRESS.getValue(), DispenseStatus.COMPLETED.getValue(),
|
||||
DispenseStatus.PREPARATION.getValue(), DispenseStatus.PREPARED.getValue(), dispenseStatus,
|
||||
PublicationStatus.ACTIVE.getValue(), DispenseStatus.SUMMARIZED.getValue(),
|
||||
DispenseStatus.SUBMITTED.getValue());
|
||||
medicineDispenseOrderPage.getRecords().forEach(medicineDispenseOrder -> {
|
||||
// 发药状态
|
||||
medicineDispenseOrder.setStatusEnum_enumText(
|
||||
EnumUtils.getInfoByValue(DispenseStatus.class, medicineDispenseOrder.getStatusEnum()));
|
||||
// 设置所在表名
|
||||
medicineDispenseOrder.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
// 处方类型(发药类型:门诊/住院等)
|
||||
if (medicineDispenseOrder.getDispenseEnum() != null) {
|
||||
medicineDispenseOrder.setDispenseEnum_enumText(
|
||||
EnumUtils.getInfoByValue(EncounterClass.class, medicineDispenseOrder.getDispenseEnum()));
|
||||
}
|
||||
});
|
||||
return R.ok(medicineDispenseOrderPage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配药
|
||||
*
|
||||
* @param dispenseMedicineList 配药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> medicinePrepare(List<DispenseItemDto> dispenseMedicineList) {
|
||||
if (dispenseMedicineList == null || dispenseMedicineList.isEmpty()) {
|
||||
throw new ServiceException("配药信息不能为空");
|
||||
}
|
||||
// 追溯码集合
|
||||
List<String> traceNoList
|
||||
= dispenseMedicineList.stream().map(DispenseItemDto::getTraceNo).collect(Collectors.toList());
|
||||
// 非输液药品的已出库追溯码
|
||||
List<String> outTraceNoList = westernMedicineDispenseMapper.getOutTraceNo(TraceNoStatus.OUT.getValue(),
|
||||
Whether.YES.getValue(), SplitPropertyCode.OUTPATIENT_MIN_UNIT_CEIL.getValue(),
|
||||
SplitPropertyCode.OUTPATIENT_MIN_UNIT_TOTAL_CEIL.getValue(), SupplyType.DISPENSE_MEDICATION.getValue());
|
||||
// 取交集
|
||||
if (!traceNoList.isEmpty() && !outTraceNoList.isEmpty()) {
|
||||
List<String> list = traceNoList.stream().filter(outTraceNoList::contains).collect(Collectors.toList());
|
||||
if (!list.isEmpty()) {
|
||||
throw new ServiceException("追溯码【" + String.join(",", list) + "】已出库");
|
||||
}
|
||||
}
|
||||
// 配药人检查
|
||||
if (dispenseMedicineList.get(0).getPreparerId() == null
|
||||
|| dispenseMedicineList.get(0).getPreparerId().equals(SecurityUtils.getPractitionerId())) {
|
||||
return R.fail("请选择调配药师");
|
||||
}
|
||||
// 获取发药单id列表
|
||||
List<Long> medDispenseIdList
|
||||
= dispenseMedicineList.stream().map(DispenseItemDto::getDispenseId).collect(Collectors.toList());
|
||||
// 药品发药信息查询
|
||||
List<MedicationDispense> dispenseList = medicationDispenseService
|
||||
.list(new LambdaQueryWrapper<MedicationDispense>().in(MedicationDispense::getId, medDispenseIdList));
|
||||
|
||||
if (dispenseList != null) {
|
||||
if (dispenseList.stream().map(MedicationDispense::getStatusEnum)
|
||||
.anyMatch(x -> !x.equals(DispenseStatus.PREPARATION.getValue()))) {
|
||||
throw new ServiceException("配药失败,请检查发药单状态");
|
||||
} else {
|
||||
for (MedicationDispense medicationDispense : dispenseList) {
|
||||
// 药品发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.PREPARED.getValue());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
// 配药人
|
||||
medicationDispense.setPreparerId(dispenseMedicineList.get(0).getPreparerId());
|
||||
// 配药时间
|
||||
medicationDispense.setPrepareTime(DateUtils.getNowDate());
|
||||
for (DispenseItemDto dispenseItemDto : dispenseMedicineList) {
|
||||
if (medicationDispense.getId().equals(dispenseItemDto.getDispenseId())) {
|
||||
// 药品追溯码
|
||||
medicationDispense.setTraceNo(dispenseItemDto.getTraceNo());
|
||||
// 批次号
|
||||
medicationDispense.setLotNumber(dispenseItemDto.getLotNumber());
|
||||
// 药品数量
|
||||
medicationDispense.setQuantity(dispenseItemDto.getQuantity());
|
||||
}
|
||||
}
|
||||
}
|
||||
// 查询对应的药品医嘱
|
||||
List<MedicationRequest> medicationRequests = medicationRequestService.listByIds(
|
||||
dispenseList.stream().map(MedicationDispense::getMedReqId).distinct().collect(Collectors.toList()));
|
||||
// 根据请求id做map
|
||||
Map<Long, List<MedicationDispense>> dispenseMap
|
||||
= dispenseList.stream().collect(Collectors.groupingBy(MedicationDispense::getMedReqId));
|
||||
for (MedicationRequest medicationRequest : medicationRequests) {
|
||||
List<MedicationDispense> medicationDispenseList = dispenseMap.get(medicationRequest.getId());
|
||||
BigDecimal dispenseQuantity = BigDecimal.ZERO;
|
||||
for (MedicationDispense medicationDispense : medicationDispenseList) {
|
||||
if (medicationRequest.getUnitCode().equals(medicationDispense.getUnitCode())) {
|
||||
dispenseQuantity = dispenseQuantity.add(medicationDispense.getQuantity());
|
||||
} else {
|
||||
throw new ServiceException("配药失败,请检查发药单单位");
|
||||
}
|
||||
}
|
||||
// 校验开药数量与待发药数量是否相同
|
||||
if (dispenseQuantity.compareTo(medicationRequest.getQuantity()) != 0) {
|
||||
throw new ServiceException("配药失败,请检查发药单数量");
|
||||
}
|
||||
}
|
||||
// 药品发放更新
|
||||
medicationDispenseService.updateBatchById(dispenseList);
|
||||
}
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 处方单核对发药
|
||||
*
|
||||
* @param dispenseMedicineList 发药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> medicineDispense(List<DispenseItemDto> dispenseMedicineList) {
|
||||
// 获取发药单id列表
|
||||
List<Long> medDispenseIdList
|
||||
= dispenseMedicineList.stream().map(DispenseItemDto::getDispenseId).collect(Collectors.toList());
|
||||
// 获取药品待发放库存信息
|
||||
List<UnDispenseInventoryDto> unDispenseInventoryList
|
||||
= returnMedicineMapper.selectInventoryInfoList(null, medDispenseIdList,
|
||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
if (unDispenseInventoryList == null || unDispenseInventoryList.isEmpty()) {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
// 发药单状态校验
|
||||
if (unDispenseInventoryList.stream().map(UnDispenseInventoryDto::getDispenseStatus)
|
||||
.anyMatch(x -> !x.equals(DispenseStatus.SUBMITTED.getValue()))) {
|
||||
throw new ServiceException("发药失败,请检查发药单状态");
|
||||
}
|
||||
|
||||
// 库存待更新列表
|
||||
List<InventoryItem> inventoryItemList = new ArrayList<>();
|
||||
// 根据批号,发放项目,发放药房进行分组处理
|
||||
Map<String, List<UnDispenseInventoryDto>> unDispenseInventoryMap
|
||||
= unDispenseInventoryList.stream().collect(Collectors.groupingBy(x -> x.getItemId()
|
||||
+ CommonConstants.Common.DASH + x.getLotNumber() + CommonConstants.Common.DASH + x.getLocationId()));
|
||||
if (!unDispenseInventoryMap.isEmpty()) {
|
||||
for (Map.Entry<String, List<UnDispenseInventoryDto>> entry : unDispenseInventoryMap.entrySet()) {
|
||||
List<UnDispenseInventoryDto> inventoryList = entry.getValue();
|
||||
if (!inventoryList.isEmpty()) {
|
||||
if (inventoryList.stream().map(UnDispenseInventoryDto::getInventoryStatusEnum)
|
||||
.allMatch(x -> x.equals(PublicationStatus.RETIRED.getValue()))) {
|
||||
// 停供库存校验
|
||||
return R.fail(inventoryList.get(0).getItemName() + "库存已停供");
|
||||
}
|
||||
// 最小单位数量
|
||||
BigDecimal minQuantity = BigDecimal.ZERO;
|
||||
// 库存数量
|
||||
BigDecimal inventoryQuantity = BigDecimal.ZERO;
|
||||
// 库存id
|
||||
Long inventoryId = null;
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : inventoryList) {
|
||||
BigDecimal quantity = unDispenseInventoryDto.getQuantity();
|
||||
if (!unDispenseInventoryDto.getDispenseUnit()
|
||||
.equals(unDispenseInventoryDto.getInventoryUnitCode())) {
|
||||
// 转换为小单位进行累加
|
||||
quantity
|
||||
= unDispenseInventoryDto.getQuantity().multiply(unDispenseInventoryDto.getPartPercent());
|
||||
}
|
||||
minQuantity = minQuantity.add(quantity);
|
||||
if (PublicationStatus.ACTIVE.getValue().equals(unDispenseInventoryDto.getInventoryStatusEnum())
|
||||
&& unDispenseInventoryDto.getInventoryQuantity().compareTo(BigDecimal.ZERO) > 0) {
|
||||
inventoryQuantity = unDispenseInventoryDto.getInventoryQuantity();
|
||||
inventoryId = unDispenseInventoryDto.getInventoryId();
|
||||
}
|
||||
}
|
||||
if (minQuantity.compareTo(inventoryQuantity) > 0) {
|
||||
// 库存不足
|
||||
return R.fail(inventoryList.get(0).getItemName() + "批号库存不足");
|
||||
} else {
|
||||
// 设置待更新的库存信息
|
||||
inventoryItemList.add(new InventoryItem().setId(inventoryId)
|
||||
.setQuantity(inventoryQuantity.subtract(minQuantity)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发药单待更新列表
|
||||
List<MedicationDispense> dispenseUpdateList = new ArrayList<>();
|
||||
// 追溯码列表
|
||||
List<TraceNoManage> tracesNoManageList = new ArrayList<>();
|
||||
TraceNoManage traceNoManage;
|
||||
// 进销存参数列表
|
||||
List<SupplyItemDetailDto> supplyItemDetailList = new ArrayList<>();
|
||||
// 当前时间
|
||||
Date nowDate = DateUtils.getNowDate();
|
||||
// 当前用户id
|
||||
Long practitionerId = SecurityUtils.getPractitionerId();
|
||||
|
||||
for (UnDispenseInventoryDto unDispenseInventoryDto : unDispenseInventoryList) {
|
||||
MedicationDispense medicationDispense = new MedicationDispense();
|
||||
// 发药单id
|
||||
medicationDispense.setId(unDispenseInventoryDto.getDispenseId());
|
||||
// 药品发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.COMPLETED.getValue());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(nowDate);
|
||||
// 发药数量
|
||||
medicationDispense.setDispenseQuantity(unDispenseInventoryDto.getQuantity());
|
||||
// 发药时间
|
||||
medicationDispense.setDispenseTime(nowDate);
|
||||
// 发药人
|
||||
medicationDispense.setPractitionerId(practitionerId);
|
||||
dispenseUpdateList.add(medicationDispense);
|
||||
|
||||
// 设置库存变更参数
|
||||
supplyItemDetailList.add(new SupplyItemDetailDto().setItemId(unDispenseInventoryDto.getItemId())
|
||||
.setLotNumber(unDispenseInventoryDto.getLotNumber())
|
||||
.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
.setRequestId(unDispenseInventoryDto.getRequestId()));
|
||||
|
||||
// 处理追溯码相关
|
||||
// 使用逗号分割追溯码并转换为List
|
||||
if (unDispenseInventoryDto.getTraceNo() != null) {
|
||||
String[] traceNoList = unDispenseInventoryDto.getTraceNo().split(CommonConstants.Common.COMMA);
|
||||
for (String item : traceNoList) {
|
||||
traceNoManage = new TraceNoManage();
|
||||
// 追溯码处理
|
||||
traceNoManage.setItemTable(CommonConstants.TableName.MED_MEDICATION_DEFINITION)
|
||||
// 项目id
|
||||
.setItemId(unDispenseInventoryDto.getItemId())
|
||||
// 仓库类型
|
||||
.setLocationTypeEnum(LocationForm.PHARMACY.getValue())
|
||||
// 仓库
|
||||
.setLocationId(unDispenseInventoryDto.getLocationId())
|
||||
// 产品批号
|
||||
.setLotNumber(unDispenseInventoryDto.getLotNumber())
|
||||
// 追溯码
|
||||
.setTraceNo(item)
|
||||
// 追溯码状态
|
||||
.setStatusEnum(TraceNoStatus.OUT.getValue())
|
||||
// 追溯码单位
|
||||
.setUnitCode(unDispenseInventoryDto.getDispenseUnit())
|
||||
// 操作类型
|
||||
.setOperationType(SupplyType.DISPENSE_MEDICATION.getValue());
|
||||
tracesNoManageList.add(traceNoManage);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 药品发放更新
|
||||
medicationDispenseService.updateBatchById(dispenseUpdateList);
|
||||
// 更新医嘱状态为已完成
|
||||
List<Long> medReqIdList = unDispenseInventoryList.stream()
|
||||
.map(UnDispenseInventoryDto::getRequestId).distinct().collect(Collectors.toList());
|
||||
medicationRequestService.update(new MedicationRequest().setStatusEnum(RequestStatus.DISPENSE_COMPLETED.getValue()),
|
||||
new LambdaUpdateWrapper<MedicationRequest>().in(MedicationRequest::getId, medReqIdList));
|
||||
// 库存更新
|
||||
inventoryItemService.updateBatchById(inventoryItemList);
|
||||
// 追溯码管理表数据追加
|
||||
if (!tracesNoManageList.isEmpty()) {
|
||||
traceNoManageService.saveBatch(tracesNoManageList);
|
||||
}
|
||||
// 返回信息
|
||||
String returnMsg = null;
|
||||
List<String> uploadFailedNoList;
|
||||
// 调用医保商品销售接口
|
||||
String ybSwitch = SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.YB_SWITCH); // 医保开关
|
||||
if (Whether.YES.getCode().equals(ybSwitch)) {
|
||||
// 设置进销存参数
|
||||
List<MedicationDefinition> medicationDefinitions = medicationDefinitionService.listByIds(
|
||||
supplyItemDetailList.stream().map(SupplyItemDetailDto::getItemId).collect(Collectors.toList()));
|
||||
// 用itemId分组
|
||||
Map<Long, MedicationDefinition> medicationMap = medicationDefinitions.stream()
|
||||
.collect(Collectors.toMap(MedicationDefinition::getId, Function.identity()));
|
||||
// 设置库存变更参数
|
||||
for (SupplyItemDetailDto dto : supplyItemDetailList) {
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dto.getItemTable())) {
|
||||
MedicationDefinition med = medicationMap.get(dto.getItemId());
|
||||
if (med != null) {
|
||||
dto.setItemBusNo(med.getBusNo()).setPartPercent(med.getPartPercent()).setRxFlag(med.getRxFlag())
|
||||
.setYbNo(med.getYbNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
uploadFailedNoList = this.ybMedicineIntegrated(medDispenseIdList, null);
|
||||
uploadFailedNoList = receiptApprovalAppService.ybInventoryIntegrated(supplyItemDetailList,
|
||||
YbInvChgType.OTHER_OUT, DateUtils.getNowDate(), true);
|
||||
if (uploadFailedNoList != null) {
|
||||
returnMsg = "3505商品销售上传错误,错误项目编码" + uploadFailedNoList;
|
||||
} else {
|
||||
returnMsg = "3505商品销售上传成功";
|
||||
}
|
||||
}
|
||||
return R.ok(returnMsg, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseMedicineList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@Override
|
||||
public R<?> medicineCancel(List<DispenseItemDto> dispenseMedicineList) {
|
||||
// 获取发药单id列表
|
||||
List<Long> medDispenseIdList
|
||||
= dispenseMedicineList.stream().map(DispenseItemDto::getDispenseId).collect(Collectors.toList());
|
||||
// 药品发药信息查询
|
||||
List<MedicationDispense> dispenseList = medicationDispenseService
|
||||
.list(new LambdaQueryWrapper<MedicationDispense>().in(MedicationDispense::getId, medDispenseIdList));
|
||||
if (dispenseList != null) {
|
||||
for (MedicationDispense medicationDispense : dispenseList) {
|
||||
// 药品发放状态
|
||||
medicationDispense.setStatusEnum(DispenseStatus.DECLINED.getValue());
|
||||
// 未发药原因
|
||||
medicationDispense.setNotPerformedReasonEnum(dispenseMedicineList.get(0).getNotPerformedReasonEnum());
|
||||
// 状态变更时间
|
||||
medicationDispense.setStatusChangedTime(DateUtils.getNowDate());
|
||||
}
|
||||
// 药品发放更新
|
||||
medicationDispenseService.updateBatchById(dispenseList);
|
||||
} else {
|
||||
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
|
||||
}
|
||||
return R.ok(MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 医保发药相关进销存接口
|
||||
*
|
||||
* @param medDispenseIdList 发药id列表
|
||||
* @param devDispenseIdList 发耗材id列表
|
||||
* @return 上传失败的编号集合
|
||||
*/
|
||||
public List<String> ybMedicineIntegrated(@Nullable List<Long> medDispenseIdList,
|
||||
@Nullable List<Long> devDispenseIdList) {
|
||||
List<String> uploadFailedNoList = new ArrayList<>();
|
||||
R<?> result;
|
||||
if ((medDispenseIdList != null && !medDispenseIdList.isEmpty())
|
||||
|| (devDispenseIdList != null && !devDispenseIdList.isEmpty())) {
|
||||
// 查询发药项目相关信息
|
||||
List<DispenseInventoryDto> dispenseInventoryList = returnMedicineMapper.selectReturnItemDetail(
|
||||
devDispenseIdList, medDispenseIdList, CommonConstants.TableName.MED_MEDICATION_DEFINITION,
|
||||
CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
for (DispenseInventoryDto dispenseInventoryDto : dispenseInventoryList) {
|
||||
if (dispenseInventoryDto.getYbNo() == null) {
|
||||
continue;
|
||||
}
|
||||
Pair<Medical3505Param, Contract> medical3505Pair = getMedical3505Param(dispenseInventoryDto);
|
||||
// 如果自费则自动取省医保
|
||||
Contract contract = medical3505Pair.getRight();
|
||||
if (contract != null) {
|
||||
if (CommonConstants.BusinessName.DEFAULT_CONTRACT_NO
|
||||
.equals(medical3505Pair.getRight().getBusNo())) {
|
||||
contract = null;
|
||||
}
|
||||
}
|
||||
result = ybService.merchandise(medical3505Pair.getLeft(), contract);
|
||||
if (result.getCode() != 200) {
|
||||
uploadFailedNoList.add(dispenseInventoryDto.getDispenseNo());
|
||||
}
|
||||
}
|
||||
}
|
||||
return uploadFailedNoList;
|
||||
}
|
||||
|
||||
private Pair<Medical3505Param, Contract> getMedical3505Param(DispenseInventoryDto dispenseInventoryDto) {
|
||||
Medical3505Param medical3505Param = new Medical3505Param();
|
||||
ChargeItem chargeItem = null;
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
// 查询费用结算信息
|
||||
chargeItem = chargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.MED_MEDICATION_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getReqId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
chargeItem = chargeItemService.getOne(new LambdaQueryWrapper<ChargeItem>()
|
||||
.eq(ChargeItem::getServiceTable, CommonConstants.TableName.WOR_DEVICE_REQUEST)
|
||||
.eq(ChargeItem::getServiceId, dispenseInventoryDto.getReqId())
|
||||
.eq(ChargeItem::getTenantId, SecurityUtils.getLoginUser().getTenantId()));
|
||||
}
|
||||
|
||||
if (chargeItem == null) {
|
||||
throw new ServiceException("未查找到收费项");
|
||||
}
|
||||
// 查询就诊诊断信息
|
||||
EncounterDiagnosis encounterDiagnosis = encounterDiagnosisService.getById(chargeItem.getEncounterDiagnosisId());
|
||||
if (encounterDiagnosis == null) {
|
||||
throw new ServiceException("未查找到就诊诊断信息");
|
||||
}
|
||||
// 查询付款信息
|
||||
List<PaymentReconciliation> paymentReconciliationList
|
||||
= paymentReconciliationService.list(new LambdaQueryWrapper<PaymentReconciliation>()
|
||||
.eq(PaymentReconciliation::getEncounterId, dispenseInventoryDto.getEncounterId())
|
||||
.eq(PaymentReconciliation::getTenantId, SecurityUtils.getLoginUser().getTenantId())
|
||||
.like(PaymentReconciliation::getChargeItemIds, chargeItem.getId())
|
||||
.eq(PaymentReconciliation::getStatusEnum, PaymentStatus.SUCCESS.getValue())
|
||||
.eq(PaymentReconciliation::getPatientId, dispenseInventoryDto.getPatientId())
|
||||
.eq(PaymentReconciliation::getPaymentEnum, PaymentType.PAY.getValue())
|
||||
.orderByDesc(PaymentReconciliation::getBillDate));
|
||||
if (paymentReconciliationList == null || paymentReconciliationList.isEmpty()) {
|
||||
throw new ServiceException("未查找到收费信息");
|
||||
}
|
||||
PaymentReconciliation paymentReconciliation = paymentReconciliationList.get(0);
|
||||
// 查询账户信息
|
||||
Account account = accountService
|
||||
.getOne(new LambdaQueryWrapper<Account>().eq(Account::getEncounterId, dispenseInventoryDto.getEncounterId())
|
||||
.eq(Account::getEncounterFlag, Whether.YES.getValue()));
|
||||
if (account == null) {
|
||||
throw new ServiceException("未查找到账户信息");
|
||||
}
|
||||
// 查询合同实体
|
||||
Contract contract
|
||||
= contractService.getOne(new LambdaQueryWrapper<Contract>().eq(Contract::getBusNo, account.getContractNo()));
|
||||
if (contract == null) {
|
||||
throw new ServiceException("未查找到合同信息");
|
||||
}
|
||||
YbMdtrtCertType mdtrtCertType;
|
||||
if (AccountType.PERSONAL_CASH_ACCOUNT.getCode().equals(account.getTypeCode())) {
|
||||
mdtrtCertType = YbMdtrtCertType.MDTRT_CERT_TYPE02;
|
||||
} else {
|
||||
mdtrtCertType = YbMdtrtCertType.getByValue(account.getTypeCode());// 2025/05/28 该值存01/02/03
|
||||
}
|
||||
if (mdtrtCertType == null) {
|
||||
throw new ServiceException("未查找到就诊凭证信息");
|
||||
}
|
||||
// 查询就诊id
|
||||
if (contract.getCategoryEnum().equals(Category.SELF.getValue())
|
||||
|| contract.getCategoryEnum().equals(Category.PUBLIC.getValue())) {
|
||||
medical3505Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo()).setMdtrtSetlType("2");
|
||||
} else {
|
||||
// todo:虽然是医保挂号,但是用什么结算的暂时未知先不做修改
|
||||
ClinicSettle clinicSettle = clinicSettleService.getOne(new LambdaQueryWrapper<ClinicSettle>()
|
||||
.in(ClinicSettle::getSetlId, List.of(paymentReconciliation.getYbSettleIds()))
|
||||
.eq(ClinicSettle::getMedType, encounterDiagnosis.getMedTypeCode()).last(" LIMIT 1"));
|
||||
if (clinicSettle != null) {
|
||||
medical3505Param.setMdtrtSn(clinicSettle.getMdtrtId()).setMdtrtSetlType("1");
|
||||
} else {
|
||||
medical3505Param.setMdtrtSn(dispenseInventoryDto.getEncounterNo()).setMdtrtSetlType("2");
|
||||
}
|
||||
}
|
||||
// // 查询发票信息
|
||||
// Invoice invoice = iInvoiceService.getById(paymentReconciliation.getInvoiceId());
|
||||
// if (invoice == null) {
|
||||
// throw new ServiceException("未查找到就诊发票信息");
|
||||
// }
|
||||
// 转换为JSON
|
||||
ArrayNode medicalTraceNo = new tools.jackson.databind.ObjectMapper().createArrayNode();
|
||||
// 获取追溯码信息
|
||||
if (dispenseInventoryDto.getTraceNo() != null) {
|
||||
List<String> traceNoList
|
||||
= Arrays.stream(dispenseInventoryDto.getTraceNo().split(CommonConstants.Common.COMMA)).map(String::trim)
|
||||
.filter(s -> !s.isEmpty()).toList();
|
||||
for (String traceNo : traceNoList) {
|
||||
ObjectNode traceNoMap = new tools.jackson.databind.ObjectMapper().createObjectNode();
|
||||
traceNoMap.put("drug_trac_codg", traceNo);
|
||||
medicalTraceNo.add(traceNoMap);
|
||||
}
|
||||
}
|
||||
medical3505Param.setMedListCodg(dispenseInventoryDto.getYbNo())
|
||||
.setFixmedinsBchno(dispenseInventoryDto.getReqId().toString())
|
||||
.setFixmedinsHilistId(dispenseInventoryDto.getItemNo())
|
||||
.setPrscDrName(dispenseInventoryDto.getPractitionerName())
|
||||
.setPharName(dispenseInventoryDto.getDispenseName())
|
||||
.setPharPracCertNo(dispenseInventoryDto.getPharPracCertNo()).setPsnCertType(mdtrtCertType.getValue())
|
||||
.setManuLotnum(dispenseInventoryDto.getLotNumber()).setManuDate(dispenseInventoryDto.getProductionDate())
|
||||
.setRtalDocno(dispenseInventoryDto.getDispenseNo())
|
||||
.setSelRetnCnt(new BigDecimal(dispenseInventoryDto.getDispenseQuantity().toString()))
|
||||
.setSelRetnTime(dispenseInventoryDto.getDispenseTime()).setExpyEnd(dispenseInventoryDto.getExpirationDate())
|
||||
.setStooutNo(dispenseInventoryDto.getDispenseNo()).setDrugtracinfo(medicalTraceNo)
|
||||
.setCertno(dispenseInventoryDto.getIdCard()).setPsnName(dispenseInventoryDto.getPatientName());
|
||||
if (dispenseInventoryDto.getInventoryUnitCode().equals(dispenseInventoryDto.getDispenseUnitCode())) {
|
||||
medical3505Param.setTrdnFlag(Whether.YES.getCode());
|
||||
} else {
|
||||
medical3505Param.setTrdnFlag(Whether.NO.getCode());
|
||||
}
|
||||
// 查看所属医院
|
||||
String fixmedinsCode
|
||||
= SecurityUtils.getLoginUser().getOptionJsonValue(CommonConstants.Option.FIXMEDINS_CODE);
|
||||
if (dispenseInventoryDto.getPreparerName() == null && HospitalCodeEnum.CCU.getCode().equals(fixmedinsCode)) {
|
||||
medical3505Param.setSelRetnOpterName(CommonConstants.CCU.DisDeviceDoctorName);
|
||||
} else {
|
||||
medical3505Param.setSelRetnOpterName(dispenseInventoryDto.getPreparerName());
|
||||
}
|
||||
if (YbRxFlag.IMPORTANT_HERBAL_SLICES.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3505Param.setRxFlag(YbRxFlag.IMPORTANT_HERBAL_SLICES.getName());
|
||||
} else if (YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3505Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
} else if (YbRxFlag.SELF_PREPARED_MEDICATION.getCode() == dispenseInventoryDto.getRxFlag()) {
|
||||
medical3505Param.setRxFlag(YbRxFlag.WESTERN_AND_CHINESE_PATENT_MEDICINE.getName());
|
||||
}
|
||||
if (CommonConstants.TableName.MED_MEDICATION_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3505Param.setFixmedinsHilistName(CommonConstants.TableName.MED_MEDICATION_DEFINITION);
|
||||
} else if (CommonConstants.TableName.ADM_DEVICE_DEFINITION.equals(dispenseInventoryDto.getItemTable())) {
|
||||
medical3505Param.setFixmedinsHilistName(CommonConstants.TableName.ADM_DEVICE_DEFINITION);
|
||||
}
|
||||
return Pair.of(medical3505Param, contract);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IInHospitalReturnMedicineAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ReturnMedicineDto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/inHospital-return-medicine")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class InHospitalReturnMedicineController {
|
||||
|
||||
@Resource
|
||||
public IInHospitalReturnMedicineAppService inHospitalReturnMedicineAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> returnMedicineInit() {
|
||||
return inHospitalReturnMedicineAppService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@GetMapping(value = "/return-patient-page")
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto,
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return inHospitalReturnMedicineAppService.getReturnMedicinePatientPage(encounterInfoDto, searchKey, pageNo,
|
||||
pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @param itemTable 项目类型
|
||||
* @return 退药信息
|
||||
*/
|
||||
@GetMapping("/medicine-return-list")
|
||||
public R<?> getReturnMedicineInfo(@RequestParam Long encounterId, @RequestParam Integer refundStatus,
|
||||
String itemTable) {
|
||||
return inHospitalReturnMedicineAppService.getReturnMedicineInfo(encounterId, refundStatus, itemTable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/medicine-return")
|
||||
public R<?> medicineReturn(@RequestBody List<ReturnMedicineDto> medicineReturnList) {
|
||||
return inHospitalReturnMedicineAppService.medicineReturn(medicineReturnList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IMedicalDeviceDispenseAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.DispenseItemDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ItemDispenseOrderDto;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 材料发送
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/8/21
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/device-dispense")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class MedicalDeviceDispenseController {
|
||||
|
||||
@Resource
|
||||
public IMedicalDeviceDispenseAppService medicalDeviceDispenseAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> deviceDispenseInit() {
|
||||
return medicalDeviceDispenseAppService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
@GetMapping("/encounter-list")
|
||||
public R<?> getEncounterInfoList(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return medicalDeviceDispenseAppService.getEncounterInfoListPage(encounterInfoSearchParam, searchKey, pageNo,
|
||||
pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发耗材单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 发耗材单
|
||||
*/
|
||||
@GetMapping("/device-order")
|
||||
public R<?> getDeviceDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return medicalDeviceDispenseAppService.getDeviceDispenseOrderList(itemDispenseOrderDto, pageNo, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 核对发耗材
|
||||
*
|
||||
* @param dispenseDeviceList 发耗材信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/device-dispense")
|
||||
public R<?> deviceDispense(@RequestBody List<DispenseItemDto> dispenseDeviceList) {
|
||||
return medicalDeviceDispenseAppService.deviceDispense(dispenseDeviceList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发放耗材(长大专属)
|
||||
*
|
||||
* @param chargeItemIds 耗材收费单ids
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/consumables-dispense")
|
||||
public R<?> dispenseMedicalConsumables(@RequestBody List<Long> chargeItemIds) {
|
||||
return medicalDeviceDispenseAppService.dispenseMedicalConsumables(chargeItemIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseDeviceList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/device-cancel")
|
||||
public R<?> deviceCancel(@RequestBody List<DispenseItemDto> dispenseDeviceList) {
|
||||
return medicalDeviceDispenseAppService.deviceCancel(dispenseDeviceList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IMedicationDetailsAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailsSearchParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* 发药明细
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/medication-details")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class MedicationDetailsController {
|
||||
|
||||
@Resource
|
||||
public IMedicationDetailsAppService medicationDetailsAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> init() {
|
||||
return medicationDetailsAppService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 门诊人员发药明细表
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊发药明细表
|
||||
*/
|
||||
@GetMapping(value = "/amb-practitioner-detail")
|
||||
public R<?> getAmbPractitionerDetailPage(MedDetailsSearchParam medDetailsSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return medicationDetailsAppService.getAmbPractitionerDetailPage(medDetailsSearchParam, pageNo, pageSize,
|
||||
searchKey, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 门诊发药明细流水账
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 门诊发药明细流水账
|
||||
*/
|
||||
@GetMapping(value = "/amb-medication-detail")
|
||||
public R<?> getAmbMedicationDispenseDetailPage(MedDetailsSearchParam medDetailsSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return medicationDetailsAppService.getAmbMedicationDispenseDetailPage(medDetailsSearchParam, pageNo, pageSize,
|
||||
searchKey, request);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 门诊/住院人员发药明细帐、住院耗材记账领用明细
|
||||
// *
|
||||
// * @param medDetailsSearchParam 查询条件
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param request 请求数据
|
||||
// * @return 门诊/住院人员发药明细、住院耗材记账领用明细分页列表
|
||||
// */
|
||||
// @GetMapping(value = "/med-detail-page")
|
||||
// public R<?> getMedDetailedAccountPage(MedDetailsSearchParam medDetailsSearchParam,
|
||||
// @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
// @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
// @RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
// return medicationDetailsAppService.getMedDetailedAccountPage(medDetailsSearchParam, pageNo, pageSize, searchKey,
|
||||
// request);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 门诊/住院发药明细流水帐、住院耗材记账领用流水账
|
||||
// *
|
||||
// * @param medDetailsSearchParam 查询条件
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param request 请求数据
|
||||
// * @return 门诊/住院发药明细流水帐、住院耗材记账领用流水账分页列表
|
||||
// */
|
||||
// @GetMapping(value = "/med-running-page")
|
||||
// public R<?> getMedRunningAccountPage(MedDetailsSearchParam medDetailsSearchParam,
|
||||
// @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
// @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
// @RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
// return medicationDetailsAppService.getMedRunningAccountPage(medDetailsSearchParam, pageNo, pageSize, searchKey,
|
||||
// request);
|
||||
// }
|
||||
/**
|
||||
* 发药明细导出
|
||||
*
|
||||
* @param medDetailsSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param response 请求数据
|
||||
* @param request 请求数据
|
||||
*/
|
||||
@GetMapping(value = "/excel-out")
|
||||
public void exportExcel(MedDetailsSearchParam medDetailsSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey,
|
||||
HttpServletRequest request, HttpServletResponse response) {
|
||||
medicationDetailsAppService.makeExcelFile(medDetailsSearchParam, pageNo, pageSize, searchKey, response, request);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IPendingMedicationDetailsAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationSearchParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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 jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
||||
/**
|
||||
* 待发药明细
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025/4/14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/pending-medication")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class PendingMedicationDetailsController {
|
||||
|
||||
@Resource
|
||||
public IPendingMedicationDetailsAppService pendingMedicationDetailsAppService;
|
||||
|
||||
/**
|
||||
* 分页查询待发药明细
|
||||
*
|
||||
* @param pendingMedicationSearchParam 查询条件
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param request 请求数据
|
||||
* @return 待发药明细
|
||||
*/
|
||||
@GetMapping("/pending-medication-page")
|
||||
public R<?> getPage(PendingMedicationSearchParam pendingMedicationSearchParam,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
|
||||
return pendingMedicationDetailsAppService.getPage(pendingMedicationSearchParam, pageNo, pageSize, searchKey,
|
||||
request);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.pharmacymanage.domain.PharmacyStockAlert;
|
||||
import com.healthlink.his.pharmacymanage.service.IPharmacyStockAlertService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-stock-alert")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class PharmacyStockAlertController {
|
||||
|
||||
private final IPharmacyStockAlertService alertService;
|
||||
|
||||
@GetMapping("/page")
|
||||
public R<?> getPage(
|
||||
@RequestParam(value = "alertLevel", required = false) String level,
|
||||
@RequestParam(value = "drugName", required = false) String drugName,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "20") Integer pageSize) {
|
||||
LambdaQueryWrapper<PharmacyStockAlert> w = new LambdaQueryWrapper<>();
|
||||
w.eq(StringUtils.hasText(level), PharmacyStockAlert::getAlertLevel, level)
|
||||
.like(StringUtils.hasText(drugName), PharmacyStockAlert::getDrugName, drugName)
|
||||
.orderByAsc(PharmacyStockAlert::getCurrentStock);
|
||||
return R.ok(alertService.page(new Page<>(pageNo, pageSize), w));
|
||||
}
|
||||
|
||||
@PostMapping("/add")
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public R<?> add(@RequestBody PharmacyStockAlert alert) {
|
||||
alert.setStatus(0);
|
||||
// 自动判断预警级别
|
||||
if (alert.getCurrentStock() <= 0) alert.setAlertLevel("OUT");
|
||||
else if (alert.getCurrentStock() <= alert.getMinStock()) alert.setAlertLevel("LOW");
|
||||
alert.setCreateTime(new Date());
|
||||
alertService.save(alert);
|
||||
return R.ok(alert);
|
||||
}
|
||||
|
||||
@GetMapping("/stats")
|
||||
public R<?> getStats() {
|
||||
Map<String, Object> stats = new HashMap<>();
|
||||
stats.put("total", alertService.count());
|
||||
LambdaQueryWrapper<PharmacyStockAlert> w = new LambdaQueryWrapper<>();
|
||||
w.eq(PharmacyStockAlert::getAlertLevel, "LOW");
|
||||
stats.put("low", alertService.count(w));
|
||||
w.eq(PharmacyStockAlert::getAlertLevel, "OUT");
|
||||
stats.put("out", alertService.count(w));
|
||||
return R.ok(stats);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IReturnMedicineAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ReturnMedicineDto;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 退药(退耗材)管理
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025/4/4
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/return-medicine")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class ReturnMedicineController {
|
||||
|
||||
@Resource
|
||||
public IReturnMedicineAppService returnMedicineAppService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> returnMedicineInit() {
|
||||
return returnMedicineAppService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param encounterInfoDto 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
@GetMapping(value = "/return-patient-page")
|
||||
public R<?> getReturnMedicinePatientPage(EncounterInfoDto encounterInfoDto,
|
||||
@RequestParam(value = "searchKey", defaultValue = "") String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return returnMedicineAppService.getReturnMedicinePatientPage(encounterInfoDto, searchKey, pageNo, pageSize,
|
||||
request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询退药信息
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param refundStatus 退药id
|
||||
* @return 退药信息
|
||||
*/
|
||||
@GetMapping("/medicine-return-list")
|
||||
public R<?> getReturnMedicineInfo(@RequestParam Long encounterId, @RequestParam Integer refundStatus) {
|
||||
return returnMedicineAppService.getReturnMedicineInfo(encounterId, refundStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药处理
|
||||
*
|
||||
* @param medicineReturnList 退药清单
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/medicine-return")
|
||||
public R<?> medicineReturn(@RequestBody List<ReturnMedicineDto> medicineReturnList) {
|
||||
return returnMedicineAppService.medicineReturn(medicineReturnList);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.ISummaryDispenseMedicineAppService;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 住院汇总发药
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025/6/3
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/summary-dispense-medicine")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class SummaryDispenseMedicineController {
|
||||
|
||||
@Resource
|
||||
public ISummaryDispenseMedicineAppService medicineSummaryDispenseService;
|
||||
|
||||
/**
|
||||
* 汇总发药
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/summary-dispense-medicine")
|
||||
public R<?> SummaryDispenseMedicine(@RequestBody List<String> summaryNoList) {
|
||||
return medicineSummaryDispenseService.SummaryDispenseMedicine(summaryNoList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param summaryNoList 汇总单列表
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/dispense-cancel")
|
||||
public R<?> dispenseCancel(@RequestBody List<String> summaryNoList) {
|
||||
return medicineSummaryDispenseService.dispenseCancel(summaryNoList);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 住院发药
|
||||
// *
|
||||
// * @param searchParam 查询条件
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param request 请求数据
|
||||
// */
|
||||
// @GetMapping(value = "/excel-out")
|
||||
// public void excelOut(MedicineSummarySearchParam searchParam,
|
||||
// @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
// @RequestParam(value = "pageSize", defaultValue = "10000") Integer pageSize,
|
||||
// @RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request,
|
||||
// HttpServletResponse response) {
|
||||
// medicineSummaryDispenseService.makeExcelFile(searchParam, pageNo, pageSize, searchKey, request, response);
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 住院汇总
|
||||
// *
|
||||
// * @param searchParam 查询条件
|
||||
// * @param searchKey 模糊查询关键字
|
||||
// * @param pageNo 当前页码
|
||||
// * @param pageSize 查询条数
|
||||
// * @param request 请求数据
|
||||
// */
|
||||
// @GetMapping("/excel-put")
|
||||
// public void excelPut(FromSearchParam searchParam,
|
||||
// @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
// @RequestParam(value = "pageSize", defaultValue = "10000") Integer pageSize,
|
||||
// @RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request,
|
||||
// HttpServletResponse response) {
|
||||
// medicineSummaryDispenseService.takeExcelField(searchParam, searchKey, pageNo, pageSize, request, response);
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,106 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.controller;
|
||||
|
||||
import com.core.common.core.domain.R;
|
||||
import com.healthlink.his.web.pharmacy.dispense.appservice.IWesternMedicineDispenseAppService;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.DispenseItemDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ItemDispenseOrderDto;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 西药发药
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025/3/14
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/pharmacy-manage/western-medicine-dispense")
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class WesternMedicineDispenseController {
|
||||
|
||||
@Resource
|
||||
public IWesternMedicineDispenseAppService westernMedicineDispenseService;
|
||||
|
||||
/**
|
||||
* 获取页面初始化信息
|
||||
*
|
||||
* @return 初始化信息
|
||||
*/
|
||||
@GetMapping(value = "/init")
|
||||
public R<?> medicineDispenseInit() {
|
||||
return westernMedicineDispenseService.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询病人列表
|
||||
*
|
||||
* @param encounterInfoSearchParam 查询条件
|
||||
* @param searchKey 模糊查询关键字
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @param request 请求数据
|
||||
* @return 病人列表
|
||||
*/
|
||||
@GetMapping("/encounter-list")
|
||||
public R<?> getEncounterInfoList(EncounterInfoSearchParam encounterInfoSearchParam, String searchKey,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, HttpServletRequest request) {
|
||||
return westernMedicineDispenseService.getEncounterInfoListPage(encounterInfoSearchParam, searchKey, pageNo,
|
||||
pageSize, request);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发药单查询
|
||||
*
|
||||
* @param itemDispenseOrderDto 查询信息
|
||||
* @param pageNo 当前页码
|
||||
* @param pageSize 查询条数
|
||||
* @return 处方单
|
||||
*/
|
||||
@GetMapping("/medicine-order")
|
||||
public R<?> getMedicineDispenseOrderList(ItemDispenseOrderDto itemDispenseOrderDto,
|
||||
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
return westernMedicineDispenseService.getMedicineDispenseOrderList(itemDispenseOrderDto, pageNo, pageSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 配药
|
||||
*
|
||||
* @param dispenseMedicineList 配药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/prepare")
|
||||
public R<?> medicinePrepare(@RequestBody List<DispenseItemDto> dispenseMedicineList) {
|
||||
return westernMedicineDispenseService.medicinePrepare(dispenseMedicineList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 核对发药
|
||||
*
|
||||
* @param dispenseMedicineList 发药信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/medicine-dispense")
|
||||
public R<?> medicineDispense(@RequestBody List<DispenseItemDto> dispenseMedicineList) {
|
||||
return westernMedicineDispenseService.medicineDispense(dispenseMedicineList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作废
|
||||
*
|
||||
* @param dispenseMedicineList 作废信息
|
||||
* @return 处理结果
|
||||
*/
|
||||
@PutMapping("/medicine-cancel")
|
||||
public R<?> medicineCancel(@RequestBody List<DispenseItemDto> dispenseMedicineList) {
|
||||
return westernMedicineDispenseService.medicineCancel(dispenseMedicineList);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发放列表初始化
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DispenseInitDto {
|
||||
|
||||
/** 科室列表 */
|
||||
private List<DepartmentOption> departmentOptions;
|
||||
|
||||
/** 未发药原因 */
|
||||
private List<NotPerformedReasonOption> notPerformedReasonOptions;
|
||||
|
||||
/** 发药状态 */
|
||||
private List<DispenseStatusOption> dispenseStatusOptions;
|
||||
|
||||
/** 发药状态 */
|
||||
private List<PreparerDoctorOption> preparerDoctorOptions;
|
||||
|
||||
/** 患者类型 */
|
||||
private List<EncounterClassOption> encounterClassOptions;
|
||||
|
||||
@Data
|
||||
public static class DepartmentOption {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
|
||||
public DepartmentOption(Long value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class NotPerformedReasonOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public NotPerformedReasonOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class EncounterClassOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public EncounterClassOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Data
|
||||
public static class PreparerDoctorOption {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
|
||||
public PreparerDoctorOption(Long value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
// 手动添加 setter 方法以确保编译正确
|
||||
public DispenseInitDto setDepartmentOptions(List<DepartmentOption> departmentOptions) {
|
||||
this.departmentOptions = departmentOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispenseInitDto setNotPerformedReasonOptions(List<NotPerformedReasonOption> notPerformedReasonOptions) {
|
||||
this.notPerformedReasonOptions = notPerformedReasonOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispenseInitDto setDispenseStatusOptions(List<DispenseStatusOption> dispenseStatusOptions) {
|
||||
this.dispenseStatusOptions = dispenseStatusOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispenseInitDto setPreparerDoctorOptions(List<PreparerDoctorOption> preparerDoctorOptions) {
|
||||
this.preparerDoctorOptions = preparerDoctorOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public DispenseInitDto setEncounterClassOptions(List<EncounterClassOption> encounterClassOptions) {
|
||||
this.encounterClassOptions = encounterClassOptions;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 药品发放和库存表连接信息
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DispenseInventoryDto {
|
||||
|
||||
/** 药品发放表主键ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dispenseId;
|
||||
|
||||
/** 就诊id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long encounterId;
|
||||
|
||||
/** 请求ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long reqId;
|
||||
|
||||
/** 退的请求id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long refundId;
|
||||
|
||||
/** 病人id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long patientId;
|
||||
|
||||
/** 请求单位编码 */
|
||||
private String dispenseUnitCode;
|
||||
|
||||
/** 请求数量 */
|
||||
private BigDecimal dispenseQuantity;
|
||||
|
||||
/** 发放状态 */
|
||||
private Integer dispenseStatus;
|
||||
|
||||
/** 库存项目表主键ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inventoryId;
|
||||
|
||||
/** 拆零单位 */
|
||||
private String inventoryUnitCode;
|
||||
|
||||
/** 当前库存数量(拆零单位) */
|
||||
private BigDecimal inventoryQuantity;
|
||||
|
||||
/** 拆零比 */
|
||||
private BigDecimal partPercent;
|
||||
|
||||
/** 批号 */
|
||||
private String lotNumber;
|
||||
|
||||
/** 生产日期 */
|
||||
private Date productionDate;
|
||||
|
||||
/** 发药时间 */
|
||||
private Date dispenseTime;
|
||||
|
||||
/** 有效期止 */
|
||||
private Date expirationDate;
|
||||
|
||||
/** 追溯码 */
|
||||
private String traceNo;
|
||||
|
||||
/** 医保编码 */
|
||||
private String ybNo;
|
||||
|
||||
/** 就诊编号 */
|
||||
private String encounterNo;
|
||||
|
||||
/** 项目编码 */
|
||||
private String itemNo;
|
||||
|
||||
/** 执业资格证号 */
|
||||
private String pharPracCertNo;
|
||||
|
||||
/** 发药编号 */
|
||||
private String dispenseNo;
|
||||
|
||||
/** 处方标志 */
|
||||
private Integer rxFlag;
|
||||
|
||||
/** 配药人 */
|
||||
private String preparerName;
|
||||
|
||||
/** 发药人 */
|
||||
private String dispenseName;
|
||||
|
||||
/** 开方人 */
|
||||
private String practitionerName;
|
||||
|
||||
/** 证件号码 */
|
||||
private String idCard;
|
||||
|
||||
/** 患者姓名 */
|
||||
private String patientName;
|
||||
|
||||
/** 所在表名 */
|
||||
private String itemTable;
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 发药/耗材信息
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-05-23
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class DispenseItemDto {
|
||||
|
||||
/**
|
||||
* 配药人
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long preparerId;
|
||||
|
||||
/**
|
||||
* 发放ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dispenseId;
|
||||
|
||||
/**
|
||||
* 发药数量
|
||||
*/
|
||||
private BigDecimal quantity;
|
||||
|
||||
/**
|
||||
* 批号
|
||||
*/
|
||||
private String lotNumber;
|
||||
|
||||
/**
|
||||
* 单据号
|
||||
*/
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 追溯码
|
||||
*/
|
||||
private String traceNo;
|
||||
|
||||
/**
|
||||
* 未发原因
|
||||
*/
|
||||
private Integer notPerformedReasonEnum;
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 发药状态选项
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
public class DispenseStatusOption {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public DispenseStatusOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 就诊人员列表
|
||||
*
|
||||
* @author WangYang
|
||||
* @date 2025-03-18
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class EncounterInfoDto {
|
||||
|
||||
/** 就诊ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long encounterId;
|
||||
|
||||
/** 发放药房 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
|
||||
/** 科室 */
|
||||
private String departmentName;
|
||||
|
||||
/** 科室 */
|
||||
private Long departmentId;
|
||||
|
||||
/** 患者姓名 */
|
||||
private String patientName;
|
||||
|
||||
/**
|
||||
* 身份证号
|
||||
*/
|
||||
private String idCard;
|
||||
|
||||
/**
|
||||
* 拼音码
|
||||
*/
|
||||
private String patientPyStr;
|
||||
|
||||
/**
|
||||
* 五笔码
|
||||
*/
|
||||
private String patientWbStr;
|
||||
|
||||
/**
|
||||
* 就诊编码
|
||||
*/
|
||||
private String encounterNo;
|
||||
|
||||
/** 性别 */
|
||||
private Integer genderEnum;
|
||||
private String genderEnum_enumText;
|
||||
|
||||
/** 发药状态 */
|
||||
private Integer statusEnum;
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/** 退药状态 */
|
||||
private Integer refundEnum;
|
||||
private String refundEnum_enumText;
|
||||
|
||||
/** 就诊日期 */
|
||||
private String receptionTime;
|
||||
|
||||
/** 住院日期 */
|
||||
private String startTime;
|
||||
|
||||
/** 年龄 */
|
||||
private String age;
|
||||
|
||||
/** 生日 */
|
||||
private Date birthDate;
|
||||
|
||||
/** 电话 */
|
||||
private String phone;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 患者列表查询条件
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class EncounterInfoSearchParam implements Serializable {
|
||||
|
||||
/** 执行状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
/** 患者类型 */
|
||||
private Integer classEnum;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class FromSearchParam implements Serializable {
|
||||
|
||||
/** 单据号 */
|
||||
private String busNo;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 汇总发药单信息
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
public class FromSummaryDto {
|
||||
|
||||
/** 单据号 */
|
||||
private String busNo;
|
||||
|
||||
/** 申请时间 */
|
||||
private Date applyTime;
|
||||
|
||||
/** 领药人 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applicantId;
|
||||
private String applicantName;
|
||||
|
||||
/** 发放地点 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long sourceLocationId;
|
||||
private String sourceLocationName;
|
||||
|
||||
/** 状态 */
|
||||
private Integer statusEnum;
|
||||
private String statusEnum_enumText;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class FromSummarySearchParam implements Serializable {
|
||||
|
||||
/** 单据号 */
|
||||
private String busNo;
|
||||
|
||||
/** 发药状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 库存明细dto
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-11-20
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class InventoryDetailDto {
|
||||
|
||||
/** 库存项目表主键ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long inventoryId;
|
||||
|
||||
/** 项目ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long itemId;
|
||||
|
||||
/** 库房ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
|
||||
/** 拆零单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String inventoryUnitCode;
|
||||
private String inventoryUnitCode_dictText;
|
||||
|
||||
/** 大单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String maxUnitCode;
|
||||
private String maxUnitCode_dictText;
|
||||
|
||||
/** 当前库存数量(拆零单位) */
|
||||
private BigDecimal inventoryQuantity;
|
||||
|
||||
/** 拆零比 */
|
||||
private BigDecimal partPercent;
|
||||
|
||||
/** 批号 */
|
||||
private String inventoryLotNumber;
|
||||
|
||||
/** 有效期止 */
|
||||
private Date expirationDate;
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发药/耗材单
|
||||
*
|
||||
* @author wangyang
|
||||
* @date 2025-03-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ItemDispenseOrderDto {
|
||||
|
||||
/**
|
||||
* 发放药房
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long locationId;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long itemId;
|
||||
|
||||
/**
|
||||
* 发放id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dispenseId;
|
||||
|
||||
/**
|
||||
* 请求id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long requestId;
|
||||
|
||||
/**
|
||||
* 就诊id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long encounterId;
|
||||
|
||||
/**
|
||||
* 发放药房
|
||||
*/
|
||||
@Excel(name = "发放药房", sort = 3)
|
||||
private String locationName;
|
||||
|
||||
/**
|
||||
* 批次号
|
||||
*/
|
||||
@Excel(name = "批次号", sort = 4)
|
||||
private String lotNumber;
|
||||
|
||||
/**
|
||||
* 科室
|
||||
*/
|
||||
@Excel(name = "科室", sort = 5)
|
||||
private String departmentName;
|
||||
|
||||
/**
|
||||
* 开单医生ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long doctorId;
|
||||
|
||||
/**
|
||||
* 开单医生
|
||||
*/
|
||||
@Excel(name = "开单医生", sort = 6)
|
||||
private String doctorName;
|
||||
|
||||
/**
|
||||
* 发药医生
|
||||
*/
|
||||
@Excel(name = "发药医生", sort = 7)
|
||||
private String dispenseDoctorName;
|
||||
|
||||
/**
|
||||
* 项目类型
|
||||
*/
|
||||
@Dict(dictCode = "med_category_code")
|
||||
private String itemType;
|
||||
@Excel(name = "项目类型", sort = 8)
|
||||
private String itemType_dictText;
|
||||
|
||||
/**
|
||||
* 发药状态
|
||||
*/
|
||||
private Integer statusEnum;
|
||||
@Excel(name = "发药状态", sort = 9)
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/**
|
||||
* 诊断名称
|
||||
*/
|
||||
@Excel(name = "诊断名称", sort = 10)
|
||||
private String conditionName;
|
||||
|
||||
/**
|
||||
* 处方号
|
||||
*/
|
||||
@Excel(name = "处方号", sort = 11)
|
||||
private String prescriptionNo;
|
||||
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
@Excel(name = "项目名称", sort = 1, width = 30)
|
||||
private String itemName;
|
||||
|
||||
/**
|
||||
* 商品名称
|
||||
*/
|
||||
private String merchandiseName;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@Excel(name = "规格", sort = 2, width = 30)
|
||||
private String totalVolume;
|
||||
|
||||
/**
|
||||
* 单次剂量
|
||||
*/
|
||||
@Excel(name = "单次剂量", sort = 12)
|
||||
private BigDecimal dose;
|
||||
|
||||
/**
|
||||
* 拆零比
|
||||
*/
|
||||
private BigDecimal partPercent;
|
||||
|
||||
/**
|
||||
* 用药频次
|
||||
*/
|
||||
@Dict(dictCode = "rate_code")
|
||||
private String rateCode;
|
||||
@Excel(name = "用药频次", sort = 13)
|
||||
private String rateCode_dictText;
|
||||
|
||||
/**
|
||||
* 用法
|
||||
*/
|
||||
@Dict(dictCode = "method_code")
|
||||
private String methodCode;
|
||||
@Excel(name = "用法", sort = 14)
|
||||
private String methodCode_dictText;
|
||||
|
||||
/**
|
||||
* 剂量单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String doseUnitCode;
|
||||
@Excel(name = "剂量单位", sort = 15)
|
||||
private String doseUnitCode_dictText;
|
||||
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
@Excel(name = "单位", sort = 16)
|
||||
private String unitCode_dictText;
|
||||
|
||||
/**
|
||||
* 单次发药数
|
||||
*/
|
||||
@Excel(name = "单次发药数", sort = 17)
|
||||
private Integer dispensePerQuantity;
|
||||
|
||||
/**
|
||||
* 每次发药供应天数
|
||||
*/
|
||||
@Excel(name = "每次发药供应天数", sort = 18)
|
||||
private Integer dispensePerDuration;
|
||||
|
||||
/**
|
||||
* 请求数量
|
||||
*/
|
||||
private BigDecimal requestQuantity;
|
||||
|
||||
/**
|
||||
* 数量
|
||||
*/
|
||||
@Excel(name = "数量", sort = 19)
|
||||
private BigDecimal quantity;
|
||||
|
||||
/**
|
||||
* 单价
|
||||
*/
|
||||
@Excel(name = "单价", sort = 20)
|
||||
private BigDecimal unitPrice;
|
||||
|
||||
/**
|
||||
* 金额
|
||||
*/
|
||||
@Excel(name = "金额", sort = 21)
|
||||
private BigDecimal totalPrice;
|
||||
/**
|
||||
* 组合号
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long groupId;
|
||||
|
||||
/**
|
||||
* 就诊NO
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@Excel(name = "就诊NO", sort = 24)
|
||||
private String encounterBusNo;
|
||||
|
||||
/**
|
||||
* 开具日期
|
||||
*/
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@Excel(name = "开具日期", sort = 25, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 25)
|
||||
private Date reqAuthoredTime;
|
||||
|
||||
/**
|
||||
* 接收皮试标志
|
||||
*/
|
||||
@Excel(name = "皮试标志", sort = 26)
|
||||
private String skinTestFlagDesc;
|
||||
private Integer skinTestFlag;
|
||||
|
||||
/**
|
||||
* 接收中药标识
|
||||
*/
|
||||
@Excel(name = "中药标识", sort = 27)
|
||||
private String tcmFlagDesc;
|
||||
private Integer tcmFlag;
|
||||
|
||||
/**
|
||||
* 所在表
|
||||
*/
|
||||
@Excel(name = "所在表", sort = 28, width = 30)
|
||||
private String itemTable;
|
||||
|
||||
/**
|
||||
* 生产厂家
|
||||
*/
|
||||
@Excel(name = "生产厂家", sort = 22, width = 35)
|
||||
private String manufacturerText;
|
||||
|
||||
/**
|
||||
* 追溯码
|
||||
*/
|
||||
@Excel(name = "追溯码", sort = 23)
|
||||
private String traceNo;
|
||||
|
||||
/**
|
||||
* 就诊类型
|
||||
*/
|
||||
@Dict(dictCode = "med_type")
|
||||
private String medTypeCode;
|
||||
private String medTypeCode_dictText;
|
||||
|
||||
/**
|
||||
* 发药类型(处方类型:门诊/住院等)
|
||||
*/
|
||||
private Integer dispenseEnum;
|
||||
private String dispenseEnum_enumText;
|
||||
|
||||
/**
|
||||
* 输液标志
|
||||
*/
|
||||
private Integer injectFlag;
|
||||
|
||||
/**
|
||||
* 拆分属性
|
||||
*/
|
||||
private Integer partAttributeEnum;
|
||||
|
||||
/**
|
||||
* 库存明细列表
|
||||
*/
|
||||
private List<InventoryDetailDto> inventoryDetailList;
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 农大门诊配/发药 参数类
|
||||
*
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class JlauDispenseParam {
|
||||
|
||||
/**
|
||||
* 配/发药信息
|
||||
*/
|
||||
private List<DispenseItemDto> dispenseMedicineList;
|
||||
|
||||
/**
|
||||
* UI选择的发药时间
|
||||
*/
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date dispenseTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,181 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 发药明细账分页列表 dto
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025-04-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedDetailedAccountPageDto {
|
||||
|
||||
/**
|
||||
* 门诊号
|
||||
*/
|
||||
private String outpatientNo;
|
||||
|
||||
/**
|
||||
* 处方号
|
||||
*/
|
||||
private String prescriptionNo;
|
||||
|
||||
/**
|
||||
* 患者
|
||||
*/
|
||||
private String patientName;
|
||||
|
||||
/**
|
||||
* 接收发药数量
|
||||
*/
|
||||
@Excel(name = "发药数量", sort = 8)
|
||||
private String dispenseQuantityStr;
|
||||
|
||||
/**
|
||||
* 接收发药金额
|
||||
*/
|
||||
@Excel(name = "发药金额", sort = 9)
|
||||
private String dispensePriceStr;
|
||||
|
||||
/**
|
||||
* 接收退药数量
|
||||
*/
|
||||
@Excel(name = "退药数量", sort = 10)
|
||||
private String refundQuantityStr;
|
||||
|
||||
/**
|
||||
* 接收退药金额
|
||||
*/
|
||||
@Excel(name = "退药金额", sort = 11)
|
||||
private String refundPriceStr;
|
||||
/**
|
||||
* 成本金额
|
||||
*/
|
||||
@Excel(name = "成本金额", sort = 12)
|
||||
private String costPriceStr;
|
||||
|
||||
/**
|
||||
* 发药人ID
|
||||
*/
|
||||
private String practitionerId;
|
||||
|
||||
/**
|
||||
* 发药人名称
|
||||
*/
|
||||
@Excel(name = "发药人", sort = 1)
|
||||
private String practitionerName;
|
||||
|
||||
/**
|
||||
* 药品项目
|
||||
*/
|
||||
@Excel(name = "药品项目", sort = 3)
|
||||
private String medicationName;
|
||||
|
||||
/**
|
||||
* 药品拼音
|
||||
*/
|
||||
private String pyStr;
|
||||
|
||||
/**
|
||||
* 项目编码
|
||||
*/
|
||||
@Excel(name = "药品编码", sort = 5)
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 发药编码
|
||||
*/
|
||||
@Excel(name = "发药单号", sort = 2)
|
||||
private String dispenseNo;
|
||||
|
||||
/**
|
||||
* 医保编码
|
||||
*/
|
||||
@Excel(name = "医保编码", sort = 6, width = 30)
|
||||
private String ybNo;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@Excel(name = "规格", sort = 7, width = 30)
|
||||
private String totalVolume;
|
||||
|
||||
/**
|
||||
* 发药数量
|
||||
*/
|
||||
private Integer dispenseQuantity;
|
||||
|
||||
/**
|
||||
* 发药金额
|
||||
*/
|
||||
private BigDecimal dispensePrice;
|
||||
|
||||
/**
|
||||
* 退药数量
|
||||
*/
|
||||
private Integer refundQuantity;
|
||||
|
||||
/**
|
||||
* 退药金额
|
||||
*/
|
||||
private BigDecimal refundPrice;
|
||||
/**
|
||||
* 成本金额
|
||||
*/
|
||||
|
||||
private BigDecimal costPrice;
|
||||
|
||||
/**
|
||||
* 批号
|
||||
*/
|
||||
@Excel(name = "生产批号", sort = 13)
|
||||
private String lotNumber;
|
||||
|
||||
/**
|
||||
* 厂商
|
||||
*/
|
||||
@Excel(name = "厂家/产地", sort = 14, width = 35)
|
||||
private String manufacturerText;
|
||||
|
||||
/**
|
||||
* 供应商
|
||||
*/
|
||||
@Excel(name = "供应商", sort = 15, width = 35)
|
||||
private String supplierName;
|
||||
|
||||
/**
|
||||
* 发药单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/**
|
||||
* 退药单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String refundUnitCode;
|
||||
private String refundUnitCode_dictText;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 发药时间
|
||||
*/
|
||||
@Excel(name = "发药时间", sort = 16, dateFormat = "yyyy-MM-dd HH:mm:ss", width = 35)
|
||||
private Date dispenseTime;
|
||||
|
||||
/**
|
||||
* 项目所在表
|
||||
*/
|
||||
@Excel(name = "项目类别", sort = 4)
|
||||
private String itemTable;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import com.healthlink.his.administration.domain.Practitioner;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 发药明细初始化信息
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025-04-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedDetailsInitDto {
|
||||
|
||||
/** 发药人 */
|
||||
private List<Practitioner> practitionerList;
|
||||
|
||||
/** 结算状态 */
|
||||
private List<statusEnumOption> statusSettlementOptions;
|
||||
|
||||
/** 出院状态 */
|
||||
private List<statusEnumOption> statusDischargeOptions;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@Data
|
||||
public static class statusEnumOption {
|
||||
private Integer value;
|
||||
private String info;
|
||||
|
||||
public statusEnumOption(Integer value, String info) {
|
||||
this.value = value;
|
||||
this.info = info;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 发药明细查询条件
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025-04-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedDetailsSearchParam {
|
||||
|
||||
/**
|
||||
* 发药时间
|
||||
*/
|
||||
private Date dispenseTime;
|
||||
|
||||
/**
|
||||
* 药房
|
||||
*/
|
||||
private Long locationId;
|
||||
|
||||
/**
|
||||
* 患者姓名
|
||||
*/
|
||||
private String patientName;
|
||||
|
||||
/**
|
||||
* 发药人
|
||||
*/
|
||||
private Long practitionerId;
|
||||
|
||||
/**
|
||||
* 药品名称
|
||||
*/
|
||||
private String medicationName;
|
||||
|
||||
/**
|
||||
* 药品项目(药品编码)
|
||||
*/
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 出院状态
|
||||
*/
|
||||
private Integer dischargeStatus;
|
||||
|
||||
/**
|
||||
* 门诊住院flg
|
||||
*/
|
||||
private Integer flag;
|
||||
|
||||
/**
|
||||
* 项目所在表
|
||||
*/
|
||||
private String itemTable;
|
||||
|
||||
/**
|
||||
* 统计类型
|
||||
*/
|
||||
private Integer inventoryScope;
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import com.core.common.annotation.Excel;
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 汇总发药信息
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-06-03
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedicineSummaryDto {
|
||||
|
||||
/**
|
||||
* 单据号
|
||||
*/
|
||||
@Excel(name = "单据号", sort = 8, width = 35)
|
||||
private String busNo;
|
||||
|
||||
/**
|
||||
* 供应请求id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long requestId;
|
||||
|
||||
/**
|
||||
* 供应发放id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long deliveryId;
|
||||
|
||||
/**
|
||||
* 项目表
|
||||
*/
|
||||
private String itemTable;
|
||||
/**
|
||||
* 项目名
|
||||
*/
|
||||
@Excel(name = "项目名", sort = 2, width = 40)
|
||||
private String itemName;
|
||||
|
||||
/**
|
||||
* 项目id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long itemId;
|
||||
|
||||
/**
|
||||
* 规格
|
||||
*/
|
||||
@Excel(name = "规格", sort = 3)
|
||||
private String totalVolume;
|
||||
|
||||
/**
|
||||
* 批号
|
||||
*/
|
||||
@Excel(name = "批号", sort = 4)
|
||||
private String lotNumber;
|
||||
|
||||
/**
|
||||
* 请求数
|
||||
*/
|
||||
@Excel(name = "数量", sort = 5)
|
||||
private BigDecimal quantity;
|
||||
|
||||
/**
|
||||
* 序号
|
||||
*/
|
||||
@Excel(name = "序号", sort = 1)
|
||||
private Integer number;
|
||||
|
||||
/**
|
||||
* 生产厂家
|
||||
*/
|
||||
@Excel(name = "生产厂家", sort = 7, width = 45)
|
||||
private String manufacturerText;
|
||||
/**
|
||||
* 单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/**
|
||||
* 常规单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String maxUnitCode;
|
||||
private String maxUnitCode_dictText;
|
||||
|
||||
/**
|
||||
* 最小单位
|
||||
*/
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String minUnitCode;
|
||||
private String minUnitCode_dictText;
|
||||
|
||||
/**
|
||||
* 发放地点
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long sourceLocationId;
|
||||
@Excel(name = "发放地点", sort = 6)
|
||||
private String sourceLocationName;
|
||||
|
||||
/**
|
||||
* 申请科室
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long orgId;
|
||||
private String orgName;
|
||||
|
||||
/**
|
||||
* 领药人
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applicantId;
|
||||
private String applicantName;
|
||||
|
||||
/**
|
||||
* 申请时间
|
||||
*/
|
||||
private Date applyTime;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
private Integer statusEnum;
|
||||
private String statusEnum_enumText;
|
||||
|
||||
/**
|
||||
* 患者信息
|
||||
*/
|
||||
private String patientInfo;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.administration.domain.Practitioner;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 住院发药初期dto
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-06-03
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedicineSummaryInitDto {
|
||||
|
||||
/** 科室列表 */
|
||||
private List<LongOptions> departmentOptions;
|
||||
/** 领药人列表 */
|
||||
private List<Practitioner> applicantOptions;
|
||||
|
||||
/** 发药状态 */
|
||||
private List<IntegerOptions> dispenseStatusOptions;
|
||||
|
||||
/** 未发药原因 */
|
||||
private List<IntegerOptions> notPerformedReasonOptions;
|
||||
|
||||
@Data
|
||||
public static class LongOptions {
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
|
||||
public LongOptions(Long value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class IntegerOptions {
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public IntegerOptions(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 患者列表查询条件
|
||||
*
|
||||
* @author yuxj
|
||||
* @date 2025-06-03
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class MedicineSummarySearchParam implements Serializable {
|
||||
|
||||
/** 就诊ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long encounterId;
|
||||
|
||||
/** 科室 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long orgId;
|
||||
|
||||
/** 领药人 */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long applicantId;
|
||||
|
||||
/** 发药状态 */
|
||||
private Integer statusEnum;
|
||||
|
||||
/** 追溯码*/
|
||||
private String traceNo;
|
||||
|
||||
/** 供应发放id */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long deliveryId;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 待发药明细分页列表 dto
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025-04-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PendingMedicationPageDto {
|
||||
|
||||
/** 药品编码 */
|
||||
private String medicineNo;
|
||||
|
||||
/** 药品名称 */
|
||||
private String medicineName;
|
||||
|
||||
/** 待发数量 */
|
||||
private String dispenseQuantity;
|
||||
|
||||
/** 请求单位编码 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/** 发药类型(处方类型) */
|
||||
private Integer dispenseEnum;
|
||||
private String dispenseEnum_enumText;
|
||||
|
||||
/** 患者姓名 */
|
||||
private String patientName;
|
||||
|
||||
/** 处方号 */
|
||||
private String prescriptionNo;
|
||||
|
||||
/** 门诊号 */
|
||||
private String outpatientNo;
|
||||
|
||||
/** 住院号 */
|
||||
private String admissionNo;
|
||||
|
||||
/** 开单时间 */
|
||||
private String createTime;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 待发药明细查询条件
|
||||
*
|
||||
* @author yuanzs
|
||||
* @date 2025-04-14
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class PendingMedicationSearchParam {
|
||||
|
||||
// /** 开始时间 */
|
||||
// private Date startTime;
|
||||
//
|
||||
// /** 结束时间 */
|
||||
// private Date endTime;
|
||||
|
||||
/** 开单时间 */
|
||||
private String createTime;
|
||||
|
||||
/** 药品编码 */
|
||||
private String medicineNo;
|
||||
|
||||
/** 药品名称 */
|
||||
private String medicineName;
|
||||
|
||||
/** 统计类型 */
|
||||
// private Integer statisticTypeEnum;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
/**
|
||||
* 退药信息
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-05-07
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ReturnMedicineDto {
|
||||
|
||||
/** 药品请求ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long requestId;
|
||||
|
||||
/** 药品发放ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dispenseId;
|
||||
|
||||
/** 业务表名 */
|
||||
private String tableName;
|
||||
|
||||
/** 退药追溯码 */
|
||||
private String traceNo;
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.healthlink.his.common.annotation.Dict;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
/**
|
||||
* 退药信息
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025-04-07
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ReturnMedicineInfoDto {
|
||||
|
||||
/** 药品请求ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long requestId;
|
||||
|
||||
/** 退药ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long refundMedicineId;
|
||||
|
||||
/** 药品发放ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long dispenseId;
|
||||
|
||||
/** 药品ID */
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long itemId;
|
||||
|
||||
/** 开单医生 */
|
||||
private String doctorName;
|
||||
|
||||
/** 批号 */
|
||||
private String lotNumber;
|
||||
|
||||
/** 药品 */
|
||||
private String itemName;
|
||||
|
||||
/** 已退数量 */
|
||||
private Integer dispenseQuantity;
|
||||
|
||||
/** 单位 */
|
||||
@Dict(dictCode = "unit_code")
|
||||
private String unitCode;
|
||||
private String unitCode_dictText;
|
||||
|
||||
/** 总价 */
|
||||
private BigDecimal totalPrice;
|
||||
|
||||
/** 退药状态 */
|
||||
private Integer refundEnum;
|
||||
private String refundEnum_enumText;
|
||||
|
||||
/** 退药请求状态 */
|
||||
private Integer reqStatus;
|
||||
private String reqStatus_enumText;
|
||||
|
||||
/** 业务表名 */
|
||||
private String serviceTable;
|
||||
|
||||
/** 请求数量 */
|
||||
private Integer quantity;
|
||||
|
||||
/** 追溯码 */
|
||||
private String traceNo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import tools.jackson.databind.annotation.JsonSerialize;
|
||||
import tools.jackson.databind.ser.std.ToStringSerializer;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025-04-04
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class ReturnMedicineInitDto {
|
||||
|
||||
/** 科室列表 */
|
||||
private List<ReturnMedicineInitDto.DepartmentOption> departmentOptions;
|
||||
|
||||
/** 退药状态 */
|
||||
private List<ReturnMedicineInitDto.RefundStatusOption> refundStatusOptions;
|
||||
|
||||
/**
|
||||
* 科室列表
|
||||
*/
|
||||
@Data
|
||||
public static class DepartmentOption {
|
||||
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long value;
|
||||
private String label;
|
||||
|
||||
public DepartmentOption(Long value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 退药状态
|
||||
*/
|
||||
@Data
|
||||
public static class RefundStatusOption {
|
||||
|
||||
private Integer value;
|
||||
private String label;
|
||||
|
||||
public RefundStatusOption(Integer value, String label) {
|
||||
this.value = value;
|
||||
this.label = label;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 待发放库存信息
|
||||
*
|
||||
* @author yangmo
|
||||
* @date 2025-04-08
|
||||
*/
|
||||
@Data
|
||||
@Accessors(chain = true)
|
||||
public class UnDispenseInventoryDto implements Serializable {
|
||||
|
||||
/** 库存ID */
|
||||
private Long inventoryId;
|
||||
|
||||
/** 发药ID */
|
||||
private Long dispenseId;
|
||||
|
||||
/** 请求ID */
|
||||
private Long requestId;
|
||||
|
||||
/** 项目ID */
|
||||
private Long itemId;
|
||||
|
||||
/** 批号 */
|
||||
private String lotNumber;
|
||||
|
||||
/** 发放药房id */
|
||||
private Long locationId;
|
||||
|
||||
/** 拆零单位 */
|
||||
private String inventoryUnitCode;
|
||||
|
||||
/** 发放单位 */
|
||||
private String dispenseUnit;
|
||||
|
||||
/** 当前库存数量(拆零单位) */
|
||||
private BigDecimal inventoryQuantity;
|
||||
|
||||
/** 已发数量 */
|
||||
private BigDecimal dispenseQuantity;
|
||||
|
||||
/** 发药状态 */
|
||||
private Integer dispenseStatus;
|
||||
|
||||
/** 发药数量 */
|
||||
private BigDecimal quantity;
|
||||
|
||||
/** 拆零比 */
|
||||
private BigDecimal partPercent;
|
||||
|
||||
/** 药品名称 */
|
||||
private String itemName;
|
||||
|
||||
/** 库存状态 */
|
||||
private Integer inventoryStatusEnum;
|
||||
|
||||
/** 有效期至 */
|
||||
private Date expirationDate;
|
||||
|
||||
/** 追溯码 */
|
||||
private String TraceNo;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.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.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ReturnMedicineInfoDto;
|
||||
|
||||
/**
|
||||
* TODO:概括描述当前类的主要用途和注意事项
|
||||
*
|
||||
* @author zwh
|
||||
* @date 2025-12-29
|
||||
*/
|
||||
@Repository
|
||||
public interface InHospitalReturnMedicineAppMapper {
|
||||
|
||||
/**
|
||||
* 查询退药患者分页列表
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param refundStatus 退药状态
|
||||
* @param pendingRefund 退药状态:待退药
|
||||
* @param refunded 退药状态:已退药
|
||||
* @param imp 患者类型:住院
|
||||
* @param medMedicationDefinition 药品表
|
||||
* @param admDeviceDefinition 耗材表
|
||||
* @return 退药患者分页列表
|
||||
*/
|
||||
Page<EncounterInfoDto> selectEncounterInfoListPage(@Param("page") Page<EncounterInfoDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<EncounterInfoDto> queryWrapper,
|
||||
@Param("refundStatus") Integer refundStatus, @Param("pendingRefund") Integer pendingRefund,
|
||||
@Param("refunded") Integer refunded, @Param("imp") Integer imp,
|
||||
@Param("medMedicationDefinition") String medMedicationDefinition,
|
||||
@Param("admDeviceDefinition") String admDeviceDefinition);
|
||||
|
||||
/**
|
||||
* 申请退药清单查询
|
||||
*
|
||||
* @param encounterId 就诊ID
|
||||
* @param medMedicationRequest 药品请求表
|
||||
* @param worDeviceRequest 耗材请求表
|
||||
* @param medMedicationDefinition 药品表
|
||||
* @param admDeviceDefinition 耗材表
|
||||
* @param itemTable 项目所在表
|
||||
* @param refundStatus 退药状态
|
||||
* @param pendingRefund 退药状态:待退药
|
||||
* @param refunded 退药状态:已退药
|
||||
* @return 申请退药清单
|
||||
*/
|
||||
List<ReturnMedicineInfoDto> selectReturnMedicineInfo(@Param("encounterId") Long encounterId,
|
||||
@Param("worDeviceRequest") String worDeviceRequest, @Param("medMedicationRequest") String medMedicationRequest,
|
||||
@Param("medMedicationDefinition") String medMedicationDefinition,
|
||||
@Param("admDeviceDefinition") String admDeviceDefinition, @Param("itemTable") String itemTable,
|
||||
@Param("refundStatus") Integer refundStatus, @Param("pendingRefund") Integer pendingRefund,
|
||||
@Param("refunded") Integer refunded);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.administration.domain.Practitioner;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.EncounterInfoSearchParam;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.ItemDispenseOrderDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface MedicalDeviceDispenseMapper {
|
||||
|
||||
/**
|
||||
* 就诊病人列表分页查询
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param statusEnum 发药状态
|
||||
* @param inProgress 发药状态:待发药
|
||||
* @param completed 发药状态:已发药
|
||||
* @param preparation 发药状态:待配药
|
||||
* @param prepared 发药状态:已配药
|
||||
* @return 就诊病人列表
|
||||
*/
|
||||
Page<EncounterInfoDto> selectEncounterInfoListPage(@Param("page") Page<EncounterInfoDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<EncounterInfoSearchParam> queryWrapper,
|
||||
@Param("statusEnum") Integer statusEnum, @Param("inProgress") Integer inProgress,
|
||||
@Param("completed") Integer completed, @Param("preparation") Integer preparation,
|
||||
@Param("prepared") Integer prepared);
|
||||
|
||||
/**
|
||||
* 处方单查询
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param inProgress 发药状态:待发药
|
||||
* @param completed 发药状态:已发药
|
||||
* @param preparation 发药状态:待配药
|
||||
* @param prepared 发药状态:已配药
|
||||
* @param dispenseStatus 发药状态
|
||||
* @return 处方单列表
|
||||
*/
|
||||
Page<ItemDispenseOrderDto> selectDeviceDispenseOrderPage(@Param("page") Page<ItemDispenseOrderDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<ItemDispenseOrderDto> queryWrapper,
|
||||
@Param("inProgress") Integer inProgress, @Param("completed") Integer completed,
|
||||
@Param("preparation") Integer preparation, @Param("prepared") Integer prepared,
|
||||
@Param("dispenseStatus") Integer dispenseStatus);
|
||||
|
||||
/**
|
||||
* 获取配药人下拉选列表
|
||||
*
|
||||
* @param pharmacist 参与者类型:药师
|
||||
* @return 配药人下拉选列表
|
||||
*/
|
||||
List<Practitioner> getPreparerDoctorList(@Param("pharmacist") String pharmacist);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailedAccountPageDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.MedDetailsSearchParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface MedicationDetailsMapper {
|
||||
|
||||
/**
|
||||
* 门诊人员发药明细表/门诊发药明细流水账
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param completed 发药状态:已发药
|
||||
* @param refunded 发药状态:已退药
|
||||
* @param statisticalType 统计类型
|
||||
* @param flg 1:住院 2:门诊
|
||||
* @param medMedicationDefinition 药品
|
||||
* @param admDeviceDefinition 耗材
|
||||
* @param costEnum 命中条件枚举:产品批号进价
|
||||
* @return 门诊人员发药明细表
|
||||
*/
|
||||
Page<MedDetailedAccountPageDto> selectAmbPractitionerDetailPage(@Param("page") Page<MedDetailedAccountPageDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<MedDetailsSearchParam> queryWrapper,
|
||||
@Param("completed") Integer completed, @Param("agree") Integer agree, @Param("refunded") Integer refunded,
|
||||
@Param("statisticalType") Integer statisticalType, @Param("flg") Integer flg,
|
||||
@Param("medMedicationDefinition") String medMedicationDefinition,
|
||||
@Param("admDeviceDefinition") String admDeviceDefinition, @Param("costEnum") String costEnum);
|
||||
|
||||
// /**
|
||||
// * 门诊发药明细流水账
|
||||
// *
|
||||
// * @param page 分页
|
||||
// * @param queryWrapper 查询条件
|
||||
// * @param amb 发药类型:门诊
|
||||
// * @param completed 发药状态:已发药
|
||||
// * @param refunded 发药状态:已退药
|
||||
// * @return 门诊发药明细流水账
|
||||
// */
|
||||
// Page<MedDetailedAccountPageDto> selectAmbMedicationDispenseDetailPage(
|
||||
// @Param("page") Page<MedDetailedAccountPageDto> page,
|
||||
// @Param(Constants.WRAPPER) QueryWrapper<MedDetailsSearchParam> queryWrapper, @Param("amb") Integer amb,
|
||||
// @Param("completed") Integer completed, @Param("refunded") Integer refunded)
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright ©2023 CJB-CNIT Team. All rights reserved
|
||||
*/
|
||||
package com.healthlink.his.web.pharmacy.dispense.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Constants;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationPageDto;
|
||||
import com.healthlink.his.web.pharmacy.dispense.dto.PendingMedicationSearchParam;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface PendingMedicationDetailsMapper {
|
||||
|
||||
/**
|
||||
* 分页查询待发药明细
|
||||
*
|
||||
* @param page 分页
|
||||
* @param queryWrapper 查询条件
|
||||
* @param inProgress 发药类型:待发药
|
||||
* @param preparation 发药类型:待配药
|
||||
* @param prepared 发药类型:已配药
|
||||
* @param summarized 发药类型:已汇总
|
||||
* @param amb 门诊类型
|
||||
* @param imp 住院类型
|
||||
* @return 待发药明细
|
||||
*/
|
||||
Page<PendingMedicationPageDto> selectPendingMedicationDetailsPage(
|
||||
@Param("page") Page<PendingMedicationPageDto> page,
|
||||
@Param(Constants.WRAPPER) QueryWrapper<PendingMedicationSearchParam> queryWrapper,
|
||||
@Param("inProgress") Integer inProgress,
|
||||
@Param("preparation") Integer preparation,
|
||||
@Param("prepared") Integer prepared,
|
||||
@Param("summarized") Integer summarized,
|
||||
@Param("amb") Integer amb,
|
||||
@Param("imp") Integer imp);
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user