完成100需求,补充99需求追溯术中产生的费用新增费用项时向表中插入SourceBillNo和generate_source_enum字段值
This commit is contained in:
@@ -2,11 +2,14 @@ package com.openhis.web.clinicalmanage.controller;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.core.common.core.domain.R;
|
import com.core.common.core.domain.R;
|
||||||
|
import com.core.common.core.domain.model.LoginUser;
|
||||||
|
import com.core.common.utils.SecurityUtils;
|
||||||
import com.openhis.web.clinicalmanage.appservice.ISurgicalScheduleAppService;
|
import com.openhis.web.clinicalmanage.appservice.ISurgicalScheduleAppService;
|
||||||
import com.openhis.web.clinicalmanage.dto.OpCreateScheduleDto;
|
import com.openhis.web.clinicalmanage.dto.OpCreateScheduleDto;
|
||||||
import com.openhis.web.clinicalmanage.dto.OpScheduleDto;
|
import com.openhis.web.clinicalmanage.dto.OpScheduleDto;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.catalina.User;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -98,4 +101,29 @@ public class SurgicalScheduleController {
|
|||||||
surgicalScheduleAppService.exportSurgerySchedule(opScheduleDto, response);
|
surgicalScheduleAppService.exportSurgerySchedule(opScheduleDto, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 验证密码
|
||||||
|
* @param password 密码
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
@PostMapping(value = "/checkPassword")
|
||||||
|
public R<?> checkPassword(@RequestParam String password) {
|
||||||
|
try {
|
||||||
|
//获取当前登录用户信息
|
||||||
|
LoginUser loginUser = SecurityUtils.getLoginUser();
|
||||||
|
if (loginUser == null) {
|
||||||
|
return R.fail("用户未登录");
|
||||||
|
}
|
||||||
|
// 直接使用 SecurityUtils.matchesPassword 进行密码验证
|
||||||
|
boolean isMatch = SecurityUtils.matchesPassword(password, loginUser.getPassword());
|
||||||
|
if (isMatch) {
|
||||||
|
return R.ok(true);
|
||||||
|
} else {
|
||||||
|
return R.fail("密码错误");
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
return R.fail("密码验证失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -635,6 +635,10 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
} else {
|
} else {
|
||||||
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
}
|
}
|
||||||
|
// 来源业务单据号:如果前端指定了来源业务单据号,设置该字段
|
||||||
|
if (adviceSaveDto.getSourceBillNo() != null) {
|
||||||
|
chargeItem.setSourceBillNo(adviceSaveDto.getSourceBillNo());
|
||||||
|
}
|
||||||
chargeItem.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); // 处方号
|
chargeItem.setPrescriptionNo(adviceSaveDto.getPrescriptionNo()); // 处方号
|
||||||
chargeItem.setPatientId(adviceSaveDto.getPatientId()); // 患者
|
chargeItem.setPatientId(adviceSaveDto.getPatientId()); // 患者
|
||||||
chargeItem.setContextEnum(adviceSaveDto.getAdviceType()); // 类型
|
chargeItem.setContextEnum(adviceSaveDto.getAdviceType()); // 类型
|
||||||
@@ -652,10 +656,6 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
chargeItem.setConditionId(adviceSaveDto.getConditionId()); // 诊断id
|
chargeItem.setConditionId(adviceSaveDto.getConditionId()); // 诊断id
|
||||||
chargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id
|
chargeItem.setEncounterDiagnosisId(adviceSaveDto.getEncounterDiagnosisId()); // 就诊诊断id
|
||||||
chargeItem.setDispenseId(dispenseId); // 发放ID
|
chargeItem.setDispenseId(dispenseId); // 发放ID
|
||||||
// 来源业务单据号:如果前端指定了来源业务单据号,设置该字段
|
|
||||||
if (adviceSaveDto.getSourceBillNo() != null) {
|
|
||||||
chargeItem.setSourceBillNo(adviceSaveDto.getSourceBillNo());
|
|
||||||
}
|
|
||||||
chargeItem.setTenantId(tenantId); // 设置租户ID (修复本次报错)
|
chargeItem.setTenantId(tenantId); // 设置租户ID (修复本次报错)
|
||||||
chargeItem.setCreateBy(currentUsername); // 设置创建人
|
chargeItem.setCreateBy(currentUsername); // 设置创建人
|
||||||
chargeItem.setCreateTime(curDate); // 设置创建时间
|
chargeItem.setCreateTime(curDate); // 设置创建时间
|
||||||
@@ -768,6 +768,16 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
|
|
||||||
// 保存耗材费用项
|
// 保存耗材费用项
|
||||||
chargeItem = new ChargeItem();
|
chargeItem = new ChargeItem();
|
||||||
|
// 生成来源:如果前端指定了生成来源,使用前端值;否则使用默认的医生开立
|
||||||
|
if (adviceSaveDto.getGenerateSourceEnum() != null) {
|
||||||
|
chargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum());
|
||||||
|
} else {
|
||||||
|
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
}
|
||||||
|
// 来源业务单据号:如果前端指定了来源业务单据号,设置该字段
|
||||||
|
if (adviceSaveDto.getSourceBillNo() != null) {
|
||||||
|
chargeItem.setSourceBillNo(adviceSaveDto.getSourceBillNo());
|
||||||
|
}
|
||||||
chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id
|
chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id
|
||||||
chargeItem.setTenantId(tenantId); // 补全租户ID
|
chargeItem.setTenantId(tenantId); // 补全租户ID
|
||||||
chargeItem.setCreateBy(currentUsername); // 补全创建人
|
chargeItem.setCreateBy(currentUsername); // 补全创建人
|
||||||
@@ -909,6 +919,16 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
|
|||||||
// 保存时保存诊疗费用项
|
// 保存时保存诊疗费用项
|
||||||
if (is_save) {
|
if (is_save) {
|
||||||
chargeItem = new ChargeItem();
|
chargeItem = new ChargeItem();
|
||||||
|
// 生成来源:如果前端指定了生成来源,使用前端值;否则使用默认的医生开立
|
||||||
|
if (adviceSaveDto.getGenerateSourceEnum() != null) {
|
||||||
|
chargeItem.setGenerateSourceEnum(adviceSaveDto.getGenerateSourceEnum());
|
||||||
|
} else {
|
||||||
|
chargeItem.setGenerateSourceEnum(GenerateSource.DOCTOR_PRESCRIPTION.getValue());
|
||||||
|
}
|
||||||
|
// 来源业务单据号:如果前端指定了来源业务单据号,设置该字段
|
||||||
|
if (adviceSaveDto.getSourceBillNo() != null) {
|
||||||
|
chargeItem.setSourceBillNo(adviceSaveDto.getSourceBillNo());
|
||||||
|
}
|
||||||
chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id
|
chargeItem.setId(adviceSaveDto.getChargeItemId()); // 费用项id
|
||||||
chargeItem.setTenantId(tenantId); // 补全租户ID
|
chargeItem.setTenantId(tenantId); // 补全租户ID
|
||||||
chargeItem.setCreateBy(currentUsername); // 补全创建人
|
chargeItem.setCreateBy(currentUsername); // 补全创建人
|
||||||
|
|||||||
@@ -60,3 +60,12 @@ export function exportSurgerySchedule(query) {
|
|||||||
params: query
|
params: query
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//签名密码验证
|
||||||
|
export function checkPassword(params) {
|
||||||
|
return request({
|
||||||
|
url: '/clinical-manage/surgery-schedule/checkPassword',
|
||||||
|
method: 'POST',
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -55,6 +55,9 @@
|
|||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" plain icon="Money" @click="handleChargeCharge(selectedRow)" :disabled="!selectedRow"> 计费 </el-button>
|
<el-button type="success" plain icon="Money" @click="handleChargeCharge(selectedRow)" :disabled="!selectedRow"> 计费 </el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
|
<el-col :span="1.5">
|
||||||
|
<el-button type="success" plain icon="Document" @click="handleMedicalAdvice(selectedRow)" :disabled="!selectedRow"> 医嘱 </el-button>
|
||||||
|
</el-col>
|
||||||
<el-col :span="1.5">
|
<el-col :span="1.5">
|
||||||
<el-button type="success" plain icon="Download" @click="handleExport">导出表格</el-button>
|
<el-button type="success" plain icon="Download" @click="handleExport">导出表格</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -62,7 +65,7 @@
|
|||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 中部表格区 -->
|
<!-- 中部表格区 -->
|
||||||
<el-table v-loading="loading" :data="surgeryList" row-key="scheduleId" :row-class-name="getRowClassName" highlight-current-row @current-change="handleCurrentChange">
|
<el-table v-loading="loading" :data="surgeryList" row-key="scheduleId" :row-class-name="getRowClassName" @current-change="handleCurrentChange">
|
||||||
<el-table-column label="ID" align="center" width="80">
|
<el-table-column label="ID" align="center" width="80">
|
||||||
<template #default="{ $index }">
|
<template #default="{ $index }">
|
||||||
{{ (applyQueryParams.pageNo - 1) * applyQueryParams.pageSize + $index + 1 }}
|
{{ (applyQueryParams.pageNo - 1) * applyQueryParams.pageSize + $index + 1 }}
|
||||||
@@ -799,6 +802,18 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 临时医嘱弹窗 -->
|
||||||
|
<el-dialog :title="temporaryMedicalTitle" v-model="showTemporaryMedical" width="80%" append-to-body :close-on-click-modal="false">
|
||||||
|
<temporary-medical
|
||||||
|
:patient-info="temporaryPatientInfo"
|
||||||
|
:billing-medicines="temporaryBillingMedicines"
|
||||||
|
v-model:temporary-advices="temporaryAdvices"
|
||||||
|
@submit="handleTemporaryMedicalSubmit"
|
||||||
|
@cancel="handleTemporaryMedicalCancel"
|
||||||
|
@delete-advice="handleDeleteTemporaryAdvice"
|
||||||
|
/>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -810,6 +825,9 @@ import { useDict } from '@/utils/dict'
|
|||||||
import download from '@/plugins/download'
|
import download from '@/plugins/download'
|
||||||
import Prescriptionlist from '@/views/clinicmanagement/bargain/component/prescriptionlist.vue'
|
import Prescriptionlist from '@/views/clinicmanagement/bargain/component/prescriptionlist.vue'
|
||||||
import useUserStore from '@/store/modules/user'
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
// 导入计费相关接口
|
||||||
|
import { getPrescriptionList } from '@/views/clinicmanagement/bargain/component/api'
|
||||||
|
|
||||||
// API 导入
|
// API 导入
|
||||||
import { getSurgerySchedulePage, addSurgerySchedule, updateSurgerySchedule, deleteSurgerySchedule, getSurgeryScheduleDetail } from '@/api/surgicalschedule'
|
import { getSurgerySchedulePage, addSurgerySchedule, updateSurgerySchedule, deleteSurgerySchedule, getSurgeryScheduleDetail } from '@/api/surgicalschedule'
|
||||||
@@ -820,6 +838,7 @@ import { getTestResultPage} from '@/views/inpatientDoctor/home/components/applic
|
|||||||
import { getTenantPage } from '@/api/system/tenant'
|
import { getTenantPage } from '@/api/system/tenant'
|
||||||
import { getContract } from '@/views/inpatientDoctor/home/components/api.js'
|
import { getContract } from '@/views/inpatientDoctor/home/components/api.js'
|
||||||
import SurgeryCharge from '../charge/surgerycharge/index.vue'
|
import SurgeryCharge from '../charge/surgerycharge/index.vue'
|
||||||
|
import TemporaryMedical from './temporaryMedical.vue'
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance()
|
const { proxy } = getCurrentInstance()
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
@@ -947,6 +966,13 @@ const chargePatientInfo = ref({})
|
|||||||
const chargeSurgeryInfo = ref({})
|
const chargeSurgeryInfo = ref({})
|
||||||
const prescriptionRef = ref()
|
const prescriptionRef = ref()
|
||||||
|
|
||||||
|
// 临时医嘱弹窗
|
||||||
|
const showTemporaryMedical = ref(false)
|
||||||
|
const temporaryMedicalTitle = ref('门诊术中临时医嘱')
|
||||||
|
const temporaryPatientInfo = ref({})
|
||||||
|
const temporaryBillingMedicines = ref([])
|
||||||
|
const temporaryAdvices = ref([])
|
||||||
|
|
||||||
// 下拉列表数据
|
// 下拉列表数据
|
||||||
const orgList = ref([])
|
const orgList = ref([])
|
||||||
const deptList = ref([])
|
const deptList = ref([])
|
||||||
@@ -1026,8 +1052,7 @@ function loadOrgList() {
|
|||||||
orgList.value = []
|
orgList.value = []
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(() => {
|
||||||
console.error('加载卫生机构列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取卫生机构列表失败')
|
proxy.$modal.msgError('获取卫生机构列表失败')
|
||||||
orgList.value = []
|
orgList.value = []
|
||||||
})
|
})
|
||||||
@@ -1046,7 +1071,6 @@ function loadDeptList() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('加载科室列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取科室列表失败')
|
proxy.$modal.msgError('获取科室列表失败')
|
||||||
deptList.value = []
|
deptList.value = []
|
||||||
})
|
})
|
||||||
@@ -1065,7 +1089,6 @@ function loadDoctorList() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('加载医生列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取医生列表失败')
|
proxy.$modal.msgError('获取医生列表失败')
|
||||||
doctorList.value = []
|
doctorList.value = []
|
||||||
})
|
})
|
||||||
@@ -1084,7 +1107,6 @@ function loadNurseList() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('加载护士列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取护士列表失败')
|
proxy.$modal.msgError('获取护士列表失败')
|
||||||
nurseList.value = []
|
nurseList.value = []
|
||||||
})
|
})
|
||||||
@@ -1103,7 +1125,6 @@ function loadOperatingRoomList() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error('加载手术室列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取手术室列表失败')
|
proxy.$modal.msgError('获取手术室列表失败')
|
||||||
operatingRoomList.value = []
|
operatingRoomList.value = []
|
||||||
})
|
})
|
||||||
@@ -1116,7 +1137,6 @@ function getList() {
|
|||||||
surgeryList.value = res.data.records
|
surgeryList.value = res.data.records
|
||||||
total.value = res.data.total
|
total.value = res.data.total
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
console.error('获取手术安排列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取手术安排列表失败,请稍后重试')
|
proxy.$modal.msgError('获取手术安排列表失败,请稍后重试')
|
||||||
surgeryList.value = []
|
surgeryList.value = []
|
||||||
total.value = 0
|
total.value = 0
|
||||||
@@ -1170,8 +1190,7 @@ function handleEdit(row) {
|
|||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError('获取手术安排详情失败')
|
proxy.$modal.msgError('获取手术安排详情失败')
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
console.error('获取手术安排详情失败:', error)
|
|
||||||
proxy.$modal.msgError('获取手术安排详情失败')
|
proxy.$modal.msgError('获取手术安排详情失败')
|
||||||
})
|
})
|
||||||
open.value = true
|
open.value = true
|
||||||
@@ -1190,8 +1209,7 @@ function handleView(row) {
|
|||||||
} else {
|
} else {
|
||||||
proxy.$modal.msgError('获取手术安排详情失败')
|
proxy.$modal.msgError('获取手术安排详情失败')
|
||||||
}
|
}
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
console.error('获取手术安排详情失败:', error)
|
|
||||||
proxy.$modal.msgError('获取手术安排详情失败')
|
proxy.$modal.msgError('获取手术安排详情失败')
|
||||||
})
|
})
|
||||||
open.value = true
|
open.value = true
|
||||||
@@ -1215,7 +1233,8 @@ function handleDelete(row) {
|
|||||||
}).then(() => {
|
}).then(() => {
|
||||||
getPageList()
|
getPageList()
|
||||||
proxy.$modal.msgSuccess('手术安排已取消')
|
proxy.$modal.msgSuccess('手术安排已取消')
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
|
return
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1232,32 +1251,18 @@ async function handleChargeCharge(row) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('计费按钮被点击,行数据:', row)
|
|
||||||
|
|
||||||
// 检查用户信息中的机构信息
|
|
||||||
console.log('完整的用户信息:', JSON.stringify(userStore, null, 2))
|
|
||||||
console.log('用户机构信息:', {
|
|
||||||
organizationId: userStore.organizationId,
|
|
||||||
orgId: userStore.orgId,
|
|
||||||
tenantId: userStore.tenantId,
|
|
||||||
userInfo: userStore.userInfo
|
|
||||||
})
|
|
||||||
|
|
||||||
// 调用接口获取账户信息
|
// 调用接口获取账户信息
|
||||||
let accountId = null
|
let accountId = null
|
||||||
try {
|
try {
|
||||||
const contractResult = await getContract({ encounterId: row.visitId })
|
const contractResult = await getContract({ encounterId: row.visitId })
|
||||||
console.log('账户信息接口返回:', contractResult)
|
|
||||||
|
|
||||||
if (contractResult.code === 200 && contractResult.data && contractResult.data.length > 0) {
|
if (contractResult.code === 200 && contractResult.data && contractResult.data.length > 0) {
|
||||||
// 从返回数据中提取accountId - data是数组,取第一个元素的accountId
|
// 从返回数据中提取accountId - data是数组,取第一个元素的accountId
|
||||||
accountId = contractResult.data[0].accountId || contractResult.data[0].id
|
accountId = contractResult.data[0].accountId || contractResult.data[0].id
|
||||||
console.log('获取到的accountId:', accountId)
|
|
||||||
} else {
|
} else {
|
||||||
console.warn('获取账户信息失败:', contractResult.msg)
|
proxy.$modal.msgError('获取账户信息失败')
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('调用账户信息接口出错:', error)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置计费弹窗数据 - 直接复制划价页面的逻辑
|
// 设置计费弹窗数据 - 直接复制划价页面的逻辑
|
||||||
@@ -1279,7 +1284,9 @@ async function handleChargeCharge(row) {
|
|||||||
// 添加账户ID
|
// 添加账户ID
|
||||||
accountId: accountId,
|
accountId: accountId,
|
||||||
// 添加手术申请单号用于追溯
|
// 添加手术申请单号用于追溯
|
||||||
sourceBillNo: row.applyId || row.operCode
|
sourceBillNo: row.applyId,
|
||||||
|
//添加计费标志手术计费
|
||||||
|
generateSourceEnum: 6
|
||||||
}
|
}
|
||||||
|
|
||||||
chargeSurgeryInfo.value = {
|
chargeSurgeryInfo.value = {
|
||||||
@@ -1287,21 +1294,12 @@ async function handleChargeCharge(row) {
|
|||||||
surgeryNo: row.operCode
|
surgeryNo: row.operCode
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('计费弹窗数据设置完成:', {
|
|
||||||
chargeDialogTitle: chargeDialogTitle.value,
|
|
||||||
chargePatientInfo: chargePatientInfo.value,
|
|
||||||
chargeSurgeryInfo: chargeSurgeryInfo.value
|
|
||||||
})
|
|
||||||
|
|
||||||
// 打开计费弹窗
|
// 打开计费弹窗
|
||||||
showChargeDialog.value = true
|
showChargeDialog.value = true
|
||||||
console.log('计费弹窗状态:', showChargeDialog.value)
|
|
||||||
|
|
||||||
// 延迟加载处方列表,确保组件已经渲染
|
// 延迟加载处方列表,确保组件已经渲染
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
console.log('nextTick执行,prescriptionRef:', prescriptionRef.value)
|
|
||||||
if (prescriptionRef.value && prescriptionRef.value.getListInfo) {
|
if (prescriptionRef.value && prescriptionRef.value.getListInfo) {
|
||||||
console.log('调用prescriptionRef.getListInfo()')
|
|
||||||
prescriptionRef.value.getListInfo()
|
prescriptionRef.value.getListInfo()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -1314,6 +1312,114 @@ function closeChargeDialog() {
|
|||||||
chargeSurgeryInfo.value = {}
|
chargeSurgeryInfo.value = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 处理医嘱按钮点击事件
|
||||||
|
function handleMedicalAdvice(row) {
|
||||||
|
// 如果没有传入行数据,使用选中的行
|
||||||
|
if (!row && selectedRow.value) {
|
||||||
|
row = selectedRow.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果还是没有行数据,显示提示
|
||||||
|
if (!row) {
|
||||||
|
proxy.$modal.msgWarning('请先选择要开具医嘱的手术安排')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置临时医嘱弹窗数据
|
||||||
|
temporaryPatientInfo.value = {
|
||||||
|
patientName: row.patientName,
|
||||||
|
visitId: row.visitId,
|
||||||
|
operCode: row.operCode,
|
||||||
|
roomCode: row.roomCode,
|
||||||
|
doctorName: userStore.nickName,
|
||||||
|
role: userStore.roles[0],
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化临时医嘱列表
|
||||||
|
temporaryAdvices.value = []
|
||||||
|
|
||||||
|
// 调用计费接口获取数据
|
||||||
|
getPrescriptionList(row.visitId).then((res) => {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
// 过滤数据,只保留 adviceType 值为 1 的药品
|
||||||
|
const filteredItems = res.data.filter(item => {
|
||||||
|
try {
|
||||||
|
// 尝试从 contentJson 中解析数据
|
||||||
|
const contentData = JSON.parse(item.contentJson)
|
||||||
|
const adviceType = Number(contentData.adviceType)
|
||||||
|
return adviceType === 3
|
||||||
|
} catch (e) {
|
||||||
|
// 如果解析失败,尝试使用顶层的 adviceType
|
||||||
|
const adviceType = Number(item.adviceType)
|
||||||
|
return adviceType === 3
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 将过滤后的数据转换为临时医嘱需要的格式
|
||||||
|
temporaryBillingMedicines.value = filteredItems.map(item => {
|
||||||
|
try {
|
||||||
|
// 从 contentJson 中解析详细数据
|
||||||
|
const contentData = JSON.parse(item.contentJson)
|
||||||
|
return {
|
||||||
|
medicineName: contentData.adviceName || item.adviceName || '',
|
||||||
|
specification: contentData.volume || contentData.specification || '',
|
||||||
|
quantity: contentData.quantity || item.quantity || 0,
|
||||||
|
batchNumber: contentData.lotNumber || item.lotNumber || '',
|
||||||
|
unitPrice: contentData.unitPrice || item.unitPrice || 0,
|
||||||
|
subtotal: contentData.totalPrice || item.totalPrice || 0,
|
||||||
|
insuranceType: contentData.insuranceType === 1 ? '医保' : '自费'
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
// 如果解析失败,使用顶层数据
|
||||||
|
return {
|
||||||
|
medicineName: item.adviceName || '',
|
||||||
|
specification: item.specification || '',
|
||||||
|
quantity: item.quantity || 0,
|
||||||
|
batchNumber: item.lotNumber || '',
|
||||||
|
unitPrice: item.unitPrice || 0,
|
||||||
|
subtotal: item.totalPrice || 0,
|
||||||
|
insuranceType: item.insuranceType === 1 ? '医保' : '自费'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 如果没有数据或接口调用失败,初始化空列表
|
||||||
|
temporaryBillingMedicines.value = []
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
temporaryBillingMedicines.value = []
|
||||||
|
})
|
||||||
|
|
||||||
|
// 打开临时医嘱弹窗
|
||||||
|
showTemporaryMedical.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭临时医嘱弹窗
|
||||||
|
function closeTemporaryMedical() {
|
||||||
|
showTemporaryMedical.value = false
|
||||||
|
temporaryPatientInfo.value = {}
|
||||||
|
temporaryBillingMedicines.value = []
|
||||||
|
temporaryAdvices.value = []
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理临时医嘱提交
|
||||||
|
function handleTemporaryMedicalSubmit(data) {
|
||||||
|
// 这里可以调用后端API保存临时医嘱数据
|
||||||
|
proxy.$modal.msgSuccess('临时医嘱提交成功')
|
||||||
|
closeTemporaryMedical()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理临时医嘱取消
|
||||||
|
function handleTemporaryMedicalCancel() {
|
||||||
|
closeTemporaryMedical()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理删除临时医嘱
|
||||||
|
function handleDeleteTemporaryAdvice(index) {
|
||||||
|
temporaryAdvices.value.splice(index, 1)
|
||||||
|
proxy.$modal.msgSuccess('临时医嘱已删除')
|
||||||
|
}
|
||||||
|
|
||||||
// 格式化计费弹窗中的日期
|
// 格式化计费弹窗中的日期
|
||||||
function formatChargeDate(date) {
|
function formatChargeDate(date) {
|
||||||
if (!date) return '-'
|
if (!date) return '-'
|
||||||
@@ -1394,15 +1500,13 @@ function submitForm() {
|
|||||||
proxy.$refs['surgeryRef'].validate((valid) => {
|
proxy.$refs['surgeryRef'].validate((valid) => {
|
||||||
if (valid) {
|
if (valid) {
|
||||||
const submitData = { ...form }
|
const submitData = { ...form }
|
||||||
console.log("scheduleId:", form.scheduleId)
|
|
||||||
if (!form.scheduleId) {
|
if (!form.scheduleId) {
|
||||||
// 新增手术安排
|
// 新增手术安排
|
||||||
addSurgerySchedule(submitData).then((res) => {
|
addSurgerySchedule(submitData).then((res) => {
|
||||||
proxy.$modal.msgSuccess('新增成功')
|
proxy.$modal.msgSuccess('新增成功')
|
||||||
open.value = false
|
open.value = false
|
||||||
getPageList()
|
getPageList()
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
console.error('新增手术安排失败:', error)
|
|
||||||
proxy.$message.error('新增手术安排失败,请检查表单信息')
|
proxy.$message.error('新增手术安排失败,请检查表单信息')
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -1411,8 +1515,7 @@ function submitForm() {
|
|||||||
proxy.$modal.msgSuccess('修改成功')
|
proxy.$modal.msgSuccess('修改成功')
|
||||||
open.value = false
|
open.value = false
|
||||||
getPageList()
|
getPageList()
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
console.error('更新手术安排失败:', error)
|
|
||||||
proxy.$message.error('更新手术安排失败,请检查表单信息')
|
proxy.$message.error('更新手术安排失败,请检查表单信息')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1455,8 +1558,7 @@ function getSurgicalScheduleList() {
|
|||||||
const responseData = res.data.data || res.data
|
const responseData = res.data.data || res.data
|
||||||
applyList.value = responseData.records || []
|
applyList.value = responseData.records || []
|
||||||
applyTotal.value = responseData.total || 0
|
applyTotal.value = responseData.total || 0
|
||||||
}).catch(error => {
|
}).catch(() => {
|
||||||
console.error('获取手术申请列表失败:', error)
|
|
||||||
proxy.$modal.msgError('获取手术申请列表失败,请稍后重试')
|
proxy.$modal.msgError('获取手术申请列表失败,请稍后重试')
|
||||||
applyList.value = []
|
applyList.value = []
|
||||||
applyTotal.value = 0
|
applyTotal.value = 0
|
||||||
|
|||||||
673
openhis-ui-vue3/src/views/surgicalschedule/temporaryMedical.vue
Normal file
673
openhis-ui-vue3/src/views/surgicalschedule/temporaryMedical.vue
Normal file
@@ -0,0 +1,673 @@
|
|||||||
|
<template>
|
||||||
|
<div class="temporary-medical-container">
|
||||||
|
<!-- 患者信息区域 -->
|
||||||
|
<div class="patient-info-section">
|
||||||
|
<div class="patient-info-header">
|
||||||
|
<h3>门诊术中临时医嘱</h3>
|
||||||
|
</div>
|
||||||
|
<div class="patient-info-content">
|
||||||
|
<el-descriptions :column="3" border>
|
||||||
|
<el-descriptions-item label="患者:">{{ patientInfo.patientName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="就诊卡号:">{{ patientInfo.visitId || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="手术单号:">{{ patientInfo.operCode || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="科室:">{{ patientInfo.roomCode || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="医师:">{{ patientInfo.doctorName || '-' }}</el-descriptions-item>
|
||||||
|
<el-descriptions-item label="角色:">{{ patientInfo.role || '-' }}</el-descriptions-item>
|
||||||
|
</el-descriptions>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 已引用计费药品区域 -->
|
||||||
|
<div class="medicine-section">
|
||||||
|
<h4>一、已引用计费药品(待生成医嘱)</h4>
|
||||||
|
<el-table :data="billingMedicines" border style="width: 100%; margin-bottom: 16px" fit>
|
||||||
|
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||||
|
<el-table-column label="药品名称" prop="medicineName" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column label="规格" prop="specification" min-width="100" align="center" />
|
||||||
|
<el-table-column label="数量" prop="quantity" width="80" align="center" />
|
||||||
|
<el-table-column label="批号" prop="batchNumber" min-width="120" align="center" />
|
||||||
|
<el-table-column label="单价" prop="unitPrice" min-width="80" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.unitPrice ? `¥${row.unitPrice}` : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="小计" prop="subtotal" min-width="100" align="center">
|
||||||
|
<template #default="{ row }">
|
||||||
|
{{ row.subtotal ? `¥${row.subtotal}` : '-' }}
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="医保" prop="insuranceType" width="80" align="center" />
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<div class="medicine-summary">
|
||||||
|
<div class="summary-item">医保内:¥{{ insuranceAmount }}</div>
|
||||||
|
<div class="summary-item">自费:¥{{ selfPayAmount }}</div>
|
||||||
|
<div class="summary-item total">总计:¥{{ totalAmount }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 临时医嘱预览区域 -->
|
||||||
|
<div class="advice-section">
|
||||||
|
<h4>二、临时医嘱预览(已生成)</h4>
|
||||||
|
<el-table :data="displayAdvices" border style="width: 100%; margin-bottom: 16px" fit>
|
||||||
|
<el-table-column label="序号" type="index" width="60" align="center" />
|
||||||
|
<el-table-column label="医嘱名称" prop="adviceName" min-width="150" show-overflow-tooltip />
|
||||||
|
<el-table-column label="剂量" prop="dosage" min-width="80" align="center" />
|
||||||
|
<el-table-column label="单位" prop="unit" min-width="80" align="center" />
|
||||||
|
<el-table-column label="用法" prop="usage" min-width="100" show-overflow-tooltip />
|
||||||
|
<el-table-column label="频次" prop="frequency" min-width="80" align="center" />
|
||||||
|
<el-table-column label="执行时间" prop="executeTime" min-width="120" align="center" />
|
||||||
|
<el-table-column label="操作" min-width="120" align="center">
|
||||||
|
<template #default="{ $index }">
|
||||||
|
<el-button link type="primary" @click="handleEditAdvice($index)">编辑</el-button>
|
||||||
|
<el-button link type="danger" @click="handleDeleteAdvice($index)">删除</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 医师电子签名区域 -->
|
||||||
|
<div class="signature-section">
|
||||||
|
<h4>三、医师电子签名</h4>
|
||||||
|
<div class="signature-content">
|
||||||
|
<div class="signature-info">
|
||||||
|
<span>签名医师:</span>
|
||||||
|
<span :class="{ 'unsigned': !isSigned }">{{ isSigned ? currentUser.name : '未签名' }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="signature-info">
|
||||||
|
<span>时间:</span>
|
||||||
|
<span>{{ signatureTime || '-' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部操作按钮 -->
|
||||||
|
<div class="footer-actions">
|
||||||
|
<el-button class="cancel-btn" @click="handleCancel">取消</el-button>
|
||||||
|
<el-button
|
||||||
|
class="sign-submit-btn"
|
||||||
|
:class="{ 'signed': isSigned }"
|
||||||
|
@click="handleSignAndSubmit"
|
||||||
|
>
|
||||||
|
{{ isSigned ? '提交' : '一键签名并生成医嘱' }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 签名密码弹窗 -->
|
||||||
|
<el-dialog v-model="showSignDialog" title="弹窗-签名密码" width="400px" append-to-body>
|
||||||
|
<div class="sign-dialog-content">
|
||||||
|
<p>请输入账户密码:</p>
|
||||||
|
<el-input
|
||||||
|
v-model="signPassword"
|
||||||
|
type="password"
|
||||||
|
placeholder="请输入密码"
|
||||||
|
style="margin-bottom: 16px"
|
||||||
|
@keyup.enter="confirmSign"
|
||||||
|
/>
|
||||||
|
<div class="dialog-actions">
|
||||||
|
<el-button @click="showSignDialog = false">取消</el-button>
|
||||||
|
<el-button type="primary" @click="confirmSign">确认</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 编辑医嘱弹窗 -->
|
||||||
|
<el-dialog v-model="showEditDialog" title="编辑医嘱" width="500px" append-to-body>
|
||||||
|
<div class="edit-dialog-content">
|
||||||
|
<el-form :model="editForm" label-width="80px">
|
||||||
|
<el-form-item label="药品名称">
|
||||||
|
<el-input v-model="editForm.adviceName" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="剂量" required>
|
||||||
|
<el-input v-model.number="editForm.dosage" placeholder="请输入剂量" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="单位">
|
||||||
|
<el-input v-model="editForm.unit" placeholder="请输入单位" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用法" required>
|
||||||
|
<el-select v-model="editForm.usage" placeholder="请选择用法" style="width: 100%">
|
||||||
|
<el-option
|
||||||
|
v-for="dict in method_code"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.label"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="频次">
|
||||||
|
<el-input v-model="editForm.frequency" disabled />
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
<div class="dialog-actions">
|
||||||
|
<el-button @click="handleCancelEdit">取消</el-button>
|
||||||
|
<el-button type="primary" @click="handleSaveEdit">保存</el-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, computed, getCurrentInstance } from 'vue'
|
||||||
|
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||||
|
import useUserStore from '@/store/modules/user'
|
||||||
|
import { checkPassword } from '@/api/surgicalschedule'
|
||||||
|
import { savePrescription } from '@/views/clinicmanagement/bargain/component/api.js'
|
||||||
|
|
||||||
|
// 定义props
|
||||||
|
const props = defineProps({
|
||||||
|
// 患者和医生信息
|
||||||
|
patientInfo: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({
|
||||||
|
patientName: '',
|
||||||
|
visitId: '',
|
||||||
|
operCode: '',
|
||||||
|
roomCode: '',
|
||||||
|
doctorName: '',
|
||||||
|
role: ''
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// 计费药品列表
|
||||||
|
billingMedicines: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
// 临时医嘱列表
|
||||||
|
temporaryAdvices: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 定义emit事件
|
||||||
|
const emit = defineEmits(['submit', 'cancel', 'delete-advice', 'update:temporaryAdvices'])
|
||||||
|
|
||||||
|
// 用户store
|
||||||
|
const userStore = useUserStore()
|
||||||
|
|
||||||
|
// 获取当前实例
|
||||||
|
const { proxy } = getCurrentInstance()
|
||||||
|
|
||||||
|
// 获取字典数据(与门诊医生站保持一致)
|
||||||
|
const { method_code } = proxy.useDict('method_code')
|
||||||
|
|
||||||
|
// 响应式数据
|
||||||
|
const isSigned = ref(false)
|
||||||
|
const signatureTime = ref('')
|
||||||
|
const showSignDialog = ref(false)
|
||||||
|
const signPassword = ref('')
|
||||||
|
const showEditDialog = ref(false)
|
||||||
|
const currentEditIndex = ref(-1)
|
||||||
|
const editForm = ref({
|
||||||
|
adviceName: '',
|
||||||
|
dosage: '',
|
||||||
|
unit: '',
|
||||||
|
usage: '',
|
||||||
|
frequency: '临时'
|
||||||
|
})
|
||||||
|
|
||||||
|
// 计算属性
|
||||||
|
const currentUser = computed(() => ({
|
||||||
|
name: userStore.name || '未知用户',
|
||||||
|
id: userStore.id
|
||||||
|
}))
|
||||||
|
|
||||||
|
const insuranceAmount = computed(() => {
|
||||||
|
return props.billingMedicines
|
||||||
|
.filter(med => med.insuranceType === '甲' || med.insuranceType === '乙')
|
||||||
|
.reduce((sum, med) => sum + (med.subtotal || 0), 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
const selfPayAmount = computed(() => {
|
||||||
|
return props.billingMedicines
|
||||||
|
.filter(med => !med.insuranceType || med.insuranceType === '自费')
|
||||||
|
.reduce((sum, med) => sum + (med.subtotal || 0), 0)
|
||||||
|
})
|
||||||
|
|
||||||
|
const totalAmount = computed(() => {
|
||||||
|
return insuranceAmount.value + selfPayAmount.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 将计费药品转换为临时医嘱数据
|
||||||
|
const convertedAdvices = computed(() => {
|
||||||
|
return props.billingMedicines.map((medicine, index) => {
|
||||||
|
// 解析规格中的数值和单位
|
||||||
|
const specMatch = medicine.specification ? medicine.specification.match(/(\d+)(\D+)/) : null
|
||||||
|
const specValue = specMatch ? parseInt(specMatch[1]) : 1
|
||||||
|
const specUnit = specMatch ? specMatch[2] : 'ml'
|
||||||
|
|
||||||
|
// 计算剂量 = 规格数值 × 数量
|
||||||
|
const dosage = specValue * (medicine.quantity || 1)
|
||||||
|
|
||||||
|
// 根据药品名称判断用法
|
||||||
|
let usage = '静脉注射'
|
||||||
|
if (medicine.medicineName && medicine.medicineName.includes('注射液')) {
|
||||||
|
usage = '静脉注射'
|
||||||
|
} else if (medicine.medicineName && medicine.medicineName.includes('片')) {
|
||||||
|
usage = '口服'
|
||||||
|
} else if (medicine.medicineName && medicine.medicineName.includes('胶囊')) {
|
||||||
|
usage = '口服'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: index + 1,
|
||||||
|
adviceName: medicine.medicineName || '',
|
||||||
|
dosage: dosage,
|
||||||
|
unit: specUnit,
|
||||||
|
usage: usage,
|
||||||
|
frequency: '临时',
|
||||||
|
executeTime: new Date().toLocaleString('zh-CN'),
|
||||||
|
originalMedicine: medicine
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
// 使用转换后的数据或传入的临时医嘱数据
|
||||||
|
const displayAdvices = computed(() => {
|
||||||
|
return props.temporaryAdvices.length > 0 ? props.temporaryAdvices : convertedAdvices.value
|
||||||
|
})
|
||||||
|
|
||||||
|
// 方法
|
||||||
|
const handleSign = () => {
|
||||||
|
showSignDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 编辑医嘱
|
||||||
|
const handleEditAdvice = (index) => {
|
||||||
|
const advice = displayAdvices.value[index]
|
||||||
|
currentEditIndex.value = index
|
||||||
|
editForm.value = {
|
||||||
|
adviceName: advice.adviceName,
|
||||||
|
dosage: advice.dosage,
|
||||||
|
unit: advice.unit,
|
||||||
|
usage: advice.usage,
|
||||||
|
frequency: advice.frequency
|
||||||
|
}
|
||||||
|
showEditDialog.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存编辑
|
||||||
|
const handleSaveEdit = () => {
|
||||||
|
if (!editForm.value.dosage || !editForm.value.usage) {
|
||||||
|
ElMessage.warning('请填写剂量和用法')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建更新后的数据
|
||||||
|
const updatedAdvice = {
|
||||||
|
...displayAdvices.value[currentEditIndex.value],
|
||||||
|
...editForm.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建完整的更新后列表
|
||||||
|
const updatedAdvices = [...displayAdvices.value]
|
||||||
|
updatedAdvices[currentEditIndex.value] = updatedAdvice
|
||||||
|
|
||||||
|
// 通知父组件更新数据
|
||||||
|
emit('update:temporaryAdvices', updatedAdvices)
|
||||||
|
|
||||||
|
showEditDialog.value = false
|
||||||
|
ElMessage.success('编辑成功')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取消编辑
|
||||||
|
const handleCancelEdit = () => {
|
||||||
|
showEditDialog.value = false
|
||||||
|
currentEditIndex.value = -1
|
||||||
|
editForm.value = {
|
||||||
|
adviceName: '',
|
||||||
|
dosage: '',
|
||||||
|
unit: '',
|
||||||
|
usage: '',
|
||||||
|
frequency: '临时'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const confirmSign = async () => {
|
||||||
|
if (!signPassword.value) {
|
||||||
|
ElMessage.warning('请输入密码')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用后端接口验证密码
|
||||||
|
try {
|
||||||
|
const response = await checkPassword({
|
||||||
|
password: signPassword.value
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response.code === 200 && response.data) {
|
||||||
|
isSigned.value = true
|
||||||
|
signatureTime.value = new Date().toLocaleString('zh-CN')
|
||||||
|
showSignDialog.value = false
|
||||||
|
signPassword.value = ''
|
||||||
|
ElMessage.success('签名成功')
|
||||||
|
|
||||||
|
// 签名成功后自动提交
|
||||||
|
handleSubmit()
|
||||||
|
} else {
|
||||||
|
ElMessage.error('密码错误,请重新输入')
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('签名失败,请重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSignAndSubmit = () => {
|
||||||
|
if (isSigned.value) {
|
||||||
|
// 如果已经签名,直接提交
|
||||||
|
handleSubmit()
|
||||||
|
} else {
|
||||||
|
// 如果未签名,打开签名弹窗
|
||||||
|
handleSign()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleDeleteAdvice = (index) => {
|
||||||
|
ElMessageBox.confirm('确定要删除这条医嘱吗?', '提示', {
|
||||||
|
confirmButtonText: '确定',
|
||||||
|
cancelButtonText: '取消',
|
||||||
|
type: 'warning'
|
||||||
|
}).then(() => {
|
||||||
|
// 检查数据来源
|
||||||
|
if (props.temporaryAdvices.length > 0) {
|
||||||
|
// 如果使用的是传入的临时医嘱数据,通知父组件删除
|
||||||
|
emit('delete-advice', index)
|
||||||
|
} else {
|
||||||
|
// 如果使用的是转换的数据,需要构建新的临时医嘱数据并通知父组件
|
||||||
|
const updatedAdvices = [...displayAdvices.value]
|
||||||
|
updatedAdvices.splice(index, 1)
|
||||||
|
emit('update:temporaryAdvices', updatedAdvices)
|
||||||
|
}
|
||||||
|
ElMessage.success('删除成功')
|
||||||
|
}).catch(() => {
|
||||||
|
// 用户取消删除
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSubmit = async () => {
|
||||||
|
if (!isSigned.value) {
|
||||||
|
ElMessage.warning('请先进行电子签名')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查是否有医嘱数据
|
||||||
|
if (displayAdvices.value.length === 0) {
|
||||||
|
ElMessage.warning('没有可保存的医嘱数据')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建保存医嘱的请求参数
|
||||||
|
const saveData = {
|
||||||
|
organizationId: props.patientInfo.organizationId || 1, // 默认科室ID
|
||||||
|
adviceSaveList: displayAdvices.value.map((advice, index) => {
|
||||||
|
// 获取原始药品数据
|
||||||
|
const originalMedicine = advice.originalMedicine
|
||||||
|
|
||||||
|
// 解析contentJson
|
||||||
|
let contentJsonData = {}
|
||||||
|
if (originalMedicine && originalMedicine.contentJson) {
|
||||||
|
try {
|
||||||
|
contentJsonData = JSON.parse(originalMedicine.contentJson)
|
||||||
|
} catch (e) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构造请求参数(与门诊医生工作站完全一致)
|
||||||
|
return {
|
||||||
|
// 基础信息
|
||||||
|
dbOpType: originalMedicine?.requestId ? '2' : '1', // 有请求ID则为修改,否则为新增
|
||||||
|
adviceType: originalMedicine?.adviceType || 1, // 使用原始类型或默认3
|
||||||
|
requestId: originalMedicine?.requestId,
|
||||||
|
chargeItemId: originalMedicine?.chargeItemId,
|
||||||
|
contentJson: originalMedicine?.contentJson,
|
||||||
|
categoryCode: contentJsonData.categoryCode || originalMedicine?.categoryCode,
|
||||||
|
positionId: originalMedicine?.positionId || contentJsonData.positionId,
|
||||||
|
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: originalMedicine?.quantity || 1,
|
||||||
|
dispensePerDuration: originalMedicine?.dispensePerDuration || contentJsonData.dispensePerDuration,
|
||||||
|
unitCode: contentJsonData.unitCode || originalMedicine?.unitCode || advice.unit,
|
||||||
|
unitPrice: originalMedicine?.unitPrice || contentJsonData.unitPrice || 0,
|
||||||
|
totalPrice: originalMedicine?.totalPrice || contentJsonData.totalPrice || 0,
|
||||||
|
definitionId: contentJsonData.definitionId || originalMedicine?.definitionId,
|
||||||
|
definitionDetailId: contentJsonData.definitionDetailId || originalMedicine?.definitionDetailId,
|
||||||
|
lotNumber: originalMedicine?.lotNumber || contentJsonData.lotNumber,
|
||||||
|
|
||||||
|
// 状态和类型
|
||||||
|
statusEnum: originalMedicine?.statusEnum || 2, // 默认状态:已发送
|
||||||
|
categoryEnum: originalMedicine?.categoryEnum || contentJsonData.categoryEnum,
|
||||||
|
|
||||||
|
// 药品/诊疗信息
|
||||||
|
adviceDefinitionId: contentJsonData.adviceDefinitionId || originalMedicine?.adviceDefinitionId,
|
||||||
|
adviceTableName: contentJsonData.adviceTableName || originalMedicine?.adviceTableName,
|
||||||
|
adviceName: advice.adviceName,
|
||||||
|
minUnitQuantity: originalMedicine?.minUnitQuantity || contentJsonData.minUnitQuantity,
|
||||||
|
|
||||||
|
// 患者和就诊信息
|
||||||
|
patientId: props.patientInfo.patientId,
|
||||||
|
practitionerId: currentUser.value.id || originalMedicine?.practitionerId, // 开方医生
|
||||||
|
locationId: contentJsonData.locationId || originalMedicine?.locationId,
|
||||||
|
performLocation: originalMedicine?.performLocation || contentJsonData.performLocation,
|
||||||
|
founderOrgId: currentUser.value.id || originalMedicine?.founderOrgId, // 开方人科室
|
||||||
|
encounterId: props.patientInfo.visitId || contentJsonData.encounterId || originalMedicine?.encounterId,
|
||||||
|
accountId: contentJsonData.accountId || originalMedicine?.accountId,
|
||||||
|
conditionId: contentJsonData.conditionId || originalMedicine?.conditionId,
|
||||||
|
encounterDiagnosisId: originalMedicine?.encounterDiagnosisId || contentJsonData.encounterDiagnosisId,
|
||||||
|
conditionDefinitionId: originalMedicine?.conditionDefinitionId || contentJsonData.conditionDefinitionId,
|
||||||
|
|
||||||
|
// 治疗信息
|
||||||
|
therapyEnum: originalMedicine?.therapyEnum || contentJsonData.therapyEnum || 1, // 默认临时医嘱
|
||||||
|
methodCode: advice.usage, // 用法(使用转换后的中文名称)
|
||||||
|
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,
|
||||||
|
|
||||||
|
// 分组信息
|
||||||
|
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
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 调用保存医嘱接口
|
||||||
|
const response = await savePrescription(saveData)
|
||||||
|
|
||||||
|
if (response.code === 200) {
|
||||||
|
ElMessage.success('临时医嘱保存成功')
|
||||||
|
|
||||||
|
// 构建提交数据
|
||||||
|
const submitData = {
|
||||||
|
patientInfo: props.patientInfo,
|
||||||
|
billingMedicines: props.billingMedicines,
|
||||||
|
temporaryAdvices: displayAdvices.value,
|
||||||
|
signature: {
|
||||||
|
doctorName: currentUser.value.name,
|
||||||
|
signatureTime: signatureTime.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 通知父组件
|
||||||
|
emit('submit', submitData)
|
||||||
|
} else {
|
||||||
|
ElMessage.error('保存医嘱失败:' + (response.msg || response.message || '未知错误'))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
ElMessage.error('保存医嘱失败,请重试')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
// 通知父组件关闭弹窗
|
||||||
|
emit('cancel')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.temporary-medical-container {
|
||||||
|
padding: 20px;
|
||||||
|
max-height: 80vh;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-info-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.patient-info-header h3 {
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
color: #333;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medicine-section,
|
||||||
|
.advice-section,
|
||||||
|
.signature-section {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medicine-section h4,
|
||||||
|
.advice-section h4,
|
||||||
|
.signature-section h4 {
|
||||||
|
margin: 0 0 16px 0;
|
||||||
|
color: #666;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.medicine-summary {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 20px;
|
||||||
|
padding: 12px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-item {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-item.total {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-content {
|
||||||
|
padding: 16px;
|
||||||
|
background-color: #f5f7fa;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-info {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-info span:first-child {
|
||||||
|
font-weight: bold;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.unsigned {
|
||||||
|
color: #f56c6c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signature-actions {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
gap: 30px;
|
||||||
|
margin-top: 24px;
|
||||||
|
padding-top: 16px;
|
||||||
|
border-top: 1px solid #e4e7ed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn {
|
||||||
|
width: 120px;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: 1px solid #dcdfe6;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-btn:hover {
|
||||||
|
border-color: #409eff;
|
||||||
|
color: #409eff;
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 4px 8px rgba(64, 158, 255, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-submit-btn {
|
||||||
|
width: 200px;
|
||||||
|
height: 48px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: bold;
|
||||||
|
background: linear-gradient(135deg, #67c23a 0%, #85ce61 100%);
|
||||||
|
border: none;
|
||||||
|
color: white;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 8px rgba(103, 194, 58, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-submit-btn:hover {
|
||||||
|
transform: translateY(-3px);
|
||||||
|
box-shadow: 0 6px 12px rgba(103, 194, 58, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-submit-btn:active {
|
||||||
|
transform: translateY(-1px);
|
||||||
|
box-shadow: 0 2px 4px rgba(103, 194, 58, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-submit-btn.signed {
|
||||||
|
background: linear-gradient(135deg, #409eff 0%, #66b1ff 100%);
|
||||||
|
box-shadow: 0 4px 8px rgba(64, 158, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-submit-btn.signed:hover {
|
||||||
|
box-shadow: 0 6px 12px rgba(64, 158, 255, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sign-dialog-content p {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dialog-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-descriptions) {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-descriptions__label) {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user