Compare commits
5 Commits
刘备
...
5a4c2b6354
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5a4c2b6354 | ||
|
|
6626c8f1cd | ||
|
|
e2f4996f47 | ||
|
|
37b57e8b12 | ||
|
|
4bd0d2dcc8 |
@@ -25,7 +25,7 @@ public class SysTenantController extends BaseController {
|
|||||||
private ISysTenantService sysTenantService;
|
private ISysTenantService sysTenantService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户分页列表(只读操作,不限制租户管理权限)
|
* 查询租户分页列表
|
||||||
*
|
*
|
||||||
* @param tenantId 租户ID查询
|
* @param tenantId 租户ID查询
|
||||||
* @param tenantCode 租户编码模糊查询
|
* @param tenantCode 租户编码模糊查询
|
||||||
@@ -35,7 +35,7 @@ public class SysTenantController extends BaseController {
|
|||||||
* @param pageSize 每页多少条
|
* @param pageSize 每页多少条
|
||||||
* @return 租户分页列表
|
* @return 租户分页列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:tenant:list')")
|
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
public R<IPage<SysTenant>> getTenantPage(@RequestParam(required = false) Integer tenantId,
|
public R<IPage<SysTenant>> getTenantPage(@RequestParam(required = false) Integer tenantId,
|
||||||
@RequestParam(required = false) String tenantCode, @RequestParam(required = false) String tenantName,
|
@RequestParam(required = false) String tenantCode, @RequestParam(required = false) String tenantName,
|
||||||
@@ -45,19 +45,19 @@ public class SysTenantController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户详情(只读操作)
|
* 查询租户详情
|
||||||
*
|
*
|
||||||
* @param tenantId 租户ID
|
* @param tenantId 租户ID
|
||||||
* @return 租户分页列表
|
* @return 租户分页列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:tenant:list')")
|
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
|
||||||
@GetMapping("/{tenantId}")
|
@GetMapping("/{tenantId}")
|
||||||
public R<SysTenant> getTenantDetail(@PathVariable Integer tenantId) {
|
public R<SysTenant> getTenantDetail(@PathVariable Integer tenantId) {
|
||||||
return R.ok(sysTenantService.getById(tenantId));
|
return R.ok(sysTenantService.getById(tenantId));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户所属用户分页列表(只读操作)
|
* 查询租户所属用户分页列表
|
||||||
*
|
*
|
||||||
* @param tenantId 租户ID查询
|
* @param tenantId 租户ID查询
|
||||||
* @param userName 用户昵称模糊查询
|
* @param userName 用户昵称模糊查询
|
||||||
@@ -67,7 +67,7 @@ public class SysTenantController extends BaseController {
|
|||||||
* @param pageSize 每页多少条
|
* @param pageSize 每页多少条
|
||||||
* @return 租户所属用户分页列表
|
* @return 租户所属用户分页列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:tenant:list')")
|
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
|
||||||
@GetMapping("/user/page")
|
@GetMapping("/user/page")
|
||||||
public R<IPage<SysUser>> getTenantUserPage(@RequestParam(required = false) Integer tenantId,
|
public R<IPage<SysUser>> getTenantUserPage(@RequestParam(required = false) Integer tenantId,
|
||||||
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
|
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
|
||||||
@@ -141,14 +141,14 @@ public class SysTenantController extends BaseController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询租户未绑定的用户列表(只读操作)
|
* 查询租户未绑定的用户列表
|
||||||
*
|
*
|
||||||
* @param tenantId 租户ID
|
* @param tenantId 租户ID
|
||||||
* @param pageNum 当前页
|
* @param pageNum 当前页
|
||||||
* @param pageSize 每页多少条
|
* @param pageSize 每页多少条
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('system:tenant:list')")
|
@PreAuthorize("@ss.hasPermi('system:tenant:operate')")
|
||||||
@GetMapping("/{tenantId}/unbind-users")
|
@GetMapping("/{tenantId}/unbind-users")
|
||||||
public R<IPage<SysUser>> getUnbindTenantUserList(@PathVariable Integer tenantId,
|
public R<IPage<SysUser>> getUnbindTenantUserList(@PathVariable Integer tenantId,
|
||||||
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
|
@RequestParam(required = false) String userName, @RequestParam(required = false) String nickName,
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import com.core.common.utils.MessageUtils;
|
|||||||
import com.openhis.administration.domain.Location;
|
import com.openhis.administration.domain.Location;
|
||||||
import com.openhis.administration.domain.Organization;
|
import com.openhis.administration.domain.Organization;
|
||||||
import com.openhis.administration.domain.OrganizationLocation;
|
import com.openhis.administration.domain.OrganizationLocation;
|
||||||
import com.openhis.workflow.domain.ActivityDefinition;
|
|
||||||
import com.openhis.administration.mapper.OrganizationLocationMapper;
|
import com.openhis.administration.mapper.OrganizationLocationMapper;
|
||||||
import com.openhis.administration.service.ILocationService;
|
import com.openhis.administration.service.ILocationService;
|
||||||
import com.openhis.administration.service.IOrganizationLocationService;
|
import com.openhis.administration.service.IOrganizationLocationService;
|
||||||
@@ -71,7 +70,6 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
// 获取科室下拉选列表
|
// 获取科室下拉选列表
|
||||||
List<Organization> organizationList = organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null);
|
List<Organization> organizationList = organizationService.getList(OrganizationType.DEPARTMENT.getValue(), null);
|
||||||
List<OrgLocInitDto.departmentOption> organizationOptions = organizationList.stream()
|
List<OrgLocInitDto.departmentOption> organizationOptions = organizationList.stream()
|
||||||
.filter(organization -> organization != null && organization.getName() != null)
|
|
||||||
.map(organization -> new OrgLocInitDto.departmentOption(organization.getId(), organization.getName()))
|
.map(organization -> new OrgLocInitDto.departmentOption(organization.getId(), organization.getName()))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
initDto.setLocationFormOptions(chargeItemStatusOptions).setDepartmentOptions(organizationOptions);
|
initDto.setLocationFormOptions(chargeItemStatusOptions).setDepartmentOptions(organizationOptions);
|
||||||
@@ -133,18 +131,12 @@ public class OrganizationLocationAppServiceImpl implements IOrganizationLocation
|
|||||||
@Override
|
@Override
|
||||||
public R<?> addOrEditOrgLoc(OrgLocQueryDto orgLocQueryDto) {
|
public R<?> addOrEditOrgLoc(OrgLocQueryDto orgLocQueryDto) {
|
||||||
|
|
||||||
// Validate required fields before processing
|
|
||||||
if (orgLocQueryDto.getOrganizationId() == null) {
|
|
||||||
return R.fail("请选择执行科室");
|
|
||||||
}
|
|
||||||
|
|
||||||
OrganizationLocation orgLoc = new OrganizationLocation();
|
OrganizationLocation orgLoc = new OrganizationLocation();
|
||||||
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
BeanUtils.copyProperties(orgLocQueryDto, orgLoc);
|
||||||
|
|
||||||
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
Long activityDefinitionId = orgLoc.getActivityDefinitionId();
|
||||||
ActivityDefinition activityDef = activityDefinitionId != null
|
String activityName = activityDefinitionId != null
|
||||||
? activityDefinitionMapper.selectById(activityDefinitionId) : null;
|
? activityDefinitionMapper.selectById(activityDefinitionId).getName() : "";
|
||||||
String activityName = activityDef != null ? activityDef.getName() : "";
|
|
||||||
|
|
||||||
List<OrganizationLocation> organizationLocationList =
|
List<OrganizationLocation> organizationLocationList =
|
||||||
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
organizationLocationService.getOrgLocListByOrgIdAndActivityDefinitionId(orgLoc.getActivityDefinitionId());
|
||||||
|
|||||||
@@ -246,16 +246,6 @@ public class OpCreateScheduleDto {
|
|||||||
*/
|
*/
|
||||||
private String communicationInfo;
|
private String communicationInfo;
|
||||||
|
|
||||||
/**
|
|
||||||
* 是否外请专家 1-是 0-否
|
|
||||||
*/
|
|
||||||
private Integer isExternalExpert;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 外请专家姓名
|
|
||||||
*/
|
|
||||||
private String externalExpertName;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 备注
|
* 备注
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -106,9 +106,4 @@ public class OpScheduleDto extends OpSchedule {
|
|||||||
* 创建人名称
|
* 创建人名称
|
||||||
*/
|
*/
|
||||||
private String createByName;
|
private String createByName;
|
||||||
|
|
||||||
/**
|
|
||||||
* 费用类别
|
|
||||||
*/
|
|
||||||
private String feeType;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,37 +231,21 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// 费用定价主表ID集合
|
// 费用定价主表ID集合
|
||||||
List<Long> chargeItemDefinitionIdList = adviceBaseDtoList.stream().map(AdviceBaseDto::getChargeItemDefinitionId)
|
List<Long> chargeItemDefinitionIdList = adviceBaseDtoList.stream().map(AdviceBaseDto::getChargeItemDefinitionId)
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
// 医嘱库存集合
|
||||||
// 判断是否包含药品或耗材类型(只有这些类型才需要库存相关查询)
|
List<AdviceInventoryDto> adviceInventoryList = doctorStationAdviceAppMapper.getAdviceInventory(locationId,
|
||||||
boolean hasMedOrDevice = adviceTypes != null
|
|
||||||
&& (adviceTypes.contains(1) || adviceTypes.contains(2));
|
|
||||||
|
|
||||||
// 医嘱库存集合 — 仅药品/耗材需要库存查询,手术/诊疗(3,6)无库存概念,跳过以减少数据库开销
|
|
||||||
List<AdviceInventoryDto> adviceInventoryList;
|
|
||||||
List<AdviceInventoryDto> adviceDraftInventoryList;
|
|
||||||
List<AdviceInventoryDto> adviceInventory;
|
|
||||||
if (hasMedOrDevice) {
|
|
||||||
adviceInventoryList = doctorStationAdviceAppMapper.getAdviceInventory(locationId,
|
|
||||||
adviceDefinitionIdList,
|
adviceDefinitionIdList,
|
||||||
CommonConstants.SqlCondition.ABOUT_INVENTORY_TABLE_STR, PublicationStatus.ACTIVE.getValue());
|
CommonConstants.SqlCondition.ABOUT_INVENTORY_TABLE_STR, PublicationStatus.ACTIVE.getValue());
|
||||||
// 待发放个数信息
|
// 待发放个数信息
|
||||||
adviceDraftInventoryList = doctorStationAdviceAppMapper.getAdviceDraftInventory(
|
List<AdviceInventoryDto> adviceDraftInventoryList = doctorStationAdviceAppMapper.getAdviceDraftInventory(
|
||||||
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
CommonConstants.TableName.MED_MEDICATION_DEFINITION, CommonConstants.TableName.ADM_DEVICE_DEFINITION,
|
||||||
DispenseStatus.DRAFT.getValue(), DispenseStatus.PREPARATION.getValue());
|
DispenseStatus.DRAFT.getValue(), DispenseStatus.PREPARATION.getValue());
|
||||||
// 预减库存
|
// 预减库存
|
||||||
adviceInventory = adviceUtils.subtractInventory(adviceInventoryList, adviceDraftInventoryList);
|
List<AdviceInventoryDto> adviceInventory = adviceUtils.subtractInventory(adviceInventoryList,
|
||||||
} else {
|
adviceDraftInventoryList);
|
||||||
adviceInventoryList = Collections.emptyList();
|
// 查询取药科室配置
|
||||||
adviceDraftInventoryList = Collections.emptyList();
|
List<AdviceInventoryDto> medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId);
|
||||||
adviceInventory = Collections.emptyList();
|
|
||||||
}
|
|
||||||
// 查询取药科室配置 — 仅药品开单场景需要
|
|
||||||
List<AdviceInventoryDto> medLocationConfig;
|
|
||||||
Map<String, Set<Long>> allowedLocByCategory;
|
|
||||||
if (hasMedOrDevice) {
|
|
||||||
medLocationConfig = doctorStationAdviceAppMapper.getMedLocationConfig(organizationId);
|
|
||||||
// 将配置转为 {categoryCode -> 允许的locationId集合}
|
// 将配置转为 {categoryCode -> 允许的locationId集合}
|
||||||
allowedLocByCategory = new HashMap<>();
|
Map<String, Set<Long>> allowedLocByCategory = new HashMap<>();
|
||||||
if (medLocationConfig != null && !medLocationConfig.isEmpty()) {
|
if (medLocationConfig != null && !medLocationConfig.isEmpty()) {
|
||||||
for (AdviceInventoryDto cfg : medLocationConfig) {
|
for (AdviceInventoryDto cfg : medLocationConfig) {
|
||||||
if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) {
|
if (cfg.getCategoryCode() == null || cfg.getLocationId() == null) {
|
||||||
@@ -271,10 +255,6 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
.add(cfg.getLocationId());
|
.add(cfg.getLocationId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
medLocationConfig = Collections.emptyList();
|
|
||||||
allowedLocByCategory = Collections.emptyMap();
|
|
||||||
}
|
|
||||||
// 费用定价子表信息 - 使用分批处理避免大量参数问题
|
// 费用定价子表信息 - 使用分批处理避免大量参数问题
|
||||||
List<AdvicePriceDto> childCharge = new ArrayList<>();
|
List<AdvicePriceDto> childCharge = new ArrayList<>();
|
||||||
if (chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) {
|
if (chargeItemDefinitionIdList != null && !chargeItemDefinitionIdList.isEmpty()) {
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.openhis.web.doctorstation.dto;
|
package com.openhis.web.doctorstation.dto;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
|
||||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
@@ -56,7 +55,6 @@ public class InfectiousDiseaseReportDto {
|
|||||||
private String sex;
|
private String sex;
|
||||||
|
|
||||||
/** 出生日期 */
|
/** 出生日期 */
|
||||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
|
||||||
private Date birthday;
|
private Date birthday;
|
||||||
|
|
||||||
/** 实足年龄 */
|
/** 实足年龄 */
|
||||||
|
|||||||
@@ -17,9 +17,6 @@ import com.openhis.common.constant.PromptMsgConstant;
|
|||||||
import com.openhis.common.enums.*;
|
import com.openhis.common.enums.*;
|
||||||
import com.openhis.common.utils.EnumUtils;
|
import com.openhis.common.utils.EnumUtils;
|
||||||
import com.openhis.common.utils.HisQueryUtils;
|
import com.openhis.common.utils.HisQueryUtils;
|
||||||
import com.core.common.utils.SecurityUtils;
|
|
||||||
import com.openhis.workflow.domain.InventoryItem;
|
|
||||||
import com.openhis.workflow.service.IInventoryItemService;
|
|
||||||
import com.openhis.web.basedatamanage.dto.LocationDto;
|
import com.openhis.web.basedatamanage.dto.LocationDto;
|
||||||
import com.openhis.web.common.dto.UnitDto;
|
import com.openhis.web.common.dto.UnitDto;
|
||||||
import com.openhis.web.inventorymanage.appservice.IProductTransferAppService;
|
import com.openhis.web.inventorymanage.appservice.IProductTransferAppService;
|
||||||
@@ -60,9 +57,6 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IPractitionerService practitionerService;
|
private IPractitionerService practitionerService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IInventoryItemService inventoryItemService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品调拨页面初始化
|
* 商品调拨页面初始化
|
||||||
*
|
*
|
||||||
@@ -202,23 +196,6 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService
|
|||||||
@Override
|
@Override
|
||||||
public R<?> addOrEditBatchTransferReceipt(List<ProductTransferDto> productTransferDtoList, Boolean flag) {
|
public R<?> addOrEditBatchTransferReceipt(List<ProductTransferDto> productTransferDtoList, Boolean flag) {
|
||||||
|
|
||||||
// 校验调拨数量:必须 > 0 且不超过源库存数量(从数据库查实时库存)
|
|
||||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
|
||||||
for (ProductTransferDto dto : productTransferDtoList) {
|
|
||||||
if (dto.getItemQuantity() == null || dto.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) {
|
|
||||||
return R.fail("调拨数量必须大于0");
|
|
||||||
}
|
|
||||||
// 查询该药品在源仓库的实时库存总量
|
|
||||||
List<InventoryItem> inventoryList = inventoryItemService.selectInventoryByItemId(
|
|
||||||
dto.getItemId(), dto.getLotNumber(), dto.getSourceLocationId(), tenantId);
|
|
||||||
java.math.BigDecimal actualStock = inventoryList.stream()
|
|
||||||
.map(InventoryItem::getQuantity)
|
|
||||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
|
|
||||||
if (dto.getItemQuantity().compareTo(actualStock) > 0) {
|
|
||||||
return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> idList = new ArrayList<>();
|
List<String> idList = new ArrayList<>();
|
||||||
if (flag) {
|
if (flag) {
|
||||||
// 批量保存按钮
|
// 批量保存按钮
|
||||||
@@ -332,22 +309,6 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService
|
|||||||
@Override
|
@Override
|
||||||
public R<?> addOrEditTransferReceipt(List<ProductTransferDto> productTransferDtoList) {
|
public R<?> addOrEditTransferReceipt(List<ProductTransferDto> productTransferDtoList) {
|
||||||
|
|
||||||
// 校验调拨数量:必须 > 0 且不超过源库存数量(从数据库查实时库存)
|
|
||||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
|
||||||
for (ProductTransferDto dto : productTransferDtoList) {
|
|
||||||
if (dto.getItemQuantity() == null || dto.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) {
|
|
||||||
return R.fail("调拨数量必须大于0");
|
|
||||||
}
|
|
||||||
List<InventoryItem> inventoryList = inventoryItemService.selectInventoryByItemId(
|
|
||||||
dto.getItemId(), dto.getLotNumber(), dto.getSourceLocationId(), tenantId);
|
|
||||||
java.math.BigDecimal actualStock = inventoryList.stream()
|
|
||||||
.map(InventoryItem::getQuantity)
|
|
||||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
|
|
||||||
if (dto.getItemQuantity().compareTo(actualStock) > 0) {
|
|
||||||
return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + ")");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
List<String> idList = new ArrayList<>();
|
List<String> idList = new ArrayList<>();
|
||||||
|
|
||||||
// 单据号取得
|
// 单据号取得
|
||||||
@@ -419,25 +380,6 @@ public class ProductTransferAppServiceImpl implements IProductTransferAppService
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public R<?> submitApproval(String busNo) {
|
public R<?> submitApproval(String busNo) {
|
||||||
// 提交前再次校验调拨数量(从数据库查实时库存)
|
|
||||||
List<SupplyRequest> requestList = supplyRequestService.getSupplyByBusNo(busNo);
|
|
||||||
if (requestList != null && !requestList.isEmpty()) {
|
|
||||||
Integer tenantId = SecurityUtils.getLoginUser().getTenantId();
|
|
||||||
for (SupplyRequest request : requestList) {
|
|
||||||
if (request.getItemQuantity() == null || request.getItemQuantity().compareTo(java.math.BigDecimal.ZERO) <= 0) {
|
|
||||||
return R.fail("调拨数量必须大于0,请检查后重新保存");
|
|
||||||
}
|
|
||||||
// 查询该药品在源仓库的实时库存总量
|
|
||||||
List<InventoryItem> inventoryList = inventoryItemService.selectInventoryByItemId(
|
|
||||||
request.getItemId(), request.getLotNumber(), request.getSourceLocationId(), tenantId);
|
|
||||||
java.math.BigDecimal actualStock = inventoryList.stream()
|
|
||||||
.map(InventoryItem::getQuantity)
|
|
||||||
.reduce(java.math.BigDecimal.ZERO, java.math.BigDecimal::add);
|
|
||||||
if (request.getItemQuantity().compareTo(actualStock) > 0) {
|
|
||||||
return R.fail("调拨数量不可超出源库存数量(当前库存:" + actualStock + "),请检查后重新保存");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// 单据提交审核
|
// 单据提交审核
|
||||||
boolean result = supplyRequestService.submitApproval(busNo);
|
boolean result = supplyRequestService.submitApproval(busNo);
|
||||||
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
|
return result ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, null))
|
||||||
|
|||||||
@@ -39,22 +39,10 @@ public interface IRequestFormManageAppService {
|
|||||||
* @param typeCode 申请单类型
|
* @param typeCode 申请单类型
|
||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
* @return 申请单列表
|
|
||||||
*/
|
|
||||||
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询申请单(支持筛选+状态+关键字)
|
|
||||||
*
|
|
||||||
* @param encounterId 就诊id
|
|
||||||
* @param typeCode 申请单类型
|
|
||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
|
||||||
* @param status 单据状态(可选)
|
* @param status 单据状态(可选)
|
||||||
* @param keyword 关键字(可选,申请单号/项目名称模糊匹配)
|
|
||||||
* @return 申请单列表
|
* @return 申请单列表
|
||||||
*/
|
*/
|
||||||
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status, String keyword);
|
List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询申请单
|
* 分页查询申请单
|
||||||
|
|||||||
@@ -414,7 +414,7 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
@Override
|
@Override
|
||||||
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode) {
|
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode) {
|
||||||
// 调用重载方法,不传筛选参数
|
// 调用重载方法,不传筛选参数
|
||||||
return getRequestForm(encounterId, typeCode, null, null);
|
return getRequestForm(encounterId, typeCode, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -424,32 +424,17 @@ public class RequestFormManageAppServiceImpl implements IRequestFormManageAppSer
|
|||||||
* @param typeCode 申请单类型
|
* @param typeCode 申请单类型
|
||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
* @return 申请单列表
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate) {
|
|
||||||
return getRequestForm(encounterId, typeCode, startDate, endDate, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 查询申请单(支持筛选+状态+关键字)
|
|
||||||
*
|
|
||||||
* @param encounterId 就诊id
|
|
||||||
* @param typeCode 申请单类型
|
|
||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
|
||||||
* @param status 单据状态(可选)
|
* @param status 单据状态(可选)
|
||||||
* @param keyword 关键字(可选,申请单号/项目名称模糊匹配)
|
|
||||||
* @return 申请单列表
|
* @return 申请单列表
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status, String keyword) {
|
public List<RequestFormQueryDto> getRequestForm(Long encounterId, String typeCode, String startDate, String endDate, String status) {
|
||||||
// 检查参数
|
// 检查参数
|
||||||
if (encounterId == null) {
|
if (encounterId == null) {
|
||||||
return new java.util.ArrayList<>();
|
return new java.util.ArrayList<>(); // 返回空列表而不是查询数据库
|
||||||
}
|
}
|
||||||
|
|
||||||
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate, status, keyword);
|
List<RequestFormQueryDto> requestFormList = requestFormManageAppMapper.getRequestForm(encounterId, typeCode, startDate, endDate, status, null);
|
||||||
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
for (RequestFormQueryDto requestFormQueryDto : requestFormList) {
|
||||||
// 查询处方详情
|
// 查询处方详情
|
||||||
List<RequestFormDetailQueryDto> requestFormDetail =
|
List<RequestFormDetailQueryDto> requestFormDetail =
|
||||||
|
|||||||
@@ -98,7 +98,6 @@ public class RequestFormManageController {
|
|||||||
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
* @param startDate 开始日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
* @param endDate 结束日期(可选,格式:yyyy-MM-dd)
|
||||||
* @param status 单据状态(可选)
|
* @param status 单据状态(可选)
|
||||||
* @param keyword 关键字(可选,申请单号/检验项目模糊匹配)
|
|
||||||
* @return 检验申请单
|
* @return 检验申请单
|
||||||
*/
|
*/
|
||||||
@GetMapping(value = "/get-inspection")
|
@GetMapping(value = "/get-inspection")
|
||||||
@@ -106,12 +105,11 @@ public class RequestFormManageController {
|
|||||||
@RequestParam(required = false) Long encounterId,
|
@RequestParam(required = false) Long encounterId,
|
||||||
@RequestParam(required = false) String startDate,
|
@RequestParam(required = false) String startDate,
|
||||||
@RequestParam(required = false) String endDate,
|
@RequestParam(required = false) String endDate,
|
||||||
@RequestParam(required = false) String status,
|
@RequestParam(required = false) String status) {
|
||||||
@RequestParam(required = false) String keyword) {
|
|
||||||
if (encounterId == null) {
|
if (encounterId == null) {
|
||||||
return R.fail("就诊ID不能为空");
|
return R.fail("就诊ID不能为空");
|
||||||
}
|
}
|
||||||
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROOF.getCode(), startDate, endDate, status, keyword));
|
return R.ok(iRequestFormManageAppService.getRequestForm(encounterId, ActivityDefCategory.PROOF.getCode(), startDate, endDate, status));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ spring:
|
|||||||
druid:
|
druid:
|
||||||
# 主库数据源
|
# 主库数据源
|
||||||
master:
|
master:
|
||||||
url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=histest1&characterEncoding=UTF-8&client_encoding=UTF-8
|
url: jdbc:postgresql://192.168.110.252:15432/postgresql?currentSchema=histest&characterEncoding=UTF-8&client_encoding=UTF-8
|
||||||
username: postgresql
|
username: postgresql
|
||||||
password: Jchl1528
|
password: Jchl1528
|
||||||
# 从库数据源
|
# 从库数据源
|
||||||
|
|||||||
@@ -100,7 +100,6 @@
|
|||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{activity} AND T1.service_table = 'wor_service_request' THEN COALESCE(T9.surgery_name, wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
|
||||||
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{medication} THEN T3."name"
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
WHEN T1.context_enum = #{device} THEN T4."name"
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
@@ -226,7 +225,6 @@
|
|||||||
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = 6 AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = 6 THEN T2."name"
|
WHEN T1.context_enum = 6 THEN T2."name"
|
||||||
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} AND T1.product_id = 0 AND T1.service_table = 'wor_service_request' THEN COALESCE(wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{activity} AND T1.service_table = 'wor_service_request' THEN COALESCE(T9.surgery_name, wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
|
||||||
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
WHEN T1.context_enum = #{activity} THEN COALESCE(wsr.content_json::json->>'surgeryName', wsr.content_json::json->>'adviceName', T2."name")
|
||||||
WHEN T1.context_enum = #{medication} THEN T3."name"
|
WHEN T1.context_enum = #{medication} THEN T3."name"
|
||||||
WHEN T1.context_enum = #{device} THEN T4."name"
|
WHEN T1.context_enum = #{device} THEN T4."name"
|
||||||
|
|||||||
@@ -89,15 +89,11 @@
|
|||||||
cs.apply_doctor_name AS apply_doctor_name,
|
cs.apply_doctor_name AS apply_doctor_name,
|
||||||
drf.create_time AS apply_time,
|
drf.create_time AS apply_time,
|
||||||
os.surgery_nature AS surgeryType,
|
os.surgery_nature AS surgeryType,
|
||||||
fc.contract_name AS feeType,
|
|
||||||
COALESCE(pi.identifier_no, ap.bus_no, '') AS identifierNo
|
COALESCE(pi.identifier_no, ap.bus_no, '') AS identifierNo
|
||||||
FROM op_schedule os
|
FROM op_schedule os
|
||||||
LEFT JOIN adm_patient ap ON os.patient_id = ap.id
|
LEFT JOIN adm_patient ap ON os.patient_id = ap.id
|
||||||
INNER JOIN cli_surgery cs ON os.oper_code = cs.surgery_no AND cs.delete_flag = '0'
|
INNER JOIN cli_surgery cs ON os.oper_code = cs.surgery_no AND cs.delete_flag = '0'
|
||||||
LEFT JOIN adm_organization o ON cs.org_id = o.id
|
LEFT JOIN adm_organization o ON cs.org_id = o.id
|
||||||
LEFT JOIN adm_encounter ae ON ae.id = cs.encounter_id AND ae.delete_flag = '0'
|
|
||||||
LEFT JOIN adm_account aa ON aa.encounter_id = ae.id AND aa.delete_flag = '0'
|
|
||||||
LEFT JOIN fin_contract fc ON fc.bus_no = aa.contract_no AND fc.delete_flag = '0'
|
|
||||||
LEFT JOIN doc_request_form drf ON drf.prescription_no=cs.surgery_no
|
LEFT JOIN doc_request_form drf ON drf.prescription_no=cs.surgery_no
|
||||||
LEFT JOIN (
|
LEFT JOIN (
|
||||||
SELECT patient_id, identifier_no
|
SELECT patient_id, identifier_no
|
||||||
|
|||||||
@@ -98,6 +98,9 @@
|
|||||||
INNER JOIN adm_organization_location AS T6 ON T6.distribution_category_code = t1.category_code AND T6.delete_flag = '0' AND T6.item_code = '1' AND T6.organization_id = #{organizationId} AND (CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
|
INNER JOIN adm_organization_location AS T6 ON T6.distribution_category_code = t1.category_code AND T6.delete_flag = '0' AND T6.item_code = '1' AND T6.organization_id = #{organizationId} AND (CURRENT_TIME :: time (6) BETWEEN T6.start_time AND T6.end_time)
|
||||||
WHERE t1.delete_flag = '0'
|
WHERE t1.delete_flag = '0'
|
||||||
AND T2.status_enum = #{statusEnum}
|
AND T2.status_enum = #{statusEnum}
|
||||||
|
<if test="pricingFlag == 1">
|
||||||
|
AND 1 = 2
|
||||||
|
</if>
|
||||||
<if test="categoryCode != null and categoryCode != ''">
|
<if test="categoryCode != null and categoryCode != ''">
|
||||||
<!-- 🔧 BugFix: 支持两种匹配方式 -->
|
<!-- 🔧 BugFix: 支持两种匹配方式 -->
|
||||||
<!-- 1. 直接匹配:distribution_category_code = category_code(都是数字代码) -->
|
<!-- 1. 直接匹配:distribution_category_code = category_code(都是数字代码) -->
|
||||||
@@ -541,9 +544,9 @@
|
|||||||
CI.service_id AS request_id,
|
CI.service_id AS request_id,
|
||||||
CI.service_id || '-ci-dev' AS unique_key,
|
CI.service_id || '-ci-dev' AS unique_key,
|
||||||
'' AS prescription_no,
|
'' AS prescription_no,
|
||||||
COALESCE(DR.requester_id, CI.enterer_id) AS requester_id,
|
CI.enterer_id AS requester_id,
|
||||||
CI.entered_date AS request_time,
|
CI.entered_date AS request_time,
|
||||||
CASE WHEN COALESCE(DR.requester_id, CI.enterer_id) = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
CASE WHEN CI.enterer_id = #{practitionerId} THEN '1' ELSE '0' END AS biz_request_flag,
|
||||||
DR.content_json AS content_json,
|
DR.content_json AS content_json,
|
||||||
NULL AS skin_test_flag,
|
NULL AS skin_test_flag,
|
||||||
NULL AS inject_flag,
|
NULL AS inject_flag,
|
||||||
|
|||||||
@@ -12,24 +12,13 @@
|
|||||||
drf.desc_json,
|
drf.desc_json,
|
||||||
drf.requester_id,
|
drf.requester_id,
|
||||||
drf.create_time,
|
drf.create_time,
|
||||||
ap.NAME AS patient_name,
|
drf.status,
|
||||||
CASE MIN(wsr.status_enum)
|
ap.NAME AS patient_name
|
||||||
WHEN 1 THEN 0
|
|
||||||
WHEN 2 THEN 1
|
|
||||||
WHEN 3 THEN 4
|
|
||||||
WHEN 4 THEN 4
|
|
||||||
WHEN 5 THEN 5
|
|
||||||
WHEN 6 THEN 5
|
|
||||||
WHEN 7 THEN 5
|
|
||||||
ELSE NULL
|
|
||||||
END AS status
|
|
||||||
FROM doc_request_form AS drf
|
FROM doc_request_form AS drf
|
||||||
LEFT JOIN adm_encounter AS ae ON ae.ID = drf.encounter_id
|
LEFT JOIN adm_encounter AS ae ON ae.ID = drf.encounter_id
|
||||||
AND ae.delete_flag = '0'
|
AND ae.delete_flag = '0'
|
||||||
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
LEFT JOIN adm_patient AS ap ON ap.ID = ae.patient_id
|
||||||
AND ap.delete_flag = '0'
|
AND ap.delete_flag = '0'
|
||||||
LEFT JOIN wor_service_request AS wsr ON wsr.prescription_no = drf.prescription_no
|
|
||||||
AND wsr.delete_flag = '0'
|
|
||||||
WHERE drf.delete_flag = '0'
|
WHERE drf.delete_flag = '0'
|
||||||
AND drf.encounter_id = #{encounterId}
|
AND drf.encounter_id = #{encounterId}
|
||||||
AND drf.type_code = #{typeCode}
|
AND drf.type_code = #{typeCode}
|
||||||
@@ -40,32 +29,8 @@
|
|||||||
AND drf.create_time <= (#{endDate}::date + INTERVAL '1 day' - INTERVAL '1 second')
|
AND drf.create_time <= (#{endDate}::date + INTERVAL '1 day' - INTERVAL '1 second')
|
||||||
</if>
|
</if>
|
||||||
<if test="status != null and status != ''">
|
<if test="status != null and status != ''">
|
||||||
AND CASE MIN(wsr.status_enum)
|
AND drf.status = #{status}::integer
|
||||||
WHEN 1 THEN 0
|
|
||||||
WHEN 2 THEN 1
|
|
||||||
WHEN 3 THEN 4
|
|
||||||
WHEN 4 THEN 4
|
|
||||||
WHEN 5 THEN 5
|
|
||||||
WHEN 6 THEN 5
|
|
||||||
WHEN 7 THEN 5
|
|
||||||
ELSE NULL
|
|
||||||
END = #{status}::integer
|
|
||||||
</if>
|
</if>
|
||||||
<if test="keyword != null and keyword != ''">
|
|
||||||
AND (drf.prescription_no ILIKE '%' || #{keyword} || '%'
|
|
||||||
OR EXISTS (
|
|
||||||
SELECT 1 FROM wor_service_request wsr2
|
|
||||||
WHERE wsr2.prescription_no = drf.prescription_no
|
|
||||||
AND wsr2.delete_flag = '0'
|
|
||||||
AND wsr2.activity_id IN (
|
|
||||||
SELECT id FROM wor_activity_definition wad
|
|
||||||
WHERE wad.delete_flag = '0'
|
|
||||||
AND wad.name ILIKE '%' || #{keyword} || '%'
|
|
||||||
)
|
|
||||||
))
|
|
||||||
</if>
|
|
||||||
GROUP BY drf.id, drf.encounter_id, drf.prescription_no, drf.name, drf.desc_json,
|
|
||||||
drf.requester_id, drf.create_time, ap.name
|
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<select id="getRequestFormDetail" resultType="com.openhis.web.regdoctorstation.dto.RequestFormDetailQueryDto">
|
<select id="getRequestFormDetail" resultType="com.openhis.web.regdoctorstation.dto.RequestFormDetailQueryDto">
|
||||||
|
|||||||
@@ -187,12 +187,6 @@ public class OpSchedule extends HisBaseEntity {
|
|||||||
/** 沟通信息 */
|
/** 沟通信息 */
|
||||||
private String communicationInfo;
|
private String communicationInfo;
|
||||||
|
|
||||||
/** 是否外请专家 1-是 0-否 */
|
|
||||||
private Integer isExternalExpert;
|
|
||||||
|
|
||||||
/** 外请专家姓名 */
|
|
||||||
private String externalExpertName;
|
|
||||||
|
|
||||||
/** 备注信息 */
|
/** 备注信息 */
|
||||||
private String remark;
|
private String remark;
|
||||||
|
|
||||||
|
|||||||
@@ -475,13 +475,8 @@ function calculateTotalPrice() {
|
|||||||
});
|
});
|
||||||
totalPrice.value = sum.toFixed(2);
|
totalPrice.value = sum.toFixed(2);
|
||||||
// Bug #464: 零售价与诊疗子项合计总价实时同步
|
// Bug #464: 零售价与诊疗子项合计总价实时同步
|
||||||
const hasValidItem = treatmentItems.value.some(
|
if (treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId !== '') {
|
||||||
(item) => item.adviceDefinitionId && item.adviceDefinitionId !== ''
|
|
||||||
);
|
|
||||||
if (hasValidItem) {
|
|
||||||
form.value.retailPrice = parseFloat(totalPrice.value);
|
form.value.retailPrice = parseFloat(totalPrice.value);
|
||||||
} else {
|
|
||||||
form.value.retailPrice = undefined;
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
totalPrice.value = '0.00';
|
totalPrice.value = '0.00';
|
||||||
@@ -491,7 +486,7 @@ function calculateTotalPrice() {
|
|||||||
|
|
||||||
// 添加表单项
|
// 添加表单项
|
||||||
function addItem() {
|
function addItem() {
|
||||||
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1, name: '', retailPrice: 0 });
|
treatmentItems.value.push({ adviceDefinitionId: '', childrenRequestNum: 1, retailPrice: 0 });
|
||||||
// 使用nextTick确保DOM更新后再计算
|
// 使用nextTick确保DOM更新后再计算
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
calculateTotalPrice();
|
calculateTotalPrice();
|
||||||
@@ -652,15 +647,12 @@ async function submitForm() {
|
|||||||
form.value.ybMatchFlag ? (form.value.ybMatchFlag = 1) : (form.value.ybMatchFlag = 0);
|
form.value.ybMatchFlag ? (form.value.ybMatchFlag = 1) : (form.value.ybMatchFlag = 0);
|
||||||
form.value.ruleId ? (form.value.ruleId = 1) : (form.value.ruleId = 0);
|
form.value.ruleId ? (form.value.ruleId = 1) : (form.value.ruleId = 0);
|
||||||
form.value.childrenJson =
|
form.value.childrenJson =
|
||||||
treatmentItems.value.some((item) => item.adviceDefinitionId != '' && item.adviceDefinitionId)
|
treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId != ''
|
||||||
? JSON.stringify(treatmentItems.value)
|
? JSON.stringify(treatmentItems.value)
|
||||||
: undefined;
|
: undefined;
|
||||||
// Bug #464 修复:零售价自动与诊疗子项合计总价同步
|
// Bug #464 修复:零售价自动与诊疗子项合计总价同步
|
||||||
// 当有子项时,零售价自动设置为子项合计总价
|
// 当有子项时,零售价自动设置为子项合计总价
|
||||||
const hasValidItem = treatmentItems.value.some(
|
if (treatmentItems.value.length > 0 && treatmentItems.value[0].adviceDefinitionId != '') {
|
||||||
(item) => item.adviceDefinitionId && item.adviceDefinitionId !== ''
|
|
||||||
);
|
|
||||||
if (hasValidItem) {
|
|
||||||
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
form.value.retailPrice = parseFloat(totalPrice.value) || 0;
|
||||||
}
|
}
|
||||||
proxy.$refs['diagnosisTreatmentRef'].validate(async (valid) => {
|
proxy.$refs['diagnosisTreatmentRef'].validate(async (valid) => {
|
||||||
|
|||||||
@@ -69,14 +69,13 @@ const throttledGetList = throttle(
|
|||||||
watch(
|
watch(
|
||||||
() => props.adviceQueryParams,
|
() => props.adviceQueryParams,
|
||||||
(newValue) => {
|
(newValue) => {
|
||||||
// 始终同步参数到 queryParams,避免弹窗打开时使用旧参数
|
// 只有在弹窗打开时才响应 adviceQueryParams 的变化,避免选择项目后弹窗关闭时触发不必要的请求
|
||||||
queryParams.value.searchKey = newValue?.searchKey;
|
|
||||||
queryParams.value.adviceType = newValue?.adviceType;
|
|
||||||
queryParams.value.categoryCode = newValue?.categoryCode;
|
|
||||||
// 只有在弹窗打开时才触发 API 请求
|
|
||||||
if (!props.popoverVisible) {
|
if (!props.popoverVisible) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
queryParams.value.searchKey = newValue?.searchKey;
|
||||||
|
queryParams.value.adviceType = newValue?.adviceType;
|
||||||
|
queryParams.value.categoryCode = newValue?.categoryCode;
|
||||||
throttledGetList();
|
throttledGetList();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
|
|||||||
@@ -519,10 +519,9 @@
|
|||||||
>
|
>
|
||||||
<template #append>
|
<template #append>
|
||||||
<!-- 审核记录:查看/审核都展示,保证留痕可追溯 -->
|
<!-- 审核记录:查看/审核都展示,保证留痕可追溯 -->
|
||||||
<!-- 修复:查看模式始终显示区块;审核模式始终显示区块(header + 空状态 或 timeline) -->
|
|
||||||
<div
|
<div
|
||||||
class="audit-records-section"
|
class="audit-records-section"
|
||||||
v-if="drawerMode === 'view' || drawerMode === 'audit'"
|
v-if="drawerMode === 'view' || (drawerMode === 'audit' && auditRecords.length > 0)"
|
||||||
>
|
>
|
||||||
<h3 class="section-title">审核记录</h3>
|
<h3 class="section-title">审核记录</h3>
|
||||||
<el-timeline v-if="auditRecords.length > 0">
|
<el-timeline v-if="auditRecords.length > 0">
|
||||||
|
|||||||
@@ -127,7 +127,6 @@ const queryParams = ref({
|
|||||||
pageSize: 100,
|
pageSize: 100,
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
adviceTypes: '1,2,3',
|
adviceTypes: '1,2,3',
|
||||||
categoryCode: '',
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 节流函数 - 与V1.3一致:300ms,首次立即响应
|
// 节流函数 - 与V1.3一致:300ms,首次立即响应
|
||||||
@@ -149,7 +148,6 @@ watch(
|
|||||||
} else {
|
} else {
|
||||||
queryParams.value.adviceTypes = '1,2,3';
|
queryParams.value.adviceTypes = '1,2,3';
|
||||||
}
|
}
|
||||||
queryParams.value.categoryCode = newValue.categoryCode || '';
|
|
||||||
throttledGetList();
|
throttledGetList();
|
||||||
},
|
},
|
||||||
{ deep: true }
|
{ deep: true }
|
||||||
@@ -178,12 +176,6 @@ function getList() {
|
|||||||
filteredData = filteredData.filter(item => types.includes(item.adviceType));
|
filteredData = filteredData.filter(item => types.includes(item.adviceType));
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据 categoryCode 过滤(如西药='2',中成药='1')
|
|
||||||
const categoryCode = queryParams.value.categoryCode;
|
|
||||||
if (categoryCode) {
|
|
||||||
filteredData = filteredData.filter(item => String(item.categoryCode) === String(categoryCode));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据搜索关键词过滤
|
// 根据搜索关键词过滤
|
||||||
if (searchKey && searchKey.length >= 1) {
|
if (searchKey && searchKey.length >= 1) {
|
||||||
const lowerSearchKey = searchKey.toLowerCase();
|
const lowerSearchKey = searchKey.toLowerCase();
|
||||||
|
|||||||
@@ -375,7 +375,7 @@ const finishCallPatient = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await completeEncounter({ encounterId: currentCallPatient.value.encounterId, firstEnum: currentCallPatient.value.firstEnum || 1 });
|
await completeEncounter(currentCallPatient.value.encounterId);
|
||||||
emit('finish');
|
emit('finish');
|
||||||
emit('update:dialogVisible', false);
|
emit('update:dialogVisible', false);
|
||||||
ElMessage.success('患者已完诊');
|
ElMessage.success('患者已完诊');
|
||||||
|
|||||||
@@ -349,17 +349,11 @@ async function getList() {
|
|||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
// 过滤掉中医诊断,只保留西医诊断
|
// 过滤掉中医诊断,只保留西医诊断
|
||||||
form.value.diagnosisList = res.data.filter(item => item.typeName !== '中医诊断');
|
form.value.diagnosisList = res.data.filter(item => item.typeName !== '中医诊断');
|
||||||
// 为旧数据添加默认分类和selectedDiseases
|
// 为旧数据添加默认分类
|
||||||
form.value.diagnosisList.forEach(item => {
|
form.value.diagnosisList.forEach(item => {
|
||||||
if (!item.classification) {
|
if (!item.classification) {
|
||||||
item.classification = '西医';
|
item.classification = '西医';
|
||||||
}
|
}
|
||||||
// 如果ybNo(诊断编码)符合传染病编码格式,添加到selectedDiseases
|
|
||||||
if (item.ybNo && /^(01|02|03)/.test(item.ybNo)) {
|
|
||||||
item.selectedDiseases = [item.ybNo];
|
|
||||||
} else {
|
|
||||||
item.selectedDiseases = item.selectedDiseases || [];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
emits('diagnosisSave', false);
|
emits('diagnosisSave', false);
|
||||||
}
|
}
|
||||||
@@ -691,78 +685,23 @@ async function handleFoodDiseasesCheck() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 传染病报告卡处理
|
* 传染病报告卡处理
|
||||||
* 通过诊断名称自动识别并勾选传染病报告卡中的疾病
|
* 通过诊断目录维护的'报卡类型'字段自动识别是否有需要填写的传染病报告卡
|
||||||
|
* 如果有则弹出诊断对应需登记的报告卡界面
|
||||||
*/
|
*/
|
||||||
function handleInfectiousDiseaseReport() {
|
function handleInfectiousDiseaseReport() {
|
||||||
// 疾病名称到报卡编码的映射(根据传染病报告卡弹窗中的疾病列表)
|
// 查找所有有报卡类型的诊断(reportTypeCode不为空)
|
||||||
const diseaseNameToCode = {
|
const diagnosesWithReportType = form.value.diagnosisList.filter(d => d.reportTypeCode);
|
||||||
// 甲类
|
|
||||||
'鼠疫': '0101',
|
|
||||||
'霍乱': '0102',
|
|
||||||
// 乙类
|
|
||||||
'传染性非典型肺炎': '0201',
|
|
||||||
'艾滋病': '0202',
|
|
||||||
'病毒性肝炎': '0203',
|
|
||||||
'脊髓灰质炎': '0204',
|
|
||||||
'人感染高致病性禽流感': '0205',
|
|
||||||
'麻疹': '0206',
|
|
||||||
'流行性出血热': '0207',
|
|
||||||
'狂犬病': '0208',
|
|
||||||
'流行性乙型脑炎': '0209',
|
|
||||||
'登革热': '0210',
|
|
||||||
'炭疽': '0211',
|
|
||||||
'细菌性和阿米巴性痢疾': '0212',
|
|
||||||
'肺结核': '0213',
|
|
||||||
'伤寒和副伤寒': '0214',
|
|
||||||
'流行性脑脊髓膜炎': '0215',
|
|
||||||
'百日咳': '0216',
|
|
||||||
'白喉': '0217',
|
|
||||||
'新生儿破伤风': '0218',
|
|
||||||
'猩红热': '0219',
|
|
||||||
'布鲁氏菌病': '0220',
|
|
||||||
'淋病': '0221',
|
|
||||||
'梅毒': '0222',
|
|
||||||
'钩端螺旋体病': '0223',
|
|
||||||
'血吸虫病': '0224',
|
|
||||||
'疟疾': '0225',
|
|
||||||
'新型冠状病毒肺炎': '0226',
|
|
||||||
'甲型H1N1流感': '0227',
|
|
||||||
'人感染H7N9禽流感': '0228',
|
|
||||||
// 丙类
|
|
||||||
'流行性感冒': '0301',
|
|
||||||
'流行性腮腺炎': '0302',
|
|
||||||
'风疹': '0303',
|
|
||||||
'急性出血性结膜炎': '0304',
|
|
||||||
'麻风病': '0305',
|
|
||||||
'流行性和地方性斑疹伤寒': '0306',
|
|
||||||
'黑热病': '0307',
|
|
||||||
'包虫病': '0308',
|
|
||||||
'丝虫病': '0309',
|
|
||||||
'除霍乱/菌痢/伤寒副伤寒以外的感染性腹泻病': '0310',
|
|
||||||
'其它感染性腹泻病': '0310',
|
|
||||||
'手足口病': '0311',
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取所有诊断名称对应的报卡编码
|
if (diagnosesWithReportType.length === 0) {
|
||||||
const allSelectedDiseases = form.value.diagnosisList
|
|
||||||
.map(d => diseaseNameToCode[d.name] || null)
|
|
||||||
.filter(code => code);
|
|
||||||
|
|
||||||
if (allSelectedDiseases.length === 0) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 优先使用主诊断
|
// 优先使用主诊断,如果没有主诊断有报卡类型则使用第一个有报卡类型的诊断
|
||||||
const mainDiagnosis = form.value.diagnosisList.find(d => d.maindiseFlag === 1);
|
const mainDiagnosisWithReport = diagnosesWithReportType.find(d => d.maindiseFlag === 1);
|
||||||
const firstDiagnosis = form.value.diagnosisList[0];
|
const targetDiagnosis = mainDiagnosisWithReport || diagnosesWithReportType[0];
|
||||||
|
|
||||||
const diagnosisToShow = {
|
|
||||||
...(mainDiagnosis || firstDiagnosis),
|
|
||||||
selectedDiseases: allSelectedDiseases
|
|
||||||
};
|
|
||||||
|
|
||||||
// 弹出传染病报告卡弹窗
|
// 弹出传染病报告卡弹窗
|
||||||
proxy.$refs.infectiousDiseaseReportRef?.show(diagnosisToShow);
|
proxy.$refs.infectiousDiseaseReportRef?.show(targetDiagnosis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -875,8 +814,7 @@ form.value.diagnosisList.push({
|
|||||||
classification: '西医', // 默认为西医
|
classification: '西医', // 默认为西医
|
||||||
onsetDate: getCurrentDate(),
|
onsetDate: getCurrentDate(),
|
||||||
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
diagnosisDoctor: props.patientInfo.practitionerName || props.patientInfo.doctorName || props.patientInfo.physicianName || userStore.name,
|
||||||
diagnosisTime: getCurrentDate(),
|
diagnosisTime: getCurrentDate()
|
||||||
selectedDiseases: data.ybNo ? [data.ybNo] : [], // 用于传染病报告卡自动勾选
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// 添加后按排序号排序
|
// 添加后按排序号排序
|
||||||
|
|||||||
@@ -16,15 +16,15 @@
|
|||||||
v-model="form.cardNo"
|
v-model="form.cardNo"
|
||||||
class="card-number-input"
|
class="card-number-input"
|
||||||
placeholder="单位自编,与网络直报一致"
|
placeholder="单位自编,与网络直报一致"
|
||||||
maxlength="20"
|
maxlength="12"
|
||||||
:disabled="readOnly || dialogReadOnly"
|
:disabled="readOnly"
|
||||||
/>
|
/>
|
||||||
</el-space>
|
</el-space>
|
||||||
</el-card>
|
</el-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-card class="report-form" shadow="never">
|
<el-card class="report-form" shadow="never">
|
||||||
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" :disabled="readOnly || dialogReadOnly">
|
<el-form ref="formRef" :model="form" :rules="rules" label-position="top" :disabled="readOnly">
|
||||||
<!-- 患者姓名、家长姓名、身份证号 -->
|
<!-- 患者姓名、家长姓名、身份证号 -->
|
||||||
<el-row :gutter="16" class="form-row">
|
<el-row :gutter="16" class="form-row">
|
||||||
<el-col :span="8" class="form-item">
|
<el-col :span="8" class="form-item">
|
||||||
@@ -476,9 +476,9 @@
|
|||||||
<template #footer>
|
<template #footer>
|
||||||
<slot name="footer" :close="handleClose" :submit-loading="submitLoading">
|
<slot name="footer" :close="handleClose" :submit-loading="submitLoading">
|
||||||
<el-space :size="16" justify="center" class="dialog-footer-space" style="display: flex; justify-content: center; width: 100%;">
|
<el-space :size="16" justify="center" class="dialog-footer-space" style="display: flex; justify-content: center; width: 100%;">
|
||||||
<el-button v-if="!(readOnly || dialogReadOnly)" type="primary" @click="handleSubmit" :loading="submitLoading" class="blue-button">保 存</el-button>
|
<el-button v-if="!readOnly" type="primary" @click="handleSubmit" :loading="submitLoading" class="blue-button">保 存</el-button>
|
||||||
<el-button type="info" @click="handleClose">关 闭</el-button>
|
<el-button type="info" @click="handleClose">关 闭</el-button>
|
||||||
<el-button v-if="!(readOnly || dialogReadOnly)" type="danger" @click="handleReset">重 置</el-button>
|
<el-button v-if="!readOnly" type="danger" @click="handleReset">重 置</el-button>
|
||||||
</el-space>
|
</el-space>
|
||||||
</slot>
|
</slot>
|
||||||
</template>
|
</template>
|
||||||
@@ -510,7 +510,6 @@ const DISEASE_NAMES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const dialogVisible = ref(false);
|
const dialogVisible = ref(false);
|
||||||
const dialogReadOnly = ref(false);
|
|
||||||
const formRef = ref(null);
|
const formRef = ref(null);
|
||||||
// 保存按钮加载状态,防止重复提交
|
// 保存按钮加载状态,防止重复提交
|
||||||
const submitLoading = ref(false);
|
const submitLoading = ref(false);
|
||||||
@@ -1038,9 +1037,8 @@ function resetAddressSelector() {
|
|||||||
* 以只读详情方式打开报卡弹窗,供报卡管理等页面复用医生站报卡样式。
|
* 以只读详情方式打开报卡弹窗,供报卡管理等页面复用医生站报卡样式。
|
||||||
* @param {Object} reportData - 报卡详情数据
|
* @param {Object} reportData - 报卡详情数据
|
||||||
*/
|
*/
|
||||||
function showReport(reportData = {}, readOnly = true) {
|
function showReport(reportData = {}) {
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
dialogReadOnly.value = readOnly;
|
|
||||||
|
|
||||||
resetAddressSelector();
|
resetAddressSelector();
|
||||||
initProvinceOptions();
|
initProvinceOptions();
|
||||||
@@ -1071,7 +1069,7 @@ function showReport(reportData = {}, readOnly = true) {
|
|||||||
addressHouse: reportData.addressHouse || '',
|
addressHouse: reportData.addressHouse || '',
|
||||||
patientBelong: reportData.patientBelong || 1,
|
patientBelong: reportData.patientBelong || 1,
|
||||||
occupation: reportData.occupation || '',
|
occupation: reportData.occupation || '',
|
||||||
caseClass: reportData.diseaseType != null ? String(reportData.diseaseType) : '',
|
caseClass: reportData.caseClass != null ? String(reportData.caseClass) : '',
|
||||||
onsetDate: normalizeDate(reportData.onsetDate),
|
onsetDate: normalizeDate(reportData.onsetDate),
|
||||||
diagDate: normalizeDate(reportData.diagDate),
|
diagDate: normalizeDate(reportData.diagDate),
|
||||||
deathDate: normalizeDate(reportData.deathDate),
|
deathDate: normalizeDate(reportData.deathDate),
|
||||||
@@ -1080,13 +1078,13 @@ function showReport(reportData = {}, readOnly = true) {
|
|||||||
selectedClassB: diseaseSelection.selectedClassB,
|
selectedClassB: diseaseSelection.selectedClassB,
|
||||||
selectedClassC: diseaseSelection.selectedClassC,
|
selectedClassC: diseaseSelection.selectedClassC,
|
||||||
otherDisease: reportData.otherDisease || (diseaseCode === 'OTHER' ? reportData.diseaseName || '' : ''),
|
otherDisease: reportData.otherDisease || (diseaseCode === 'OTHER' ? reportData.diseaseName || '' : ''),
|
||||||
diseaseType: reportData.diseaseSubtype || '',
|
diseaseType: reportData.diseaseType || '',
|
||||||
reportOrg: reportData.reportOrg || '',
|
reportOrg: reportData.reportOrg || '',
|
||||||
reportOrgPhone: reportData.reportOrgPhone || '',
|
reportOrgPhone: reportData.reportOrgPhone || '',
|
||||||
reportDoc: reportData.reportDoc || '',
|
reportDoc: reportData.reportDoc || '',
|
||||||
reportDate: normalizeDate(reportData.reportDate || reportData.createdAt),
|
reportDate: normalizeDate(reportData.reportDate || reportData.createdAt),
|
||||||
correctName: reportData.revisedDiseaseName || '',
|
correctName: reportData.correctName || '',
|
||||||
withdrawReason: reportData.returnReason || '',
|
withdrawReason: reportData.withdrawReason || '',
|
||||||
remark: reportData.remark || '',
|
remark: reportData.remark || '',
|
||||||
encounterId: reportData.encounterId || reportData.visitId || '',
|
encounterId: reportData.encounterId || reportData.visitId || '',
|
||||||
patientId: reportData.patientId || reportData.patId || '',
|
patientId: reportData.patientId || reportData.patId || '',
|
||||||
@@ -1207,7 +1205,6 @@ function calculateAge() {
|
|||||||
*/
|
*/
|
||||||
async function show(diagnosisData) {
|
async function show(diagnosisData) {
|
||||||
dialogVisible.value = true;
|
dialogVisible.value = true;
|
||||||
dialogReadOnly.value = false;
|
|
||||||
|
|
||||||
// 重置地址选择器状态
|
// 重置地址选择器状态
|
||||||
resetAddressSelector();
|
resetAddressSelector();
|
||||||
@@ -1241,13 +1238,14 @@ async function show(diagnosisData) {
|
|||||||
let cardNo = '';
|
let cardNo = '';
|
||||||
try {
|
try {
|
||||||
const res = await getNextCardNo(orgCode);
|
const res = await getNextCardNo(orgCode);
|
||||||
if (res.code === 200 && res.data && res.data.length >= 12) {
|
if (res.code === 200 && res.data) {
|
||||||
cardNo = res.data;
|
cardNo = res.data;
|
||||||
|
} else {
|
||||||
|
cardNo = 'TEMP_' + Date.now();
|
||||||
}
|
}
|
||||||
// API失败或返回不合规时保持为空字符串,由用户手动填写或后端自动生成
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('获取卡片编号失败:', err);
|
console.error('获取卡片编号失败:', err);
|
||||||
// 保持为空,不使用不合规的临时值
|
cardNo = 'TEMP_' + Date.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
form.value = {
|
form.value = {
|
||||||
@@ -1426,9 +1424,9 @@ async function buildSubmitData() {
|
|||||||
function validateFormManually() {
|
function validateFormManually() {
|
||||||
const errors = [];
|
const errors = [];
|
||||||
|
|
||||||
// 卡片编号验证(至少12位,后端自动生成16位编号)
|
// 卡片编号验证(可选,但如果填写了必须是12位)
|
||||||
if (form.value.cardNo && form.value.cardNo.length < 12) {
|
if (form.value.cardNo && form.value.cardNo.length !== 12) {
|
||||||
errors.push('卡片编号至少12位');
|
errors.push('卡片编号必须为12位');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 身份证号验证
|
// 身份证号验证
|
||||||
|
|||||||
@@ -316,7 +316,6 @@
|
|||||||
<span class="cat-title">{{ cat.categoryName }}</span>
|
<span class="cat-title">{{ cat.categoryName }}</span>
|
||||||
<span v-if="categoryLoadingSet.has(cat.typeId)" class="loading-dot"></span>
|
<span v-if="categoryLoadingSet.has(cat.typeId)" class="loading-dot"></span>
|
||||||
</template>
|
</template>
|
||||||
<!-- 检查项目(部位/项目列表) -->
|
|
||||||
<div
|
<div
|
||||||
v-for="item in cat.items"
|
v-for="item in cat.items"
|
||||||
:key="item.id"
|
:key="item.id"
|
||||||
@@ -334,27 +333,6 @@
|
|||||||
<div v-if="categoryLoadingSet.has(cat.typeId)" class="category-loading-hint">
|
<div v-if="categoryLoadingSet.has(cat.typeId)" class="category-loading-hint">
|
||||||
加载中...
|
加载中...
|
||||||
</div>
|
</div>
|
||||||
<!-- Bug #428修复: 渲染分类联动加载的检查方法列表 -->
|
|
||||||
<div
|
|
||||||
v-if="cat.methods && cat.methods.length > 0"
|
|
||||||
class="method-section"
|
|
||||||
>
|
|
||||||
<div class="method-section-title">检查方法</div>
|
|
||||||
<div
|
|
||||||
v-for="method in cat.methods"
|
|
||||||
:key="method.id"
|
|
||||||
class="method-row"
|
|
||||||
>
|
|
||||||
<el-checkbox
|
|
||||||
:model-value="isMethodSelected(method, cat)"
|
|
||||||
@change="(val) => handleMethodSelect(val, method, cat)"
|
|
||||||
class="method-checkbox"
|
|
||||||
>
|
|
||||||
{{ method.name }}
|
|
||||||
</el-checkbox>
|
|
||||||
<span class="method-price-tag">¥{{ method.packagePrice || method.price || 0 }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</el-collapse-item>
|
</el-collapse-item>
|
||||||
</el-collapse>
|
</el-collapse>
|
||||||
</div>
|
</div>
|
||||||
@@ -940,13 +918,6 @@ function handleSave() {
|
|||||||
ElMessage.warning('请至少选择一个检查明细项目');
|
ElMessage.warning('请至少选择一个检查明细项目');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 检查每个项目是否已选择检查方法
|
|
||||||
const itemsWithoutMethod = selectedItems.value.filter(item => !item.selectedMethod);
|
|
||||||
if (itemsWithoutMethod.length > 0) {
|
|
||||||
const names = itemsWithoutMethod.map(item => item.name).join('、');
|
|
||||||
ElMessage.warning(`以下项目未选择检查方法:${names},请在右侧勾选后再保存`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// 从已选项目推导检查类型编码(取第一个项目的 checkType,如 CT / ECG / GI)
|
// 从已选项目推导检查类型编码(取第一个项目的 checkType,如 CT / ECG / GI)
|
||||||
const firstCheckType = selectedItems.value[0]?.checkType || 'unknown';
|
const firstCheckType = selectedItems.value[0]?.checkType || 'unknown';
|
||||||
form.examTypeCode = firstCheckType;
|
form.examTypeCode = firstCheckType;
|
||||||
@@ -1069,78 +1040,6 @@ function handleDelete(row) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bug #428修复: 判断某个检查方法是否已被选中(任意项目关联了该方法)
|
|
||||||
function isMethodSelected(method, cat) {
|
|
||||||
return selectedItems.value.some(item =>
|
|
||||||
item.selectedMethod?.id === method.id && item.checkType === cat.typeName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Bug #428修复: 勾选检查方法
|
|
||||||
async function handleMethodSelect(checked, method, cat) {
|
|
||||||
if (checked) {
|
|
||||||
// 找到该方法所属的第一个检查项目
|
|
||||||
const targetItem = cat.items[0];
|
|
||||||
if (!targetItem) {
|
|
||||||
// 如果分类下没有项目,尝试从其他分类找同名项目或创建
|
|
||||||
console.warn('分类下没有检查项目,无法关联方法');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果该项目已存在,只更新 selectedMethod
|
|
||||||
const existingItem = selectedItems.value.find(s => s.id === targetItem.id);
|
|
||||||
if (existingItem) {
|
|
||||||
existingItem.selectedMethod = method;
|
|
||||||
updateMethodDisplay();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果该项目不存在,创建一个并关联方法
|
|
||||||
if (selectedItems.value.length > 0) {
|
|
||||||
const currentCategory = selectedItems.value[0].checkType;
|
|
||||||
const newCategory = cat.typeCode || '';
|
|
||||||
if (currentCategory !== newCategory) {
|
|
||||||
ElMessage.warning('一个检查单不能同时选择多个项目类型的检查项目');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
selectedItems.value.push({
|
|
||||||
id: targetItem.id, name: targetItem.name,
|
|
||||||
price: targetItem.price, quantity: 1,
|
|
||||||
serviceFee: targetItem.serviceFee || 0,
|
|
||||||
unit: targetItem.unit || '次',
|
|
||||||
applyPart: targetItem.name,
|
|
||||||
checkType: cat.typeName,
|
|
||||||
nationalCode: targetItem.nationalCode || '',
|
|
||||||
checked: true,
|
|
||||||
methods: [method],
|
|
||||||
selectedMethod: method,
|
|
||||||
expanded: false,
|
|
||||||
isPackage: !!targetItem.packageName,
|
|
||||||
packageId: targetItem.packageId || null
|
|
||||||
});
|
|
||||||
|
|
||||||
// 自动回填执行科室
|
|
||||||
if (selectedItems.value.length === 1 && cat?.performDeptName) {
|
|
||||||
form.performDeptCode = cat.performDeptName;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 同时勾选左侧项目的 checkbox
|
|
||||||
targetItem.checked = true;
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// 取消选择方法:将 selectedItems 中关联该方法的项的 selectedMethod 清空
|
|
||||||
const itemsWithMethod = selectedItems.value.filter(
|
|
||||||
item => item.selectedMethod?.id === method.id
|
|
||||||
);
|
|
||||||
for (const item of itemsWithMethod) {
|
|
||||||
item.selectedMethod = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
updateMethodDisplay();
|
|
||||||
}
|
|
||||||
|
|
||||||
// ====== 勾选逻辑 ======
|
// ====== 勾选逻辑 ======
|
||||||
async function handleItemSelect(checked, item, cat) {
|
async function handleItemSelect(checked, item, cat) {
|
||||||
if (checked) {
|
if (checked) {
|
||||||
@@ -1206,6 +1105,12 @@ async function handleItemSelect(checked, item, cat) {
|
|||||||
form.performDeptCode = cat.performDeptName;
|
form.performDeptCode = cat.performDeptName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果有且仅有一个检查方法,自动选中并更新显示
|
||||||
|
if (methods.length === 1) {
|
||||||
|
const lastIdx = selectedItems.value.length - 1;
|
||||||
|
selectedItems.value[lastIdx].selectedMethod = methods[0];
|
||||||
|
updateMethodDisplay(); // Bug #384修复: 联动更新显示
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const idx = selectedItems.value.findIndex(s => s.id === item.id);
|
const idx = selectedItems.value.findIndex(s => s.id === item.id);
|
||||||
if (idx > -1) selectedItems.value.splice(idx, 1);
|
if (idx > -1) selectedItems.value.splice(idx, 1);
|
||||||
@@ -1461,53 +1366,6 @@ defineExpose({ getList });
|
|||||||
margin-left: 6px;
|
margin-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #428修复: 分类下检查方法区域样式 */
|
|
||||||
.method-section {
|
|
||||||
padding: 6px 8px;
|
|
||||||
background: #f0f7ff;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-top: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-section-title {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: #409eff;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
padding-bottom: 3px;
|
|
||||||
border-bottom: 1px dashed #d9ecff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 3px 4px;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-row:hover {
|
|
||||||
background: #e8f4ff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-checkbox {
|
|
||||||
flex: 1;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-checkbox :deep(.el-checkbox__label) {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #303133;
|
|
||||||
}
|
|
||||||
|
|
||||||
.method-price-tag {
|
|
||||||
font-size: 11px;
|
|
||||||
color: #e6a23c;
|
|
||||||
font-weight: 500;
|
|
||||||
flex-shrink: 0;
|
|
||||||
margin-left: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 已选择 tags */
|
/* 已选择 tags */
|
||||||
.selected-panel {
|
.selected-panel {
|
||||||
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
width: 140px; /* Bug #384修复: 加宽以适应展开内容 */
|
||||||
@@ -1579,41 +1437,6 @@ defineExpose({ getList });
|
|||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bug #428修复: 套餐明细列表样式 */
|
|
||||||
.package-details-list {
|
|
||||||
padding: 6px 10px;
|
|
||||||
background: #fffbe6;
|
|
||||||
border-top: 1px solid #ffe58f;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-row {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 2px 6px;
|
|
||||||
border-radius: 3px;
|
|
||||||
font-size: 11px;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-row:hover {
|
|
||||||
background: #fff9e6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-name {
|
|
||||||
color: #303133;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail-info {
|
|
||||||
color: #909399;
|
|
||||||
font-size: 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bug #384修复: 检查方法勾选框列表 */
|
/* Bug #384修复: 检查方法勾选框列表 */
|
||||||
.method-list {
|
.method-list {
|
||||||
padding: 6px 10px;
|
padding: 6px 10px;
|
||||||
|
|||||||
@@ -109,7 +109,6 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const encounterId = ref();
|
const encounterId = ref();
|
||||||
const firstEnum = ref(1); // 初复诊标识:1=初诊,2=复诊
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getPatientList();
|
getPatientList();
|
||||||
});
|
});
|
||||||
@@ -128,7 +127,6 @@ function getPatientList() {
|
|||||||
|
|
||||||
function clickRow(row) {
|
function clickRow(row) {
|
||||||
encounterId.value = row.encounterId;
|
encounterId.value = row.encounterId;
|
||||||
firstEnum.value = row.firstEnum ?? row.first_enum ?? 1;
|
|
||||||
emits('cellClick', row);
|
emits('cellClick', row);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,7 +182,7 @@ function handleComplete() {
|
|||||||
}
|
}
|
||||||
proxy.$modal.confirm('是否完成该患者问诊?').then(() => {
|
proxy.$modal.confirm('是否完成该患者问诊?').then(() => {
|
||||||
proxy.$modal.loading();
|
proxy.$modal.loading();
|
||||||
completeEncounter({ encounterId: encounterId.value, firstEnum: firstEnum.value }).then(() => {
|
completeEncounter(encounterId.value).then(() => {
|
||||||
proxy.$modal.closeLoading();
|
proxy.$modal.closeLoading();
|
||||||
proxy.$modal.msgSuccess('完成问诊成功');
|
proxy.$modal.msgSuccess('完成问诊成功');
|
||||||
getPatientList();
|
getPatientList();
|
||||||
|
|||||||
@@ -1021,21 +1021,7 @@ const mapAdviceTypeLabel = (type, adviceTableName) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const found = adviceTypeList.value.find((item) => item.value === type);
|
const found = adviceTypeList.value.find((item) => item.value === type);
|
||||||
if (found) {
|
return found ? found.label : '';
|
||||||
return found.label;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 🔧 Bug #458 Fix: 诊疗/手术类型字典缺失时的兜底,避免保存后"医嘱类型"列显示为空
|
|
||||||
if (adviceTableName === 'wor_activity_definition' || adviceTableName === 'wor_service_request') {
|
|
||||||
if (type === 6) return '手术';
|
|
||||||
if (type === 4) return '手术';
|
|
||||||
if (type === 1) return '检验';
|
|
||||||
if (type === 2) return '检查';
|
|
||||||
if (type === 5) return '其他';
|
|
||||||
return '诊疗';
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 西药处方管理相关变量
|
// 西药处方管理相关变量
|
||||||
@@ -2513,9 +2499,7 @@ function handleSave(prescriptionId) {
|
|||||||
'contentJson', 'definitionDetailId', 'definitionId', 'diagnosisName',
|
'contentJson', 'definitionDetailId', 'definitionId', 'diagnosisName',
|
||||||
'dosageInstruction', 'effectiveOrgId', 'encounterDiagnosisId',
|
'dosageInstruction', 'effectiveOrgId', 'encounterDiagnosisId',
|
||||||
'encounterId', 'lotNumber', 'patientId', 'practitionerId',
|
'encounterId', 'lotNumber', 'patientId', 'practitionerId',
|
||||||
'prescriptionNo', 'skinTestFlag', 'unitPrice', 'volume', 'ybClassEnum',
|
'prescriptionNo', 'skinTestFlag', 'unitPrice', 'volume', 'ybClassEnum'
|
||||||
// 🔧 Bug Fix: 添加 therapyEnum 字段(医嘱类型:1=长期, 2=临时)
|
|
||||||
'therapyEnum'
|
|
||||||
];
|
];
|
||||||
let filteredContent = {};
|
let filteredContent = {};
|
||||||
standardFields.forEach(field => {
|
standardFields.forEach(field => {
|
||||||
@@ -3159,9 +3143,7 @@ function handleSaveBatch(prescriptionId) {
|
|||||||
// 🔧 Bug Fix: 添加 definitionId 和 definitionDetailId 字段
|
// 🔧 Bug Fix: 添加 definitionId 和 definitionDetailId 字段
|
||||||
'definitionId', 'definitionDetailId',
|
'definitionId', 'definitionDetailId',
|
||||||
// 🔧 Bug Fix: 添加 categoryEnum 字段(耗材必填)
|
// 🔧 Bug Fix: 添加 categoryEnum 字段(耗材必填)
|
||||||
'categoryEnum',
|
'categoryEnum'
|
||||||
// 🔧 Bug Fix: 添加 therapyEnum 字段(医嘱类型:1=长期, 2=临时)
|
|
||||||
'therapyEnum'
|
|
||||||
];
|
];
|
||||||
let filteredItem = {};
|
let filteredItem = {};
|
||||||
standardItemFields.forEach(field => {
|
standardItemFields.forEach(field => {
|
||||||
@@ -3360,7 +3342,7 @@ function syncGroupFields(row) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function setValue(row) {
|
function setValue(row) {
|
||||||
unitCodeList.value = [];
|
unitCodeList.value = [];
|
||||||
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: 'unit' });
|
unitCodeList.value.push({ value: row.unitCode, label: row.unitCode_dictText, type: 'unit' });
|
||||||
|
|
||||||
@@ -3412,8 +3394,8 @@ async function setValue(row) {
|
|||||||
showPopover: false, // 确保查询框关闭
|
showPopover: false, // 确保查询框关闭
|
||||||
};
|
};
|
||||||
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
console.log('[BugFix] setValue - prescriptionList[rowIndex].adviceType_dictText:', prescriptionList.value[rowIndex.value].adviceType_dictText);
|
||||||
// 🔧 Bug #455: 执行科室默认逻辑:使用positionId(诊疗执行科室配置) → 患者就诊科室,不再使用row.orgId(项目所属科室)
|
// 🔧 修复执行科室逻辑:优先使用项目维护的所属科室(row.orgId),其次使用positionId,最后回退到患者科室
|
||||||
prescriptionList.value[rowIndex.value].orgId = row.positionId || props.patientInfo?.orgId;
|
prescriptionList.value[rowIndex.value].orgId = row.orgId || row.positionId || props.patientInfo?.orgId;
|
||||||
prescriptionList.value[rowIndex.value].dose = row.dose || row.doseQuantity;
|
prescriptionList.value[rowIndex.value].dose = row.dose || row.doseQuantity;
|
||||||
prescriptionList.value[rowIndex.value].quantity = row.quantity || 1;
|
prescriptionList.value[rowIndex.value].quantity = row.quantity || 1;
|
||||||
prescriptionList.value[rowIndex.value].unitCodeList = unitCodeList.value;
|
prescriptionList.value[rowIndex.value].unitCodeList = unitCodeList.value;
|
||||||
@@ -3532,7 +3514,7 @@ async function setValue(row) {
|
|||||||
prescriptionList.value[rowIndex.value].positionId = finalLocationId;
|
prescriptionList.value[rowIndex.value].positionId = finalLocationId;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
await getOrgList();
|
getOrgList();
|
||||||
// 会诊类型(adviceType == 5)和诊疗类型(adviceType == 3)的处理
|
// 会诊类型(adviceType == 5)和诊疗类型(adviceType == 3)的处理
|
||||||
if (row.adviceType == 5) {
|
if (row.adviceType == 5) {
|
||||||
// 会诊类型:设置默认值
|
// 会诊类型:设置默认值
|
||||||
|
|||||||
@@ -56,8 +56,6 @@
|
|||||||
<!-- 手术等级 -->
|
<!-- 手术等级 -->
|
||||||
<el-table-column label="手术等级" align="center" prop="surgeryLevel_dictText" width="100" />
|
<el-table-column label="手术等级" align="center" prop="surgeryLevel_dictText" width="100" />
|
||||||
|
|
||||||
<!-- 手术室确认时间 -->
|
|
||||||
|
|
||||||
<el-table-column label="手术室确认时间" align="center" prop="operatingRoomConfirmTime" width="180">
|
<el-table-column label="手术室确认时间" align="center" prop="operatingRoomConfirmTime" width="180">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
{{ scope.row.operatingRoomConfirmTime ? parseTime(scope.row.operatingRoomConfirmTime, '{y}-{m}-{d} {h}:{i}:{s}') : '-' }}
|
{{ scope.row.operatingRoomConfirmTime ? parseTime(scope.row.operatingRoomConfirmTime, '{y}-{m}-{d} {h}:{i}:{s}') : '-' }}
|
||||||
@@ -511,10 +509,6 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
const loading = ref(true)
|
const loading = ref(true)
|
||||||
const surgeryLoading = ref(false)
|
|
||||||
const anesthesiaLoading = ref(false)
|
|
||||||
let surgerySearchTimer = null
|
|
||||||
let anesthesiaSearchTimer = null
|
|
||||||
const surgeryList = ref([])
|
const surgeryList = ref([])
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const viewOpen = ref(false)
|
const viewOpen = ref(false)
|
||||||
@@ -1133,13 +1127,12 @@ function submitForm() {
|
|||||||
// 新增手术
|
// 新增手术
|
||||||
addSurgery(form.value).then((res) => {
|
addSurgery(form.value).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '手术申请提交成功!')
|
proxy.$modal.msgSuccess(res.msg || '新增成功')
|
||||||
// 保存麻醉方式
|
// 保存麻醉方式
|
||||||
sessionStorage.setItem('anesthesiaType', form.value.anesthesiaTypeEnum)
|
sessionStorage.setItem('anesthesiaType', form.value.anesthesiaTypeEnum)
|
||||||
open.value = false
|
open.value = false
|
||||||
emit('saved') // 通知父组件刷新医嘱列表
|
|
||||||
// 刷新手术申请列表
|
|
||||||
getList()
|
getList()
|
||||||
|
emit('saved') // 🔧 触发保存事件,通知父组件刷新医嘱列表
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '新增手术失败,请检查表单信息')
|
proxy.$modal.msgError(res.msg || '新增手术失败,请检查表单信息')
|
||||||
}
|
}
|
||||||
@@ -1151,13 +1144,12 @@ function submitForm() {
|
|||||||
// 修改手术
|
// 修改手术
|
||||||
updateSurgery(form.value).then((res) => {
|
updateSurgery(form.value).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '手术申请修改成功!')
|
proxy.$modal.msgSuccess(res.msg || '修改成功')
|
||||||
// 保存麻醉方式
|
// 保存麻醉方式
|
||||||
sessionStorage.setItem('anesthesiaType', form.value.anesthesiaTypeEnum)
|
sessionStorage.setItem('anesthesiaType', form.value.anesthesiaTypeEnum)
|
||||||
open.value = false
|
open.value = false
|
||||||
emit('saved') // 通知父组件刷新医嘱列表
|
|
||||||
// 刷新手术申请列表
|
|
||||||
getList()
|
getList()
|
||||||
|
emit('saved') // 🔧 触发保存事件,通知父组件刷新医嘱列表
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '更新手术失败,请检查表单信息')
|
proxy.$modal.msgError(res.msg || '更新手术失败,请检查表单信息')
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,12 +151,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<InfectiousDiseaseReportDialog
|
<el-dialog
|
||||||
ref="infectiousDiseaseReportRef"
|
v-model="detailVisible"
|
||||||
:read-only="detailMode === 'view'"
|
:title="detailMode === 'view' ? '报卡详情 - 中华人民共和国传染病报告卡' : '编辑报卡 - 中华人民共和国传染病报告卡'"
|
||||||
@success="detailVisible = false"
|
width="1100px"
|
||||||
@close="detailVisible = false"
|
destroy-on-close
|
||||||
|
class="card-detail-dialog"
|
||||||
|
>
|
||||||
|
<InfectiousReport
|
||||||
|
:mode=" detailMode"
|
||||||
|
:card-data="currentCard"
|
||||||
|
@submit-edit="handleSaveEdit"
|
||||||
|
style="max-height: 75vh; overflow-y: auto;"
|
||||||
/>
|
/>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="detailVisible = false">关闭</el-button>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -164,7 +175,7 @@
|
|||||||
import { ref, reactive, onMounted, onActivated, onBeforeUnmount, nextTick, computed } from 'vue';
|
import { ref, reactive, onMounted, onActivated, onBeforeUnmount, nextTick, computed } from 'vue';
|
||||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||||
import { DataAnalysis, Warning, CircleCheck, Check, RefreshRight } from '@element-plus/icons-vue';
|
import { DataAnalysis, Warning, CircleCheck, Check, RefreshRight } from '@element-plus/icons-vue';
|
||||||
import InfectiousDiseaseReportDialog from '../components/diagnosis/infectiousDiseaseReportDialog.vue';
|
import InfectiousReport from '../components/infectiousReport/index.vue';
|
||||||
import {
|
import {
|
||||||
getDoctorCardStatistics,
|
getDoctorCardStatistics,
|
||||||
getDoctorCardList,
|
getDoctorCardList,
|
||||||
@@ -174,6 +185,7 @@ import {
|
|||||||
batchDeleteCards,
|
batchDeleteCards,
|
||||||
exportCardToWord,
|
exportCardToWord,
|
||||||
getCardDetail,
|
getCardDetail,
|
||||||
|
updateDoctorCard,
|
||||||
} from './api';
|
} from './api';
|
||||||
|
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
@@ -199,7 +211,7 @@ const queryParams = reactive({
|
|||||||
|
|
||||||
const detailVisible = ref(false);
|
const detailVisible = ref(false);
|
||||||
const detailMode = ref('view');
|
const detailMode = ref('view');
|
||||||
const infectiousDiseaseReportRef = ref(null);
|
const currentCard = ref({});
|
||||||
|
|
||||||
// 计算表格高度:根据视口高度动态调整
|
// 计算表格高度:根据视口高度动态调整
|
||||||
const tableHeight = computed(() => {
|
const tableHeight = computed(() => {
|
||||||
@@ -315,11 +327,9 @@ async function handleView(row) {
|
|||||||
try {
|
try {
|
||||||
const res = await getCardDetail(row.cardNo);
|
const res = await getCardDetail(row.cardNo);
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
currentCard.value = res.data || {};
|
||||||
detailMode.value = 'view';
|
detailMode.value = 'view';
|
||||||
detailVisible.value = true;
|
detailVisible.value = true;
|
||||||
nextTick(() => {
|
|
||||||
infectiousDiseaseReportRef.value?.showReport(res.data || {});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取详情失败');
|
ElMessage.error('获取详情失败');
|
||||||
@@ -330,17 +340,57 @@ async function handleEdit(row) {
|
|||||||
try {
|
try {
|
||||||
const res = await getCardDetail(row.cardNo);
|
const res = await getCardDetail(row.cardNo);
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
|
currentCard.value = res.data || {};
|
||||||
detailMode.value = 'edit';
|
detailMode.value = 'edit';
|
||||||
detailVisible.value = true;
|
detailVisible.value = true;
|
||||||
nextTick(() => {
|
|
||||||
infectiousDiseaseReportRef.value?.showReport(res.data || {}, false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('获取详情失败');
|
ElMessage.error('获取详情失败');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function handleSaveEdit(submitData) {
|
||||||
|
// submitData 来自 InfectiousReport 组件的 submit-edit 事件
|
||||||
|
try {
|
||||||
|
const updateData = {
|
||||||
|
cardNo: submitData.cardNo,
|
||||||
|
phone: submitData.phone,
|
||||||
|
contactPhone: submitData.contactPhone,
|
||||||
|
onsetDate: submitData.onsetDate,
|
||||||
|
diagDate: submitData.diagDate,
|
||||||
|
diseaseCode: submitData.diseaseCode,
|
||||||
|
diseaseType: submitData.diseaseType,
|
||||||
|
otherDisease: submitData.otherDisease,
|
||||||
|
caseClass: submitData.caseClass,
|
||||||
|
occupation: submitData.occupation,
|
||||||
|
patientBelong: submitData.patientBelong,
|
||||||
|
addressProv: submitData.addressProv,
|
||||||
|
addressCity: submitData.addressCity,
|
||||||
|
addressCounty: submitData.addressCounty,
|
||||||
|
addressTown: submitData.addressTown,
|
||||||
|
addressVillage: submitData.addressVillage,
|
||||||
|
addressHouse: submitData.addressHouse,
|
||||||
|
workplace: submitData.workplace,
|
||||||
|
parentName: submitData.parentName,
|
||||||
|
deathDate: submitData.deathDate,
|
||||||
|
correctName: submitData.correctName,
|
||||||
|
withdrawReason: submitData.withdrawReason,
|
||||||
|
remark: submitData.remark,
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await updateDoctorCard(updateData);
|
||||||
|
if (res.code === 200) {
|
||||||
|
ElMessage.success('保存成功');
|
||||||
|
detailVisible.value = false;
|
||||||
|
getList();
|
||||||
|
} else {
|
||||||
|
ElMessage.error(res.msg || '保存失败');
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('保存失败:' + (error.message || '网络错误'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function handleSubmit(row) {
|
async function handleSubmit(row) {
|
||||||
try {
|
try {
|
||||||
await ElMessageBox.confirm('确认提交该报卡?', '提示', {
|
await ElMessageBox.confirm('确认提交该报卡?', '提示', {
|
||||||
@@ -750,4 +800,17 @@ function handleResize() {
|
|||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 报卡详情弹窗 */
|
||||||
|
:deep(.card-detail-dialog .el-dialog__body) {
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.card-detail-dialog .infectious-report-container) {
|
||||||
|
padding: 16px;
|
||||||
|
height: auto;
|
||||||
|
max-height: 70vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -168,7 +168,7 @@ import {computed, getCurrentInstance, ref, watch} from 'vue';
|
|||||||
import {Refresh, Search} from '@element-plus/icons-vue';
|
import {Refresh, Search} from '@element-plus/icons-vue';
|
||||||
import {patientInfo} from '../../store/patient.js';
|
import {patientInfo} from '../../store/patient.js';
|
||||||
import {getCheck} from './api';
|
import {getCheck} from './api';
|
||||||
import {getDepartmentList} from '@/api/public.js';
|
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
@@ -293,8 +293,8 @@ const hasMatchedFields = computed(() => {
|
|||||||
|
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = () => {
|
||||||
getDepartmentList().then((res) => {
|
getOrgList().then((res) => {
|
||||||
orgOptions.value = res.data || [];
|
orgOptions.value = res.data.records;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -306,7 +306,6 @@ const recursionFun = (targetDepartment) => {
|
|||||||
name = obj.name;
|
name = obj.name;
|
||||||
}
|
}
|
||||||
const subObjArray = obj['children'];
|
const subObjArray = obj['children'];
|
||||||
if (subObjArray && subObjArray.length > 0) {
|
|
||||||
for (let index = 0; index < subObjArray.length; index++) {
|
for (let index = 0; index < subObjArray.length; index++) {
|
||||||
const item = subObjArray[index];
|
const item = subObjArray[index];
|
||||||
if (item.id == targetDepartment) {
|
if (item.id == targetDepartment) {
|
||||||
@@ -314,11 +313,10 @@ const recursionFun = (targetDepartment) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleViewDetail = async (row) => {
|
const handleViewDetail = (row) => {
|
||||||
console.log('targetDepartment========>', JSON.stringify(row));
|
console.log('targetDepartment========>', JSON.stringify(row));
|
||||||
|
|
||||||
currentDetail.value = row;
|
currentDetail.value = row;
|
||||||
@@ -326,15 +324,6 @@ const handleViewDetail = async (row) => {
|
|||||||
if (row.descJson) {
|
if (row.descJson) {
|
||||||
try {
|
try {
|
||||||
const obj = JSON.parse(row.descJson);
|
const obj = JSON.parse(row.descJson);
|
||||||
// 确保科室数据已加载
|
|
||||||
if (!orgOptions.value || orgOptions.value.length === 0) {
|
|
||||||
await new Promise((resolve) => {
|
|
||||||
getDepartmentList().then((res) => {
|
|
||||||
orgOptions.value = res.data || [];
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||||
descJsonData.value = obj;
|
descJsonData.value = obj;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -41,6 +41,8 @@
|
|||||||
<el-option label="全部" value="" />
|
<el-option label="全部" value="" />
|
||||||
<el-option label="待签发" value="0" />
|
<el-option label="待签发" value="0" />
|
||||||
<el-option label="已签发" value="1" />
|
<el-option label="已签发" value="1" />
|
||||||
|
<el-option label="已采集" value="2" />
|
||||||
|
<el-option label="已收样" value="3" />
|
||||||
<el-option label="报告已出" value="4" />
|
<el-option label="报告已出" value="4" />
|
||||||
<el-option label="已作废" value="5" />
|
<el-option label="已作废" value="5" />
|
||||||
</el-select>
|
</el-select>
|
||||||
@@ -101,15 +103,8 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
<el-table-column prop="requesterId_dictText" label="申请者" width="120" />
|
||||||
<el-table-column label="操作" align="center" fixed="right" width="160">
|
<el-table-column label="操作" align="center" fixed="right">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<template v-if="scope.row.billStatus == 0 || scope.row.status == 0">
|
|
||||||
<el-button link type="primary" @click="handleEdit(scope.row)">修改</el-button>
|
|
||||||
<el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="scope.row.billStatus == 1 || scope.row.status == 1">
|
|
||||||
<el-button link type="warning" @click="handleWithdraw(scope.row)">撤回</el-button>
|
|
||||||
</template>
|
|
||||||
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
<el-button link type="primary" @click="handleViewDetail(scope.row)">详情</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
@@ -186,8 +181,8 @@
|
|||||||
import {computed, getCurrentInstance, ref, watch} from 'vue';
|
import {computed, getCurrentInstance, ref, watch} from 'vue';
|
||||||
import {Refresh, Search} from '@element-plus/icons-vue';
|
import {Refresh, Search} from '@element-plus/icons-vue';
|
||||||
import {patientInfo} from '../../store/patient.js';
|
import {patientInfo} from '../../store/patient.js';
|
||||||
import {getInspection, deleteRequestForm, withdrawRequestForm} from './api';
|
import {getInspection} from './api';
|
||||||
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
import {getDepartmentList} from '@/api/public.js';
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
@@ -296,6 +291,8 @@ const parseBillStatus = (status) => {
|
|||||||
const statusMap = {
|
const statusMap = {
|
||||||
'0': '待签发',
|
'0': '待签发',
|
||||||
'1': '已签发',
|
'1': '已签发',
|
||||||
|
'2': '已采集',
|
||||||
|
'3': '已收样',
|
||||||
'4': '报告已出',
|
'4': '报告已出',
|
||||||
'5': '已作废',
|
'5': '已作废',
|
||||||
};
|
};
|
||||||
@@ -356,13 +353,11 @@ const getLocationInfo = async () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const recursionFun = (targetDepartment) => {
|
const recursionFun = (targetDepartment) => {
|
||||||
if (!targetDepartment) return '';
|
|
||||||
let name = '';
|
let name = '';
|
||||||
for (let index = 0; index < orgOptions.value.length; index++) {
|
for (let index = 0; index < orgOptions.value.length; index++) {
|
||||||
const obj = orgOptions.value[index];
|
const obj = orgOptions.value[index];
|
||||||
if (obj.id == targetDepartment) {
|
if (obj.id == targetDepartment) {
|
||||||
name = obj.name;
|
name = obj.name;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
const subObjArray = obj['children'];
|
const subObjArray = obj['children'];
|
||||||
if (subObjArray && subObjArray.length > 0) {
|
if (subObjArray && subObjArray.length > 0) {
|
||||||
@@ -370,11 +365,9 @@ const recursionFun = (targetDepartment) => {
|
|||||||
const item = subObjArray[i];
|
const item = subObjArray[i];
|
||||||
if (item.id == targetDepartment) {
|
if (item.id == targetDepartment) {
|
||||||
name = item.name;
|
name = item.name;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (name) break;
|
|
||||||
}
|
}
|
||||||
return name;
|
return name;
|
||||||
};
|
};
|
||||||
@@ -392,6 +385,7 @@ const handleViewDetail = async (row) => {
|
|||||||
const obj = JSON.parse(row.descJson);
|
const obj = JSON.parse(row.descJson);
|
||||||
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
obj.targetDepartment = recursionFun(obj.targetDepartment);
|
||||||
descJsonData.value = obj;
|
descJsonData.value = obj;
|
||||||
|
// descJsonData.value = JSON.parse(row.descJson);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('解析 descJson 失败:', e);
|
console.error('解析 descJson 失败:', e);
|
||||||
descJsonData.value = null;
|
descJsonData.value = null;
|
||||||
@@ -402,61 +396,6 @@ const handleViewDetail = async (row) => {
|
|||||||
detailDialogVisible.value = true;
|
detailDialogVisible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改检验申请单(待签发状态)
|
|
||||||
*/
|
|
||||||
const handleEdit = (row) => {
|
|
||||||
// 复用详情查看逻辑,后续可扩展为打开编辑弹窗
|
|
||||||
handleViewDetail(row);
|
|
||||||
proxy.$modal?.msgInfo?.('修改功能待接入,请通过详情弹窗查看后重新开立');
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除检验申请单(仅待签发状态可删除)
|
|
||||||
*/
|
|
||||||
const handleDelete = async (row) => {
|
|
||||||
try {
|
|
||||||
await proxy.$modal?.confirm?.(`确定要删除申请单 "${row.prescriptionNo}" 吗?此操作不可恢复。`);
|
|
||||||
} catch {
|
|
||||||
return; // 用户取消
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await deleteRequestForm({ prescriptionNo: row.prescriptionNo });
|
|
||||||
if (res?.code === 200) {
|
|
||||||
proxy.$modal?.msgSuccess?.('删除成功');
|
|
||||||
await fetchData();
|
|
||||||
} else {
|
|
||||||
proxy.$modal?.msgError?.(res?.msg || '删除失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
proxy.$modal?.msgError?.(e.message || '删除异常');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 撤回检验申请单(已签发状态撤回至待签发)
|
|
||||||
*/
|
|
||||||
const handleWithdraw = async (row) => {
|
|
||||||
try {
|
|
||||||
await proxy.$modal?.confirm?.(`确定要撤回申请单 "${row.prescriptionNo}" 吗?撤回后将恢复为待签发状态。`);
|
|
||||||
} catch {
|
|
||||||
return; // 用户取消
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const res = await withdrawRequestForm({ prescriptionNo: row.prescriptionNo });
|
|
||||||
if (res?.code === 200) {
|
|
||||||
proxy.$modal?.msgSuccess?.('撤回成功');
|
|
||||||
await fetchData();
|
|
||||||
} else {
|
|
||||||
proxy.$modal?.msgError?.(res?.msg || '撤回失败');
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
proxy.$modal?.msgError?.(e.message || '撤回异常');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => patientInfo.value?.encounterId,
|
() => patientInfo.value?.encounterId,
|
||||||
async (val) => {
|
async (val) => {
|
||||||
|
|||||||
@@ -112,8 +112,6 @@ const showApplicationFormDialog = (name) => {
|
|||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
applicationFormName.value = components.value[name];
|
applicationFormName.value = components.value[name];
|
||||||
applicationFormDialogVisible.value = true;
|
applicationFormDialogVisible.value = true;
|
||||||
// 列表(项目列表)
|
|
||||||
applicationFormNameRef?.value.getList?.();
|
|
||||||
// 科室列表
|
// 科室列表
|
||||||
applicationFormNameRef?.value.getLocationInfo();
|
applicationFormNameRef?.value.getLocationInfo();
|
||||||
// 诊断目录列表
|
// 诊断目录列表
|
||||||
@@ -123,8 +121,6 @@ const showApplicationFormDialog = (name) => {
|
|||||||
applicationFormName.value = components.value[name];
|
applicationFormName.value = components.value[name];
|
||||||
applicationFormDialogVisible.value = true;
|
applicationFormDialogVisible.value = true;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 列表(项目列表)
|
|
||||||
applicationFormNameRef?.value.getList?.();
|
|
||||||
// 科室列表
|
// 科室列表
|
||||||
applicationFormNameRef?.value.getLocationInfo();
|
applicationFormNameRef?.value.getLocationInfo();
|
||||||
// 诊断目录列表
|
// 诊断目录列表
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
import {getCurrentInstance, onBeforeMount, onMounted, reactive, watch} from 'vue';
|
import {getCurrentInstance, onBeforeMount, onMounted, reactive, watch} from 'vue';
|
||||||
import {patientInfo} from '../../../store/patient.js';
|
import {patientInfo} from '../../../store/patient.js';
|
||||||
import {getApplicationList, saveInspection} from './api';
|
import {getApplicationList, saveInspection} from './api';
|
||||||
import {getOrgList} from '@/views/doctorstation/components/api.js';
|
import {getDepartmentList} from '@/api/public.js';
|
||||||
import {getEncounterDiagnosis} from '../../api.js';
|
import {getEncounterDiagnosis} from '../../api.js';
|
||||||
import {ElMessage} from 'element-plus';
|
import {ElMessage} from 'element-plus';
|
||||||
|
|
||||||
@@ -208,10 +208,12 @@ const projectWithDepartment = (selectProjectIds, type) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (findItem && isRelease) {
|
if (type == 1) {
|
||||||
|
if (isRelease) {
|
||||||
form.targetDepartment = findItem.id;
|
form.targetDepartment = findItem.id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return isRelease;
|
return isRelease;
|
||||||
};
|
};
|
||||||
// 监听选择项目变化
|
// 监听选择项目变化
|
||||||
@@ -270,8 +272,8 @@ const submit = () => {
|
|||||||
};
|
};
|
||||||
/** 查询科室 */
|
/** 查询科室 */
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = () => {
|
||||||
getOrgList().then((res) => {
|
getDepartmentList().then((res) => {
|
||||||
orgOptions.value = res.data.records;
|
orgOptions.value = res.data || [];
|
||||||
console.log('科室========>', JSON.stringify(orgOptions.value));
|
console.log('科室========>', JSON.stringify(orgOptions.value));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -308,7 +310,7 @@ function getDiagnosisList() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, getList });
|
defineExpose({ state, submit, getLocationInfo, getDiagnosisList });
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.LaboratoryTests-container {
|
.LaboratoryTests-container {
|
||||||
|
|||||||
@@ -1,242 +1,125 @@
|
|||||||
<!--
|
<!--
|
||||||
* @Author: sjjh
|
* @Author: sjjh
|
||||||
* @Date: 2025-09-05 22:35:29
|
* @Date: 2025-09-05 22:35:29
|
||||||
* @Description: 检查申请单 - 现代化医疗风格布局
|
* @Description: 检查
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<div class="medicalExaminations-container">
|
<div class="medicalExaminations-container">
|
||||||
<!-- 顶部标题栏 -->
|
|
||||||
<div class="form-header">
|
|
||||||
<div class="header-left">
|
|
||||||
<el-icon class="header-icon"><Files /></el-icon>
|
|
||||||
<span class="header-title">检查申请单</span>
|
|
||||||
</div>
|
|
||||||
<div class="header-right">
|
|
||||||
<span class="urgency-label">紧急程度</span>
|
|
||||||
<el-radio-group v-model="form.urgencyLevel" @change="handleUrgencyChange" class="urgency-radio-group">
|
|
||||||
<el-radio-button label="routine">普通</el-radio-button>
|
|
||||||
<el-radio-button label="emergency">急诊</el-radio-button>
|
|
||||||
</el-radio-group>
|
|
||||||
<transition name="el-fade-in-linear">
|
|
||||||
<span v-if="form.urgencyLevel === 'emergency'" class="emergency-tip">
|
|
||||||
<el-icon><WarningFilled /></el-icon>
|
|
||||||
急诊单将进入绿色通道
|
|
||||||
</span>
|
|
||||||
</transition>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 主体内容区 -->
|
|
||||||
<div class="form-body">
|
|
||||||
<!-- 选择检查项目 -->
|
|
||||||
<div class="section-card">
|
|
||||||
<div class="section-header">
|
|
||||||
<el-icon><Document /></el-icon>
|
|
||||||
<span>选择检查项目</span>
|
|
||||||
</div>
|
|
||||||
<div v-loading="loading" class="transfer-wrapper">
|
<div v-loading="loading" class="transfer-wrapper">
|
||||||
<el-transfer
|
<el-transfer
|
||||||
v-model="transferValue"
|
v-model="transferValue"
|
||||||
:data="applicationList"
|
:data="applicationList"
|
||||||
filter-placeholder="项目代码/名称"
|
filter-placeholder="项目代码/名称"
|
||||||
filterable
|
filterable
|
||||||
:titles="['可选项目', '已选项目']"
|
:titles="['未选择', '已选择']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="bloodTransfusion-form">
|
||||||
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="demo-ruleForm">
|
||||||
<!-- 申请信息 -->
|
<el-row :gutter="20">
|
||||||
<div class="section-card">
|
<!-- <el-col :span="12">
|
||||||
<div class="section-header">
|
<el-form-item label="项目类别" prop="categoryType" style="width: 100%">
|
||||||
<el-icon><EditPen /></el-icon>
|
<el-input v-model="form.categoryType" autocomplete="off" />
|
||||||
<span>申请信息</span>
|
</el-form-item>
|
||||||
</div>
|
</el-col> -->
|
||||||
|
|
||||||
<el-form :model="form" :rules="rules" ref="formRef" label-position="top" class="info-form">
|
|
||||||
<!-- 第一行:发往科室 + 期望检查时间 -->
|
|
||||||
<el-row :gutter="16">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="发往科室" prop="targetDepartment">
|
<el-form-item label="发往科室" prop="targetDepartment" style="width: 100%">
|
||||||
|
<!-- <el-input v-model="form.targetDepartment" autocomplete="off" /> -->
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
clearable
|
clearable
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
v-model="form.targetDepartment"
|
v-model="form.targetDepartment"
|
||||||
filterable
|
filterable
|
||||||
:data="orgOptions"
|
:data="orgOptions"
|
||||||
:props="{ value: 'id', label: 'name', children: 'children' }"
|
:props="{
|
||||||
|
value: 'id',
|
||||||
|
label: 'name',
|
||||||
|
children: 'children',
|
||||||
|
}"
|
||||||
value-key="id"
|
value-key="id"
|
||||||
check-strictly
|
check-strictly
|
||||||
placeholder="请选择执行科室"
|
placeholder="请选择科室"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="期望检查时间">
|
<el-form-item label="紧急程度" prop="urgencyLevel" style="width: 100%">
|
||||||
|
<el-select v-model="form.urgencyLevel" placeholder="请选择紧急程度" clearable style="width: 100%">
|
||||||
|
<el-option label="普通" value="routine" />
|
||||||
|
<el-option label="急诊" value="emergency" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="过敏史" prop="allergyHistory" style="width: 100%">
|
||||||
|
<el-input v-model="form.allergyHistory" autocomplete="off" type="textarea" placeholder="如:造影剂过敏史等" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="检查目的" prop="examinationPurpose" style="width: 100%">
|
||||||
|
<el-input v-model="form.examinationPurpose" autocomplete="off" type="textarea" placeholder="请说明检查目的" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="病史摘要" prop="medicalHistorySummary" style="width: 100%">
|
||||||
|
<el-input v-model="form.medicalHistorySummary" autocomplete="off" type="textarea" placeholder="请简要描述患者病史" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="期望检查时间" prop="expectedExaminationTime" style="width: 100%">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
v-model="form.expectedExaminationTime"
|
v-model="form.expectedExaminationTime"
|
||||||
type="datetime"
|
type="datetime"
|
||||||
placeholder="默认当前时间"
|
placeholder="请选择期望检查时间"
|
||||||
style="width: 100%"
|
style="width: 100%"
|
||||||
value-format="YYYY-MM-DD HH:mm:ss"
|
value-format="YYYY-MM-DD HH:mm:ss"
|
||||||
format="YYYY-MM-DD HH:mm"
|
|
||||||
:disabled-date="disabledFutureDate"
|
|
||||||
:default-value="new Date()"
|
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 第二行:症状 + 体征 -->
|
|
||||||
<el-row :gutter="16">
|
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="症状">
|
<el-form-item label="症状" prop="symptom" style="width: 100%">
|
||||||
<el-input v-model="form.symptom" autocomplete="off" type="textarea" :rows="2" placeholder="请输入患者症状" />
|
<el-input v-model="form.symptom" autocomplete="off" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="体征">
|
<el-form-item label="体征" prop="sign" style="width: 100%">
|
||||||
<el-input v-model="form.sign" autocomplete="off" type="textarea" :rows="2" placeholder="请输入患者体征" />
|
<el-input v-model="form.sign" autocomplete="off" type="textarea" />
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 第三行:临床诊断 + 其他诊断 -->
|
|
||||||
<el-row :gutter="16">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="临床诊断">
|
|
||||||
<el-input disabled v-model="form.clinicalDiagnosis" placeholder="自动带入主诊断" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="其他诊断">
|
<el-form-item label="临床诊断" prop="clinicalDiagnosis" style="width: 100%">
|
||||||
<el-input disabled v-model="form.otherDiagnosis" placeholder="自动带入其他诊断" />
|
<el-input disabled v-model="form.clinicalDiagnosis" autocomplete="off" />
|
||||||
</el-form-item>
|
|
||||||
</el-col>
|
|
||||||
</el-row>
|
|
||||||
|
|
||||||
<!-- 第四行:相关结果 + 注意事项 -->
|
|
||||||
<el-row :gutter="16">
|
|
||||||
<el-col :span="12">
|
|
||||||
<el-form-item label="相关结果">
|
|
||||||
<el-input v-model="form.relatedResult" autocomplete="off" type="textarea" :rows="2" placeholder="请输入相关检验结果" />
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<el-form-item label="注意事项">
|
<el-form-item label="其他诊断" prop="otherDiagnosis" style="width: 100%">
|
||||||
<el-input v-model="form.attention" autocomplete="off" type="textarea" :rows="2" placeholder="请输入检查注意事项" />
|
<el-input disabled v-model="form.otherDiagnosis" autocomplete="off" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="相关结果" prop="relatedResult" style="width: 100%">
|
||||||
|
<el-input v-model="form.relatedResult" autocomplete="off" type="textarea" />
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item label="注意事项" prop="attention" style="width: 100%">
|
||||||
|
<el-input v-model="form.attention" autocomplete="off" type="textarea" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
<!-- 过敏史卡片 -->
|
|
||||||
<div class="section-card allergy-card">
|
|
||||||
<div class="section-header">
|
|
||||||
<el-icon><Warning /></el-icon>
|
|
||||||
<span>过敏史</span>
|
|
||||||
<span v-if="form.allergyHistory" class="header-count">{{ form.allergyHistory.length }}字</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="allergy-content">
|
|
||||||
<div class="allergy-input-row">
|
|
||||||
<el-input
|
|
||||||
v-model="form.allergyHistory"
|
|
||||||
autocomplete="off"
|
|
||||||
type="textarea"
|
|
||||||
:rows="2"
|
|
||||||
:class="{ 'allergy-danger': isSevereAllergy }"
|
|
||||||
placeholder="如:造影剂过敏史等(系统将自动从患者档案带入)"
|
|
||||||
/>
|
|
||||||
<span v-if="isSevereAllergy" class="allergy-severe-tag">
|
|
||||||
<el-icon><WarningFilled /></el-icon>
|
|
||||||
严重过敏
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="allergy-confirm">
|
|
||||||
<el-checkbox v-model="form.allergyConfirmed" size="small">
|
|
||||||
已通过口头询问确认无过敏史
|
|
||||||
</el-checkbox>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 检查目的卡片 -->
|
|
||||||
<div class="section-card purpose-card">
|
|
||||||
<div class="section-header">
|
|
||||||
<el-icon><Aim /></el-icon>
|
|
||||||
<span>检查目的</span>
|
|
||||||
<span class="required-mark">必填</span>
|
|
||||||
</div>
|
|
||||||
<el-input
|
|
||||||
v-model="form.examinationPurpose"
|
|
||||||
autocomplete="off"
|
|
||||||
type="textarea"
|
|
||||||
:rows="2"
|
|
||||||
maxlength="200"
|
|
||||||
show-word-limit
|
|
||||||
placeholder="请输入检查目的,如:明确诊断、术后复查、疗效评估等"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 病史摘要卡片 -->
|
|
||||||
<div class="section-card history-card">
|
|
||||||
<div class="section-header">
|
|
||||||
<el-icon><DocumentCopy /></el-icon>
|
|
||||||
<span>病史摘要</span>
|
|
||||||
<span class="required-mark">必填</span>
|
|
||||||
<el-button
|
|
||||||
type="primary"
|
|
||||||
plain
|
|
||||||
size="small"
|
|
||||||
class="sync-btn"
|
|
||||||
@click="handleSyncHistory"
|
|
||||||
:loading="syncingHistory"
|
|
||||||
>
|
|
||||||
<el-icon><Refresh /></el-icon>
|
|
||||||
同步现病史/体征
|
|
||||||
</el-button>
|
|
||||||
</div>
|
|
||||||
<el-input
|
|
||||||
v-model="form.medicalHistorySummary"
|
|
||||||
autocomplete="off"
|
|
||||||
type="textarea"
|
|
||||||
:rows="3"
|
|
||||||
placeholder="请简要描述患者病史摘要"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- 急诊确认弹窗 -->
|
|
||||||
<el-dialog
|
|
||||||
v-model="emergencyDialogVisible"
|
|
||||||
title="急诊确认"
|
|
||||||
width="400px"
|
|
||||||
:close-on-click-modal="false"
|
|
||||||
>
|
|
||||||
<div class="emergency-dialog-content">
|
|
||||||
<el-icon class="emergency-dialog-icon"><WarningFilled /></el-icon>
|
|
||||||
<p class="emergency-dialog-text">请确认患者符合急诊指征</p>
|
|
||||||
<p class="emergency-dialog-sub">急诊申请单将进入绿色通道优先处理</p>
|
|
||||||
</div>
|
|
||||||
<template #footer>
|
|
||||||
<el-button @click="cancelEmergency">取消</el-button>
|
|
||||||
<el-button type="danger" @click="confirmEmergency">确认急诊</el-button>
|
|
||||||
</template>
|
|
||||||
</el-dialog>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="MedicalExaminations">
|
<script setup name="MedicalExaminations">
|
||||||
import {getCurrentInstance, onMounted, reactive, ref, watch, computed} from 'vue';
|
import {getCurrentInstance, onBeforeMount, onMounted, reactive, watch} from 'vue';
|
||||||
import {patientInfo} from '../../../store/patient.js';
|
import {patientInfo} from '../../../store/patient.js';
|
||||||
import {getDepartmentList} from '@/api/public.js';
|
import {getDepartmentList} from '@/api/public.js';
|
||||||
import {getEncounterDiagnosis} from '../../api.js';
|
import {getEncounterDiagnosis} from '../../api.js';
|
||||||
import {getApplicationList, saveCheckd} from './api';
|
import {getApplicationList, saveCheckd} from './api';
|
||||||
import {ElMessage, ElMessageBox} from 'element-plus';
|
import {ElMessage} from 'element-plus';
|
||||||
import {WarningFilled, Warning, Refresh, Files, Document, EditPen, Aim, DocumentCopy} from '@element-plus/icons-vue';
|
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
|
|
||||||
// 递归查找树形科室节点
|
// 递归查找树形科室节点
|
||||||
const findTreeItem = (list, id) => {
|
const findTreeItem = (list, id) => {
|
||||||
if (!list || list.length === 0) return null;
|
if (!list || list.length === 0) return null;
|
||||||
@@ -249,28 +132,13 @@ const findTreeItem = (list, id) => {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
const emits = defineEmits(['submitOk']);
|
const emits = defineEmits(['submitOk']);
|
||||||
const props = defineProps({});
|
const props = defineProps({});
|
||||||
const orgOptions = ref([]);
|
const orgOptions = ref([]); // 科室选项
|
||||||
const state = reactive({});
|
const state = reactive({});
|
||||||
const applicationListAll = ref();
|
const applicationListAll = ref();
|
||||||
const applicationList = ref();
|
const applicationList = ref();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
|
|
||||||
// 过敏史相关
|
|
||||||
const syncingHistory = ref(false);
|
|
||||||
const emergencyDialogVisible = ref(false);
|
|
||||||
const pendingUrgencyLevel = ref('');
|
|
||||||
|
|
||||||
// 严重过敏关键词
|
|
||||||
const severeAllergyKeywords = ['造影剂', '碘', '青霉素', '普鲁卡因', '头孢', '麻醉剂', '海鲜', '过敏性休克'];
|
|
||||||
|
|
||||||
const isSevereAllergy = computed(() => {
|
|
||||||
if (!form.allergyHistory) return false;
|
|
||||||
return severeAllergyKeywords.some(keyword => form.allergyHistory.includes(keyword));
|
|
||||||
});
|
|
||||||
|
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
if (!patientInfo.value?.inHospitalOrgId) {
|
if (!patientInfo.value?.inHospitalOrgId) {
|
||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
@@ -282,7 +150,7 @@ const getList = () => {
|
|||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
categoryCode: '23',
|
categoryCode: '23',
|
||||||
organizationId: patientInfo.value.inHospitalOrgId,
|
organizationId: patientInfo.value.inHospitalOrgId,
|
||||||
adviceTypes: [3],
|
adviceTypes: [3], //1 药品 2耗材 3诊疗
|
||||||
})
|
})
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
@@ -307,532 +175,192 @@ const getList = () => {
|
|||||||
loading.value = false;
|
loading.value = false;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const transferValue = ref([]);
|
const transferValue = ref([]);
|
||||||
|
|
||||||
const form = reactive({
|
const form = reactive({
|
||||||
targetDepartment: '',
|
// categoryType: '', // 项目类别
|
||||||
urgencyLevel: 'routine',
|
targetDepartment: '', // 发往科室
|
||||||
allergyHistory: '',
|
urgencyLevel: '', // 紧急程度
|
||||||
examinationPurpose: '',
|
allergyHistory: '', // 过敏史
|
||||||
medicalHistorySummary: '',
|
examinationPurpose: '', // 检查目的
|
||||||
expectedExaminationTime: '',
|
medicalHistorySummary: '', // 病史摘要
|
||||||
symptom: '',
|
expectedExaminationTime: '', // 期望检查时间
|
||||||
sign: '',
|
symptom: '', // 症状
|
||||||
clinicalDiagnosis: '',
|
sign: '', // 体征
|
||||||
otherDiagnosis: '',
|
clinicalDiagnosis: '', // 临床诊断
|
||||||
relatedResult: '',
|
otherDiagnosis: '', // 其他诊断
|
||||||
attention: '',
|
relatedResult: '', // 相关结果
|
||||||
primaryDiagnosisList: [],
|
attention: '', // 注意事项
|
||||||
otherDiagnosisList: [],
|
primaryDiagnosisList: [], //主诊断目录
|
||||||
allergyConfirmed: false,
|
otherDiagnosisList: [], //其他断目录
|
||||||
});
|
});
|
||||||
|
const rules = reactive({});
|
||||||
// 表单校验规则
|
onBeforeMount(() => {});
|
||||||
const rules = reactive({
|
onMounted(() => {
|
||||||
examinationPurpose: [
|
getList();
|
||||||
{ required: true, message: '请输入检查目的', trigger: 'blur' },
|
|
||||||
{ max: 200, message: '检查目的不能超过200个字符', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
medicalHistorySummary: [
|
|
||||||
{ required: true, message: '请输入病史摘要', trigger: 'blur' },
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
/**
|
||||||
// 禁用过去的时间
|
* type(1:watch监听类型 2:点击保存类型)
|
||||||
const disabledFutureDate = (time) => {
|
* selectProjectIds(选中项目的id数组)
|
||||||
return time.getTime() < Date.now() - 8.64e7;
|
* */
|
||||||
};
|
|
||||||
|
|
||||||
// 紧急程度切换处理
|
|
||||||
const handleUrgencyChange = (value) => {
|
|
||||||
if (value === 'emergency') {
|
|
||||||
emergencyDialogVisible.value = true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 确认急诊
|
|
||||||
const confirmEmergency = () => {
|
|
||||||
emergencyDialogVisible.value = false;
|
|
||||||
ElMessage({
|
|
||||||
type: 'success',
|
|
||||||
message: '已设置为急诊检查,将进入绿色通道',
|
|
||||||
duration: 3000,
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
// 取消急诊
|
|
||||||
const cancelEmergency = () => {
|
|
||||||
emergencyDialogVisible.value = false;
|
|
||||||
form.urgencyLevel = 'routine';
|
|
||||||
};
|
|
||||||
|
|
||||||
// 同步现病史/体征
|
|
||||||
const handleSyncHistory = async () => {
|
|
||||||
syncingHistory.value = true;
|
|
||||||
try {
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 800));
|
|
||||||
if (form.symptom || form.sign) {
|
|
||||||
form.medicalHistorySummary = `${form.symptom ? '症状:' + form.symptom + '\n' : ''}${form.sign ? '体征:' + form.sign : ''}`;
|
|
||||||
} else {
|
|
||||||
form.medicalHistorySummary = '患者目前一般情况可,无特殊不适主诉。';
|
|
||||||
}
|
|
||||||
ElMessage({ type: 'success', message: '已同步现病史/体征' });
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error('同步失败');
|
|
||||||
} finally {
|
|
||||||
syncingHistory.value = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// 自动带入患者过敏史
|
|
||||||
const loadPatientAllergyHistory = () => {
|
|
||||||
if (!patientInfo.value?.patientId) return;
|
|
||||||
};
|
|
||||||
|
|
||||||
const projectWithDepartment = (selectProjectIds, type) => {
|
const projectWithDepartment = (selectProjectIds, type) => {
|
||||||
|
//1.获取选中的项目 2.判断项目的执行科室是否相同 3.判断执行科室是否配置 4.将项目的执行科室复值到执行科室下拉选位置
|
||||||
let isRelease = true;
|
let isRelease = true;
|
||||||
|
// 选中项目的数组
|
||||||
const arr = [];
|
const arr = [];
|
||||||
|
// 根据选中的项目id查找对应的项目
|
||||||
selectProjectIds.forEach((element) => {
|
selectProjectIds.forEach((element) => {
|
||||||
const searchData = applicationList.value.find((item) => {
|
const searchData = applicationList.value.find((item) => {
|
||||||
return element == item.adviceDefinitionId;
|
return element == item.adviceDefinitionId;
|
||||||
});
|
});
|
||||||
arr.push(searchData);
|
arr.push(searchData);
|
||||||
});
|
});
|
||||||
// 只有当选择了项目(arr 非空)时才设置 targetDepartment
|
// 清空科室
|
||||||
|
form.targetDepartment = '';
|
||||||
if (arr.length > 0) {
|
if (arr.length > 0) {
|
||||||
const obj = arr[0];
|
const obj = arr[0];
|
||||||
// 检查是否有未定义的项目(applicationList 中找不到)
|
// 判断科室是否相同
|
||||||
if (!obj) {
|
const isCompare = arr.every((item) => {
|
||||||
console.warn('未找到项目定义,无法设置执行科室');
|
return item.orgId == obj.orgId;
|
||||||
return false;
|
});
|
||||||
}
|
|
||||||
const isCompare = arr.every((item) => item && item.orgId == obj.orgId);
|
|
||||||
if (!isCompare) {
|
if (!isCompare) {
|
||||||
ElMessage({ type: 'error', message: '执行科室不同' });
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '执行科室不同',
|
||||||
|
});
|
||||||
isRelease = false;
|
isRelease = false;
|
||||||
}
|
}
|
||||||
|
// 选中项目中的执行科室id与全部科室数据做匹配
|
||||||
const findItem = findTreeItem(orgOptions.value, obj.orgId);
|
const findItem = findTreeItem(orgOptions.value, obj.orgId);
|
||||||
|
|
||||||
if (!findItem) {
|
if (!findItem) {
|
||||||
isRelease = false;
|
isRelease = false;
|
||||||
ElMessage({ type: 'error', message: '未找到项目执行的科室' });
|
ElMessage({
|
||||||
|
type: 'error',
|
||||||
|
message: '未找到项目执行的科室',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (type == 1 && isRelease) {
|
if (type == 1) {
|
||||||
|
if (isRelease) {
|
||||||
form.targetDepartment = findItem.id;
|
form.targetDepartment = findItem.id;
|
||||||
console.log('targetDepartment 设置为:', form.targetDepartment, '科室名称:', findItem.name);
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
// 清空选择时,也要清空 targetDepartment
|
|
||||||
form.targetDepartment = '';
|
|
||||||
}
|
}
|
||||||
return isRelease;
|
return isRelease;
|
||||||
};
|
};
|
||||||
|
// 监听选择项目变化
|
||||||
watch(() => transferValue.value, (newValue) => {
|
watch(
|
||||||
|
() => transferValue.value,
|
||||||
|
(newValue) => {
|
||||||
projectWithDepartment(newValue, 1);
|
projectWithDepartment(newValue, 1);
|
||||||
});
|
}
|
||||||
|
);
|
||||||
const getPriorityCode = () => {
|
|
||||||
return form.urgencyLevel === 'emergency' ? 1 : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
if (transferValue.value.length == 0) {
|
if (transferValue.value.length == 0) {
|
||||||
return proxy.$message.error('请选择检查项目');
|
return proxy.$message.error('请选择申请单');
|
||||||
}
|
}
|
||||||
if (!projectWithDepartment(transferValue.value, 2)) {
|
if (!projectWithDepartment(transferValue.value, 2)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!form.examinationPurpose) {
|
|
||||||
return ElMessageBox.alert('请输入检查目的', '提示', { confirmButtonText: '确定', type: 'warning' });
|
|
||||||
}
|
|
||||||
if (!form.medicalHistorySummary) {
|
|
||||||
return ElMessageBox.alert('请输入病史摘要', '提示', { confirmButtonText: '确定', type: 'warning' });
|
|
||||||
}
|
|
||||||
if (!form.allergyHistory && !form.allergyConfirmed) {
|
|
||||||
return ElMessageBox.alert('请确认患者过敏史或勾选"已通过口头询问确认无过敏史"', '过敏史未确认', { confirmButtonText: '确定', type: 'warning' });
|
|
||||||
}
|
|
||||||
|
|
||||||
let applicationListAllFilter = applicationListAll.value.filter((item) => {
|
let applicationListAllFilter = applicationListAll.value.filter((item) => {
|
||||||
return transferValue.value.includes(item.adviceDefinitionId);
|
return transferValue.value.includes(item.adviceDefinitionId);
|
||||||
});
|
});
|
||||||
applicationListAllFilter = applicationListAllFilter.map((item) => {
|
applicationListAllFilter = applicationListAllFilter.map((item) => {
|
||||||
return {
|
return {
|
||||||
adviceDefinitionId: item.adviceDefinitionId,
|
adviceDefinitionId: item.adviceDefinitionId /** 诊疗定义id */,
|
||||||
quantity: 1,
|
quantity: 1, // /** 请求数量 */
|
||||||
unitCode: item.priceList[0].unitCode,
|
unitCode: item.priceList[0].unitCode /** 请求单位编码 */,
|
||||||
unitPrice: item.priceList[0].price,
|
unitPrice: item.priceList[0].price /** 单价 */,
|
||||||
totalPrice: item.priceList[0].price,
|
totalPrice: item.priceList[0].price /** 总价 */,
|
||||||
positionId: item.positionId,
|
positionId: item.positionId, //执行科室id
|
||||||
ybClassEnum: item.ybClassEnum,
|
ybClassEnum: item.ybClassEnum, //类别医保编码
|
||||||
conditionId: item.conditionId,
|
conditionId: item.conditionId, //诊断ID
|
||||||
encounterDiagnosisId: item.encounterDiagnosisId,
|
encounterDiagnosisId: item.encounterDiagnosisId, //就诊诊断id
|
||||||
adviceType: item.adviceType,
|
adviceType: item.adviceType, ///** 医嘱类型 */
|
||||||
definitionId: item.priceList[0].definitionId,
|
definitionId: item.priceList[0].definitionId, //费用定价主表ID */
|
||||||
definitionDetailId: item.priceList[0].definitionDetailId,
|
definitionDetailId: item.definitionDetailId, //费用定价子表ID */
|
||||||
accountId: patientInfo.value.accountId,
|
accountId: patientInfo.value.accountId, // // 账户id
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const submitForm = { ...form, priorityCode: getPriorityCode() };
|
|
||||||
console.log('提交 descJson:', JSON.stringify(submitForm));
|
|
||||||
|
|
||||||
saveCheckd({
|
saveCheckd({
|
||||||
activityList: applicationListAllFilter,
|
activityList: applicationListAllFilter,
|
||||||
patientId: patientInfo.value.patientId,
|
patientId: patientInfo.value.patientId, //患者ID
|
||||||
encounterId: patientInfo.value.encounterId,
|
encounterId: patientInfo.value.encounterId, // 就诊ID
|
||||||
organizationId: patientInfo.value.inHospitalOrgId,
|
organizationId: patientInfo.value.inHospitalOrgId, // 医疗机构ID
|
||||||
requestFormId: '',
|
requestFormId: '', // 申请单ID
|
||||||
name: '检查申请单',
|
name: '检查申请单',
|
||||||
descJson: JSON.stringify(submitForm),
|
descJson: JSON.stringify(form),
|
||||||
categoryEnum: '2',
|
categoryEnum: '2', // 1 检验 2 检查 3 输血 4 手术
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
proxy.$message.success(res.msg);
|
proxy.$message.success(res.msg);
|
||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
resetForm();
|
|
||||||
emits('submitOk');
|
emits('submitOk');
|
||||||
} else {
|
} else {
|
||||||
proxy.$message.error(res.message);
|
proxy.$message.error(res.message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
/** 查询科室 */
|
||||||
const resetForm = () => {
|
|
||||||
form.targetDepartment = '';
|
|
||||||
form.urgencyLevel = 'routine';
|
|
||||||
form.allergyHistory = '';
|
|
||||||
form.examinationPurpose = '';
|
|
||||||
form.medicalHistorySummary = '';
|
|
||||||
form.expectedExaminationTime = '';
|
|
||||||
form.symptom = '';
|
|
||||||
form.sign = '';
|
|
||||||
form.clinicalDiagnosis = '';
|
|
||||||
form.otherDiagnosis = '';
|
|
||||||
form.relatedResult = '';
|
|
||||||
form.attention = '';
|
|
||||||
form.primaryDiagnosisList = [];
|
|
||||||
form.otherDiagnosisList = [];
|
|
||||||
form.allergyConfirmed = false;
|
|
||||||
transferValue.value = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
const getLocationInfo = () => {
|
const getLocationInfo = () => {
|
||||||
getDepartmentList().then((res) => {
|
getDepartmentList().then((res) => {
|
||||||
orgOptions.value = res.data || [];
|
orgOptions.value = res.data || [];
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
// 获取诊断目录
|
||||||
function getDiagnosisList() {
|
function getDiagnosisList() {
|
||||||
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
getEncounterDiagnosis(patientInfo.value.encounterId).then((res) => {
|
||||||
|
console.log('诊断目录========>', JSON.stringify(res.data));
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
const datas = (res.data || []).map((item) => {
|
const datas = (res.data || []).map((item) => {
|
||||||
let obj = { ...item };
|
let obj = {
|
||||||
if (obj.diagSrtNo == null) obj.diagSrtNo = '1';
|
...item,
|
||||||
|
};
|
||||||
|
if (obj.diagSrtNo == null) {
|
||||||
|
obj.diagSrtNo = '1';
|
||||||
|
}
|
||||||
return obj;
|
return obj;
|
||||||
});
|
});
|
||||||
form.primaryDiagnosisList = datas.filter((item) => item?.maindiseFlag == 1);
|
// 主诊断
|
||||||
|
form.primaryDiagnosisList = datas.filter((item) => {
|
||||||
|
return item?.maindiseFlag == 1;
|
||||||
|
});
|
||||||
|
console.log('@@@@@@========>', form.primaryDiagnosisList);
|
||||||
if (form.primaryDiagnosisList.length == 1) {
|
if (form.primaryDiagnosisList.length == 1) {
|
||||||
form.clinicalDiagnosis = form.primaryDiagnosisList[0].name;
|
const obj = form.primaryDiagnosisList[0];
|
||||||
|
form.clinicalDiagnosis = obj.name;
|
||||||
}
|
}
|
||||||
form.otherDiagnosisList = datas.filter((item) => item?.maindiseFlag !== 1);
|
//其他诊断
|
||||||
form.otherDiagnosis = form.otherDiagnosisList.map((item) => item.name).join(',');
|
form.otherDiagnosisList = datas.filter((item) => {
|
||||||
|
return item?.maindiseFlag !== 1;
|
||||||
|
});
|
||||||
|
const otherDiagnosisNameList = form.otherDiagnosisList.map((item) => {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
form.otherDiagnosis = otherDiagnosisNameList.join(',');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
defineExpose({ state, submit, getLocationInfo, getDiagnosisList });
|
||||||
onMounted(() => {
|
|
||||||
getList();
|
|
||||||
getLocationInfo();
|
|
||||||
loadPatientAllergyHistory();
|
|
||||||
});
|
|
||||||
|
|
||||||
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, resetForm });
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
// 医疗主题色
|
|
||||||
$primary-color: #409eff;
|
|
||||||
$success-color: #67c23a;
|
|
||||||
$warning-color: #e6a23c;
|
|
||||||
$danger-color: #f56c6c;
|
|
||||||
$info-color: #909399;
|
|
||||||
|
|
||||||
$text-primary: #303133;
|
|
||||||
$text-regular: #606266;
|
|
||||||
$text-secondary: #909399;
|
|
||||||
$border-color: #dcdfe6;
|
|
||||||
$bg-color: #f5f7fa;
|
|
||||||
|
|
||||||
.medicalExaminations-container {
|
.medicalExaminations-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
background: $bg-color;
|
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
|
|
||||||
|
|
||||||
// 顶部标题栏
|
|
||||||
.form-header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 14px 20px;
|
|
||||||
background: linear-gradient(135deg, #fff 0%, #f0f7ff 100%);
|
|
||||||
border-bottom: 1px solid $border-color;
|
|
||||||
|
|
||||||
.header-left {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
|
|
||||||
.header-icon {
|
|
||||||
font-size: 24px;
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: $text-primary;
|
|
||||||
letter-spacing: 1px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-right {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 12px;
|
|
||||||
|
|
||||||
.urgency-label {
|
|
||||||
font-size: 13px;
|
|
||||||
color: $text-secondary;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.urgency-radio-group {
|
|
||||||
:deep(.el-radio-button__inner) {
|
|
||||||
border-radius: 4px;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-radio-button:first-child .el-radio-button__inner) {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.el-radio-button:last-child .el-radio-button__inner) {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.emergency-tip {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
color: $danger-color;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
background: #fef0f0;
|
|
||||||
padding: 4px 10px;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid #fde2e2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 主体内容区
|
|
||||||
.form-body {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 12px;
|
|
||||||
padding: 16px;
|
|
||||||
overflow-y: auto;
|
|
||||||
|
|
||||||
&::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb {
|
|
||||||
background: #d0d3da;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-track {
|
|
||||||
background: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片通用样式
|
|
||||||
.section-card {
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.04);
|
|
||||||
|
|
||||||
.section-header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 8px;
|
|
||||||
padding-bottom: 12px;
|
|
||||||
margin-bottom: 12px;
|
|
||||||
border-bottom: 1px dashed $border-color;
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: $text-primary;
|
|
||||||
|
|
||||||
> i {
|
|
||||||
font-size: 16px;
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header-count {
|
|
||||||
margin-left: auto;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 400;
|
|
||||||
color: $text-secondary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.required-mark {
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: #fff;
|
|
||||||
background: $danger-color;
|
|
||||||
padding: 2px 8px;
|
|
||||||
border-radius: 10px;
|
|
||||||
margin-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.transfer-wrapper {
|
.transfer-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 300px;
|
min-height: 300px;
|
||||||
width: 100%;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.el-transfer) {
|
.el-transfer {
|
||||||
--el-transfer-panel-width: 480px !important;
|
--el-transfer-panel-width: 480px !important;
|
||||||
display: flex !important;
|
|
||||||
flex-direction: row !important;
|
|
||||||
}
|
|
||||||
// 信息表单
|
|
||||||
.info-form {
|
|
||||||
:deep(.el-form-item) {
|
|
||||||
margin-bottom: 14px;
|
|
||||||
|
|
||||||
.el-form-item__label {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: $text-regular;
|
|
||||||
padding-bottom: 6px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-input__wrapper,
|
.bloodTransfusion-form {
|
||||||
.el-textarea__inner {
|
padding: 8px 8px 0 8px;
|
||||||
border-radius: 6px;
|
height: 100%;
|
||||||
transition: all 0.2s;
|
width: 100%;
|
||||||
|
|
||||||
&:hover {
|
|
||||||
box-shadow: 0 0 0 1px $primary-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:focus {
|
|
||||||
box-shadow: 0 0 0 2px rgba($primary-color, 0.2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-input.is-disabled .el-input__wrapper {
|
|
||||||
background: #f5f7fa;
|
|
||||||
cursor: not-allowed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 过敏史卡片
|
|
||||||
.allergy-card {
|
|
||||||
.allergy-content {
|
|
||||||
.allergy-input-row {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
:deep(.el-textarea) {
|
|
||||||
.el-textarea__inner.allergy-danger {
|
|
||||||
border-color: $danger-color !important;
|
|
||||||
background-color: #fef0f0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.allergy-severe-tag {
|
|
||||||
position: absolute;
|
|
||||||
right: 12px;
|
|
||||||
top: 8px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
color: $danger-color;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 600;
|
|
||||||
background: #fef0f0;
|
|
||||||
padding: 3px 10px;
|
|
||||||
border-radius: 12px;
|
|
||||||
border: 1px solid #fde2e2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.allergy-confirm {
|
|
||||||
margin-top: 10px;
|
|
||||||
padding-left: 4px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 病史摘要卡片
|
|
||||||
.history-card {
|
|
||||||
.section-header {
|
|
||||||
.sync-btn {
|
|
||||||
margin-left: auto;
|
|
||||||
font-size: 12px;
|
|
||||||
padding: 6px 12px;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 急诊确认弹窗
|
|
||||||
.emergency-dialog-content {
|
|
||||||
text-align: center;
|
|
||||||
padding: 24px 0;
|
|
||||||
|
|
||||||
.emergency-dialog-icon {
|
|
||||||
font-size: 52px;
|
|
||||||
color: $danger-color;
|
|
||||||
margin-bottom: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emergency-dialog-text {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
color: $text-primary;
|
|
||||||
margin: 0 0 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.emergency-dialog-sub {
|
|
||||||
font-size: 14px;
|
|
||||||
color: $text-secondary;
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 过渡动画
|
|
||||||
.fade-in-linear-enter-active,
|
|
||||||
.fade-in-linear-leave-active {
|
|
||||||
transition: opacity 0.2s linear;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-in-linear-enter-from,
|
|
||||||
.fade-in-linear-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="surgery-container">
|
<div class="surgery-container">
|
||||||
<div class="transfer-wrapper">
|
<div class="transfer-wrapper">
|
||||||
<div v-loading="loading" style="min-height: 300px;">
|
|
||||||
<el-transfer
|
<el-transfer
|
||||||
v-model="transferValue"
|
v-model="transferValue"
|
||||||
:data="applicationList"
|
:data="applicationList"
|
||||||
@@ -15,7 +14,6 @@
|
|||||||
:titles="['未选择', '已选择']"
|
:titles="['未选择', '已选择']"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="bloodTransfusion-form">
|
<div class="bloodTransfusion-form">
|
||||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="demo-ruleForm">
|
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="demo-ruleForm">
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
@@ -106,13 +104,11 @@ const state = reactive({});
|
|||||||
const applicationListAll = ref([]);
|
const applicationListAll = ref([]);
|
||||||
const applicationList = ref([]);
|
const applicationList = ref([]);
|
||||||
const orgOptions = ref([]); // 科室选项
|
const orgOptions = ref([]); // 科室选项
|
||||||
const loading = ref(false); // 加载状态
|
|
||||||
const getList = () => {
|
const getList = () => {
|
||||||
if (!patientInfo.value?.inHospitalOrgId) {
|
if (!patientInfo.value?.inHospitalOrgId) {
|
||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
loading.value = true;
|
|
||||||
getApplicationList({
|
getApplicationList({
|
||||||
pageSize: 500,
|
pageSize: 500,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
@@ -142,9 +138,6 @@ const getList = () => {
|
|||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.warn('手术项目列表加载失败(可能无权限):', e?.message || e);
|
console.warn('手术项目列表加载失败(可能无权限):', e?.message || e);
|
||||||
applicationList.value = [];
|
applicationList.value = [];
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
loading.value = false;
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
const transferValue = ref([]);
|
const transferValue = ref([]);
|
||||||
@@ -308,7 +301,7 @@ function getDiagnosisList() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
defineExpose({ state, submit, getLocationInfo, getDiagnosisList, getList });
|
defineExpose({ state, submit, getLocationInfo, getDiagnosisList });
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.surgery-container {
|
.surgery-container {
|
||||||
|
|||||||
@@ -197,6 +197,7 @@
|
|||||||
style="width: 62%"
|
style="width: 62%"
|
||||||
v-model="scope.row.adviceName"
|
v-model="scope.row.adviceName"
|
||||||
placeholder="请选择项目"
|
placeholder="请选择项目"
|
||||||
|
@input="handleChange"
|
||||||
@click="handleFocus(scope.row, scope.$index)"
|
@click="handleFocus(scope.row, scope.$index)"
|
||||||
@keyup.enter.stop="handleFocus(scope.row, scope.$index)"
|
@keyup.enter.stop="handleFocus(scope.row, scope.$index)"
|
||||||
@keydown="
|
@keydown="
|
||||||
@@ -379,7 +380,7 @@ const form = ref({
|
|||||||
prescriptionList: prescriptionList.value,
|
prescriptionList: prescriptionList.value,
|
||||||
});
|
});
|
||||||
const adviceQueryParams = ref({
|
const adviceQueryParams = ref({
|
||||||
adviceType: '',
|
adviceType: 1,
|
||||||
categoryCode: '', // 初始为空,等待加载配置后动态设置
|
categoryCode: '', // 初始为空,等待加载配置后动态设置
|
||||||
searchKey: '',
|
searchKey: '',
|
||||||
});
|
});
|
||||||
@@ -685,7 +686,7 @@ function loadConfiguredCategories() {
|
|||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 创建新对象触发响应式更新
|
// 创建新对象触发响应式更新
|
||||||
adviceQueryParams.value = {
|
adviceQueryParams.value = {
|
||||||
adviceType: '',
|
adviceType: 1,
|
||||||
categoryCode: defaultCategoryCode,
|
categoryCode: defaultCategoryCode,
|
||||||
searchKey: '',
|
searchKey: '',
|
||||||
};
|
};
|
||||||
@@ -801,7 +802,9 @@ function clickRowDb(row, column, event) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
row.showPopover = false;
|
row.showPopover = false;
|
||||||
// 仅”待签发(statusEnum==1)”允许编辑;”已签发(statusEnum==2)”及之后状态不允许编辑
|
// 允许所有 statusEnum==1 的医嘱进入编辑:
|
||||||
|
// 1. 新医嘱(无 requestId):待保存
|
||||||
|
// 2. 护士退回医嘱(有 requestId):退回后状态重置为 DRAFT(1),需允许医生编辑修改后重新签发
|
||||||
if (row.statusEnum == 1) {
|
if (row.statusEnum == 1) {
|
||||||
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
// 确保治疗类型为字符串,方便与单选框 label 对齐,默认为长期医嘱('1')
|
||||||
row.therapyEnum = String(row.therapyEnum ?? '1');
|
row.therapyEnum = String(row.therapyEnum ?? '1');
|
||||||
|
|||||||
@@ -270,7 +270,7 @@ function normalizeDayTimeHm(part) {
|
|||||||
return `${h}:${m}`;
|
return `${h}:${m}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleGetPrescription(skipAutoSelectAll = false) {
|
function handleGetPrescription() {
|
||||||
if (patientInfoList.value.length > 0) {
|
if (patientInfoList.value.length > 0) {
|
||||||
loading.value = true;
|
loading.value = true;
|
||||||
let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');
|
let encounterIds = patientInfoList.value.map((i) => i.encounterId).join(',');
|
||||||
@@ -430,12 +430,10 @@ function handleGetPrescription(skipAutoSelectAll = false) {
|
|||||||
|
|
||||||
// 将分组结果转换为数组形式
|
// 将分组结果转换为数组形式
|
||||||
prescriptionList.value = Object.values(groupedPrescriptions);
|
prescriptionList.value = Object.values(groupedPrescriptions);
|
||||||
// 默认选中全部行(执行后刷新时不自动全选,保持用户操作状态)
|
// 默认选中全部行
|
||||||
if (!skipAutoSelectAll) {
|
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
defaultSelectAllRows();
|
defaultSelectAllRows();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('医嘱执行-获取处方列表数据处理失败:', error);
|
console.error('医嘱执行-获取处方列表数据处理失败:', error);
|
||||||
prescriptionList.value = [];
|
prescriptionList.value = [];
|
||||||
@@ -471,17 +469,18 @@ function handleExecute() {
|
|||||||
console.log(list, 'list');
|
console.log(list, 'list');
|
||||||
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
|
adviceExecute({ exeDate: exeDate.value, adviceExecuteDetailList: list }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
// 仅当选中医嘱中包含耗材类医嘱时,才调用耗材批号匹配(排除纯药品医嘱场景)
|
handleGetPrescription();
|
||||||
const hasDevice = list.some((item) =>
|
// 仅当选中医嘱中包含药品/耗材类医嘱时,才调用耗材批号匹配
|
||||||
|
const hasMedOrDevice = list.some(
|
||||||
|
(item) =>
|
||||||
|
item.adviceTable === 'med_medication_request' ||
|
||||||
String(item.adviceTable || '').includes('device'),
|
String(item.adviceTable || '').includes('device'),
|
||||||
);
|
);
|
||||||
if (hasDevice) {
|
if (hasMedOrDevice) {
|
||||||
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
|
lotNumberMatch({ encounterIdList: encounterIds }, { skipErrorMsg: true }).catch((error) => {
|
||||||
console.warn('lotNumberMatch failed after adviceExecute:', error);
|
console.warn('lotNumberMatch failed after adviceExecute:', error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// 刷新列表(不自动全选,保持用户操作前的选择状态)
|
|
||||||
handleGetPrescription(true);
|
|
||||||
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
|
proxy.$modal.msgSuccess(res.msg || '医嘱执行成功');
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '医嘱执行失败');
|
proxy.$modal.msgError(res.msg || '医嘱执行失败');
|
||||||
@@ -505,7 +504,7 @@ function handleNoExecute() {
|
|||||||
adviceNoExecute({ adviceExecuteDetailList: list }).then((res) => {
|
adviceNoExecute({ adviceExecuteDetailList: list }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '操作成功');
|
proxy.$modal.msgSuccess(res.msg || '操作成功');
|
||||||
handleGetPrescription(true);
|
handleGetPrescription();
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '操作失败');
|
proxy.$modal.msgError(res.msg || '操作失败');
|
||||||
}
|
}
|
||||||
@@ -544,7 +543,7 @@ function handleCancel() {
|
|||||||
adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => {
|
adviceCancel({ adviceExecuteDetailList: producerIds }).then((res) => {
|
||||||
if (res.code == 200) {
|
if (res.code == 200) {
|
||||||
proxy.$modal.msgSuccess(res.msg || '取消执行成功');
|
proxy.$modal.msgSuccess(res.msg || '取消执行成功');
|
||||||
handleGetPrescription(true);
|
handleGetPrescription();
|
||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError(res.msg || '取消执行失败');
|
proxy.$modal.msgError(res.msg || '取消执行失败');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<el-radio-group v-model="type" class="ml20" @change="handleRadioChange">
|
<el-radio-group v-model="type" class="ml20" @change="handleRadioChange">
|
||||||
<el-radio :label="null">全部</el-radio>
|
<el-radio :label="1">全部</el-radio>
|
||||||
<el-radio :label="1">长期</el-radio>
|
<el-radio :label="2">长期</el-radio>
|
||||||
<el-radio :label="2">临时</el-radio>
|
<el-radio :label="3">临时</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-button class="ml20" type="primary" plain @click="handleGetPrescription">
|
<el-button class="ml20" type="primary" plain @click="handleGetPrescription">
|
||||||
查询
|
查询
|
||||||
@@ -159,7 +159,7 @@ import {formatDateStr} from '@/utils/index';
|
|||||||
const activeNames = ref([]);
|
const activeNames = ref([]);
|
||||||
const prescriptionList = ref([]);
|
const prescriptionList = ref([]);
|
||||||
const deadline = ref(formatDateStr(new Date(), 'YYYY-MM-DD') + ' 23:59:59');
|
const deadline = ref(formatDateStr(new Date(), 'YYYY-MM-DD') + ' 23:59:59');
|
||||||
const type = ref(null);
|
const type = ref(1);
|
||||||
const { proxy } = getCurrentInstance();
|
const { proxy } = getCurrentInstance();
|
||||||
const loading = ref(false);
|
const loading = ref(false);
|
||||||
const chooseAll = ref(false);
|
const chooseAll = ref(false);
|
||||||
@@ -181,7 +181,7 @@ function handleGetPrescription() {
|
|||||||
getPrescriptionList({
|
getPrescriptionList({
|
||||||
encounterIds: encounterIds,
|
encounterIds: encounterIds,
|
||||||
requestStatus: props.requestStatus,
|
requestStatus: props.requestStatus,
|
||||||
...(type.value != null ? { therapyEnum: type.value } : {}),
|
...(type.value !== undefined ? { therapyEnum: type.value } : {}),
|
||||||
pageSize: 10000,
|
pageSize: 10000,
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
|
|||||||
@@ -744,7 +744,11 @@ function handleSubmitApproval() {
|
|||||||
} else {
|
} else {
|
||||||
submitApproval(receiptHeaderForm.busNo).then((response) => {
|
submitApproval(receiptHeaderForm.busNo).then((response) => {
|
||||||
proxy.$modal.msgSuccess('提交审批成功');
|
proxy.$modal.msgSuccess('提交审批成功');
|
||||||
|
// proxy.$tab.closePage(route).then(({ visitedViews }) => { // 关闭当前页
|
||||||
|
// toLastView(visitedViews, route)
|
||||||
|
// })
|
||||||
tagsViewStore.delView(router.currentRoute.value);
|
tagsViewStore.delView(router.currentRoute.value);
|
||||||
|
// 跳转到调拨管理页面
|
||||||
router.replace({ path: 'transferManagentList' });
|
router.replace({ path: 'transferManagentList' });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -867,6 +871,7 @@ function handleUnitCodeChange(row, index, value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function handleItemQuantityChange(row, value) {
|
function handleItemQuantityChange(row, value) {
|
||||||
|
debugger;
|
||||||
let quantityTemp = ''; // 转换成小单位的临时变量 做校验
|
let quantityTemp = ''; // 转换成小单位的临时变量 做校验
|
||||||
// 大单位情况
|
// 大单位情况
|
||||||
if (row.unitCodeMap[row.unitCode] == 'unit') {
|
if (row.unitCodeMap[row.unitCode] == 'unit') {
|
||||||
@@ -877,6 +882,12 @@ function handleItemQuantityChange(row, value) {
|
|||||||
row.itemQuantity = value;
|
row.itemQuantity = value;
|
||||||
quantityTemp = value;
|
quantityTemp = value;
|
||||||
}
|
}
|
||||||
|
if (row.totalSourceQuantity < quantityTemp) {
|
||||||
|
proxy.$modal.msgWarning('调拨数量不可超出源库存数量');
|
||||||
|
row.itemQuantity = 0;
|
||||||
|
row.itemQuantityDisplay = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2);
|
row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2);
|
||||||
// 更新总数据中对应的记录
|
// 更新总数据中对应的记录
|
||||||
const totalIndex = totalIncentoryInfoList.value.findIndex((item) => item.id === row.id);
|
const totalIndex = totalIncentoryInfoList.value.findIndex((item) => item.id === row.id);
|
||||||
@@ -907,12 +918,11 @@ function remakeBlur(row, index) {
|
|||||||
editBatchTransfer(index);
|
editBatchTransfer(index);
|
||||||
}
|
}
|
||||||
function handleSave() {
|
function handleSave() {
|
||||||
// 校验单价
|
const invalidRow = totalIncentoryInfoList.value.find(
|
||||||
const invalidPriceRow = totalIncentoryInfoList.value.find(
|
|
||||||
(row) => !row.price || row.price <= 0
|
(row) => !row.price || row.price <= 0
|
||||||
);
|
);
|
||||||
if (invalidPriceRow) {
|
if (invalidRow) {
|
||||||
proxy.$modal.msgError('调拨单价不能为空或为0,请检查!');
|
proxy.$message.warning('调拨单价不能为空或为0,请检查!');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
addTransferProductBatch(totalIncentoryInfoList.value).then((res) => {
|
addTransferProductBatch(totalIncentoryInfoList.value).then((res) => {
|
||||||
|
|||||||
@@ -970,6 +970,12 @@ function handleItemQuantityChange(row, value) {
|
|||||||
row.itemQuantity = value;
|
row.itemQuantity = value;
|
||||||
quantityTemp = value;
|
quantityTemp = value;
|
||||||
}
|
}
|
||||||
|
if (row.totalSourceQuantity < quantityTemp) {
|
||||||
|
proxy.$modal.msgWarning('调拨数量不可超出源库存数量');
|
||||||
|
row.itemQuantity = 0;
|
||||||
|
row.itemQuantityDisplay = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2);
|
row.totalPrice = ((row.price * quantityTemp) / row.partPercent).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1016,7 +1022,11 @@ function handleSubmitApproval() {
|
|||||||
} else {
|
} else {
|
||||||
submitApproval(receiptHeaderForm.busNo).then((response) => {
|
submitApproval(receiptHeaderForm.busNo).then((response) => {
|
||||||
proxy.$modal.msgSuccess('提交审批成功');
|
proxy.$modal.msgSuccess('提交审批成功');
|
||||||
|
// proxy.$tab.closePage(route).then(({ visitedViews }) => { // 关闭当前页
|
||||||
|
// toLastView(visitedViews, route)
|
||||||
|
// })
|
||||||
tagsViewStore.delView(router.currentRoute.value);
|
tagsViewStore.delView(router.currentRoute.value);
|
||||||
|
// 跳转到调拨管理页面
|
||||||
router.replace({ path: 'transferManagentList' });
|
router.replace({ path: 'transferManagentList' });
|
||||||
store.clearCurrentDataDB();
|
store.clearCurrentDataDB();
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -829,7 +829,7 @@
|
|||||||
</el-descriptions>
|
</el-descriptions>
|
||||||
</div>
|
</div>
|
||||||
<div style="padding: 10px">
|
<div style="padding: 10px">
|
||||||
<prescriptionlist v-if="showChargeDialog" :patientInfo="chargePatientInfo" ref="prescriptionRef" />
|
<prescriptionlist :patientInfo="chargePatientInfo" ref="prescriptionRef" />
|
||||||
<div class="overlay" v-if="disabled"></div>
|
<div class="overlay" v-if="disabled"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1136,14 +1136,12 @@ function loadDeptList() {
|
|||||||
const tree = res.data?.records || res.data || []
|
const tree = res.data?.records || res.data || []
|
||||||
deptList.value = flattenOrgTree(tree)
|
deptList.value = flattenOrgTree(tree)
|
||||||
} else {
|
} else {
|
||||||
// 权限不足时静默降级,不弹窗阻断(Bug #441)
|
proxy.$modal.msgError('获取科室列表失败')
|
||||||
console.warn('科室列表加载失败(可能无权限):', res.message || res.code)
|
|
||||||
deptList.value = []
|
deptList.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// 网络错误或权限拒绝:静默降级
|
proxy.$modal.msgError('获取科室列表失败')
|
||||||
console.warn('科室列表加载失败:', error?.message || error)
|
|
||||||
deptList.value = []
|
deptList.value = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1156,14 +1154,12 @@ function loadDoctorList() {
|
|||||||
const records = res.data?.records || []
|
const records = res.data?.records || []
|
||||||
doctorList.value = records.map(mapPractitionerToOption).filter(it => it.code && it.name)
|
doctorList.value = records.map(mapPractitionerToOption).filter(it => it.code && it.name)
|
||||||
} else {
|
} else {
|
||||||
// 权限不足时静默降级,不弹窗阻断(Bug #441)
|
proxy.$modal.msgError('获取医生列表失败')
|
||||||
console.warn('医生列表加载失败(可能无权限):', res.message || res.code)
|
|
||||||
doctorList.value = []
|
doctorList.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// 网络错误或权限拒绝:静默降级
|
proxy.$modal.msgError('获取医生列表失败')
|
||||||
console.warn('医生列表加载失败:', error?.message || error)
|
|
||||||
doctorList.value = []
|
doctorList.value = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1176,14 +1172,12 @@ function loadNurseList() {
|
|||||||
const records = res.data?.records || []
|
const records = res.data?.records || []
|
||||||
nurseList.value = records.map(mapPractitionerToOption).filter(it => it.code && it.name)
|
nurseList.value = records.map(mapPractitionerToOption).filter(it => it.code && it.name)
|
||||||
} else {
|
} else {
|
||||||
// 权限不足时静默降级,不弹窗阻断(Bug #441)
|
proxy.$modal.msgError('获取护士列表失败')
|
||||||
console.warn('护士列表加载失败(可能无权限):', res.message || res.code)
|
|
||||||
nurseList.value = []
|
nurseList.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// 网络错误或权限拒绝:静默降级
|
proxy.$modal.msgError('获取护士列表失败')
|
||||||
console.warn('护士列表加载失败:', error?.message || error)
|
|
||||||
nurseList.value = []
|
nurseList.value = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1196,14 +1190,12 @@ function loadOperatingRoomList() {
|
|||||||
const records = res.data?.records || []
|
const records = res.data?.records || []
|
||||||
operatingRoomList.value = records.map(mapOperatingRoomToOption).filter(it => it.roomCode)
|
operatingRoomList.value = records.map(mapOperatingRoomToOption).filter(it => it.roomCode)
|
||||||
} else {
|
} else {
|
||||||
// 权限不足时静默降级,不弹窗阻断(Bug #441)
|
proxy.$modal.msgError('获取手术室列表失败')
|
||||||
console.warn('手术室列表加载失败(可能无权限):', res.message || res.code)
|
|
||||||
operatingRoomList.value = []
|
operatingRoomList.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// 网络错误或权限拒绝:静默降级
|
proxy.$modal.msgError('获取手术室列表失败')
|
||||||
console.warn('手术室列表加载失败:', error?.message || error)
|
|
||||||
operatingRoomList.value = []
|
operatingRoomList.value = []
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1412,10 +1404,6 @@ async function handleChargeCharge(row) {
|
|||||||
|
|
||||||
// 关闭计费弹窗
|
// 关闭计费弹窗
|
||||||
function closeChargeDialog() {
|
function closeChargeDialog() {
|
||||||
// 先关闭 prescriptionlist 内所有已打开的项目字典 popover
|
|
||||||
if (prescriptionRef.value && prescriptionRef.value.closeAllPopovers) {
|
|
||||||
prescriptionRef.value.closeAllPopovers()
|
|
||||||
}
|
|
||||||
showChargeDialog.value = false
|
showChargeDialog.value = false
|
||||||
chargePatientInfo.value = {}
|
chargePatientInfo.value = {}
|
||||||
chargeSurgeryInfo.value = {}
|
chargeSurgeryInfo.value = {}
|
||||||
@@ -1922,7 +1910,6 @@ function resetForm() {
|
|||||||
allergyRemark: undefined,
|
allergyRemark: undefined,
|
||||||
surgeryNature: undefined,
|
surgeryNature: undefined,
|
||||||
surgerySite: undefined,
|
surgerySite: undefined,
|
||||||
incisionType: undefined,
|
|
||||||
admissionTime: undefined,
|
admissionTime: undefined,
|
||||||
entryTime: undefined,
|
entryTime: undefined,
|
||||||
roomCode: undefined,
|
roomCode: undefined,
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
-- Bug #462: 诊疗目录编辑弹窗中"所需标本"下拉框数据加载失败
|
|
||||||
-- 根因: sys_dict_type 表中缺少 specimen_code 字典类型,sys_dict_data 表中缺少对应数据
|
|
||||||
-- 修复: 插入字典类型及7条标本数据
|
|
||||||
|
|
||||||
-- 插入字典类型
|
|
||||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
|
||||||
VALUES ('标本类型', 'specimen_code', '0', 'admin', NOW(), '诊疗项目所需标本类型字典');
|
|
||||||
|
|
||||||
-- 插入标本数据
|
|
||||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, status, create_by, create_time, remark)
|
|
||||||
VALUES
|
|
||||||
(1, '血液', '1', 'specimen_code', '0', 'admin', NOW(), '血液标本'),
|
|
||||||
(2, '尿液', '2', 'specimen_code', '0', 'admin', NOW(), '尿液标本'),
|
|
||||||
(3, '粪便', '3', 'specimen_code', '0', 'admin', NOW(), '粪便标本'),
|
|
||||||
(4, '呼吸道', '4', 'specimen_code', '0', 'admin', NOW(), '呼吸道标本'),
|
|
||||||
(5, '无菌体液', '5', 'specimen_code', '0', 'admin', NOW(), '无菌体液标本'),
|
|
||||||
(6, '生殖道', '6', 'specimen_code', '0', 'admin', NOW(), '生殖道标本'),
|
|
||||||
(7, '其他', '7', 'specimen_code', '0', 'admin', NOW(), '其他标本');
|
|
||||||
Reference in New Issue
Block a user