Merge branch 'master' of codeup.aliyun.com:61c0318acd8b75daa5a125f7/medical/openhis

This commit is contained in:
Zhang.YC
2025-03-31 11:02:42 +08:00
35 changed files with 1552 additions and 161 deletions

View File

@@ -96,11 +96,11 @@ public class DiagnosisTreatmentDto {
/** 财务类别 */
@Dict(dictCode = "fin_type_code")
private String typeCode;
private String typeCode_dictText;
private String itemTypeCode;
private String itemTypeCode_dictText;
/** 医保类别 */
@Dict(dictCode = "med_chrgitm_type")
@Dict(dictCode = "yb_type")
private String ybType;
private String ybType_dictText;

View File

@@ -16,7 +16,7 @@ import lombok.experimental.Accessors;
public class DiagnosisTreatmentSelParam {
/** 目录类别 */
private Integer categoryCode;
private String categoryCode;
/** 类型 */
private Integer typeEnum;

View File

@@ -32,7 +32,6 @@ public class DiagnosisTreatmentUpDto {
private String categoryCode;
/** 编码 */
@NotBlank(message = "项目编码不能为空")
private String busNo;
/** 项目名称 */
@@ -40,16 +39,14 @@ public class DiagnosisTreatmentUpDto {
private String name;
/** 项目名称拼音 */
@NotBlank(message = "项目名称拼音不能为空")
private String pyStr;
/** 五笔拼音 */
@NotBlank(message = "五笔拼音不能为空")
private String wbStr;
/** 类型 */
@NotBlank(message = "类型不能为空")
private String typeCode;
@NotNull(message = "类型不能为空")
private Integer typeEnum;
/** 使用单位 */
@NotBlank(message = "使用单位不能为空")

View File

@@ -27,7 +27,6 @@ public class DiseaseManageUpDto {
private ConditionDefinitionSource sourceEnum;
/** 编码 */
@NotBlank(message = "疾病编码不能为空")
private String conditionCode;
/** 诊断名称 */

View File

@@ -0,0 +1,80 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.appservice;
import com.core.common.core.domain.R;
import com.openhis.web.inventorymanage.dto.ProductTransferDto;
import com.openhis.web.inventorymanage.dto.SupplySearchParam;
import javax.servlet.http.HttpServletRequest;
/**
* 商品调拨 appService
*
* @author zwh
* @date 2025-03-08
*/
public interface IProductTransferAppService {
/**
* 商品调拨页面初始化
*
* @return 初始化信息
*/
R<?> productTransferInit();
/**
* 商品调拨单据列表
*
* @param supplySearchParam 查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @return 商品调拨单据分页列表
*/
R<?> getPage(SupplySearchParam supplySearchParam, Integer pageNo, Integer pageSize, String searchKey,
HttpServletRequest request);
/**
* 商品调拨单据详情
*
* @param busNo 单据号
* @return 入库单据详情
*/
R<?> getDetail(String busNo);
/**
* 添加/编辑商品调拨单据
*
* @param productTransferDto 入库单据
* @return 编辑结果
*/
R<?> addOrEditTransferReceipt(ProductTransferDto productTransferDto);
/**
* 删除单据
*
* @param supplyRequestId 供应请求id
* @return 操作结果
*/
R<?> deleteReceipt(Long supplyRequestId);
/**
* 提交审批
*
* @param busNo 单据号
* @return 操作结果
*/
R<?> submitApproval(String busNo);
/**
* 撤回审批
*
* @param busNo 单据号
* @return 操作结果
*/
R<?> withdrawApproval(String busNo);
}

View File

@@ -8,7 +8,6 @@ import java.util.HashSet;
import javax.servlet.http.HttpServletRequest;
import com.openhis.web.inventorymanage.dto.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -17,6 +16,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.inventorymanage.appservice.IInventoryDetailsAppService;
import com.openhis.web.inventorymanage.dto.*;
import com.openhis.web.inventorymanage.mapper.InventoryDetailsMapper;
/**
@@ -72,11 +72,12 @@ public class InventoryDetailsAppServiceImpl implements IInventoryDetailsAppServi
* @return 领用出库明细分页列表
*/
@Override
public IPage<RequisitionOutDetailDto> requisitionOutGetPage(RequisitionOutSearchParam requisitionOutSearchParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
public IPage<RequisitionOutDetailDto> requisitionOutGetPage(RequisitionOutSearchParam requisitionOutSearchParam,
String searchKey, Integer pageNo, Integer pageSize, HttpServletRequest request) {
QueryWrapper<RequisitionOutSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam,
searchKey, new HashSet<>(Arrays.asList("bus_no","item_name","item_no")), request);
QueryWrapper<RequisitionOutSearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam, searchKey,
new HashSet<>(Arrays.asList("bus_no", "item_name", "item_no")), request);
Page<RequisitionOutDetailDto> requisitionOutInfo =
inventoryDetailsMapper.selectRequisitionOutDetailsPage(new Page<>(pageNo, pageSize), queryWrapper);
@@ -95,11 +96,13 @@ public class InventoryDetailsAppServiceImpl implements IInventoryDetailsAppServi
* @return 商品调拨明细分页列表
*/
@Override
public IPage<InventoryTransferDetailDto> inventoryTransferGetPage(RequisitionOutSearchParam requisitionOutSearchParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
public IPage<InventoryTransferDetailDto> inventoryTransferGetPage(
RequisitionOutSearchParam requisitionOutSearchParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request) {
QueryWrapper<RequisitionOutSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam,
searchKey, new HashSet<>(Arrays.asList("bus_no","item_name","item_no")), request);
QueryWrapper<RequisitionOutSearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam, searchKey,
new HashSet<>(Arrays.asList("bus_no", "item_name", "item_no")), request);
Page<InventoryTransferDetailDto> inventoryTransferInfo =
inventoryDetailsMapper.selectInventoryTransferDetailsPage(new Page<>(pageNo, pageSize), queryWrapper);
@@ -118,11 +121,13 @@ public class InventoryDetailsAppServiceImpl implements IInventoryDetailsAppServi
* @return 商品调拨明细分页列表
*/
@Override
public IPage<InventoryStockTakeDetailDto> inventoryStockTakeGetPage(RequisitionOutSearchParam requisitionOutSearchParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) {
public IPage<InventoryStockTakeDetailDto> inventoryStockTakeGetPage(
RequisitionOutSearchParam requisitionOutSearchParam, String searchKey, Integer pageNo, Integer pageSize,
HttpServletRequest request) {
QueryWrapper<RequisitionOutSearchParam> queryWrapper = HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam,
searchKey, new HashSet<>(Arrays.asList("bus_no","item_name","item_no")), request);
QueryWrapper<RequisitionOutSearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(requisitionOutSearchParam, searchKey,
new HashSet<>(Arrays.asList("bus_no", "item_name", "item_no")), request);
Page<InventoryStockTakeDetailDto> inventoryStockTakeInfo =
inventoryDetailsMapper.selectInventoryStockTakeDetailsPage(new Page<>(pageNo, pageSize), queryWrapper);

View File

@@ -0,0 +1,253 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.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.AssignSeqUtil;
import com.core.common.utils.DateUtils;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.bean.BeanUtils;
import com.openhis.administration.domain.Location;
import com.openhis.administration.service.ILocationService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.*;
import com.openhis.common.utils.EnumUtils;
import com.openhis.common.utils.HisQueryUtils;
import com.openhis.web.basedatamanage.dto.LocationQueryDto;
import com.openhis.web.inventorymanage.appservice.IProductTransferAppService;
import com.openhis.web.inventorymanage.dto.*;
import com.openhis.web.inventorymanage.mapper.ProductTransferMapper;
import com.openhis.workflow.domain.SupplyRequest;
import com.openhis.workflow.service.ISupplyRequestService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 商品调拨 impl
*
* @author zwh
* @date 2025-03-08
*/
@Service
public class ProductTransferAppServiceImpl implements IProductTransferAppService {
@Autowired
private ProductTransferMapper productTransferMapper;
@Autowired
private ISupplyRequestService supplyRequestService;
@Autowired
private ILocationService locationService;
@Autowired
private AssignSeqUtil assignSeqUtil;
/**
* 商品调拨页面初始化
*
* @return 初始化信息
*/
@Override
public R<?> productTransferInit() {
ProductTransferInitDto initDto = new ProductTransferInitDto();
// 单据号
initDto.setBusNo(assignSeqUtil.getSeqByDay(AssignSeqEnum.PURCHASE_NUM.getPrefix(), 12));
// 入库项目类型
List<ProductTransferInitDto.categoryListOption> categoryListOptions = Stream.of(ItemType.values())
.map(itemType -> new ProductTransferInitDto.categoryListOption(itemType.getValue(), itemType.getInfo()))
.collect(Collectors.toList());
// 审批状态
List<ProductTransferInitDto.supplyStatusOption> supplyStatusOptions = Stream.of(SupplyStatus.values())
.map(supplyStatus -> new ProductTransferInitDto.supplyStatusOption(supplyStatus.getValue(),
supplyStatus.getInfo())).collect(Collectors.toList());
// 获取药房
List<Location> pharmacyList = locationService.getPharmacyList();
// 药库列表
List<Location> cabinetList = locationService.getCabinetList();
// 将位置列表转为树结构
List<LocationQueryDto> pharmacyLocationTree = buildTree(pharmacyList);
List<LocationQueryDto> cabinetLocationTree = buildTree(cabinetList);
initDto.setCategoryListOptions(categoryListOptions).setSupplyStatusOptions(supplyStatusOptions)
.setSourceTypeListOptions(pharmacyLocationTree).setPurposeTypeListOptions(cabinetLocationTree);
return R.ok(initDto);
}
/**
* 将位置列表转换为树结构
*
* @param records 位置列表
* @return tree
*/
private List<LocationQueryDto> buildTree(List<Location> records) {
// 按b_no的层级排序确保父节点先处理
List<Location> sortedRecords = records.stream()
.sorted(Comparator.comparingInt(r -> r.getBusNo().split("\\.").length)).collect(Collectors.toList());
Map<String, LocationQueryDto> nodeMap = new HashMap<>();
List<LocationQueryDto> tree = new ArrayList<>();
for (Location record : sortedRecords) {
String bNo = record.getBusNo();
String[] parts = bNo.split("\\.");
LocationQueryDto node = new LocationQueryDto();
org.springframework.beans.BeanUtils.copyProperties(record, node);
// 将当前节点加入映射
nodeMap.put(bNo, node);
if (parts.length == 1) {
// 根节点
tree.add(node);
} else {
// 获取父节点的b_no去掉最后一部分
String parentBNo = String.join(".", Arrays.copyOf(parts, parts.length - 1));
LocationQueryDto parent = nodeMap.get(parentBNo);
if (parent != null) {
parent.getChildren().add(node);
} else {
// 处理父节点不存在的情况(例如数据缺失)
// 可根据需求调整为将节点加入根或抛出异常
tree.add(node);
}
}
}
return tree;
}
/**
* 商品调拨单据列表
*
* @param supplySearchParam 供应申请查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @return 商品调拨单据分页列表
*/
@Override
public R<?> getPage(SupplySearchParam supplySearchParam, Integer pageNo, Integer pageSize, String searchKey,
HttpServletRequest request) {
// 设置模糊查询的字段名
HashSet<String> searchFields = new HashSet<>();
searchFields.add(CommonConstants.FieldName.SupplyBusNo);
// 构建查询条件
QueryWrapper<SupplySearchParam> queryWrapper =
HisQueryUtils.buildQueryWrapper(supplySearchParam, searchKey, searchFields, request);
// 查询商品调拨单据分页列表
Page<ProductTransferPageDto> transferReceiptPage = productTransferMapper.selectProductTransferPage(
new Page<>(pageNo, pageSize), queryWrapper, SupplyType.PRODUCT_ALLOCATION.getValue());
transferReceiptPage.getRecords().forEach(e -> {
// 单据状态
e.setStatusEnum_enumText(EnumUtils.getInfoByValue(SupplyStatus.class, e.getStatusEnum()));
});
return R.ok(transferReceiptPage);
}
/**
* 商品调拨单据详情
*
* @param busNo 单据号
* @return 商品调拨单据详情
*/
@Override
public R<?> getDetail(String busNo) {
List<ProductTransferDetailDto> productTransferDetailList = productTransferMapper.selectDetail(busNo);
if (productTransferDetailList.isEmpty()) {
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00006, null));
}
return R.ok(productTransferDetailList);
}
/**
* 添加/编辑商品调拨单据
*
* @param productTransferDto 商品调拨单据
* @return 编辑结果
*/
@Override
public R<?> addOrEditTransferReceipt(ProductTransferDto productTransferDto) {
// 初始化单据信息
SupplyRequest supplyRequest = new SupplyRequest();
BeanUtils.copyProperties(productTransferDto, supplyRequest);
if (productTransferDto.getId() != null) {
// 更新单据信息
supplyRequestService.updateById(supplyRequest);
} else {
// 生成商品调拨单据
supplyRequest
// 单据分类:库存供应
.setCategoryEnum(SupplyCategory.STOCK_SUPPLY.getValue())
// 单据类型:商品调拨
.setTypeEnum(SupplyType.PRODUCT_ALLOCATION.getValue())
// 申请时间
.setApplyTime(DateUtils.getNowDate());
supplyRequestService.save(supplyRequest);
}
// 返回单据id
return R.ok(supplyRequest.getId(), null);
}
/**
* 删除单据
*
* @param supplyRequestId 供应请求id
* @return 操作结果
*/
@Override
public R<?> deleteReceipt(Long supplyRequestId) {
// 删除单据
boolean result = supplyRequestService.removeById(supplyRequestId);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 提交审批
*
* @param busNo 单据号
* @return 操作结果
*/
@Override
public R<?> submitApproval(String busNo) {
// 单据提交审核
boolean result = supplyRequestService.submitApproval(busNo);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
/**
* 撤回审批
*
* @param busNo 单据号
* @return 操作结果
*/
@Override
public R<?> withdrawApproval(String busNo) {
// 撤回审核
boolean result = supplyRequestService.withdrawApproval(busNo);
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
: R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
}

View File

@@ -4,6 +4,7 @@
package com.openhis.web.inventorymanage.appservice.impl;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -184,6 +185,55 @@ public class ReceiptApprovalAppServiceImpl implements IReceiptApprovalAppService
return R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, null));
}
// 商品调拨
if (agreedList.get(0).getTypeEnum() == SupplyType.PRODUCT_ALLOCATION.getValue()) {
// 获取供应项目所在表
String itemTable = supplyRequestService.getItemTable(agreedList);
// 查询供应项目的详细信息
List<SupplyItemDetailDto> supplyItemDetailList = this.getSupplyItemDetail(busNo, itemTable);
for (SupplyItemDetailDto supplyItemDetailDto : supplyItemDetailList) {
// 根据产品批号,仓库和仓位 查询库存表信息
InventoryItem inventoryItem =
inventoryItemService.selectInventoryByLotNumber(supplyItemDetailDto.getLotNumber(),
supplyItemDetailDto.getSourceLocationId(), supplyItemDetailDto.getPurposeLocationStoreId());
// 包装数量
BigDecimal baseQuantity = inventoryItem.getBaseQuantity();
// 最小数量
BigDecimal minQuantity = inventoryItem.getMinQuantity();
if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getUnitCode())) {
baseQuantity = baseQuantity.min(supplyItemDetailDto.getItemQuantity());
minQuantity = minQuantity
.min(supplyItemDetailDto.getPartPercent().multiply(supplyItemDetailDto.getItemQuantity()));
} else if (supplyItemDetailDto.getItemUnit().equals(supplyItemDetailDto.getMinUnitCode())) {
baseQuantity = baseQuantity.min(supplyItemDetailDto.getItemQuantity()
.divide(supplyItemDetailDto.getPartPercent(), RoundingMode.HALF_UP));
minQuantity = minQuantity.min(supplyItemDetailDto.getItemQuantity());
}
// 更新库存数量
inventoryItemService.updateInventoryQuantity(inventoryItem.getId(), baseQuantity, minQuantity,
loginUser, now);
}
// 将供应项目的详细信息装配为库存项目和采购账单
Pair<List<ChargeItem>, List<InventoryItem>> listPair =
InventoryManageAssembler.assembleChargeAndInventory(supplyItemDetailList, now, loginUser);
// 入库
inventoryItemService.stockIn(listPair.getRight());
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null));
}
// 获取供应项目所在表
String itemTable = supplyRequestService.getItemTable(agreedList);
// 获取供应的物品

View File

@@ -0,0 +1,113 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.controller;
import com.core.common.core.domain.R;
import com.openhis.web.inventorymanage.appservice.IProductTransferAppService;
import com.openhis.web.inventorymanage.dto.SupplySearchParam;
import com.openhis.web.inventorymanage.dto.ProductTransferDto;
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 javax.servlet.http.HttpServletRequest;
/**
* 商品调拨 controller
*
* @author MY
* @date 2025-03-19
*/
@RestController
@RequestMapping("/inventory-manage/transfer")
@Slf4j
public class ProductTransferController {
@Autowired
private IProductTransferAppService productTransferAppService;
/**
* 商品调拨页面初始化
*
* @return 初始化信息
*/
@GetMapping(value = "/init")
public R<?> productTransferInit() {
return productTransferAppService.productTransferInit();
}
/**
* 商品调拨单据列表
*
* @param supplySearchParam 供应申请查询条件
* @param pageNo 当前页码
* @param pageSize 查询条数
* @param searchKey 模糊查询关键字
* @param request 请求数据
* @return 商品调拨分页列表
*/
@GetMapping(value = "/product-transfer-page")
public R<?> getPage(SupplySearchParam supplySearchParam,
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(name = "searchKey", required = false) String searchKey, HttpServletRequest request) {
return productTransferAppService.getPage(supplySearchParam, pageNo, pageSize, searchKey, request);
}
/**
* 商品调拨单据详情
*
* @param busNo 单据号
* @return 供应申请单据详情
*/
@GetMapping(value = "/product-transfer-detail")
public R<?> getDetail(@RequestParam String busNo) {
return productTransferAppService.getDetail(busNo);
}
/**
* 添加/编辑商品调拨单据
*
* @param productTransferDto 商品调拨单据
* @return 操作结果
*/
@PutMapping("/product-transfer-edit")
public R<?> addOrEditTransferReceipt(@Validated @RequestBody ProductTransferDto productTransferDto) {
return productTransferAppService.addOrEditTransferReceipt(productTransferDto);
}
/**
* 删除单据
*
* @param supplyRequestId 供应请求id
* @return 操作结果
*/
@DeleteMapping("/product-transfer-del")
public R<?> deleteTransferReceipt(@RequestParam Long supplyRequestId) {
return productTransferAppService.deleteReceipt(supplyRequestId);
}
/**
* 提交审批
*
* @param busNo 单据号
* @return 操作结果
*/
@PutMapping("/submit-approval")
public R<?> submitApproval(@RequestParam String busNo) {
return productTransferAppService.submitApproval(busNo);
}
/**
* 撤回审批
*
* @param busNo 单据号
* @return 操作结果
*/
@PutMapping("/withdraw-approval")
public R<?> withdrawApproval(@RequestParam String busNo) {
return productTransferAppService.withdrawApproval(busNo);
}
}

View File

@@ -3,11 +3,11 @@
*/
package com.openhis.web.inventorymanage.dto;
import java.util.Date;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
/**
* 入库单据分页查询条件
*

View File

@@ -10,7 +10,6 @@ import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.sun.jna.platform.unix.solaris.LibKstat;
import lombok.Data;
import lombok.experimental.Accessors;
@@ -67,8 +66,6 @@ public class InventoryStockTakeDetailDto implements Serializable {
/** 盈亏原因 */
/** 目的仓库类型 */
private Integer purposeTypeEnum;

View File

@@ -10,7 +10,6 @@ import java.util.Date;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.sun.jna.platform.unix.solaris.LibKstat;
import lombok.Data;
import lombok.experimental.Accessors;

View File

@@ -0,0 +1,35 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.ArrayList;
import java.util.List;
/**
* @author
* @date 2025-02-21
*/
@Data
@Accessors(chain = true)
public class LocationQueryDto {
/** ID */
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 编码 */
private String no;
/** 名称 */
private String name;
/** 子集合 */
private List<LocationQueryDto> children = new ArrayList<>();
}

View File

@@ -0,0 +1,111 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 调拨单据详情
*
* @author zwh
* @date 2025-03-04
*/
@Data
@Accessors(chain = true)
public class ProductTransferDetailDto implements Serializable {
private static final long serialVersionUID = 1L;
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 单据号 */
private String busNo;
/** 申请时间 */
private Date applyTime;
/** 源仓库类型 */
private Integer sourceTypeEnum;
private String sourceTypeEnum_dictText;
/** 源仓库名称 */
private String sourceLocationName;
/** 源货位名称 */
private String sourceLocationStoreName;
/** 目的仓库类型 */
private Integer purposeTypeEnum;
private String purposeTypeEnum_dictText;
/** 目的仓库名称 */
private String purposeLocationName;
/** 目的货位名称 */
private String purposeLocationStoreName;
/** 项目(药品类型) */
private String itemTable;
/** 规格 */
private String totalVolume;
/** 供应商名称 */
private String supplierName;
/** 物品计量单位 */
@Dict(dictCode = "unit_code")
private String unitCode;
private String unitCode_dictText;
/** 数量 */
private BigDecimal itemQuantity;
/** 源库存数量 */
private BigDecimal totalSourceQuantity;
/** 目的库存数量 */
private BigDecimal totalPurposeQuantity;
/** 单价 */
private BigDecimal price;
/** 总价 */
private BigDecimal totalPrice;
/** 产品批号 */
private String lotNumber;
/** 开始时间 */
private Date startTime;
/** 结束时间 */
private Date endTime;
/** 追溯码 */
private String traceNo;
/** 理由 */
private String reason;
/** 售价 */
private BigDecimal sellPrice;
/** 拆零售价 */
private BigDecimal minSellPrice;
}

View File

@@ -0,0 +1,122 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
/**
* 商品调拨单据
*
* @author MY
* @date 2025-03-18
*/
@Data
@Accessors(chain = true)
public class ProductTransferDto implements Serializable {
private static final long serialVersionUID = 1L;
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 项目 */
private String itemTable;
/** 数量 */
@NotNull
@Min(1)
private Integer itemQuantity;
/** 物品编码 */
@NotNull
private Long itemId;
/** 物品计量单位 */
@NotNull
private String unitCode;
/** 请求细节 */
private String detailJson;
/** 供应商 */
@NotNull
private Long supplierId;
/** 源仓库类型 */
@NotNull
private Integer sourceTypeEnum;
/** 源仓库 */
@NotNull
private Long sourceLocationId;
/** 源仓位 */
@NotNull
private Long sourceLocationStoreId;
/** 目的仓库类型 */
@NotNull
private Integer purposeTypeEnum;
/** 目的仓库 */
@NotNull
private Long purposeLocationId;
/** 目的仓位 */
@NotNull
private Long purposeLocationStoreId;
/** 申请人 */
@NotNull
private Long applicantId;
/** 申请时间 */
private Date applyTime;
/** 产品批号 */
@NotNull
private String lotNumber;
/** 追溯码 */
@NotNull
private String traceNo;
/** 开始时间 */
@NotNull
private Date startTime;
/** 结束时间 */
@NotNull
private Date endTime;
/** 单价 */
@NotNull
private BigDecimal price;
/** 总价 */
@NotNull
private BigDecimal totalPrice;
/** 售价 */
@NotNull
private BigDecimal sellPrice;
/** 拆零售价 */
@NotNull
private BigDecimal minSellPrice;
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import com.openhis.web.basedatamanage.dto.LocationQueryDto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 商品调拨初始化 dto
*
* @author my
* @date 2025-03-20
*/
@Data
@Accessors(chain = true)
public class ProductTransferInitDto {
/**
* 单据号
*/
private String busNo;
/**
* 源仓库
*/
private List<LocationQueryDto> sourceTypeListOptions;
/**
* 目的仓库
*/
private List<LocationQueryDto> purposeTypeListOptions;
/**
* 药品类型
*/
private List<ProductTransferInitDto.categoryListOption> categoryListOptions;
/**
* 审批状态
*/
private List<ProductTransferInitDto.supplyStatusOption> supplyStatusOptions;
/**
* 药品类型
*/
@Data
public static class categoryListOption {
private Integer value;
private String label;
public categoryListOption(Integer value, String label) {
this.value = value;
this.label = label;
}
}
/**
* 审批状态
*/
@Data
public static class supplyStatusOption {
private Integer value;
private String label;
public supplyStatusOption(Integer value, String label) {
this.value = value;
this.label = label;
}
}
}

View File

@@ -0,0 +1,70 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.openhis.common.annotation.Dict;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.Date;
/**
* 商品调拨分页列表 dto
*
* @author zwh
* @date 2025-02-18
*/
@Data
@Accessors(chain = true)
public class ProductTransferPageDto implements Serializable {
private static final long serialVersionUID = 1L;
/** ID */
@TableId(type = IdType.ASSIGN_ID)
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/** 单据号 */
private String supplyBusNo;
/** 状态 */
private Integer statusEnum;
private String statusEnum_enumText;
/** 类型 */
private Integer typeEnum;
private String typeEnum_enumText;
/** 项目(药品类型) */
private String itemTable;
/** 源仓库名称 */
private String sourceLocationName;
/** 目的仓库名称 */
private String purposeLocationName;
/** 审批人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long approverId;
private String approverId_dictText;
/** 审批时间 */
private Date approvalTime;
/** 申请人 */
@Dict(dictCode = "id", dictText = "name", dictTable = "adm_practitioner")
private Long applicantId;
private String applicantId_dictText;
/** 制单日期 */
private Date createTime;
}

View File

@@ -66,6 +66,20 @@ public class PurchaseInventoryInitDto {
}
}
/**
* 入库项目类型
*/
@Data
public static class itemTypeOption {
private Integer value;
private String label;
public itemTypeOption(Integer value, String label) {
this.value = value;
this.label = label;
}
}
/**
* 入库项目类型
*/

View File

@@ -4,7 +4,6 @@
package com.openhis.web.inventorymanage.dto;
import java.io.Serializable;
import java.util.Date;
import org.hibernate.validator.constraints.Length;

View File

@@ -3,7 +3,6 @@
*/
package com.openhis.web.inventorymanage.dto;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@@ -48,6 +47,12 @@ public class SupplyItemDetailDto {
/** 审批人 */
private Long approverId;
/** 源仓库 */
private Long sourceLocationId;
/** 源仓位 */
private Long sourceLocationStoreId;
/** 目的仓库 */
private Long purposeLocationId;

View File

@@ -0,0 +1,37 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.dto;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
/**
* 供应申请共通查询条件
*
* @author my
* @date 2025-03-19
*/
@Data
@Accessors(chain = true)
public class SupplySearchParam implements Serializable {
private static final long serialVersionUID = 1L;
/** 状态 */
private Integer statusEnum;
/** 源仓库 */
private Integer sourceLocationId;
/** 目的仓库 */
private Integer purposeLocationId;
/** 申请人 */
private Long applicantId;
/** 经手人 */
private Long practitionerId;
}

View File

@@ -3,13 +3,13 @@
*/
package com.openhis.web.inventorymanage.mapper;
import com.openhis.web.inventorymanage.dto.*;
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.openhis.web.inventorymanage.dto.*;
/**
* 采购入库查询用 mapper
@@ -47,7 +47,8 @@ public interface InventoryDetailsMapper {
* @param queryWrapper 查询条件
* @return 商品调拨分页列表
*/
Page<InventoryTransferDetailDto> selectInventoryTransferDetailsPage(@Param("page") Page<InventoryTransferDetailDto> page,
Page<InventoryTransferDetailDto> selectInventoryTransferDetailsPage(
@Param("page") Page<InventoryTransferDetailDto> page,
@Param(Constants.WRAPPER) QueryWrapper<RequisitionOutSearchParam> queryWrapper);
/**
@@ -57,6 +58,7 @@ public interface InventoryDetailsMapper {
* @param queryWrapper 查询条件
* @return 商品盘点分页列表
*/
Page<InventoryStockTakeDetailDto> selectInventoryStockTakeDetailsPage(@Param("page") Page<InventoryTransferDetailDto> page,
Page<InventoryStockTakeDetailDto> selectInventoryStockTakeDetailsPage(
@Param("page") Page<InventoryTransferDetailDto> page,
@Param(Constants.WRAPPER) QueryWrapper<RequisitionOutSearchParam> queryWrapper);
}

View File

@@ -0,0 +1,45 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.web.inventorymanage.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.openhis.web.inventorymanage.dto.SupplySearchParam;
import com.openhis.web.inventorymanage.dto.ProductTransferDetailDto;
import com.openhis.web.inventorymanage.dto.ProductTransferPageDto;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 商品调拨查询用 mapper
*
* @author zwh
* @date 2025-03-10
*/
@Repository
public interface ProductTransferMapper {
/**
* 查询商品调拨单据分页列表
*
* @param page 分页
* @param queryWrapper 查询条件
* @param productTransfer 单据类型:采购入库
* @return 商品调拨单据分页列表
*/
Page<ProductTransferPageDto> selectProductTransferPage(@Param("page") Page<ProductTransferPageDto> page,
@Param(Constants.WRAPPER) QueryWrapper<SupplySearchParam> queryWrapper,
@Param("productTransfer") Integer productTransfer);
/**
* 查询单据详情
*
* @param busNo 单据号
* @return 单据详情
*/
List<ProductTransferDetailDto> selectDetail(@Param("busNo") String busNo);
}

View File

@@ -0,0 +1,174 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.web.inventorymanage.mapper.ProductTransferMapper">
<select id="selectProductTransferPage"
resultType="com.openhis.web.inventorymanage.dto.ProductTransferPageDto">
SELECT T2.id,
T2.bus_no AS supply_bus_no, -- 商品调拨单据号
T2.item_table, -- 项目(药品类型)
T2.status_enum, -- 单据状态
T2.source_location_name, -- 源仓库名称
T2.purpose_location_name, -- 目的仓库名称
T2.approver_id, -- 审批人ID
T2.approval_time, -- 审批时间
T2.applicant_id, -- 申请人ID
T2.create_time -- 创建时间
FROM (SELECT T1.id,
T1.bus_no,
T1.status_enum,
T1.approver_id,
T1.approval_time,
T1.applicant_id,
T1.create_time,
T1.item_table,
T2."name" AS source_location_name, -- 源仓库
T3."name" AS purpose_location_name -- 目的仓库
FROM wor_supply_request AS T1
LEFT JOIN adm_location T2
ON T1.source_location_id = T2.id
LEFT JOIN adm_location T3
ON T1.purpose_location_id = T3.id
WHERE type_enum = #{productTransfer}
GROUP BY T1.id,
T1.bus_no,
T1.status_enum,
T1.approver_id,
T1.approval_time,
T1.applicant_id,
T1.create_time,
T1.item_table,
T2."name",
T3."name"
ORDER BY T1.bus_no desc
) AS T2
${ew.customSqlSegment}
</select>
<select id="selectDetail" resultType="com.openhis.web.inventorymanage.dto.ProductTransferDetailDto">
SELECT T1.id,
T1.bus_no, -- 商品调拨单据号
T1.apply_time, -- 申请时间
T1.source_type_enum, -- 源仓库类型
T5."name" AS source_location_name, -- 源仓库
T6."name" AS source_location_store_name, -- 源仓位
T1.purpose_type_enum, -- 目的仓库类型
T7."name" AS purpose_location_name, -- 目的仓库
T8."name" AS purpose_location_store_name, -- 目的货位
T1.item_table, -- 项目(药品类型)
T2."name" AS item_name, -- 药品名称
T3.total_volume, -- 规格
T4."name" AS supplier_name, -- 供应商名称
T1.unit_code, -- 物品计量单位
T1.item_quantity, -- 调拨数量
T1.price, -- 采购单价
T1.total_price, -- 总价
T1.lot_number, -- 产品批号
T1.start_time, -- 开始时间
T1.end_time, -- 结束时间
T1.trace_no, -- 追溯码
T1.reason, -- 理由
T1.sell_price, -- 售价
T1.min_sell_price, -- 拆零售价
(SELECT COALESCE(SUM(CASE
WHEN T1.unit_code = T9.base_unit_code THEN T9.base_quantity
WHEN T1.unit_code = T9.min_unit_code THEN T9.min_quantity
ELSE 0 END ), 0)
FROM wor_inventory_item T9
WHERE T9.item_id = T1.item_id
AND T9.location_id = T1.source_location_id
AND T9.location_store_id = T1.source_location_store_id
) AS total_source_quantity, -- 总库存数量(源库存)
(SELECT COALESCE(SUM(CASE
WHEN T1.unit_code = T9.base_unit_code THEN T9.base_quantity
WHEN T1.unit_code = T9.min_unit_code THEN T9.min_quantity
ELSE 0 END ), 0)
FROM wor_inventory_item T9
WHERE T9.item_id = T1.item_id
AND T9.location_id = T1.purpose_location_id
AND T9.location_store_id = T1.purpose_location_store_id
) AS total_purpose_quantity -- 总库存数量(目的库存)
FROM wor_supply_request T1
LEFT JOIN med_medication_definition T2
ON T1.item_id = T2.id
LEFT JOIN med_medication T3
ON T3.medication_def_id = T2.id
LEFT JOIN adm_supplier T4
ON T4.id = T1.supplier_id
LEFT JOIN adm_location T5
ON T1.source_location_id = T5.id
LEFT JOIN adm_location T6
ON T1.source_location_store_id = T6.id
LEFT JOIN adm_location T7
ON T1.purpose_location_id = T7.id
LEFT JOIN adm_location T8
ON T1.purpose_location_store_id = T8.id
LEFT JOIN wor_inventory_item T9
ON T1.item_id = T9.item_id
AND T1.purpose_location_id = T9.location_id
AND T1.purpose_location_store_id = T9.location_store_id
WHERE T1.bus_no = #{busNo}
AND T1.delete_flag = '0'
UNION
SELECT T1.id,
T1.bus_no, -- 商品调拨单据号
T1.apply_time, -- 申请时间
T1.source_type_enum, -- 源仓库类型
T5."name" AS source_location_name_location_name, -- 源仓库
T6."name" AS source_location_name_location_store_name, -- 源仓位
T1.purpose_type_enum, -- 目的仓库类型
T7."name" AS purpose_location_name, -- 目的仓库
T8."name" AS purpose_location_store_name, -- 目的货位
T1.item_table, -- 项目(药品类型)
T2."name" AS item_name, -- 药品名称
T2."size" AS total_volume, -- 规格
T4."name" AS supplier_name, -- 供应商名称
T1.unit_code, -- 物品计量单位
T1.item_quantity, -- 调拨数量
T1.price, -- 采购单价
T1.total_price, -- 总价
T1.lot_number, -- 产品批号
T1.start_time, -- 开始时间
T1.end_time, -- 结束时间
T1.trace_no, -- 追溯码
T1.reason, -- 理由
T1.sell_price, -- 售价
T1.min_sell_price, -- 拆零售价
(SELECT COALESCE(SUM(CASE
WHEN T1.unit_code = T9.base_unit_code THEN T9.base_quantity
WHEN T1.unit_code = T9.min_unit_code THEN T9.min_quantity
ELSE 0 END ), 0)
FROM wor_inventory_item T9
WHERE T9.item_id = T1.item_id
AND T9.location_id = T1.source_location_id
AND T9.location_store_id = T1.source_location_store_id
) AS total_source_quantity, -- 总库存数量(源库存)
(SELECT COALESCE(SUM(CASE
WHEN T1.unit_code = T9.base_unit_code THEN T9.base_quantity
WHEN T1.unit_code = T9.min_unit_code THEN T9.min_quantity
ELSE 0 END ), 0)
FROM wor_inventory_item T9
WHERE T9.item_id = T1.item_id
AND T9.location_id = T1.purpose_location_id
AND T9.location_store_id = T1.purpose_location_store_id
) AS total_purpose_quantity -- 总库存数量(目的库存)
FROM wor_supply_request T1
LEFT JOIN adm_device_definition T2
ON T1.item_id = T2.id
LEFT JOIN adm_supplier T4
ON T4.id = T1.supplier_id
LEFT JOIN adm_location T5
ON T1.source_location_id = T5.id
LEFT JOIN adm_location T6
ON T1.source_location_store_id = T6.id
LEFT JOIN adm_location T7
ON T1.purpose_location_id = T7.id
LEFT JOIN adm_location T8
ON T1.purpose_location_store_id = T8.id
LEFT JOIN wor_inventory_item T9
ON T1.item_id = T9.item_id
AND T1.purpose_location_id = T9.location_id
AND T1.purpose_location_store_id = T9.location_store_id
WHERE T1.bus_no = #{busNo}
AND T1.delete_flag = '0'
</select>
</mapper>

View File

@@ -13,6 +13,8 @@
T1.sell_price,
T1.min_sell_price,
T1.approver_id,
T1.source_location_id,
T1.source_location_store_id,
T1.purpose_location_id,
T1.purpose_location_store_id,
T1.supplier_id,
@@ -56,6 +58,8 @@
T1.sell_price,
T1.min_sell_price,
T1.approver_id,
T1.source_location_id,
T1.source_location_store_id,
T1.purpose_location_id,
T1.purpose_location_store_id,
T1.supplier_id,

View File

@@ -125,7 +125,7 @@
AND T2.instance_table = 'wor_activity_definition'
<if test="id!= null">
AND T2.id = #{id}
AND T1.id = #{id}
</if>
<if test="tenantId!= null">
AND T1.tenant_id = #{tenantId}

View File

@@ -0,0 +1,45 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.common.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 药品类型
*
* @author zwh
* @date 2025-03-10
*/
@Getter
@AllArgsConstructor
public enum CategoryType implements HisEnumInterface {
/**
* 中药
*/
MEDICINE(1, "1", "中药"),
/**
* 西药
*/
CHEMICAL(2, "2", "西药"),
/**
* 中成药
*/
TRADITIONAL(3, "3", "中成药"),
/**
* 耗材
*/
DEVICE(4, "4", "耗材");
@EnumValue
private Integer value;
private String code;
private String info;
}

View File

@@ -0,0 +1,35 @@
/*
* Copyright ©2023 CJB-CNIT Team. All rights reserved
*/
package com.openhis.common.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 仓库类型
*
* @author zwh
* @date 2025-03-10
*/
@Getter
@AllArgsConstructor
public enum InventoryType implements HisEnumInterface {
/**
* 仓库
*/
INVENTORY(1, "1", "仓库"),
/**
* 药房
*/
PHARMACY(2, "2", "药房");
@EnumValue
private Integer value;
private String code;
private String info;
}

View File

@@ -1,9 +1,11 @@
package com.openhis.workflow.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.core.common.core.domain.model.LoginUser;
import com.openhis.workflow.domain.InventoryItem;
import com.openhis.workflow.domain.SupplyRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
@@ -20,4 +22,27 @@ public interface IInventoryItemService extends IService<InventoryItem> {
* @param InventoryItemList 入库项目
*/
void stockIn(List<InventoryItem> InventoryItemList);
/**
* 更新库房数量
*
* @param id 主键
* @param baseQuantity 常规单位库存数量
* @param minQuantity 最小单位库存数量
* @param loginUser 登录用户信息
* @param now 当前时间
* @return 更新件数
*/
Boolean updateInventoryQuantity(Long id, BigDecimal baseQuantity, BigDecimal minQuantity, LoginUser loginUser, Date now);
/**
* 查询
*
* @param lotNumber 产品批号
* @param locationId 仓库
* @param locationStoreId 库位
* @return 单据详情
*/
InventoryItem selectInventoryByLotNumber(String lotNumber, Long locationId, Long locationStoreId);
}

View File

@@ -1,7 +1,8 @@
package com.openhis.workflow.service.impl;
import com.openhis.administration.domain.ChargeItem;
import com.openhis.workflow.domain.SupplyRequest;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.core.common.core.domain.model.LoginUser;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -9,6 +10,8 @@ import com.openhis.workflow.domain.InventoryItem;
import com.openhis.workflow.mapper.InventoryItemMapper;
import com.openhis.workflow.service.IInventoryItemService;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
/**
@@ -34,4 +37,53 @@ public class InventoryItemServiceImpl extends ServiceImpl<InventoryItemMapper, I
}
}
}
/**
* 更新库房数量
*
* @param id 主键
* @param baseQuantity 常规单位库存数量
* @param minQuantity 最小单位库存数量
* @param loginUser 登录用户信息
* @param now 当前时间
* @return 更新件数
*/
@Override
public Boolean updateInventoryQuantity(Long id, BigDecimal baseQuantity,BigDecimal minQuantity, LoginUser loginUser, Date now) {
int updateCount = baseMapper.update(null,
new LambdaUpdateWrapper<InventoryItem>().eq(InventoryItem::getId, id)
.set(InventoryItem::getUpdateTime, now)
.set(InventoryItem::getUpdateBy, loginUser.getUserId())
.set(InventoryItem::getBaseQuantity, baseQuantity)
.set(InventoryItem::getMinQuantity, minQuantity));
return updateCount > 0;
}
/**
* 查询库房信息
*
* @param lotNumber 产品批号
* @param locationId 仓库
* @param locationStoreId 库位
*/
@Override
public InventoryItem selectInventoryByLotNumber(String lotNumber, Long locationId, Long locationStoreId) {
// 查询取库房信息
InventoryItem inventoryItem =
baseMapper.selectOne(new LambdaQueryWrapper<InventoryItem>()
.eq(InventoryItem::getLotNumber, lotNumber)
.eq(InventoryItem::getLocationId, locationId)
.eq(InventoryItem::getLocationStoreId, locationStoreId));
if (inventoryItem == null) {
return null;
}
return inventoryItem;
}
}

View File

@@ -10,12 +10,12 @@
label-position="left"
>
<el-row :gutter="24">
<el-col :span="8">
<el-col :span="8" v-if="form.id != undefined">
<el-form-item label="编号" prop="busNo">
<el-input
v-model="form.busNo"
placeholder="请输入编码"
:disabled="form.id != undefined"
disabled
/>
</el-form-item>
</el-col>
@@ -61,25 +61,24 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="目录分类" prop="categoryEnum">
<el-tree-select
v-model="form.categoryEnum"
:data="diseaseTreatmentCategoryList"
:props="{
value: 'id',
label: 'info',
children: 'children',
}"
value-key="id"
placeholder="请选择地点"
check-strictly
<el-form-item label="目录分类" prop="categoryCode">
<el-select
v-model="form.categoryCode"
clearable
:disabled="form.categoryCode != ''"
>
<el-option
v-for="category in activity_category_code"
:key="category.value"
:label="category.label"
:value="category.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="类型" prop="typeCode">
<el-select v-model="form.typeCode" placeholder="" clearable>
<el-form-item label="类型" prop="typeEnum">
<el-select v-model="form.typeEnum" placeholder="" clearable>
<el-option
v-for="item in typeEnumOptions"
:key="item.value"
@@ -140,11 +139,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="身体部位" prop="bodySiteCode">
<el-select
v-model="form.bodySiteCode"
clearable
:disabled="form.id != undefined"
>
<el-select v-model="form.bodySiteCode" clearable>
<el-option
v-for="category in body_site_code"
:key="category.value"
@@ -156,11 +151,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="所需标本" prop="specimenCode">
<el-select
v-model="form.specimenCode"
clearable
:disabled="form.id != undefined"
>
<el-select v-model="form.specimenCode" clearable>
<el-option
v-for="category in specimen_code"
:key="category.value"
@@ -186,11 +177,7 @@
</el-col>
<el-col :span="8">
<el-form-item label="使用单位" prop="permittedUnitCode">
<el-select
v-model="form.permittedUnitCode"
clearable
:disabled="form.id != undefined"
>
<el-select v-model="form.permittedUnitCode" clearable>
<el-option
v-for="category in unit_code"
:key="category.value"
@@ -201,12 +188,8 @@
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="财务类型" prop="minimalFee">
<el-select
v-model="form.minimalFee"
clearable
:disabled="form.id != undefined"
>
<el-form-item label="财务类型" prop="itemTypeCode">
<el-select v-model="form.itemTypeCode" clearable>
<el-option
v-for="category in fin_type_code"
:key="category.value"
@@ -220,25 +203,37 @@
<el-row :gutter="24">
<el-col :span="8">
<el-form-item label="购入价" prop="purchasePrice">
<el-input v-model="form.purchasePrice" placeholder="" />
<el-input
v-model="form.purchasePrice"
placeholder=""
:disabled="form.id != undefined"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="零售价" prop="retailPrice">
<el-input v-model="form.retailPrice" placeholder="" />
<el-input
v-model="form.retailPrice"
placeholder=""
:disabled="form.id != undefined"
/>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="最高零售价" prop="maximumRetailPrice">
<el-input v-model="form.maximumRetailPrice" placeholder="" />
<el-input
v-model="form.maximumRetailPrice"
placeholder=""
:disabled="form.id != undefined"
/>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="24">
<el-col :span="16">
<el-form-item label="说明" prop="description">
<el-form-item label="说明" prop="descriptionText">
<el-input
v-model="form.description"
v-model="form.descriptionText"
:autosize="{ minRows: 4, maxRows: 10 }"
type="textarea"
placeholder=""
@@ -267,19 +262,21 @@ import {
} from "./diagnosistreatment";
const { proxy } = getCurrentInstance();
const { unit_code, yb_type, fin_type_code } = proxy.useDict(
const { unit_code, yb_type, fin_type_code, activity_category_code } =
proxy.useDict(
"unit_code",
"yb_type",
"fin_type_code"
"fin_type_code",
"activity_category_code"
);
const title = ref("");
const visible = ref(false);
const emits = defineEmits(["submit"]); // 声明自定义事件
const categoryEnum = ref("");
const categoryCode = ref("");
const deptOptions = ref(undefined); // 部门树选项
const locationOptions = ref(undefined); // 地点树选项
const diseaseTreatmentCategoryList = ref(undefined);
const diagnosisCategoryOptions = ref(undefined);
const statusFlagOptions = ref(undefined);
const exeOrganizations = ref(undefined);
const typeEnumOptions = ref(undefined);
@@ -287,13 +284,13 @@ const typeEnumOptions = ref(undefined);
const data = reactive({
form: {},
rules: {
busNo: [{ required: true, message: "编码不能为空", trigger: "blur" }],
// busNo: [{ required: true, message: "编码不能为空", trigger: "blur" }],
name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
statusEnum: [{ required: true, message: "状态不能为空", trigger: "blur" }],
categoryEnum: [
categoryCode: [
{ required: true, message: "诊疗目录不能为空", trigger: "blur" },
],
typeCode: [
typeEnum: [
{ required: true, message: "器材种类不能为空", trigger: "blur" },
],
permittedUnitCode: [
@@ -303,6 +300,19 @@ const data = reactive({
ybMatchFlag: [
{ required: true, message: "医保对码标记不能为空", trigger: "blur" },
],
purchasePrice: [
{ required: true, message: "购入价不能为空", trigger: "blur" },
],
retailPrice: [
{ required: true, message: "零售价不能为空", trigger: "blur" },
],
maximumRetailPrice: [
{ required: true, message: "最高零售价不能为空", trigger: "blur" },
],
ybType: [{ required: true, message: "医保类型不能为空", trigger: "blur" }],
itemTypeCode: [
{ required: true, message: "财务类型不能为空", trigger: "blur" },
],
},
});
@@ -321,7 +331,7 @@ const props = defineProps({
type: String,
required: true,
},
diseaseTreatmentCategoryList: {
diagnosisCategoryOptions: {
type: Object,
required: false,
},
@@ -346,11 +356,11 @@ function show() {
getDeptTree();
title.value = "";
title.value = props.title;
diseaseTreatmentCategoryList.value = props.diseaseTreatmentCategoryList;
diagnosisCategoryOptions.value = props.diagnosisCategoryOptions;
statusFlagOptions.value = props.statusFlagOptions;
exeOrganizations.value = props.exeOrganizations;
typeEnumOptions.value = props.typeEnumOptions;
form.value.categoryEnum = props.currentCategoryEnum;
form.value.categoryCode = props.currentCategoryEnum;
console.log(props.currentCategoryEnum, "11111");
console.log(props, "22222", title.value);
visible.value = true;
@@ -363,7 +373,7 @@ function edit() {
title.value = "";
title.value = props.title;
form.value = props.item;
diseaseTreatmentCategoryList.value = props.diseaseTreatmentCategoryList;
diagnosisCategoryOptions.value = props.diagnosisCategoryOptions;
statusFlagOptions.value = props.statusFlagOptions;
exeOrganizations.value = props.exeOrganizations;
typeEnumOptions.value = props.typeEnumOptions;
@@ -379,8 +389,8 @@ function reset() {
orgId: undefined, // 执行科室
pyStr: undefined, // 拼音码
wbStr: undefined, // 五笔码
categoryEnum: undefined, // 类别
typeCode: undefined, // 类型编码
categoryCode: undefined, // 类别
typeEnum: undefined, // 类型编码
statusEnum: undefined, // 状态(包括 1预置2启用3停用
ybFlag: undefined, // 医保标记
ybMatchFlag: undefined, // 医保对码标记
@@ -390,11 +400,11 @@ function reset() {
specimenCode: undefined, // 所需标本
ruleId: undefined, // 执行科室
permittedUnitCode: undefined, // 使用单位
minimalFee: undefined, // 最小收费
itemTypeCode: undefined, // 最小收费
purchasePrice: undefined, // 购入价
retailPrice: undefined, // 零售价
maximumRetailPrice: undefined, // 最高零售价
description: undefined, // 说明
descriptionText: undefined, // 说明
};
proxy.resetForm("diagnosisTreatmentRef");
}

View File

@@ -1,11 +1,12 @@
<template>
<div class="app-container">
<el-row :gutter="20">
<!--器材目录-->
<!--诊疗目录-->
<el-col :span="4" :xs="24">
<div class="head-title">诊疗目录</div>
<div class="head-container">
<el-tree
:data="diseaseTreatmentCategoryList"
:data="diagnosisCategoryOptions"
:props="{ label: 'info', children: 'children' }"
:expand-on-click-node="false"
:filter-node-method="filterNode"
@@ -17,7 +18,7 @@
/>
</div>
</el-col>
<!--器材目录-->
<!--诊疗目录-->
<el-col :span="20" :xs="24">
<el-form
:model="queryParams"
@@ -62,15 +63,15 @@
clearable
>
<el-option
v-for="item in exeOrganizations"
v-for="item in statusWeatherOption"
:key="item.value"
:label="item.label"
:label="item.info"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<!-- <el-col :span="4">
<el-form-item label="执行科室" prop="ruleId" label-width="100">
<el-select
v-model="queryParams.ruleId"
@@ -85,11 +86,11 @@
/>
</el-select>
</el-form-item>
</el-col>
</el-col> -->
<el-col :span="4">
<el-form-item label="类型" prop="typeCode" label-width="100">
<el-form-item label="类型" prop="typeEnum" label-width="100">
<el-select
v-model="queryParams.typeCode"
v-model="queryParams.typeEnum"
placeholder=""
clearable
>
@@ -198,8 +199,8 @@
<el-table-column
label="目录类别"
align="center"
key="category_enumText"
prop="category_enumText"
key="categoryCode_dictText"
prop="categoryCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
@@ -214,8 +215,8 @@
<el-table-column
label="使用单位"
align="center"
key="permittedUnitCode"
prop="permittedUnitCode"
key="permittedUnitCode_dictText"
prop="permittedUnitCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
@@ -249,38 +250,53 @@
<el-table-column
label="归属科室"
align="center"
key="orgId"
prop="orgId"
key="orgId_dictText"
prop="orgId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="所在位置"
align="center"
key="locationId"
prop="locationId"
key="locationId_dictText"
prop="locationId_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="身体部位"
align="center"
key="bodySiteCode"
prop="bodySiteCode"
key="bodySiteCode_dictText"
prop="bodySiteCode_dictText"
:show-overflow-tooltip="true"
/>
<el-table-column
label="所需标本"
align="center"
key="specimenCode"
prop="specimenCode"
key="specimenCode_dictText"
prop="specimenCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="财务类别"
align="center"
key="itemTypeCode_dictText"
prop="itemTypeCode_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="医保类别"
align="center"
key="ybType_dictText"
prop="ybType_dictText"
:show-overflow-tooltip="true"
width="100"
/>
<el-table-column
label="售价"
align="center"
key="price"
prop="price"
key="retailPrice"
prop="retailPrice"
:show-overflow-tooltip="true"
width="100"
/>
@@ -338,7 +354,7 @@
<diagnosis-treatment-dialog
ref="diagnosisTreatmentRef"
:currentCategoryEnum="currentCategoryEnum"
:diseaseTreatmentCategoryList="diseaseTreatmentCategoryList"
:diagnosisCategoryOptions="diagnosisCategoryOptions"
:statusFlagOptions="statusFlagOptions"
:exeOrganizations="exeOrganizations"
:typeEnumOptions="typeEnumOptions"
@@ -376,13 +392,14 @@ const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const diseaseTreatmentCategoryList = ref(undefined);
const diagnosisCategoryOptions = ref(undefined);
const statusFlagOptions = ref(undefined);
const exeOrganizations = ref(undefined);
const typeEnumOptions = ref(undefined);
// 使用 ref 定义当前器材数据
const statusWeatherOption = ref(undefined);
// 使用 ref 定义当前诊疗数据
const currentData = ref({});
// 使用 ref 定义当前查看器材数据
// 使用 ref 定义当前查看诊疗数据
const viewData = ref({});
const currentCategoryEnum = ref("");
@@ -392,11 +409,11 @@ const data = reactive({
pageNo: 1,
pageSize: 10,
searchKey: undefined, // 品名/商品名/英文品名/编码/拼音
typeCode: undefined, // 类型(包括 1中药2成药
typeEnum: undefined, // 类型(包括 1中药2成药
statusEnum: undefined, // 状态(包括 1预置2启用3停用
ybMatchFlag: undefined, // 是否医保匹配(包括 10
ruleId: undefined, // 执行科室
categoryEnum: undefined, // 目录分类
categoryCode: undefined, // 目录分类
},
rules: {},
});
@@ -412,16 +429,21 @@ const filterNode = (value, data) => {
/** 诊断目录分类查询下拉树结构 */
function getDiseaseTreatmentList() {
getDiseaseTreatmentInit().then((response) => {
console.log(response, "response器材目录分类查询下拉树结构");
diseaseTreatmentCategoryList.value =
response.data.diseaseTreatmentCategoryList.sort((a, b) => { return parseInt(a.value) - parseInt(b.value) });
console.log(response, "response诊疗目录分类查询下拉树结构");
diagnosisCategoryOptions.value =
response.data.diagnosisCategoryOptions.sort((a, b) => {
return parseInt(a.value) - parseInt(b.value);
});
diagnosisCategoryOptions.value.push({ info: "全部", value: "" });
statusFlagOptions.value = response.data.statusFlagOptions;
exeOrganizations.value = response.data.exeOrganizations;
typeEnumOptions.value = response.data.typeEnumOptions;
statusWeatherOption.value = response.data.statusWeatherOption;
});
}
/** 查询诊断目录列表 */
function getList() {
console.log(queryParams.value, "queryParams***********************");
loading.value = true;
getDiagnosisTreatmentList(queryParams.value).then((res) => {
loading.value = false;
@@ -433,7 +455,7 @@ function getList() {
/** 节点单击事件 */
function handleNodeClick(data) {
console.log(data, "节点单击事件");
queryParams.value.categoryEnum = data.value;
queryParams.value.categoryCode = data.value;
currentCategoryEnum.value = data.value;
handleQuery();
}
@@ -495,19 +517,21 @@ function handleSelectionChange(selection) {
/** 打开新增弹窗 */
function openAddDiagnosisTreatment() {
if (currentCategoryEnum.value) {
// if (currentCategoryEnum.value) {
console.log("打开新增弹窗");
title.value = "新增";
nextTick(() => {
proxy.$refs.diagnosisTreatmentRef.show();
});
} else {
proxy.$modal.msgError("请先选择目录分类!");
}
// } else {
// proxy.$modal.msgError("请先选择目录分类!");
// }
}
/** 打开编辑弹窗 */
function openEditDiagnosisTreatment(row) {
getDiagnosisTreatmentOne(row.id).then((response) => {
console.log(response, "response88888");
currentData.value = response.data;
currentData.value.ybFlag == 1
? (currentData.value.ybFlag = true)

View File

@@ -226,12 +226,12 @@
/>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" v-if="form.id != undefined">
<el-form-item label="编码" prop="conditionCode">
<el-input
v-model="form.conditionCode"
placeholder="请输入编码"
:disabled="form.id != undefined"
disabled
/>
</el-form-item>
</el-col>
@@ -250,14 +250,14 @@
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="类型" prop="ybNo">
<el-form-item label="疾病类型" prop="typeCode">
<el-select
v-model="form.statusEnum"
v-model="form.typeCode"
placeholder="请选择"
clearable
>
<el-option
v-for="dict in statusFlagOptions"
v-for="dict in conditionDefinitionOptions"
:key="dict.value"
:label="dict.info"
:value="dict.value"
@@ -266,7 +266,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="医保标记" prop="ybFlag">
<el-form-item label="状态" prop="statusEnum">
<el-select
v-model="form.statusEnum"
placeholder="请选择"
@@ -359,9 +359,9 @@ const data = reactive({
},
rules: {
name: [{ required: true, message: "名称不能为空", trigger: "blur" }],
conditionCode: [
{ required: true, message: "编码不能为空", trigger: "blur" },
],
// conditionCode: [
// { required: true, message: "编码不能为空", trigger: "blur" },
// ],
},
});
@@ -473,9 +473,10 @@ function cancel() {
}
/** 新增按钮操作 */
function handleAdd() {
if (conditionDefinition.value === undefined) {
return proxy.$modal.msgError("请选择病种目录分类");
}
// if (conditionDefinition.value === undefined) {
// return proxy.$modal.msgError("请选择病种目录分类");
// }
form.value.typeCode = conditionDefinition.value
reset();
open.value = true;
title.value = "新增";

View File

@@ -411,7 +411,11 @@ function handleCurrentChange(row) {
listWesternmedicine(currentRow.value).then((response) => {
console.log("121212", response);
personInfo.value = response.data.prescriptionPatientInfoDto;
medicineInfoList.value = response.data.prescriptionMedicineInfoDtoList;
medicineInfoList.value = Array.isArray(
response.data.prescriptionMedicineInfoDtoList
)
? response.data.prescriptionMedicineInfoDtoList
: [response.data.prescriptionMedicineInfoDtoList];
// 统计每个 prescriptionNo 的行数
const groupCounts = countGroupRows(medicineInfoList.value);
// 设置每行的标记
@@ -427,7 +431,11 @@ function submitMedicine(row) {
updateMedicion(row.prescriptionNo).then((response) => {
proxy.$modal.msgSuccess("发药成功");
listWesternmedicine(currentRow.value).then((response) => {
medicineInfoList.value = response.data;
medicineInfoList.value = Array.isArray(
response.data.prescriptionMedicineInfoDtoList
)
? response.data.prescriptionMedicineInfoDtoList
: [response.data.prescriptionMedicineInfoDtoList];
// 统计每个 prescriptionNo 的行数
const groupCounts = countGroupRows(medicineInfoList.value);
// 设置每行的标记
@@ -453,7 +461,13 @@ function handleConfirm() {
}
);
listWesternmedicine(currentRow.value).then((response) => {
medicineInfoList.value = response.data;
console.log("1212*******12", response);
medicineInfoList.value = Array.isArray(
response.data.prescriptionMedicineInfoDtoList
)
? response.data.prescriptionMedicineInfoDtoList
: [response.data.prescriptionMedicineInfoDtoList];
// medicineInfoList.value = response.data;
// 统计每个 prescriptionNo 的行数
const groupCounts = countGroupRows(medicineInfoList.value);
// 设置每行的标记