Compare commits
12 Commits
zhaoyun
...
develop-cl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5132de3680 | ||
| 232577caaa | |||
| 926c1f68e3 | |||
| f11fa023c4 | |||
| 1ac2252c34 | |||
| 2b2fcc0f20 | |||
| 72b0040921 | |||
| e439cf46cf | |||
| 24ad69dfed | |||
| 310847eae4 | |||
| fd0fe29e54 | |||
| 1406bbfcee |
2
his-repo
2
his-repo
Submodule his-repo updated: 5de8a22418...ea1271db8a
@@ -77,8 +77,10 @@ public class DoctorStationAdviceController {
|
||||
*/
|
||||
@PostMapping(value = "/save-advice")
|
||||
@RepeatSubmit(interval = 5000, message = "请勿重复提交医嘱,请稍候再试")
|
||||
public R<?> saveAdvice(@RequestBody AdviceSaveParam adviceSaveParam) {
|
||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, AdviceOpType.SAVE_ADVICE.getCode());
|
||||
public R<?> saveAdvice(@RequestBody AdviceSaveParam adviceSaveParam,
|
||||
@RequestParam(required = false, defaultValue = "1") String adviceOpType) {
|
||||
// 🔧 Bug #445 修复:使用前端传入的 adviceOpType 参数(1=保存草稿,2=签发),而非硬编码
|
||||
return iDoctorStationAdviceAppService.saveAdvice(adviceSaveParam, adviceOpType);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -178,11 +178,24 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
inpatientAdviceParam.setEncounterIds(null);
|
||||
Integer exeStatus = inpatientAdviceParam.getExeStatus();
|
||||
inpatientAdviceParam.setExeStatus(null);
|
||||
// requestStatus由前端tab传入,通过QueryWrapper自动添加到SQL外层WHERE过滤
|
||||
// 提取requestStatus手动处理,支持COMPLETED(3)和CHECK_VERIFIED(10)同时查询
|
||||
Integer requestStatus = inpatientAdviceParam.getRequestStatus();
|
||||
inpatientAdviceParam.setRequestStatus(null);
|
||||
// 构建查询条件
|
||||
QueryWrapper<InpatientAdviceParam> queryWrapper
|
||||
= HisQueryUtils.buildQueryWrapper(inpatientAdviceParam, null, null, null);
|
||||
|
||||
// 手动拼接requestStatus条件:COMPLETED(3)时同时包含CHECK_VERIFIED(10)
|
||||
// UNION查询外层列名为request_status(T1.status_enum AS request_status),不是status_enum
|
||||
if (requestStatus != null) {
|
||||
if (RequestStatus.COMPLETED.getValue().equals(requestStatus)) {
|
||||
queryWrapper.in("request_status",
|
||||
RequestStatus.COMPLETED.getValue(), RequestStatus.CHECK_VERIFIED.getValue());
|
||||
} else {
|
||||
queryWrapper.eq("request_status", requestStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// 手动拼接住院患者id条件
|
||||
if (encounterIds != null && !encounterIds.isEmpty()) {
|
||||
List<Long> encounterIdList
|
||||
@@ -315,19 +328,29 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
|
||||
Date checkDate = new Date();
|
||||
if (!serviceRequestList.isEmpty()) {
|
||||
// 更新服务请求状态已完成
|
||||
serviceRequestService.updateCompleteRequestStatus(
|
||||
serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList(), practitionerId, checkDate);
|
||||
List<ServiceRequest> serviceRequests = serviceRequestService
|
||||
.listByIds(serviceRequestList.stream().map(PerformInfoDto::getRequestId).collect(Collectors.toList()));
|
||||
for (ServiceRequest serviceRequest : serviceRequests) {
|
||||
// 判断医嘱类型
|
||||
List<Long> serviceReqIds = serviceRequestList.stream().map(PerformInfoDto::getRequestId).toList();
|
||||
// 先查询服务请求,按 categoryEnum 分流:检查类(23)走 CHECK_VERIFIED,其余走 COMPLETED
|
||||
List<ServiceRequest> allServiceRequests = serviceRequestService.listByIds(serviceReqIds);
|
||||
List<Long> checkReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
List<Long> otherReqIds = allServiceRequests.stream()
|
||||
.filter(sr -> !ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
// 检查类 → 已校对(CHECK_VERIFIED=10)
|
||||
if (!checkReqIds.isEmpty()) {
|
||||
serviceRequestService.updateCheckVerifiedStatus(checkReqIds, practitionerId, checkDate);
|
||||
}
|
||||
// 其他类 → 已完成(COMPLETED=3)
|
||||
if (!otherReqIds.isEmpty()) {
|
||||
serviceRequestService.updateCompleteRequestStatus(otherReqIds, practitionerId, checkDate);
|
||||
}
|
||||
// 处理转科/出院等特殊医嘱
|
||||
for (ServiceRequest serviceRequest : allServiceRequests) {
|
||||
if (ActivityDefCategory.TRANSFER.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
// 更新患者状态 待转科
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.PENDING_TRANSFER.getValue());
|
||||
} else if (ActivityDefCategory.DISCHARGE.getValue().equals(serviceRequest.getCategoryEnum())) {
|
||||
// 更新患者状态 待出院
|
||||
encounterService.updateEncounterStatus(serviceRequest.getEncounterId(),
|
||||
EncounterZyStatus.AWAITING_DISCHARGE.getValue());
|
||||
}
|
||||
@@ -442,6 +465,15 @@ public class AdviceProcessAppServiceImpl implements IAdviceProcessAppService {
|
||||
List<ServiceRequestUseExe> actUseExeList = this.assemblyActivity(activityList);
|
||||
// 处理诊疗执行
|
||||
this.exeActivity(actUseExeList, exeDate);
|
||||
// 检查类医嘱执行后,状态改为"待接收"(PENDING_RECEIVE=11)
|
||||
List<Long> actReqIds = activityList.stream().map(AdviceExecuteDetailParam::getRequestId).toList();
|
||||
List<ServiceRequest> executedReqs = serviceRequestService.listByIds(actReqIds);
|
||||
List<Long> checkReqIds = executedReqs.stream()
|
||||
.filter(sr -> ActivityDefCategory.TEST.getValue().equals(sr.getCategoryEnum()))
|
||||
.map(ServiceRequest::getId).toList();
|
||||
if (!checkReqIds.isEmpty()) {
|
||||
serviceRequestService.updatePendingReceiveStatus(checkReqIds);
|
||||
}
|
||||
}
|
||||
|
||||
return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[]{"医嘱执行"}));
|
||||
|
||||
@@ -47,10 +47,19 @@
|
||||
) THEN 5
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
INNER JOIN lab_specimen ls ON ls.service_id = ws.id
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ls.collection_status_enum >= 1
|
||||
AND ws.status_enum = 12
|
||||
) THEN 4
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 11
|
||||
) THEN 3
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
AND ws.status_enum = 10
|
||||
) THEN 2
|
||||
WHEN EXISTS (
|
||||
SELECT 1 FROM wor_service_request ws
|
||||
WHERE ws.prescription_no = drf.prescription_no AND ws.delete_flag = '0'
|
||||
|
||||
@@ -57,7 +57,22 @@ public enum RequestStatus implements HisEnumInterface {
|
||||
/**
|
||||
* 未知
|
||||
*/
|
||||
UNKNOWN(9, "unknown", "未知");
|
||||
UNKNOWN(9, "unknown", "未知"),
|
||||
|
||||
/**
|
||||
* 已校对(检查申请:护士校对通过)
|
||||
*/
|
||||
CHECK_VERIFIED(10, "check_verified", "已校对"),
|
||||
|
||||
/**
|
||||
* 待接收(检查申请:等待医技科室接单)
|
||||
*/
|
||||
PENDING_RECEIVE(11, "pending_receive", "待接收"),
|
||||
|
||||
/**
|
||||
* 已接收(检查申请:医技科室已接单)
|
||||
*/
|
||||
CHECK_RECEIVED(12, "check_received", "已接收");
|
||||
|
||||
@EnumValue
|
||||
private final Integer value;
|
||||
|
||||
@@ -39,6 +39,22 @@ public interface IServiceRequestService extends IService<ServiceRequest> {
|
||||
*/
|
||||
void updateCompleteRequestStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate);
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:已校对(护士校对检查申请后状态为CHECK_VERIFIED,而非COMPLETED)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
* @param practitionerId 校对人
|
||||
* @param checkDate 校对时间
|
||||
*/
|
||||
void updateCheckVerifiedStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate);
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:待接收(护士执行检查申请后状态为PENDING_RECEIVE)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
void updatePendingReceiveStatus(List<Long> serReqIdList);
|
||||
|
||||
/**
|
||||
* 获取执行过的诊疗数据
|
||||
*
|
||||
|
||||
@@ -66,6 +66,31 @@ public class ServiceRequestServiceImpl extends ServiceImpl<ServiceRequestMapper,
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:已校对(护士校对检查申请后状态为CHECK_VERIFIED,而非COMPLETED)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
@Override
|
||||
public void updateCheckVerifiedStatus(List<Long> serReqIdList, Long practitionerId, Date checkDate) {
|
||||
baseMapper.update(new ServiceRequest().setStatusEnum(RequestStatus.CHECK_VERIFIED.getValue())
|
||||
.setPerformerCheckId(SecurityUtils.getLoginUser().getPractitionerId()).setCheckTime(DateUtils.getNowDate()),
|
||||
new LambdaUpdateWrapper<ServiceRequest>().in(ServiceRequest::getId, serReqIdList)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新检查申请状态:待接收(护士执行检查申请后状态为PENDING_RECEIVE)
|
||||
*
|
||||
* @param serReqIdList 服务请求id列表
|
||||
*/
|
||||
@Override
|
||||
public void updatePendingReceiveStatus(List<Long> serReqIdList) {
|
||||
baseMapper.update(new ServiceRequest().setStatusEnum(RequestStatus.PENDING_RECEIVE.getValue()),
|
||||
new LambdaUpdateWrapper<ServiceRequest>().in(ServiceRequest::getId, serReqIdList)
|
||||
.eq(ServiceRequest::getDeleteFlag, DelFlag.NO.getCode()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行过的诊疗数据
|
||||
*
|
||||
|
||||
@@ -34,6 +34,12 @@ export const RequestStatus = {
|
||||
ENDED: 7,
|
||||
/** 未知 */
|
||||
UNKNOWN: 9,
|
||||
/** 已校对(检查申请:护士校对通过) */
|
||||
CHECK_VERIFIED: 10,
|
||||
/** 待接收(检查申请:等待医技科室接单) */
|
||||
PENDING_RECEIVE: 11,
|
||||
/** 已接收(检查申请:医技科室已接单) */
|
||||
CHECK_RECEIVED: 12,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -48,6 +54,9 @@ export const RequestStatusDescriptions = {
|
||||
6: '停嘱',
|
||||
7: '不执行',
|
||||
9: '未知',
|
||||
10: '已校对',
|
||||
11: '待接收',
|
||||
12: '已接收',
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,9 +25,9 @@ export function getAdviceBaseInfo(queryParams) {
|
||||
/**
|
||||
* 保存处方(单条)
|
||||
* @param {Object} data - 处方数据
|
||||
* @param {String} adviceOpType - 医嘱操作类型:'0'=保存草稿,'1'=签发医嘱
|
||||
* @param {String} adviceOpType - 医嘱操作类型:'1'=保存草稿(SAVE_ADVICE),'2'=签发(SIGN_ADVICE)
|
||||
*/
|
||||
export function savePrescription(data, adviceOpType = '0') {
|
||||
export function savePrescription(data, adviceOpType = '1') {
|
||||
return request({
|
||||
url: '/doctor-station/advice/save-advice',
|
||||
method: 'post',
|
||||
|
||||
@@ -1174,7 +1174,9 @@ function handleSaveSign(row, index) {
|
||||
cleanRow.sourceBillNo = props.patientInfo.sourceBillNo;
|
||||
}
|
||||
// 🔧 门诊计费场景:保存为草稿,让药品出现在临时医嘱弹窗"已引用计费药品(待生成医嘱)"中
|
||||
const adviceOpType = props.patientInfo.sourceBillNo ? '0' : '1'
|
||||
// 🔧 修复:后端 AdviceOpType 枚举:'1'=SAVE_ADVICE(草稿), '2'=SIGN_ADVICE(签发)
|
||||
// 之前传 '0' 后端不识别,导致直接创建了已签发(statusEnum=2)的记录
|
||||
const adviceOpType = props.patientInfo.sourceBillNo ? '1' : '1'
|
||||
savePrescription({ adviceSaveList: [cleanRow] }, adviceOpType).then((res) => {
|
||||
if (res.code === 200) {
|
||||
proxy.$modal.msgSuccess('保存成功');
|
||||
|
||||
@@ -1,30 +1,30 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
ref="queryRef"
|
||||
:model="queryParams"
|
||||
:inline="true"
|
||||
label-width="90px"
|
||||
>
|
||||
<el-form-item label="查询日期:">
|
||||
<el-form-item label="查询日期">
|
||||
<el-date-picker
|
||||
v-model="queryTime"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 300px; margin-right: 20px"
|
||||
@change="getValue"
|
||||
style="width: 300px"
|
||||
value-format="YYYY-MM-DD"
|
||||
@change="getValue"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="费用性质:">
|
||||
<el-form-item label="费用性质">
|
||||
<el-select
|
||||
v-model="contractNo"
|
||||
placeholder="费用性质"
|
||||
clearable
|
||||
style="width: 160px"
|
||||
@change="getValue"
|
||||
style="width: 150px; margin-right: 30px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in contractList"
|
||||
@@ -33,88 +33,241 @@
|
||||
:value="item.busNo"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" plain icon="Search" @click="getValue">查询</el-button>
|
||||
<el-button type="primary" plain icon="Printer" @click="print">打印</el-button>
|
||||
</el-form-item>
|
||||
<el-form-item class="search-buttons">
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Search"
|
||||
@click="getValue"
|
||||
>
|
||||
查询
|
||||
</el-button>
|
||||
<el-button
|
||||
type="primary"
|
||||
plain
|
||||
icon="Printer"
|
||||
@click="print"
|
||||
>
|
||||
打印
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<div v-loading="loading" class="report-container">
|
||||
<div class="report-title">门诊收费日结单</div>
|
||||
<div class="report-section">
|
||||
<div class="section-title">基本信息</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">经办人姓名:</span><span class="value">{{ userStore.nickName }}</span></div>
|
||||
<div class="report-item"><span class="label">科室:</span><span class="value">{{ userStore.orgName }}</span></div>
|
||||
<div class="report-item span-2"><span class="label">时间:</span><span class="value">{{ queryTime[0] + '~' + queryTime[1] }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="report-section">
|
||||
<div class="section-title">收费汇总</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">实际现金收入:</span><span class="value">{{ formatValue(reportValue.cashSum) }}</span></div>
|
||||
<div class="report-item"><span class="label">现金:</span><span class="value">{{ formatValue(reportValue.rmbCashSum) }}</span></div>
|
||||
<div class="report-item"><span class="label">微信:</span><span class="value">{{ formatValue(reportValue.vxCashSum) }}</span></div>
|
||||
<div class="report-item"><span class="label">支付宝:</span><span class="value">{{ formatValue(reportValue.aliCashSum) }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="report-section">
|
||||
<div class="section-title">医保支付</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">统筹支付:</span><span class="value">{{ formatValue(reportValue.tcSum) }}</span></div>
|
||||
<div class="report-item"><span class="label">账户支付:</span><span class="value">{{ formatValue(reportValue.zhSum) }}</span></div>
|
||||
<div class="report-item span-2"><span class="label">基金支付总额:</span><span class="value">{{ formatValue(reportValue.fundSum) }}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="divider"></div>
|
||||
<div class="report-section">
|
||||
<div class="section-title">费用明细</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">诊查费:</span><span class="value">{{ formatValue(reportValue.DIAGNOSTIC_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">检查费:</span><span class="value">{{ formatValue(reportValue.CHECK_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">化验费:</span><span class="value">{{ formatValue(reportValue.DIAGNOSTIC_TEST_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">治疗费:</span><span class="value">{{ formatValue(reportValue.MEDICAL_EXPENSE_FEE) }}</span></div>
|
||||
</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">西药费:</span><span class="value">{{ formatValue(reportValue.WEST_MEDICINE) }}</span></div>
|
||||
<div class="report-item"><span class="label">中药饮片费:</span><span class="value">{{ formatValue(reportValue.CHINESE_MEDICINE_SLICES_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">中成药费:</span><span class="value">{{ formatValue(reportValue.CHINESE_MEDICINE_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">卫生材料费:</span><span class="value">{{ formatValue(reportValue.SANITARY_MATERIALS_FEE) }}</span></div>
|
||||
</div>
|
||||
<div class="report-row cols-4">
|
||||
<div class="report-item"><span class="label">诊疗费:</span><span class="value">{{ formatValue(reportValue.GENERAL_CONSULTATION_FEE) }}</span></div>
|
||||
<div class="report-item"><span class="label">挂号费:</span><span class="value">{{ formatValue(reportValue.REGISTRATION_FEE) }}</span></div>
|
||||
<div class="report-item span-2"><span class="label">其他费用:</span><span class="value">{{ formatValue(reportValue.OTHER_FEE) }}</span></div>
|
||||
</div>
|
||||
<div
|
||||
v-loading="loading"
|
||||
class="report-container"
|
||||
>
|
||||
<div class="report-title">
|
||||
门诊收费日结单
|
||||
</div>
|
||||
|
||||
<el-row :gutter="20" class="info-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="info-cell">
|
||||
<span class="info-label">经办人姓名:</span>
|
||||
<span class="info-value">{{ userStore.nickName || '全部' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="info-cell">
|
||||
<span class="info-label">科室:</span>
|
||||
<span class="info-value">{{ userStore.orgName || '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="info-cell">
|
||||
<span class="info-label">机构:</span>
|
||||
<span class="info-value">{{ userStore.hospitalName || '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="info-cell">
|
||||
<span class="info-label">时间:</span>
|
||||
<span class="info-value">{{ queryTime && queryTime.length === 2 ? queryTime[0] + ' ~ ' + queryTime[1] : '-' }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<div class="section-title">收入汇总</div>
|
||||
<el-row :gutter="16" class="data-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">总收入:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.cashSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">现金:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.rmbCashSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">微信:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.vxCashSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">支付宝:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.aliCashSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<div class="section-title">医保支付</div>
|
||||
<el-row :gutter="16" class="data-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">统筹支付:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.tcSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">账户支付:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.zhSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">基金支付总额:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.fundSum) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">医保统筹+账户:</span>
|
||||
<span class="data-value">{{ formatValue(Number(reportValue.zhSum || 0) + Number(reportValue.fundSum || 0)) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-divider />
|
||||
|
||||
<div class="section-title">费用明细</div>
|
||||
<el-row :gutter="16" class="data-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">诊查费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.DIAGNOSTIC_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">检查费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.CHECK_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">化验费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.DIAGNOSTIC_TEST_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">治疗费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.MEDICAL_EXPENSE_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="data-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">西药费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.WEST_MEDICINE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">中药饮片费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.CHINESE_MEDICINE_SLICES_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">中成药费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.CHINESE_MEDICINE_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">卫生材料费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.SANITARY_MATERIALS_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="data-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">普通挂号费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.GENERAL_CONSULTATION_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">挂号费:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.REGISTRATION_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">其他费用:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.OTHER_FEE) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell">
|
||||
<span class="data-label">退费金额:</span>
|
||||
<span class="data-value">{{ formatValue(reportValue.returnFee) }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="16" class="data-row summary-row">
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell summary-cell">
|
||||
<span class="data-label summary-label">费用总额:</span>
|
||||
<span class="data-value value-highlight">{{ totalFeeAmount }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :xs="24" :sm="12" :md="6">
|
||||
<div class="data-cell summary-cell">
|
||||
<span class="data-label summary-label">医保报销:</span>
|
||||
<span class="data-value value-highlight">{{ insuranceReimbursement }}</span>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="dayEnd">
|
||||
import {getContractList, getRreportReturnIssue, getTotal} from './component/api';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import {formatDateStr} from '@/utils/index';
|
||||
<script setup name="DayEnd">
|
||||
import { ref, reactive, toRefs, getCurrentInstance, computed } from 'vue';
|
||||
import Decimal from 'decimal.js';
|
||||
import { getTotal, getContractList, getRreportReturnIssue } from './component/api';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import { formatDateStr } from '@/utils/index';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const purchaseinventoryRef = ref(null);
|
||||
const purchaseinventoryList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const reportValue = ref({});
|
||||
const total = ref(0);
|
||||
const loading = ref(false);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref('');
|
||||
const contractList = ref(undefined);
|
||||
const reportValue = ref({});
|
||||
const occurrenceTime = ref([]);
|
||||
const contractList = ref([]);
|
||||
const queryTime = ref([
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
@@ -260,93 +413,173 @@ function formatValue(value) {
|
||||
return value == null || value == undefined ? '0.00 元' : value.toFixed(2) + ' 元';
|
||||
}
|
||||
|
||||
// 计算属性:费用总额
|
||||
const totalFeeAmount = computed(() => {
|
||||
const v = reportValue.value;
|
||||
const sum =
|
||||
Number(v.DIAGNOSTIC_FEE || 0) +
|
||||
Number(v.CHECK_FEE || 0) +
|
||||
Number(v.DIAGNOSTIC_TEST_FEE || 0) +
|
||||
Number(v.MEDICAL_EXPENSE_FEE || 0) +
|
||||
Number(v.WEST_MEDICINE || 0) +
|
||||
Number(v.CHINESE_MEDICINE_SLICES_FEE || 0) +
|
||||
Number(v.CHINESE_MEDICINE_FEE || 0) +
|
||||
Number(v.GENERAL_CONSULTATION_FEE || 0) +
|
||||
Number(v.REGISTRATION_FEE || 0) +
|
||||
Number(v.OTHER_FEE || 0) +
|
||||
Number(v.SANITARY_MATERIALS_FEE || 0);
|
||||
return formatValue(sum);
|
||||
});
|
||||
|
||||
// 计算属性:医保报销(统筹+账户)
|
||||
const insuranceReimbursement = computed(() => {
|
||||
const v = reportValue.value;
|
||||
const sum = Number(v.tcSum || 0) + Number(v.zhSum || 0);
|
||||
return formatValue(sum);
|
||||
});
|
||||
|
||||
getList();
|
||||
getPharmacyCabinetLists();
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.report-container {
|
||||
width: 100%;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
padding: 24px 32px;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
|
||||
.app-container {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
.report-container {
|
||||
max-width: 1200px;
|
||||
margin: 16px auto;
|
||||
padding: 24px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
|
||||
.report-title {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.report-section {
|
||||
margin: 8px 0;
|
||||
}
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin: 0 0 20px;
|
||||
color: #303133;
|
||||
margin: 8px 0;
|
||||
padding-left: 8px;
|
||||
border-left: 3px solid #409eff;
|
||||
}
|
||||
.report-row {
|
||||
display: grid;
|
||||
margin: 12px 0;
|
||||
gap: 10px 16px;
|
||||
align-items: baseline;
|
||||
|
||||
.info-row {
|
||||
padding: 12px 0;
|
||||
}
|
||||
.cols-4 {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
.span-2 {
|
||||
grid-column: span 2;
|
||||
}
|
||||
.report-item {
|
||||
|
||||
.info-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
min-width: 0;
|
||||
padding: 6px 0;
|
||||
min-height: 32px;
|
||||
}
|
||||
.label {
|
||||
display: inline-block;
|
||||
width: 140px;
|
||||
flex-shrink: 0;
|
||||
color: #606266;
|
||||
|
||||
.info-label {
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
min-width: 80px;
|
||||
}
|
||||
|
||||
.info-value {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.data-row {
|
||||
padding: 4px 0;
|
||||
}
|
||||
|
||||
.data-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px 12px;
|
||||
margin-bottom: 4px;
|
||||
background: #fafafa;
|
||||
border-radius: 4px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.data-label {
|
||||
color: #606266;
|
||||
font-size: 13px;
|
||||
white-space: nowrap;
|
||||
min-width: 100px;
|
||||
text-align: right;
|
||||
padding-right: 8px;
|
||||
}
|
||||
|
||||
.data-value {
|
||||
color: #303133;
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
}
|
||||
.value {
|
||||
color: #303133;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
.value-highlight {
|
||||
color: #409eff;
|
||||
font-weight: 700;
|
||||
font-size: 15px;
|
||||
}
|
||||
.divider {
|
||||
height: 1px;
|
||||
background-color: #dcdfe6;
|
||||
margin: 16px 0;
|
||||
|
||||
.summary-row {
|
||||
margin-top: 8px;
|
||||
}
|
||||
@media screen and (max-width: 1200px) {
|
||||
.cols-4 {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
.span-2 {
|
||||
grid-column: span 2;
|
||||
}
|
||||
|
||||
.summary-cell {
|
||||
background: #ecf5ff;
|
||||
border: 1px solid #d9ecff;
|
||||
}
|
||||
@media screen and (max-width: 768px) {
|
||||
.cols-4 {
|
||||
grid-template-columns: 1fr;
|
||||
|
||||
.summary-label {
|
||||
font-weight: 600;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #409eff;
|
||||
padding: 8px 0 8px 12px;
|
||||
margin: 8px 0 4px;
|
||||
border-left: 3px solid #409eff;
|
||||
background: linear-gradient(90deg, rgba(64, 158, 255, 0.05) 0%, transparent 100%);
|
||||
}
|
||||
|
||||
.search-buttons {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.search-buttons .el-form-item__content {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
:deep(.el-divider--horizontal) {
|
||||
margin: 12px 0;
|
||||
}
|
||||
|
||||
.el-form--inline .el-form-item {
|
||||
margin-bottom: 12px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.data-label {
|
||||
min-width: 80px;
|
||||
text-align: left;
|
||||
padding-right: 4px;
|
||||
}
|
||||
.span-2 {
|
||||
grid-column: span 1;
|
||||
|
||||
.data-value {
|
||||
text-align: left;
|
||||
}
|
||||
.label {
|
||||
width: 100px;
|
||||
|
||||
.info-label {
|
||||
min-width: 70px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
352
openhis-ui-vue3/src/views/clinicmanagement/dayEnd/index.vue.orig
Executable file
352
openhis-ui-vue3/src/views/clinicmanagement/dayEnd/index.vue.orig
Executable file
@@ -0,0 +1,352 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
:model="queryParams"
|
||||
ref="queryRef"
|
||||
:inline="true"
|
||||
v-show="showSearch"
|
||||
label-width="90px"
|
||||
>
|
||||
<el-form-item label="查询日期:">
|
||||
<el-date-picker
|
||||
v-model="queryTime"
|
||||
type="daterange"
|
||||
start-placeholder="开始日期"
|
||||
end-placeholder="结束日期"
|
||||
style="width: 300px; margin-right: 20px"
|
||||
@change="getValue"
|
||||
value-format="YYYY-MM-DD"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="费用性质:">
|
||||
<el-select
|
||||
v-model="contractNo"
|
||||
placeholder="费用性质"
|
||||
clearable
|
||||
@change="getValue"
|
||||
style="width: 150px; margin-right: 30px"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in contractList"
|
||||
:key="item.busNo"
|
||||
:label="item.contractName"
|
||||
:value="item.busNo"
|
||||
/>
|
||||
</el-select>
|
||||
<el-button type="primary" plain icon="Search" @click="getValue">查询</el-button>
|
||||
<el-button type="primary" plain icon="Printer" @click="print">打印</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div v-loading="loading" style="width: 1300px">
|
||||
<div style="text-align: center">
|
||||
<h2>门诊收费日结单</h2>
|
||||
</div>
|
||||
<el-row
|
||||
:gutter="5"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="4">
|
||||
<span class="label">经办人姓名:</span>
|
||||
<span class="value">{{ userStore.nickName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<span class="label">科室:</span>
|
||||
<span class="value">{{ userStore.orgName }}</span>
|
||||
</el-col>
|
||||
<el-col :span="7">
|
||||
<span class="label">时间:</span>
|
||||
<span class="value">{{ queryTime[0] + '~' + queryTime[1] }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="divider"></div>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<span class="label">总收入:</span>
|
||||
<span class="value">{{ formatValue(reportValue.cashSum) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">现金:</span>
|
||||
<span class="value">{{ formatValue(reportValue.rmbCashSum) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">微信:</span>
|
||||
<span class="value">{{ formatValue(reportValue.vxCashSum) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">支付宝:</span>
|
||||
<span class="value">{{ formatValue(reportValue.aliCashSum) }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="divider"></div>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<span class="label">统筹支付:</span>
|
||||
<span class="value">{{ formatValue(reportValue.tcSum) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">账户支付:</span>
|
||||
<span class="value">{{ formatValue(reportValue.zhSum) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">基金支付总额:</span>
|
||||
<span class="value">{{ formatValue(reportValue.fundSum) }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="divider"></div>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<span class="label">诊查费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.DIAGNOSTIC_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">检查费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.CHECK_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">化验费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.DIAGNOSTIC_TEST_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">治疗费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.MEDICAL_EXPENSE_FEE) }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<span class="label">西药费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.WEST_MEDICINE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">中药饮片费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.CHINESE_MEDICINE_SLICES_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">中成药费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.CHINESE_MEDICINE_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">卫生材料费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.SANITARY_MATERIALS_FEE) }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
style="margin: 20px 0; display: flex; align-items: center; justify-content: flex-start; padding: 0 20px"
|
||||
>
|
||||
<el-col :span="5">
|
||||
<span class="label">诊疗费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.GENERAL_CONSULTATION_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">挂号费:</span>
|
||||
<span class="value">{{ formatValue(reportValue.REGISTRATION_FEE) }}</span>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span class="label">其他费用:</span>
|
||||
<span class="value">{{ formatValue(reportValue.OTHER_FEE) }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="dayEnd">
|
||||
import {getContractList, getRreportReturnIssue, getTotal} from './component/api';
|
||||
import useUserStore from '@/store/modules/user';
|
||||
import {formatDateStr} from '@/utils/index';
|
||||
import Decimal from 'decimal.js';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
const router = useRouter();
|
||||
const { proxy } = getCurrentInstance();
|
||||
|
||||
const purchaseinventoryRef = ref(null);
|
||||
const purchaseinventoryList = ref([]);
|
||||
const open = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
const title = ref('');
|
||||
const contractList = ref(undefined);
|
||||
const reportValue = ref({});
|
||||
const queryTime = ref([
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
formatDateStr(new Date(), 'YYYY-MM-DD'),
|
||||
]);
|
||||
const contractNo = ref('0000');
|
||||
|
||||
const data = reactive({
|
||||
queryParams: {
|
||||
form: {},
|
||||
pageNo: 1,
|
||||
pageSize: 10,
|
||||
searchKey: undefined,
|
||||
purposeLocationId: undefined,
|
||||
sourceLocationId: undefined,
|
||||
supplierId: undefined,
|
||||
approvalTimeSTime: undefined,
|
||||
approvalTimeETime: undefined,
|
||||
},
|
||||
rules: {},
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
getValue();
|
||||
function getValue() {
|
||||
loading.value = true;
|
||||
getTotal({
|
||||
contractNo: contractNo.value,
|
||||
startTime: queryTime.value[0] + ' 00:00:00',
|
||||
endTime: queryTime.value[1] + ' 23:59:59',
|
||||
entererId: userStore.practitionerId,
|
||||
}).then((res) => {
|
||||
loading.value = false;
|
||||
reportValue.value = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
getContract();
|
||||
function getContract() {
|
||||
getContractList().then((response) => {
|
||||
contractList.value = response.data;
|
||||
});
|
||||
}
|
||||
|
||||
function getPharmacyCabinetLists() {
|
||||
}
|
||||
/** 查询调拨管理项目列表 */
|
||||
function getList() {
|
||||
loading.value = true;
|
||||
getRreportReturnIssue(queryParams.value).then((res) => {
|
||||
loading.value = false;
|
||||
purchaseinventoryList.value = res.data.records;
|
||||
total.value = res.data.total;
|
||||
});
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
function handleQuery() {
|
||||
queryParams.value.approvalTimeSTime =
|
||||
occurrenceTime.value && occurrenceTime.value.length == 2
|
||||
? occurrenceTime.value[0] + ' 00:00:00'
|
||||
: '';
|
||||
queryParams.value.approvalTimeETime =
|
||||
occurrenceTime.value && occurrenceTime.value.length == 2
|
||||
? occurrenceTime.value[1] + ' 23:59:59'
|
||||
: '';
|
||||
queryParams.value.pageNo = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 清空条件按钮操作 */
|
||||
function handleClear() {
|
||||
queryParams.value.approvalTimeSTime = '';
|
||||
queryParams.value.approvalTimeETime = '';
|
||||
occurrenceTime.value = '';
|
||||
proxy.resetForm('queryRef');
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 选择条数 */
|
||||
function handleSelectionChange(selection) {
|
||||
ids.value = selection.map((item) => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 打印门诊日结 */
|
||||
async function print() {
|
||||
console.log(reportValue.value, '==reportValue.value==');
|
||||
const result = {
|
||||
data: [
|
||||
{
|
||||
...reportValue.value,
|
||||
nickName: userStore.nickName,
|
||||
orgName: userStore.orgName,
|
||||
fixmedinsName: userStore.hospitalName,
|
||||
queryTime: queryTime.value[0] + '~' + queryTime.value[1],
|
||||
zfAmount: new Decimal(reportValue.value.zhSum || 0).add(reportValue.value.fundSum || 0),
|
||||
feeAmount: new Decimal(reportValue.value.DIAGNOSTIC_FEE || 0)
|
||||
.add(reportValue.value.CHECK_FEE || 0)
|
||||
.add(reportValue.value.DIAGNOSTIC_TEST_FEE || 0)
|
||||
.add(reportValue.value.MEDICAL_EXPENSE_FEE || 0)
|
||||
.add(reportValue.value.WEST_MEDICINE || 0)
|
||||
.add(reportValue.value.CHINESE_MEDICINE_SLICES_FEE || 0)
|
||||
.add(reportValue.value.CHINESE_MEDICINE_FEE || 0)
|
||||
.add(reportValue.value.GENERAL_CONSULTATION_FEE || 0)
|
||||
.add(reportValue.value.REGISTRATION_FEE || 0)
|
||||
.add(reportValue.value.OTHER_FEE || 0)
|
||||
.add(reportValue.value.SANITARY_MATERIALS_FEE || 0),
|
||||
},
|
||||
],
|
||||
};
|
||||
console.log(result, '==result.data==');
|
||||
let jsonString = JSON.stringify(result, null, 2);
|
||||
console.log(jsonString, 'jsonstring');
|
||||
await CefSharp.BindObjectAsync('boundAsync');
|
||||
await boundAsync
|
||||
.printReport(getPrintFileName(contractNo.value), jsonString)
|
||||
.then((response) => {
|
||||
console.log(response, 'response');
|
||||
var res = JSON.parse(response);
|
||||
if (!res.IsSuccess) {
|
||||
proxy.$modal.msgError('调用打印插件失败:' + res.ErrorMessage);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
proxy.$modal.msgError('调用打印插件失败:' + error);
|
||||
});
|
||||
}
|
||||
|
||||
function getPrintFileName(value) {
|
||||
switch (value) {
|
||||
case '0000':
|
||||
return '门诊日结单(按登录角色查询)自费.grf';
|
||||
case '229900':
|
||||
return '门诊日结单(按登录角色查询)省医保.grf';
|
||||
case '220100':
|
||||
return '门诊日结单(按登录角色查询)市医保.grf';
|
||||
}
|
||||
}
|
||||
|
||||
function formatValue(value) {
|
||||
return value == null || value == undefined ? '0.00 元' : value.toFixed(2) + ' 元';
|
||||
}
|
||||
|
||||
getList();
|
||||
getPharmacyCabinetLists();
|
||||
</script>
|
||||
<style scoped>
|
||||
.label {
|
||||
display: inline-block;
|
||||
width: 120px !important;
|
||||
}
|
||||
.value {
|
||||
float: right;
|
||||
}
|
||||
.el-col {
|
||||
margin-right: 50px;
|
||||
}
|
||||
.divider {
|
||||
height: 3px;
|
||||
background-color: #000;
|
||||
margin: 20px 0;
|
||||
}
|
||||
</style>
|
||||
@@ -615,8 +615,8 @@ const handleDelete = async (row) => {
|
||||
} else {
|
||||
proxy.$modal?.msgError?.(res?.msg || '删除失败');
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '删除异常');
|
||||
} catch {
|
||||
// 响应拦截器已处理错误提示,此处静默
|
||||
}
|
||||
};
|
||||
|
||||
@@ -640,8 +640,8 @@ const handleWithdraw = async (row) => {
|
||||
} else {
|
||||
proxy.$modal?.msgError?.(res?.msg || '撤回失败');
|
||||
}
|
||||
} catch (e) {
|
||||
proxy.$modal?.msgError?.(e.message || '撤回异常');
|
||||
} catch {
|
||||
// 响应拦截器已处理错误提示,此处静默
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -539,7 +539,7 @@ const submit = () => {
|
||||
requestFormId: requestFormId,
|
||||
name: selectedNames,
|
||||
descJson: JSON.stringify(submitForm),
|
||||
categoryEnum: '22',
|
||||
categoryEnum: '23',
|
||||
}).then((res) => {
|
||||
if (res.code === 200) {
|
||||
ElMessage.success(res.msg || (props.isEditMode ? '修改成功' : '保存成功'));
|
||||
|
||||
@@ -230,6 +230,8 @@
|
||||
待保存
|
||||
</el-tag>
|
||||
<el-tag v-else-if="scope.row.statusEnum == 1" type="primary">待签发</el-tag>
|
||||
<el-tag v-else-if="scope.row.statusEnum == 10" type="primary">已校对</el-tag>
|
||||
<el-tag v-else-if="scope.row.statusEnum == 11" type="primary">待接收</el-tag>
|
||||
<el-tag v-else-if="scope.row.statusEnum == 3" type="success">已完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.statusEnum == 6" type="error">停止</el-tag>
|
||||
<el-tag v-else type="info">{{ scope.row.chargeStatus_enumText }}</el-tag>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div busNo="app-container">
|
||||
<div class="app-container">
|
||||
<el-form
|
||||
style="margin-top: 20px; margin-left: 20px"
|
||||
:model="queryParams"
|
||||
@@ -97,7 +97,7 @@
|
||||
|
||||
<el-row
|
||||
:gutter="10"
|
||||
busNo="mb8"
|
||||
class="mb8"
|
||||
style="margin-left: 20px; margin-right: 0px; margin-bottom: 5px"
|
||||
>
|
||||
<el-col :span="1.5">
|
||||
@@ -268,7 +268,7 @@
|
||||
/>
|
||||
<el-row
|
||||
:gutter="10"
|
||||
busNo="mb8"
|
||||
class="mb8"
|
||||
style="
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
@@ -298,6 +298,7 @@ const { proxy } = getCurrentInstance();
|
||||
const totalAmount = ref(0);
|
||||
const purchaseinventoryListAll = ref([]);
|
||||
const xiaojiTotal = ref([]);
|
||||
const rowSpanMap = ref({});
|
||||
const rowSpan = ref(1);
|
||||
const issuerOptions = ref([]);
|
||||
const payeeOptions = ref([]);
|
||||
@@ -548,93 +549,92 @@ function handleTotalAmount() {
|
||||
}, 0);
|
||||
}
|
||||
|
||||
// 门诊号合并行处理
|
||||
function getTotals(row, i) {
|
||||
let totalPriceSums = Number(purchaseinventoryList.value[i].totalPrice);
|
||||
|
||||
for (let j = 1; i - j >= 0; j++) {
|
||||
if (purchaseinventoryList.value[i].busNo == purchaseinventoryList.value[i - j].busNo) {
|
||||
totalPriceSums += Number(purchaseinventoryList.value[i - j].totalPrice);
|
||||
}
|
||||
}
|
||||
|
||||
xiaojiTotal.value.push({
|
||||
inde: i + 1,
|
||||
busNo: row.busNo,
|
||||
genderEnum_enumText: row.genderEnum_enumText,
|
||||
totalPrice: totalPriceSums.toFixed(4) || 0.0,
|
||||
});
|
||||
|
||||
purchaseinventoryList.value.splice(i + 1, 0, {
|
||||
busNo: row.busNo,
|
||||
genderEnum_enumText: row.genderEnum_enumText,
|
||||
departmentName: '小计',
|
||||
totalPrice: totalPriceSums.toFixed(4) || 0.0,
|
||||
});
|
||||
}
|
||||
|
||||
// 表格合并行方法
|
||||
// 表格合并行方法(纯函数,不修改数据)
|
||||
const arraySpanMethod = ({ row, column, rowIndex, columnIndex }) => {
|
||||
if (columnIndex === 1 && purchaseinventoryList.value.length > 0) {
|
||||
if (
|
||||
rowIndex === 0 ||
|
||||
(rowIndex > 0 && row.busNo !== purchaseinventoryList.value[rowIndex - 1]?.busNo)
|
||||
) {
|
||||
let rowspan = 1;
|
||||
let totalPriceSum = 0;
|
||||
|
||||
for (let i = rowIndex + 1; i < purchaseinventoryList.value.length + 1; i++) {
|
||||
if (purchaseinventoryList.value[i - 1].departmentName != '合计') {
|
||||
if (
|
||||
purchaseinventoryList.value[i] &&
|
||||
purchaseinventoryList.value[i].busNo === row.busNo
|
||||
) {
|
||||
rowspan++;
|
||||
totalPriceSum += Number(purchaseinventoryList.value[i].totalPrice);
|
||||
|
||||
if (i == purchaseinventoryList.value.length - 1) {
|
||||
let findIndexTotal = xiaojiTotal.value.findIndex((k) => k.busNo == row.busNo);
|
||||
if (findIndexTotal < 0) {
|
||||
getTotals(row, i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
totalPriceSum += Number(row.totalPrice);
|
||||
let findIndexTotal = xiaojiTotal.value.findIndex((k) => k.busNo == row.busNo);
|
||||
|
||||
if (findIndexTotal < 0) {
|
||||
xiaojiTotal.value.push({
|
||||
inde: i,
|
||||
genderEnum_enumText: row.genderEnum_enumText,
|
||||
busNo: row.busNo,
|
||||
totalPrice: totalPriceSum,
|
||||
});
|
||||
|
||||
purchaseinventoryList.value.splice(i, 0, {
|
||||
busNo: row.busNo,
|
||||
genderEnum_enumText: row.genderEnum_enumText,
|
||||
departmentName: '小计',
|
||||
totalPrice: totalPriceSum.toFixed(4) || 0.0,
|
||||
});
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
rowspan++;
|
||||
}
|
||||
|
||||
return { rowspan, colspan: 1 };
|
||||
// 合并门诊号列(columnIndex === 1)
|
||||
if (columnIndex === 1) {
|
||||
const spanInfo = rowSpanMap.value[rowIndex];
|
||||
if (spanInfo) {
|
||||
return { rowspan: spanInfo.rowspan, colspan: spanInfo.colspan || 1 };
|
||||
} else {
|
||||
return { rowspan: 0, colspan: 0 };
|
||||
}
|
||||
}
|
||||
// 其他列不合并
|
||||
return { rowspan: 1, colspan: 1 };
|
||||
};
|
||||
|
||||
// 预处理列表数据:插入小计行、计算合并行信息
|
||||
// 此函数替代了原来在 arraySpanMethod 中 splice 修改数据的做法
|
||||
function processListWithSubtotals(list) {
|
||||
rowSpanMap.value = {};
|
||||
xiaojiTotal.value = [];
|
||||
|
||||
const result = [];
|
||||
let i = 0;
|
||||
|
||||
while (i < list.length) {
|
||||
const row = list[i];
|
||||
// 跳过已有的合计行
|
||||
if (row.departmentName === '合计') {
|
||||
result.push(row);
|
||||
rowSpanMap.value[result.length - 1] = { rowspan: 1, colspan: 1 };
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const currentBusNo = row.busNo;
|
||||
let rowspan = 0;
|
||||
let totalPriceSum = 0;
|
||||
let j = i;
|
||||
|
||||
// 计算相同门诊号的行数
|
||||
while (j < list.length && list[j].busNo === currentBusNo && list[j].departmentName !== '合计') {
|
||||
rowspan++;
|
||||
totalPriceSum += Number(list[j].totalPrice) || 0;
|
||||
j++;
|
||||
}
|
||||
|
||||
// 设置第一行的 rowspan
|
||||
const startRow = result.length;
|
||||
rowSpanMap.value[startRow] = { rowspan, colspan: 1 };
|
||||
|
||||
// 添加数据行
|
||||
for (let k = i; k < j; k++) {
|
||||
result.push(list[k]);
|
||||
}
|
||||
|
||||
// 添加小计行(多于1行时才添加)
|
||||
if (rowspan > 1) {
|
||||
const subtotalRow = {
|
||||
...list[i],
|
||||
departmentName: '小计',
|
||||
totalPrice: totalPriceSum.toFixed(4),
|
||||
};
|
||||
// 小计行不合并
|
||||
rowSpanMap.value[result.length] = { rowspan: 1, colspan: 1 };
|
||||
result.push(subtotalRow);
|
||||
xiaojiTotal.value.push({
|
||||
inde: result.length,
|
||||
busNo: currentBusNo,
|
||||
genderEnum_enumText: list[i].genderEnum_enumText,
|
||||
totalPrice: totalPriceSum.toFixed(4),
|
||||
});
|
||||
}
|
||||
|
||||
i = j;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// 统计类型变化处理
|
||||
function inventoryChange(val) {
|
||||
queryParams.value.statisticsType = val;
|
||||
xiaojiTotal.value = [];
|
||||
purchaseinventoryList.value = [];
|
||||
rowSpanMap.value = {};
|
||||
getList();
|
||||
}
|
||||
|
||||
@@ -694,8 +694,11 @@ function getList(type) {
|
||||
: '0.0000' + (k.quantityUnit_dictText ? k.quantityUnit_dictText : '');
|
||||
});
|
||||
|
||||
// 处理搜索关键词时的合计
|
||||
if (queryParams.value.searchKey) {
|
||||
// 处理搜索关键词或单页数据
|
||||
if (queryParams.value.searchKey || (total.value && total.value <= queryParams.value.pageSize)) {
|
||||
// 先处理小计行和合并信息
|
||||
purchaseinventoryList.value = processListWithSubtotals(purchaseinventoryList.value);
|
||||
|
||||
purchaseinventoryList.value.forEach((k) => {
|
||||
if (k.departmentName !== '小计' && k.departmentName !== '合计') {
|
||||
totalPrice2 += Number(k.totalPrice) || 0;
|
||||
@@ -703,39 +706,24 @@ function getList(type) {
|
||||
});
|
||||
|
||||
totalPrice2 = totalPrice2 ? totalPrice2.toFixed(4) : totalPrice2;
|
||||
purchaseinventoryList.value.push({ departmentName: '合计', totalPrice: totalPrice2 });
|
||||
loading.value = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// 处理分页数据
|
||||
purchaseinventoryList.value.forEach((k) => {
|
||||
if (total.value && total.value <= queryParams.value.pageSize) {
|
||||
totalPrice2 += Number(k.totalPrice);
|
||||
}
|
||||
});
|
||||
|
||||
if (total.value <= res.data.size) {
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
// 单页数据合计
|
||||
if (total.value && total.value <= queryParams.value.pageSize) {
|
||||
totalPrice2 = totalPrice2 ? totalPrice2.toFixed(4) : totalPrice2;
|
||||
let pageNoAll = total.value / queryParams.value.pageSize;
|
||||
|
||||
let pageNoAll = total.value / queryParams.value.pageSize;
|
||||
if (Math.ceil(pageNoAll) == queryParams.value.pageNo) {
|
||||
purchaseinventoryList.value.push({ departmentName: '合计', totalPrice: totalPrice2 });
|
||||
rowSpanMap.value[purchaseinventoryList.value.length - 1] = { rowspan: 1, colspan: 1 };
|
||||
}
|
||||
}
|
||||
|
||||
// 多页数据处理
|
||||
if (total.value && total.value > queryParams.value.pageSize && !queryParams.value.searchKey) {
|
||||
|
||||
loading.value = false;
|
||||
} else if (total.value && total.value > queryParams.value.pageSize && !queryParams.value.searchKey) {
|
||||
// 多页数据:先处理当前页数据确保rowSpanMap正确初始化,避免表格格式错乱
|
||||
purchaseinventoryList.value = processListWithSubtotals(purchaseinventoryList.value);
|
||||
loading.value = false;
|
||||
|
||||
// 然后获取全部数据进行完整处理
|
||||
let queryParamsValue = { ...queryParams.value };
|
||||
queryParamsValue.pageSize = total.value;
|
||||
queryParamsValue.pageNo = 1;
|
||||
|
||||
// 移除空值参数
|
||||
Object.keys(queryParamsValue).forEach(key => {
|
||||
if (queryParamsValue[key] === undefined || queryParamsValue[key] === null || queryParamsValue[key] === '') {
|
||||
delete queryParamsValue[key];
|
||||
@@ -746,7 +734,7 @@ function getList(type) {
|
||||
purchaseinventoryListAll.value = res.data.records || [];
|
||||
|
||||
if (purchaseinventoryListAll.value.length > 0) {
|
||||
purchaseinventoryListAll.value.map((k, index) => {
|
||||
purchaseinventoryListAll.value.map((k) => {
|
||||
k.totalPrice = k.totalPrice ? k.totalPrice.toFixed(4) : '0.0000';
|
||||
k.price = k.price ? k.price.toFixed(4) : '0.0000';
|
||||
k.number = k.number
|
||||
@@ -754,45 +742,16 @@ function getList(type) {
|
||||
: '0.0000' + (k.quantityUnit_dictText ? k.quantityUnit_dictText : '');
|
||||
|
||||
totalPrice2 += Number(k.totalPrice);
|
||||
|
||||
// 处理跨页门诊号小计
|
||||
for (let m = 1; m < index; m++) {
|
||||
if (
|
||||
queryParams.value.pageNo > 1 &&
|
||||
index == queryParams.value.pageSize * (queryParams.value.pageNo - 1) &&
|
||||
k.busNo == purchaseinventoryListAll.value[index - m]?.busNo
|
||||
) {
|
||||
let dispenseNoIndex1 = purchaseinventoryList.value.findIndex(
|
||||
(o) => o.departmentName == '小计' && o.busNo == purchaseinventoryListAll.value[index - m].busNo
|
||||
);
|
||||
|
||||
if (dispenseNoIndex1 > 0) {
|
||||
purchaseinventoryList.value[dispenseNoIndex1].totalPrice =
|
||||
(Number(purchaseinventoryList.value[dispenseNoIndex1].totalPrice) +
|
||||
Number(purchaseinventoryListAll.value[index - m].totalPrice)).toFixed(4) || '0.0000';
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
index + m == queryParams.value.pageSize * queryParams.value.pageNo &&
|
||||
k.busNo == purchaseinventoryListAll.value[index + m]?.busNo
|
||||
) {
|
||||
if (
|
||||
purchaseinventoryList.value[purchaseinventoryList.value.length - 1]
|
||||
.departmentName == '小计'
|
||||
) {
|
||||
purchaseinventoryList.value.splice(purchaseinventoryList.value.length - 1, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
purchaseinventoryList.value = processListWithSubtotals(purchaseinventoryListAll.value);
|
||||
|
||||
totalPrice2 = totalPrice2 ? totalPrice2.toFixed(4) : totalPrice2;
|
||||
loading.value = false;
|
||||
|
||||
let pageNoAll = total.value / queryParams.value.pageSize;
|
||||
if (Math.ceil(pageNoAll) == queryParams.value.pageNo) {
|
||||
purchaseinventoryList.value.push({ departmentName: '合计', totalPrice: totalPrice2 });
|
||||
rowSpanMap.value[purchaseinventoryList.value.length - 1] = { rowspan: 1, colspan: 1 };
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1519,13 +1519,14 @@ function handleMedicalAdvice(row) {
|
||||
}
|
||||
|
||||
// 🔧 每次打开临时医嘱都重新拉取最新数据,确保计费弹窗签发后数据自动更新
|
||||
// 先清空旧数据
|
||||
// 🔧 修复 Bug #446: 先保存旧数据再清空,避免竟态条件
|
||||
const prevAdvices = [...temporaryAdvices.value]
|
||||
temporaryBillingMedicines.value = []
|
||||
temporaryAdvices.value = []
|
||||
// 🔧 修复 Bug #446: 如果是同一 encounter 且已有提交的医嘱(有 requestId),保留签名状态
|
||||
const hasSubmittedAdvices = temporaryAdvices.value.length > 0 &&
|
||||
temporaryAdvices.value[0]?.originalMedicine?.encounterId === row.visitId &&
|
||||
temporaryAdvices.value.some(a => a.originalMedicine?.requestId);
|
||||
const hasSubmittedAdvices = prevAdvices.length > 0 &&
|
||||
prevAdvices[0]?.originalMedicine?.encounterId === row.visitId &&
|
||||
prevAdvices.some(a => a.originalMedicine?.requestId);
|
||||
temporarySigned.value = hasSubmittedAdvices; // 修复:根据已有数据状态设置,而非盲目重置
|
||||
temporaryMedicalLoading.value = true // 🔧 新增:开始加载
|
||||
|
||||
@@ -1585,7 +1586,13 @@ function handleMedicalAdvice(row) {
|
||||
adviceType: item.adviceType || contentData.adviceType || item.advice_type || null,
|
||||
chargeItemId: item.chargeItemId || contentData.chargeItemId || item.charge_item_id || null,
|
||||
definitionId: item.definitionId || contentData.definitionId || item.definition_id || null,
|
||||
definitionDetailId: item.definitionDetailId || contentData.definitionDetailId || item.definition_detail_id || null
|
||||
definitionDetailId: item.definitionDetailId || contentData.definitionDetailId || item.definition_detail_id || null,
|
||||
// 🔧 修复:传递 requestId,临时医嘱签署时需要用于更新已有记录而非新建
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
};
|
||||
} catch (e) {
|
||||
// 如果解析失败,使用顶层数据 - 兼容 snake_case 和 camelCase 以及后端不同字段名
|
||||
@@ -1606,7 +1613,13 @@ function handleMedicalAdvice(row) {
|
||||
adviceType: item.adviceType || item.advice_type || null,
|
||||
chargeItemId: item.chargeItemId || item.charge_item_id || null,
|
||||
definitionId: item.definitionId || item.definition_id || null,
|
||||
definitionDetailId: item.definitionDetailId || item.definition_detail_id || null
|
||||
definitionDetailId: item.definitionDetailId || item.definition_detail_id || null,
|
||||
// 🔧 修复:传递 requestId,临时医嘱签署时需要用于更新已有记录而非新建
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -1694,73 +1707,134 @@ function closeTemporaryMedical() {
|
||||
// 处理临时医嘱提交
|
||||
// 🔧 修复:提交成功后,更新 temporaryAdvices 中的 requestId,以便下次提交时执行更新操作
|
||||
function handleTemporaryMedicalSubmit(data) {
|
||||
// 🔧 修复:使用用户修改后的数据,而不是重新加载数据
|
||||
// 这样可以确保用户修改的内容(如剂量)在保存后仍然正确显示
|
||||
if (data.temporaryAdvices && data.temporaryAdvices.length > 0) {
|
||||
// 🔧 关键修复:更新 temporaryAdvices 中的数据,保留用户的修改
|
||||
// 但是需要从后端返回的数据中获取 requestId,以便下次提交时执行更新操作
|
||||
// 如果后端返回了医嘱ID(requestId),我们需要更新到 temporaryAdvices 中
|
||||
temporaryAdvices.value = data.temporaryAdvices.map((advice, index) => {
|
||||
const originalMedicine = advice.originalMedicine || {}
|
||||
|
||||
// 🔧 关键修复:从后端返回的数据中获取 requestId(如果有)
|
||||
// 后端返回的医嘱ID可能需要通过某个字段获取,这里暂时假设后端会返回
|
||||
// 如果后端返回的 response 中包含医嘱ID,需要更新到 originalMedicine 中
|
||||
// 这里暂时保留原逻辑,等待用户提供后端返回的具体数据结构
|
||||
|
||||
return {
|
||||
...advice,
|
||||
// 确保 originalMedicine 包含所有必要字段
|
||||
originalMedicine: {
|
||||
...originalMedicine,
|
||||
// 保留用户的修改
|
||||
contentJson: originalMedicine.contentJson || JSON.stringify({
|
||||
dose: advice.dosage,
|
||||
methodCode: advice.usage,
|
||||
rateCode: advice.frequency,
|
||||
quantity: advice.quantity,
|
||||
totalPrice: advice.totalPrice
|
||||
// 🔧 Bug #445 修复:提交成功后重新拉取数据,确保"待生成"列表正确更新
|
||||
if (data.patientInfo && data.patientInfo.visitId) {
|
||||
const row = { visitId: data.patientInfo.visitId, operCode: data.patientInfo.operCode }
|
||||
temporarySigned.value = true
|
||||
ElMessage.success('临时医嘱已生成(已签发)')
|
||||
|
||||
// 重新拉取最新数据,后端已将 statusEnum 从 1(草稿) 更新为 2(已签发)
|
||||
getPrescriptionList(row.visitId, 6, row.operCode).then((res) => {
|
||||
if (res.code === 200 && res.data) {
|
||||
const seenIds = new Set()
|
||||
const filteredItems = res.data.filter(item => {
|
||||
if (item.encounterId !== row.visitId) return false
|
||||
const at = Number(item.adviceType ?? item.advice_type)
|
||||
if (at !== 1 && at !== 2) return false
|
||||
const medicineName = item.adviceName || item.advice_name
|
||||
if (!medicineName || medicineName.trim() === '') return false
|
||||
const excludedKeywords = ['术', '超声', '多普勒', '检查', '检验', '彩超', 'X线', 'CT', 'MRI', '扫描', '造影']
|
||||
if (excludedKeywords.some(kw => medicineName.includes(kw))) return false
|
||||
const itemId = item.requestId || item.id
|
||||
if (itemId && seenIds.has(itemId)) return false
|
||||
if (itemId) seenIds.add(itemId)
|
||||
return true
|
||||
})
|
||||
|
||||
const draftItems = filteredItems.filter(item => item.statusEnum === 1)
|
||||
const activeItems = filteredItems.filter(item => item.statusEnum === 2)
|
||||
|
||||
// 更新待生成列表:只保留未生成的项目
|
||||
temporaryBillingMedicines.value = draftItems.map(item => {
|
||||
try {
|
||||
const jsonContent = item.contentJson || item.content_json
|
||||
const contentData = jsonContent ? JSON.parse(jsonContent) : {}
|
||||
return {
|
||||
medicineName: contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || item.chargeName || item.charge_name || contentData.itemName || contentData.item_name || '未知药品',
|
||||
specification: contentData.volume || contentData.specification || item.volume || item.specification || '',
|
||||
quantity: contentData.quantity || item.quantity || 0,
|
||||
batchNumber: contentData.lotNumber || contentData.lot_number || item.lotNumber || item.lot_number || '',
|
||||
unitPrice: contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0,
|
||||
subtotal: contentData.totalPrice || contentData.total_price || item.totalPrice || item.total_price ||
|
||||
(contentData.unitPrice || contentData.unit_price || item.unitPrice || item.unit_price || 0) *
|
||||
(contentData.quantity || item.quantity || 0),
|
||||
insuranceType: (contentData.insuranceType || contentData.insurance_type) === 1 ? '医保' : (item.insuranceType === 1 || item.insurance_type === 1) ? '医保' : '自费',
|
||||
adviceDefinitionId: item.adviceDefinitionId || contentData.adviceDefinitionId || item.advice_definition_id || null,
|
||||
adviceTableName: item.adviceTableName || contentData.adviceTableName || item.advice_table_name || null,
|
||||
adviceType: item.adviceType || contentData.adviceType || item.advice_type || null,
|
||||
chargeItemId: item.chargeItemId || contentData.chargeItemId || item.charge_item_id || null,
|
||||
definitionId: item.definitionId || contentData.definitionId || item.definition_id || null,
|
||||
definitionDetailId: item.definitionDetailId || contentData.definitionDetailId || item.definition_detail_id || null,
|
||||
// 🔧 修复:传递 requestId
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
medicineName: item.adviceName || item.advice_name || item.chargeName || '',
|
||||
specification: item.specification || item.volume || '',
|
||||
quantity: item.quantity || item.quantity_value || item.quantityValue || 0,
|
||||
batchNumber: item.lotNumber || item.lot_number || '',
|
||||
unitPrice: item.unitPrice || item.unit_price || 0,
|
||||
subtotal: item.totalPrice || item.total_price || 0,
|
||||
insuranceType: (item.insuranceType || item.insurance_type) === 1 ? '医保' : '自费',
|
||||
adviceDefinitionId: item.adviceDefinitionId || item.advice_definition_id || null,
|
||||
adviceTableName: item.adviceTableName || item.advice_table_name || null,
|
||||
adviceType: item.adviceType || item.advice_type || null,
|
||||
chargeItemId: item.chargeItemId || item.charge_item_id || null,
|
||||
definitionId: item.definitionId || item.definition_id || null,
|
||||
definitionDetailId: item.definitionDetailId || item.definition_detail_id || null,
|
||||
// 🔧 修复:传递 requestId
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// 更新已生成列表
|
||||
temporaryAdvices.value = activeItems.map((item, index) => {
|
||||
try {
|
||||
const jsonContent = item.contentJson || item.content_json
|
||||
const contentData = jsonContent ? JSON.parse(jsonContent) : {}
|
||||
const medicineName = contentData.adviceName || contentData.advice_name || item.adviceName || item.advice_name || ''
|
||||
const spec = contentData.volume || contentData.specification || item.volume || item.specification || ''
|
||||
const specMatch = spec.match(/(\d+)(\D+)/)
|
||||
const specValue = specMatch ? parseInt(specMatch[1]) : 1
|
||||
const specUnit = specMatch ? specMatch[2] : 'ml'
|
||||
const dosage = specValue * (contentData.quantity || item.quantity || 1)
|
||||
let usageCode = contentData.methodCode || 'iv'
|
||||
return {
|
||||
id: index + 1, adviceName: medicineName, dosage, unit: specUnit,
|
||||
usage: usageCode, frequency: '临时',
|
||||
executeTime: new Date().toLocaleString('zh-CN'),
|
||||
originalMedicine: { ...item, medicineName, specification: spec, quantity: contentData.quantity || item.quantity || 1, encounterId: row.visitId }
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
id: index + 1, adviceName: item.adviceName || '', dosage: 1, unit: 'ml',
|
||||
usage: 'iv', frequency: '临时', executeTime: new Date().toLocaleString('zh-CN'),
|
||||
originalMedicine: { ...item, medicineName: item.adviceName || '', specification: item.volume || '', quantity: item.quantity || 1, encounterId: row.visitId }
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}).catch(() => {
|
||||
// 拉取失败时使用本地过滤作为兜底
|
||||
if (data.temporaryAdvices && data.temporaryAdvices.length > 0) {
|
||||
const submittedKeys = new Set(
|
||||
data.temporaryAdvices.map(a => {
|
||||
const om = a.originalMedicine || {}
|
||||
return `${om.medicineName || a.adviceName || ''}|||${om.specification || ''}|||${om.quantity || 0}`
|
||||
}).filter(k => k !== '|||0')
|
||||
)
|
||||
if (submittedKeys.size > 0) {
|
||||
temporaryBillingMedicines.value = (temporaryBillingMedicines.value || []).filter(m => {
|
||||
return !submittedKeys.has(`${m.medicineName || ''}|||${m.specification || ''}|||${m.quantity || 0}`)
|
||||
})
|
||||
}
|
||||
temporaryAdvices.value = data.temporaryAdvices
|
||||
}
|
||||
})
|
||||
|
||||
// 🔧 修复 Bug #445: 使用稳定的字段组合匹配已提交项目,而不是依赖可能为空的 requestId/chargeItemId
|
||||
// 构建已提交项目的匹配键集合(药品名称 + 规格 + 数量)
|
||||
const submittedKeys = new Set(
|
||||
(data.temporaryAdvices || [])
|
||||
.map(a => {
|
||||
const om = a.originalMedicine || {}
|
||||
const name = om.medicineName || om.adviceName || om.advice_name || a.adviceName || ''
|
||||
const spec = om.specification || om.volume || ''
|
||||
const qty = om.quantity || 0
|
||||
return `${name}|||${spec}|||${qty}`
|
||||
})
|
||||
.filter(k => k !== '|||0') // 过滤掉空项
|
||||
)
|
||||
|
||||
if (submittedKeys.size > 0) {
|
||||
temporaryBillingMedicines.value = (temporaryBillingMedicines.value || []).filter(m => {
|
||||
const key = `${m.medicineName || ''}|||${m.specification || ''}|||${m.quantity || 0}`
|
||||
return !submittedKeys.has(key)
|
||||
})
|
||||
} else {
|
||||
// 如果没有任何匹配键,清空待生成列表(所有项目都已提交)
|
||||
temporaryBillingMedicines.value = []
|
||||
}
|
||||
|
||||
} else {
|
||||
// 如果没有传递数据,则清空
|
||||
temporaryAdvices.value = []
|
||||
temporaryBillingMedicines.value = []
|
||||
}
|
||||
|
||||
// 🔧 设置签名状态,保持按钮名称一致
|
||||
temporarySigned.value = true
|
||||
|
||||
// 显示成功提示,不关闭弹窗,让用户可以查看已签发的医嘱状态
|
||||
ElMessage.success('临时医嘱已生成(已签发),可继续查看或修改')
|
||||
|
||||
}
|
||||
function handleTemporaryMedicalCancel() {
|
||||
// 🔧 修复:用户点击取消时才清空数据,因为用户可能要放弃修改
|
||||
@@ -1911,7 +1985,13 @@ function handleQuoteBilling() {
|
||||
orgId: contentData.orgId || item.orgId || contentData.positionId || item.positionId || userStore.orgId,
|
||||
positionId: contentData.positionId || item.positionId || userStore.orgId,
|
||||
definitionId: contentData.definitionId || item.definitionId,
|
||||
definitionDetailId: contentData.definitionDetailId || item.definitionDetailId
|
||||
definitionDetailId: contentData.definitionDetailId || item.definitionDetailId,
|
||||
// 🔧 修复:传递 requestId
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
}
|
||||
} catch (e) {
|
||||
return {
|
||||
@@ -1927,7 +2007,13 @@ function handleQuoteBilling() {
|
||||
orgId: item.orgId || item.positionId || userStore.orgId,
|
||||
positionId: item.positionId || userStore.orgId,
|
||||
definitionId: item.definitionId,
|
||||
definitionDetailId: item.definitionDetailId
|
||||
definitionDetailId: item.definitionDetailId,
|
||||
// 🔧 修复:传递 requestId
|
||||
requestId: item.requestId || null,
|
||||
// 🔧 保留原始 contentJson,临时医嘱签发时需要展开所有字段传给后端
|
||||
contentJson: item.contentJson || item.content_json || null,
|
||||
// 🔧 标记是否已签发,用于临时医嘱弹窗控制按钮状态
|
||||
_signed: item.statusEnum === 2
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -317,10 +317,11 @@ const getMethodCodeDict = computed(() => {
|
||||
return dict
|
||||
})
|
||||
|
||||
// 🔧 修复 Bug #446: 检查计费药品是否已全部提交(有 requestId),用于区分"首次签名"和"已提交重开"
|
||||
// 🔧 检查是否已全部签发(statusEnum=2),用于控制"一键签名"按钮是否禁用
|
||||
// 注意:不能依赖 requestId,因为草稿记录也有 requestId
|
||||
const allItemsSubmitted = computed(() => {
|
||||
const meds = props.billingMedicines || []
|
||||
return meds.length > 0 && meds.every(m => m.requestId)
|
||||
return meds.length > 0 && meds.every(m => m._signed)
|
||||
})
|
||||
|
||||
// 展开/收起控制
|
||||
@@ -425,32 +426,20 @@ const displayAdvices = ref([])
|
||||
|
||||
// 初始化 displayAdvices
|
||||
const initDisplayAdvices = () => {
|
||||
// 只要有用户修改过的数据,就优先使用用户修改后的数据
|
||||
// 避免自动转换覆盖用户的修改
|
||||
// 区域二只显示已生成(已签发)的数据,没有时保持为空,不自动转换区域一的草稿
|
||||
if (props.temporaryAdvices && props.temporaryAdvices.length > 0) {
|
||||
// 🔧 修复:将旧编码映射到新编码
|
||||
displayAdvices.value = props.temporaryAdvices.map(mapUsageCode)
|
||||
} else {
|
||||
// 否则自动转换第一区域的已引用计费药品
|
||||
displayAdvices.value = convertedAdvices.value
|
||||
displayAdvices.value = []
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
initDisplayAdvices()
|
||||
|
||||
// 组件挂载时,如果没有传入临时医嘱数据,将自动转换后的数据同步到父组件
|
||||
// 确保修改可以被父组件保存,下次打开仍然能看到
|
||||
onMounted(() => {
|
||||
|
||||
|
||||
// 初始化 displayAdvices
|
||||
initDisplayAdvices()
|
||||
|
||||
if ((!props.temporaryAdvices || props.temporaryAdvices.length === 0) && convertedAdvices.value.length > 0) {
|
||||
console.log('=== onMounted 触发 emit ===')
|
||||
emit('update:temporary-advices', convertedAdvices.value)
|
||||
}
|
||||
// 🔧 修复:不再自动把区域一草稿转为区域二数据
|
||||
})
|
||||
|
||||
// 🔧 新增:监听 temporary-advices prop 的变化,同步更新 displayAdvices
|
||||
@@ -465,23 +454,9 @@ watch(() => props.temporaryAdvices, (newVal, oldVal) => {
|
||||
}
|
||||
}, { deep: true, immediate: true })
|
||||
|
||||
// 监听第一区域的计费药品变化,如果第一区域更新了,并且用户还没修改过第二区域数据,自动更新第二区域
|
||||
// 🔧 修复:不再自动把区域一草稿转为区域二数据,区域二只显示已签发的记录
|
||||
watch(() => props.billingMedicines, (newVal) => {
|
||||
console.log('=== watch billingMedicines 被调用 ===')
|
||||
console.log('=== newVal ===', newVal)
|
||||
console.log('=== props.temporaryAdvices ===', props.temporaryAdvices)
|
||||
console.log('=== props.temporaryAdvices.length ===', props.temporaryAdvices?.length)
|
||||
|
||||
// 🔧 修复:只有当 temporary-advices 为空时才自动更新,避免覆盖用户的修改
|
||||
if (!props.temporaryAdvices || props.temporaryAdvices.length === 0) {
|
||||
if (newVal.length > 0) {
|
||||
console.log('=== watch 触发 emit ===')
|
||||
displayAdvices.value = convertedAdvices.value
|
||||
emit('update:temporary-advices', convertedAdvices.value)
|
||||
}
|
||||
} else {
|
||||
console.log('=== watch 不触发 emit,因为 props.temporaryAdvices 已有数据 ===')
|
||||
}
|
||||
// 空 watcher,仅保留结构避免破坏其他逻辑
|
||||
}, { deep: true })
|
||||
|
||||
// 🔧 新增:监听字典加载,确保字典加载后编辑弹窗能正确显示
|
||||
@@ -697,7 +672,9 @@ const handleSubmit = async () => {
|
||||
}
|
||||
|
||||
// 检查是否有医嘱数据
|
||||
if (displayAdvices.value.length === 0) {
|
||||
// 🔧 修复:签发应该处理区域一中所有待签发的药品(billingMedicines),而非区域二中已有数据(displayAdvices)
|
||||
const itemsToSign = convertedAdvices.value
|
||||
if (itemsToSign.length === 0) {
|
||||
ElMessage.warning('没有可保存的医嘱数据')
|
||||
return
|
||||
}
|
||||
@@ -709,7 +686,7 @@ const handleSubmit = async () => {
|
||||
// 构建保存医嘱的请求参数
|
||||
const saveData = {
|
||||
organizationId: props.patientInfo.orgId || props.patientInfo.organizationId || 1, // 使用计费时的orgId
|
||||
adviceSaveList: displayAdvices.value.map((advice, index) => {
|
||||
adviceSaveList: itemsToSign.map((advice, index) => {
|
||||
// 获取原始药品数据
|
||||
const originalMedicine = advice.originalMedicine
|
||||
|
||||
@@ -764,53 +741,44 @@ const handleSubmit = async () => {
|
||||
// 重新序列化contentJson
|
||||
const updatedContentJson = JSON.stringify(contentJsonData);
|
||||
|
||||
// 构造请求参数(与门诊医生工作站完全一致)
|
||||
// 🔧 构造请求参数:与计费弹窗 handleSave 保持完全一致的模式
|
||||
// 先展开原始 contentJson 的所有字段,然后用当前值覆盖(保证不丢字段)
|
||||
return {
|
||||
...contentJsonData,
|
||||
// 基础信息
|
||||
// 🔧 修复:dbOpType 的判断逻辑 - 如果有 requestId 则为修改,否则为新增
|
||||
// 但对于从计费药品转换来的数据,即使没有 requestId,也应该先更新 chargeItemId
|
||||
dbOpType: originalMedicine?.requestId ? '2' : (originalMedicine?.chargeItemId ? '2' : '1'),
|
||||
adviceType: originalMedicine?.adviceType || 1, // 使用原始类型或默认1
|
||||
adviceType: originalMedicine?.adviceType || 1,
|
||||
requestId: originalMedicine?.requestId,
|
||||
chargeItemId: originalMedicine?.chargeItemId,
|
||||
contentJson: updatedContentJson,
|
||||
categoryCode: contentJsonData.categoryCode || originalMedicine?.categoryCode,
|
||||
pharmacologyCategoryCode: contentJsonData.pharmacologyCategoryCode || originalMedicine?.pharmacologyCategoryCode,
|
||||
partPercent: originalMedicine?.partPercent || contentJsonData.partPercent || 1,
|
||||
partAttributeEnum: originalMedicine?.partAttributeEnum || contentJsonData.partAttributeEnum,
|
||||
executeNum: contentJsonData.executeNum || originalMedicine?.executeNum || 1,
|
||||
prescriptionNo: originalMedicine?.prescriptionNo,
|
||||
|
||||
// 数量和单位:使用重新计算后的数量
|
||||
quantity: quantity,
|
||||
dispensePerDuration: originalMedicine?.dispensePerDuration || contentJsonData.dispensePerDuration,
|
||||
unitCode: contentJsonData.unitCode || originalMedicine?.unitCode || advice.unit,
|
||||
unitPrice: unitPrice,
|
||||
// 总价根据新的数量重新计算
|
||||
totalPrice: totalPrice,
|
||||
definitionId: originalMedicine?.definitionId ? String(originalMedicine.definitionId) : contentJsonData.definitionId ? String(contentJsonData.definitionId) : advice.definitionId ? String(advice.definitionId) : null,
|
||||
definitionDetailId: originalMedicine?.definitionDetailId ? String(originalMedicine.definitionDetailId) : contentJsonData.definitionDetailId ? String(contentJsonData.definitionDetailId) : advice.definitionDetailId ? String(advice.definitionDetailId) : null,
|
||||
lotNumber: originalMedicine?.lotNumber || contentJsonData.lotNumber,
|
||||
|
||||
// 状态和类型
|
||||
statusEnum: originalMedicine?.statusEnum || 2, // 默认状态:已发送
|
||||
categoryEnum: originalMedicine?.categoryEnum || contentJsonData.categoryEnum || 1,
|
||||
|
||||
// 药品/诊疗信息 - 🔧 修复:优先使用originalMedicine中的adviceDefinitionId和adviceTableName
|
||||
// 🔧 关键修复:确保adviceDefinitionId不为null,使用definitionId作为后备
|
||||
adviceDefinitionId: originalMedicine?.adviceDefinitionId || contentJsonData.adviceDefinitionId || advice.definitionId || contentJsonData.definitionId || definitionId,
|
||||
// 药品/诊疗信息
|
||||
adviceDefinitionId: originalMedicine?.adviceDefinitionId || contentJsonData.adviceDefinitionId || advice.definitionId || contentJsonData.definitionId,
|
||||
adviceTableName: originalMedicine?.adviceTableName || contentJsonData.adviceTableName || 'med_medication_definition',
|
||||
adviceName: advice.adviceName,
|
||||
minUnitQuantity: originalMedicine?.minUnitQuantity || contentJsonData.minUnitQuantity,
|
||||
|
||||
// 患者和就诊信息
|
||||
patientId: props.patientInfo.patientId,
|
||||
practitionerId: currentUser.value.id || originalMedicine?.practitionerId, // 开方医生
|
||||
practitionerId: currentUser.value.id || originalMedicine?.practitionerId,
|
||||
locationId: originalMedicine?.positionId || contentJsonData.locationId || props.patientInfo.orgId || props.patientInfo.positionId,
|
||||
positionId: originalMedicine?.positionId || contentJsonData.positionId,
|
||||
orgId: originalMedicine?.orgId || props.patientInfo.orgId || props.patientInfo.positionId,
|
||||
performLocation: originalMedicine?.performLocation || contentJsonData.performLocation,
|
||||
founderOrgId: currentUser.value.id || originalMedicine?.founderOrgId, // 开方人科室
|
||||
founderOrgId: currentUser.value.id || originalMedicine?.founderOrgId,
|
||||
encounterId: props.patientInfo.visitId || contentJsonData.encounterId || originalMedicine?.encounterId,
|
||||
accountId: contentJsonData.accountId || originalMedicine?.accountId,
|
||||
conditionId: contentJsonData.conditionId || originalMedicine?.conditionId,
|
||||
@@ -818,12 +786,10 @@ const handleSubmit = async () => {
|
||||
conditionDefinitionId: originalMedicine?.conditionDefinitionId || contentJsonData.conditionDefinitionId,
|
||||
|
||||
// 治疗信息
|
||||
therapyEnum: originalMedicine?.therapyEnum || contentJsonData.therapyEnum || 1, // 默认临时医嘱
|
||||
// 🔧 修复:methodCode 使用编码,而不是中文名称
|
||||
methodCode: methodCode, // 用法(使用编码)
|
||||
rateCode: advice.frequency, // 频次
|
||||
therapyEnum: originalMedicine?.therapyEnum || contentJsonData.therapyEnum || 1,
|
||||
methodCode: methodCode,
|
||||
rateCode: advice.frequency,
|
||||
dose: advice.dosage,
|
||||
firstDose: originalMedicine?.firstDose || contentJsonData.firstDose,
|
||||
doseUnitCode: contentJsonData.doseUnitCode || originalMedicine?.doseUnitCode || advice.unit,
|
||||
skinTestFlag: originalMedicine?.skinTestFlag || contentJsonData.skinTestFlag,
|
||||
injectFlag: originalMedicine?.injectFlag || contentJsonData.injectFlag,
|
||||
@@ -832,55 +798,30 @@ const handleSubmit = async () => {
|
||||
groupId: originalMedicine?.groupId,
|
||||
packageId: originalMedicine?.packageId || contentJsonData.packageId,
|
||||
|
||||
// 诊疗活动信息
|
||||
activityId: contentJsonData.adviceDefinitionId || originalMedicine?.adviceDefinitionId, // 对于诊疗类型,使用 adviceDefinitionId 作为 activity_id
|
||||
|
||||
// 医保信息
|
||||
ybClassEnum: originalMedicine?.ybClassEnum || contentJsonData.ybClassEnum,
|
||||
|
||||
// 中药信息
|
||||
chineseHerbsDoseQuantity: originalMedicine?.chineseHerbsDoseQuantity || contentJsonData.chineseHerbsDoseQuantity || 1
|
||||
// 🔧 补充:手术计费上下文
|
||||
generateSourceEnum: 6,
|
||||
sourceBillNo: props.patientInfo?.operCode || originalMedicine?.sourceBillNo || ''
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 调用保存医嘱接口
|
||||
// 如果已签名,则执行签发操作('1'),否则执行保存操作('0')
|
||||
const adviceOpType = isSigned.value ? '1' : '0'
|
||||
const response = await savePrescription(saveData, adviceOpType)
|
||||
// 🔧 修复:使用 savePrescription + adviceOpType='2'(后端 AdviceOpType: '2'=SIGN_ADVICE 签发)
|
||||
const response = await savePrescription(saveData, '2')
|
||||
|
||||
if (response.code === 200) {
|
||||
ElMessage.success('临时医嘱保存成功')
|
||||
|
||||
// 🔧 关键修复:处理后端返回的医嘱 ID
|
||||
// 后端返回的 data 数组只包含新创建的医嘱记录的 ID,不包含已更新的记录
|
||||
// 我们需要正确地映射这些 ID 到对应的临时医嘱数据
|
||||
if (response.data && Array.isArray(response.data) && response.data.length > 0) {
|
||||
// 创建一个索引,记录哪些记录是新创建的
|
||||
let newDataIndex = 0
|
||||
|
||||
displayAdvices.value.forEach((advice, index) => {
|
||||
const originalMedicine = advice.originalMedicine || {}
|
||||
// 如果这个记录没有 requestId,说明是新创建的
|
||||
if (!originalMedicine.requestId) {
|
||||
if (newDataIndex < response.data.length) {
|
||||
// 更新 originalMedicine 中的 requestId
|
||||
if (!displayAdvices.value[index].originalMedicine) {
|
||||
displayAdvices.value[index].originalMedicine = {}
|
||||
}
|
||||
displayAdvices.value[index].originalMedicine.requestId = response.data[newDataIndex]
|
||||
newDataIndex++
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 🔧 签名成功,后端已更新已有记录的 statusEnum 为 2
|
||||
// 不需要手动更新 requestId(签名操作是 UPDATE,不是 INSERT,后端不返回新 ID)
|
||||
|
||||
// 🔧 修复:将保存后的医嘱数据(包含用户的修改和后端返回的 requestId)传递给父组件
|
||||
// 这样父组件可以使用用户修改后的数据,而不是重新加载数据
|
||||
// 🔧 修复:将保存后的医嘱数据传递给父组件
|
||||
const submitData = {
|
||||
patientInfo: props.patientInfo,
|
||||
billingMedicines: props.billingMedicines,
|
||||
temporaryAdvices: displayAdvices.value, // 使用用户修改后的数据,包含后端返回的 requestId
|
||||
temporaryAdvices: itemsToSign,
|
||||
signature: {
|
||||
doctorName: currentUser.value.name,
|
||||
signatureTime: signatureTime.value
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user