Merge remote-tracking branch 'origin/develop' into develop

This commit is contained in:
2026-03-31 16:10:42 +08:00
13 changed files with 463 additions and 229 deletions

View File

@@ -186,6 +186,14 @@ public class DiagTreatMAppServiceImpl implements IDiagTreatMAppService {
public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey, public R<?> getDiseaseTreatmentPage(DiagnosisTreatmentSelParam DiagnosisTreatmentSelParam, String searchKey,
Integer pageNo, Integer pageSize, HttpServletRequest request) { Integer pageNo, Integer pageSize, HttpServletRequest request) {
// 如果没有指定状态默认只查询启用状态status_enum=2避免显示未启用的项目导致保存失败
if (DiagnosisTreatmentSelParam == null) {
DiagnosisTreatmentSelParam = new DiagnosisTreatmentSelParam();
}
if (DiagnosisTreatmentSelParam.getStatusEnum() == null) {
DiagnosisTreatmentSelParam.setStatusEnum(PublicationStatus.ACTIVE.getValue());
}
// 临时保存ybType值并从参数对象中移除避免HisQueryUtils构建yb_type条件 // 临时保存ybType值并从参数对象中移除避免HisQueryUtils构建yb_type条件
String ybTypeValue = null; String ybTypeValue = null;
if (DiagnosisTreatmentSelParam != null && StringUtils.isNotEmpty(DiagnosisTreatmentSelParam.getYbType())) { if (DiagnosisTreatmentSelParam != null && StringUtils.isNotEmpty(DiagnosisTreatmentSelParam.getYbType())) {

View File

@@ -19,4 +19,11 @@ public interface IDoctorStationInspectionLabApplyService {
* @return 删除结果 * @return 删除结果
*/ */
R<?> deleteInspectionLabApply(String applyNo); R<?> deleteInspectionLabApply(String applyNo);
/**
* 生成检验申请单号
* 规则LS + YYYYMMDD + 5位流水号每日从1开始递增
* @return 申请单号
*/
String generateApplyNo();
} }

View File

@@ -1,6 +1,7 @@
package com.openhis.web.doctorstation.appservice.impl; package com.openhis.web.doctorstation.appservice.impl;
import com.core.common.core.domain.R; import com.core.common.core.domain.R;
import com.core.common.core.redis.RedisCache;
import com.core.common.enums.DelFlag; import com.core.common.enums.DelFlag;
import com.core.common.utils.SecurityUtils; import com.core.common.utils.SecurityUtils;
import com.openhis.common.enums.DbOpType; import com.openhis.common.enums.DbOpType;
@@ -35,6 +36,8 @@ import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
@@ -76,6 +79,9 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
@Autowired @Autowired
private IServiceRequestService serviceRequestService; private IServiceRequestService serviceRequestService;
@Autowired
private RedisCache redisCache;
/** /**
* 保存检验申请单信息 * 保存检验申请单信息
* @param doctorStationLabApplyDto * @param doctorStationLabApplyDto
@@ -116,8 +122,8 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
//设置从表申请单明细的申请单号 //设置从表申请单明细的申请单号
inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo()); inspectionLabApplyItem.setApplyNo(doctorStationLabApplyDto.getApplyNo());
//检验科代码,取值于检验申请单 //执行科室代码,取值于检验申请单明细(前端传递的字典值)
inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyDto.getApplyDeptCode()); inspectionLabApplyItem.setPerformDeptCode(doctorStationLabApplyItemDto.getPerformDeptCode());
//同主表状态,可单独回写 //同主表状态,可单独回写
inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus()); inspectionLabApplyItem.setItemStatus(doctorStationLabApplyDto.getApplyStatus());
// 设置项目序号 (打印顺序),按照遍历序号进行排序 // 设置项目序号 (打印顺序),按照遍历序号进行排序
@@ -194,6 +200,12 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
} }
} }
// 如果没有指定执行科室,使用当前医生所在的科室作为默认执行科室
if (positionId == null) {
positionId = SecurityUtils.getDeptId();
log.debug("检验项目未指定执行科室,使用当前科室:{}", positionId);
}
// 4. 创建医嘱保存对象 // 4. 创建医嘱保存对象
AdviceSaveDto adviceSaveDto = new AdviceSaveDto(); AdviceSaveDto adviceSaveDto = new AdviceSaveDto();
// 设置医嘱操作类型 // 设置医嘱操作类型
@@ -279,14 +291,41 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
} }
/** /**
* 根据申请单号查询检验申请单 * 根据申请单号查询检验申请单(包含检验项目明细)
* *
* @param applyNo * @param applyNo
* @return * @return
*/ */
@Override @Override
public Object getInspectionApplyByApplyNo(String applyNo) { public Object getInspectionApplyByApplyNo(String applyNo) {
return doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo); // 查询主表数据
DoctorStationLabApplyDto applyDto = (DoctorStationLabApplyDto) doctorStationLabApplyMapper.getInspectionApplyByApplyNo(applyNo);
if (applyDto == null) {
return null;
}
// 查询检验项目明细
List<InspectionLabApplyItem> itemList = inspectionLabApplyItemService.list(
new QueryWrapper<InspectionLabApplyItem>()
.eq("apply_no", applyNo)
.eq("delete_flag", "0")
.orderByAsc("item_seq")
);
// 转换为 DTO 列表
List<DoctorStationLabApplyItemDto> itemDtoList = new ArrayList<>();
if (itemList != null && !itemList.isEmpty()) {
for (InspectionLabApplyItem item : itemList) {
DoctorStationLabApplyItemDto itemDto = new DoctorStationLabApplyItemDto();
BeanUtils.copyProperties(item, itemDto);
itemDtoList.add(itemDto);
}
// 从第一个明细项获取执行科室代码
applyDto.setExecuteDepartment(itemList.get(0).getPerformDeptCode());
}
applyDto.setLabApplyItemList(itemDtoList);
return applyDto;
} }
/** /**
@@ -514,4 +553,38 @@ public class DoctorStationLabApplyServiceImpl implements IDoctorStationInspectio
} }
} }
/**
* 生成检验申请单号
* 规则LS + YYYYMMDD + 5位流水号每日从1开始递增
* 支持并发安全:使用 Redis 原子递增保证唯一性
* @return 申请单号
*/
@Override
public String generateApplyNo() {
// 获取当前日期
LocalDate today = LocalDate.now();
String dateStr = today.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
// 生成前缀LS + 日期
String prefix = "LS" + dateStr;
// Redis key 用于存储当天的流水号
String redisKey = "lab_apply_no:" + dateStr;
// 使用 Redis 原子递增获取流水号(并发安全)
long sequence = redisCache.incr(redisKey, 1);
// 设置 Redis key 过期时间为 2 天,避免数据积累
redisCache.expire(redisKey, 2 * 24 * 60 * 60);
// 格式化流水号为5位不足前补0
String sequenceStr = String.format("%05d", sequence);
// 生成完整的申请单号
String applyNo = prefix + sequenceStr;
log.debug("生成检验申请单号:{}", applyNo);
return applyNo;
}
} }

View File

@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*;
import javax.validation.Valid; import javax.validation.Valid;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.util.HashMap;
import java.util.Map;
/** /**
* 门诊医生站-检验控制器 * 门诊医生站-检验控制器
@@ -62,4 +64,18 @@ public class DoctorStationInspectionLabApplyController {
log.debug("删除检验申请单:{}", applyNo); log.debug("删除检验申请单:{}", applyNo);
return R.ok(iDoctorStationInspectionLabApplyService.deleteInspectionLabApply(applyNo)); return R.ok(iDoctorStationInspectionLabApplyService.deleteInspectionLabApply(applyNo));
} }
/**
* 生成检验申请单号
* 规则LS + YYYYMMDD + 5位流水号每日从1开始递增
* @return 申请单号
*/
@GetMapping(value = "/generate-apply-no")
public R<?> generateApplyNo(){
log.debug("生成检验申请单号");
String applyNo = iDoctorStationInspectionLabApplyService.generateApplyNo();
Map<String, String> result = new HashMap<>();
result.put("applyNo", applyNo);
return R.ok(result);
}
} }

View File

@@ -135,6 +135,10 @@ public class DoctorStationLabApplyDto {
* 就诊id * 就诊id
*/ */
private Long encounterId; private Long encounterId;
/**
* 执行科室代码(从明细项获取)
*/
private String executeDepartment;
/** /**
* 检验项目数据列表 * 检验项目数据列表
*/ */

View File

@@ -11,6 +11,11 @@ import java.util.List;
*/ */
@Repository @Repository
public interface DoctorStationLabApplyMapper { public interface DoctorStationLabApplyMapper {
/**
* 根据申请单号查询检验申请单
* @param applyNo 申请单号
* @return 检验申请单DTO
*/
Object getInspectionApplyByApplyNo(String applyNo); Object getInspectionApplyByApplyNo(String applyNo);
/** /**

View File

@@ -146,6 +146,9 @@ public class InspectionPackageController extends BaseController {
if (inspectionPackage.getIsDisabled() != null) { if (inspectionPackage.getIsDisabled() != null) {
queryWrapper.eq("is_disabled", inspectionPackage.getIsDisabled()); queryWrapper.eq("is_disabled", inspectionPackage.getIsDisabled());
} }
if (inspectionPackage.getUserId() != null && !inspectionPackage.getUserId().isEmpty()) {
queryWrapper.like("user_id", inspectionPackage.getUserId());
}
} }
// 默认只查询未删除的记录 // 默认只查询未删除的记录

View File

@@ -4,9 +4,36 @@
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.openhis.web.doctorstation.mapper.DoctorStationLabApplyMapper"> <mapper namespace="com.openhis.web.doctorstation.mapper.DoctorStationLabApplyMapper">
<!-- 根据申请单号查询检验申请单 --> <!-- 根据申请单号查询检验申请单(返回完整字段) -->
<select id="getInspectionApplyByApplyNo" resultType="com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto"> <select id="getInspectionApplyByApplyNo" resultType="com.openhis.web.doctorstation.dto.DoctorStationLabApplyDto">
SELECT apply_no AS applyNo SELECT
apply_no AS applyNo,
patient_id AS patientId,
patient_name AS patientName,
medicalrecord_number AS medicalrecordNumber,
natureof_cost AS natureofCost,
visit_no AS visitNo,
apply_dept_code AS applyDeptCode,
apply_department AS applyDepartment,
apply_doc_code AS applyDocCode,
apply_doc_name AS applyDocName,
apply_time AS applyTime,
clinic_diag AS clinicDiag,
clinic_desc AS clinicDesc,
contraindication AS contraindication,
medical_history_summary AS medicalHistorySummary,
purposeof_inspection AS purposeofInspection,
physical_examination AS physicalExamination,
inspection_item AS inspectionItem,
specimen_type_code AS specimenTypeCode,
specimen_name AS specimenName,
priority_code AS priorityCode,
apply_status AS applyStatus,
apply_remark AS applyRemark,
create_time AS createTime,
operator_id AS operatorId,
create_by AS createBy,
tenant_id AS tenantId
FROM lab_apply FROM lab_apply
WHERE apply_no = #{applyNo} WHERE apply_no = #{applyNo}
AND delete_flag = '0' AND delete_flag = '0'

View File

@@ -959,7 +959,7 @@ export function saveInspectionApplication(data) {
} }
/** /**
* 查询申请单号 * 查询申请单号是否存在
*/ */
export function checkInspectionApplicationNo(applyNo){ export function checkInspectionApplicationNo(applyNo){
// 如果申请单号为空返回一个rejected promise以避免向后端发送空值 // 如果申请单号为空返回一个rejected promise以避免向后端发送空值
@@ -979,6 +979,19 @@ export function checkInspectionApplicationNo(applyNo){
}); });
} }
/**
* 根据申请单号获取检验申请单详情
* @param {string} applyNo 申请单号
* @returns {Promise} { code: 200, data: DoctorStationLabApplyDto }
*/
export function getInspectionApplyDetail(applyNo) {
return request({
url: '/doctor-station/inspection/apply-no',
method: 'get',
params: { applyNo: applyNo },
});
}
/** /**
* 删除检验申请单 * 删除检验申请单
* @param {string} applyNo 申请单号 * @param {string} applyNo 申请单号
@@ -990,6 +1003,18 @@ export function deleteInspectionApplication(applyNo) {
}); });
} }
/**
* 生成检验申请单号
* 规则LS + YYYYMMDD + 5位流水号每日从1开始递增
* @returns {Promise} { code: 200, data: { applyNo: string } }
*/
export function generateInspectionApplyNo() {
return request({
url: '/doctor-station/inspection/generate-apply-no',
method: 'get',
});
}
/** /**
* 分页获取检验类型列表(分类) * 分页获取检验类型列表(分类)
* @param {Object} queryParams - 查询参数 * @param {Object} queryParams - 查询参数

View File

@@ -15,6 +15,7 @@
<!-- 会诊申请列表 --> <!-- 会诊申请列表 -->
<div class="consultation-list"> <div class="consultation-list">
<el-table <el-table
ref="consultationTableRef"
:data="consultationList" :data="consultationList"
border border
stripe stripe
@@ -807,6 +808,9 @@ const handleRowClick = async (row) => {
console.log('行点击处理完成selectedRow:', selectedRow.value); console.log('行点击处理完成selectedRow:', selectedRow.value);
}; };
// 表格引用
const consultationTableRef = ref(null);
// 新增 // 新增
const handleNew = () => { const handleNew = () => {
console.log('点击新增按钮'); console.log('点击新增按钮');
@@ -816,6 +820,11 @@ const handleNew = () => {
formRef.value.clearValidate(); formRef.value.clearValidate();
} }
// 🔧 Bug #262 修复:清除表格的当前行选中状态,确保后续点击行能正常触发 current-change 事件
if (consultationTableRef.value) {
consultationTableRef.value.setCurrentRow(null);
}
selectedRow.value = null; selectedRow.value = null;
// 获取当前登录用户信息 // 获取当前登录用户信息
@@ -841,7 +850,8 @@ const handleNew = () => {
patientName: props.patientInfo.patientName || '', patientName: props.patientInfo.patientName || '',
genderText: props.patientInfo.genderEnum === 1 ? '男' : '女', genderText: props.patientInfo.genderEnum === 1 ? '男' : '女',
age: props.patientInfo.age || '', age: props.patientInfo.age || '',
patientBusNo: props.patientInfo.busNo || '', // 🔧 Bug #263 修复:就诊卡号应取值于 identifierNo而非 busNo
patientBusNo: props.patientInfo.identifierNo || '',
requestingPhysician: userStore.nickName || '', requestingPhysician: userStore.nickName || '',
department: userStore.orgName || '', department: userStore.orgName || '',
provisionalDiagnosis: '', provisionalDiagnosis: '',
@@ -922,7 +932,8 @@ const handleSave = async () => {
patientId: props.patientInfo.patientId, patientId: props.patientInfo.patientId,
encounterId: props.patientInfo.encounterId, encounterId: props.patientInfo.encounterId,
patientName: props.patientInfo.patientName, patientName: props.patientInfo.patientName,
patientBusNo: props.patientInfo.busNo, // 🔧 Bug #263 修复:就诊卡号应取值于 identifierNo
patientBusNo: props.patientInfo.identifierNo || '',
patientIdentifierNo: props.patientInfo.identifierNo, patientIdentifierNo: props.patientInfo.identifierNo,
genderEnum: props.patientInfo.genderEnum, genderEnum: props.patientInfo.genderEnum,
age: ageValue, age: ageValue,

View File

@@ -181,11 +181,12 @@
style="width: 100%" style="width: 100%"
:class="{ 'is-error': validationErrors.executeDepartment }" :class="{ 'is-error': validationErrors.executeDepartment }"
> >
<el-option label="医学检验科" value="medical_lab" /> <el-option
<el-option label="放射科" value="radiology" /> v-for="item in inspection_lab_dept"
<el-option label="超声科" value="ultrasound" /> :key="item.value"
<el-option label="病理科" value="pathology" /> :label="item.label"
<el-option label="核医学科" value="nuclear_medicine" /> :value="item.value"
/>
</el-select> </el-select>
</el-form-item> </el-form-item>
@@ -294,19 +295,19 @@
</template> </template>
<el-row type="flex" :gutter="16" wrap> <el-row type="flex" :gutter="16" wrap>
<el-col :xs="12" :sm="6" :md="6" :lg="6"> <el-col :xs="12" :sm="6" :md="6" :lg="6">
<!-- 🔧 Bug #268 修复只有急标记能编辑 --> <!-- 只有急标记能编辑 -->
<el-checkbox v-model="formData.priorityCode" :true-value="1" :false-value="0"></el-checkbox> <el-checkbox v-model="formData.priorityCode" :true-value="1" :false-value="0"></el-checkbox>
</el-col> </el-col>
<el-col :xs="12" :sm="6" :md="6" :lg="6"> <el-col :xs="12" :sm="6" :md="6" :lg="6">
<!-- 🔧 Bug #268 修复收费标记默认不勾选并不可编辑 --> <!-- 收费标记默认不勾选并不可编辑 -->
<el-checkbox v-model="formData.applyStatus" :true-value="1" :false-value="0" disabled>收费</el-checkbox> <el-checkbox v-model="formData.applyStatus" :true-value="1" :false-value="0" disabled>收费</el-checkbox>
</el-col> </el-col>
<el-col :xs="12" :sm="6" :md="6" :lg="6"> <el-col :xs="12" :sm="6" :md="6" :lg="6">
<!-- 🔧 Bug #268 修复退费标记默认不勾选并不可编辑 --> <!-- 退费标记默认不勾选并不可编辑 -->
<el-checkbox v-model="formData.needRefund" :true-value="true" :false-value="false" disabled>退费</el-checkbox> <el-checkbox v-model="formData.needRefund" :true-value="true" :false-value="false" disabled>退费</el-checkbox>
</el-col> </el-col>
<el-col :xs="12" :sm="6" :md="6" :lg="6"> <el-col :xs="12" :sm="6" :md="6" :lg="6">
<!-- 🔧 Bug #268 修复执行标记默认不勾选并不可编辑 --> <!-- 执行标记默认不勾选并不可编辑 -->
<el-checkbox v-model="formData.needExecute" :true-value="true" :false-value="false" disabled>执行</el-checkbox> <el-checkbox v-model="formData.needExecute" :true-value="true" :false-value="false" disabled>执行</el-checkbox>
</el-col> </el-col>
</el-row> </el-row>
@@ -547,7 +548,9 @@ import {
saveInspectionApplication, saveInspectionApplication,
getInspectionTypeList, getInspectionTypeList,
getInspectionItemList, getInspectionItemList,
getEncounterDiagnosis getEncounterDiagnosis,
generateInspectionApplyNo,
getInspectionApplyDetail
} from '../api' } from '../api'
import useUserStore from '@/store/modules/user.js' import useUserStore from '@/store/modules/user.js'
// 迁移到 hiprint // 迁移到 hiprint
@@ -557,7 +560,7 @@ import { debounce } from 'lodash-es'
// 获取当前组件实例和字典 // 获取当前组件实例和字典
const { proxy } = getCurrentInstance() const { proxy } = getCurrentInstance()
const { activity_category_code } = proxy.useDict('activity_category_code') const { activity_category_code, inspection_lab_dept } = proxy.useDict('activity_category_code', 'inspection_lab_dept')
// 获取"检验"分类的字典值(与检验项目设置维护保持一致) // 获取"检验"分类的字典值(与检验项目设置维护保持一致)
const inspectionCategoryCode = computed(() => { const inspectionCategoryCode = computed(() => {
@@ -630,7 +633,6 @@ async function initData() {
formData.clinicDiag = '' formData.clinicDiag = ''
} }
} catch (error) { } catch (error) {
console.error('获取主诊断信息失败:', error)
formData.clinicDiag = '' formData.clinicDiag = ''
} }
} }
@@ -658,7 +660,7 @@ const formData = reactive({
applyTime: new Date(), applyTime: new Date(),
applyDepartment: '', applyDepartment: '',
applyDocName: '', applyDocName: '',
executeDepartment: 'medical_lab', executeDepartment: '',
clinicDesc: '', clinicDesc: '',
contraindication: '', contraindication: '',
clinicDiag: '', clinicDiag: '',
@@ -669,7 +671,8 @@ const formData = reactive({
inspectionItemsText: '', inspectionItemsText: '',
applyRemark: '', applyRemark: '',
priorityCode: 0, priorityCode: 0,
applyStatus: 1, // 收费标记默认不勾选
applyStatus: 0,
needRefund: false, needRefund: false,
needExecute: false, needExecute: false,
inspectionDoctor: '', inspectionDoctor: '',
@@ -735,8 +738,7 @@ async function loadInspectionData() {
try { try {
// 只获取检验类型列表 // 只获取检验类型列表
const typeRes = await getInspectionTypeList().catch(error => { const typeRes = await getInspectionTypeList().catch(() => {
console.error('获取检验类型失败:', error)
return { data: [] } return { data: [] }
}) })
@@ -766,10 +768,8 @@ async function loadInspectionData() {
// 预加载第一个分类的项目 // 预加载第一个分类的项目
await loadCategoryItems(categories[0].key) await loadCategoryItems(categories[0].key)
} else { } else {
console.warn('未获取到检验类型分类')
} }
} catch (error) { } catch (error) {
console.error('加载检验类型分类失败:', error)
} finally { } finally {
inspectionLoading.value = false inspectionLoading.value = false
} }
@@ -847,7 +847,6 @@ async function loadCategoryItems(categoryKey, loadMore = false) {
category.loaded = true category.loaded = true
} catch (error) { } catch (error) {
console.error(`加载分类 [${category.label}] 项目失败:`, error)
// 加载失败时设置空数据 // 加载失败时设置空数据
if (!loadMore) { if (!loadMore) {
category.items = [] category.items = []
@@ -950,7 +949,6 @@ async function querySearchInspectionItems(queryString, cb) {
cb(suggestions) cb(suggestions)
} catch (error) { } catch (error) {
console.error('搜索检验项目失败:', error)
cb([]) cb([])
} }
} }
@@ -1088,56 +1086,19 @@ const checkApplicationNoExists = async (applyNo) => {
} }
}; };
// 生成申请单号 // 调用后端接口生成申请单号LS + YYYYMMDD + 5位流水号
// 后端使用 Redis 原子递增保证并发安全
const generateApplicationNo = async () => { const generateApplicationNo = async () => {
let applyNo; try {
let isUnique = false; const res = await generateInspectionApplyNo();
let attempts = 0; if (res.code === 200 && res.data && res.data.applyNo) {
const maxAttempts = 10; // 最大尝试次数 return res.data.applyNo;
} else {
// 循环直到生成唯一的申请单号 return null;
while (!isUnique && attempts < maxAttempts) {
const now = new Date();
// 生成20位申请单号年(4位) + 月(2位) + 日(2位) + 时(2位) + 分(2位) + 秒(2位) + 毫秒(3位) + 随机数(3位)
const year = String(now.getFullYear()); // 取4位年份
const month = String(now.getMonth() + 1).padStart(2, '0'); // 月份从0开始需要+1
const day = String(now.getDate()).padStart(2, '0');
const hours = String(now.getHours()).padStart(2, '0');
const minutes = String(now.getMinutes()).padStart(2, '0');
const seconds = String(now.getSeconds()).padStart(2, '0');
const milliseconds = String(now.getMilliseconds()).padStart(3, '0'); // 毫秒取3位
// 生成3位随机数增加唯一性避免并发冲突
const randomNum = Math.floor(Math.random() * 1000).toString().padStart(3, '0'); // 3位随机数
// 年(4)+月(2)+日(2)+时(2)+分(2)+秒(2)+毫秒(3)+随机数(3) = 20位
applyNo = `${year}${month}${day}${hours}${minutes}${seconds}${milliseconds}${randomNum}`;
// 确保生成的申请单号不为空
if (!applyNo || applyNo.trim() === '') {
console.debug('生成的申请单号为空,重新生成');
attempts++;
continue;
} }
} catch (error) {
// 检查生成的单号是否已存在于数据库中 return null;
const existsInDatabase = await checkApplicationNoExists(applyNo);
// 只有当单号不在数据库中时,才是唯一的
isUnique = !existsInDatabase;
attempts++;
} }
if (!isUnique) {
const timestamp = Date.now().toString();
const randomPart = Math.floor(Math.random() * 1000).toString().padStart(3, '0');
const fallbackNo = 'F' + timestamp.slice(-17) + randomPart; // 使用F开头表示备用方案
return fallbackNo;
}
return applyNo;
}; };
// 重置表单 // 重置表单
@@ -1153,7 +1114,7 @@ async function resetForm() {
applyDeptCode: props.patientInfo.organizationName, applyDeptCode: props.patientInfo.organizationName,
applyDocCode: userId.value || '', applyDocCode: userId.value || '',
applyDocName: userNickName.value || userName.value || '', applyDocName: userNickName.value || userName.value || '',
executeDepartment: 'medical_lab', executeDepartment: '',
clinicDesc: '', clinicDesc: '',
contraindication: '', contraindication: '',
clinicDiag: '', clinicDiag: '',
@@ -1163,7 +1124,7 @@ async function resetForm() {
labApplyItemList: [], labApplyItemList: [],
applyRemark: '', applyRemark: '',
priorityCode: 0, priorityCode: 0,
applyStatus: 1, applyStatus: 0,
needRefund: false, needRefund: false,
needExecute: false, needExecute: false,
patientId: props.patientInfo.patientId || '', patientId: props.patientInfo.patientId || '',
@@ -1197,7 +1158,6 @@ async function resetForm() {
formData.clinicDiag = '' formData.clinicDiag = ''
} }
} catch (error) { } catch (error) {
console.error('获取主诊断信息失败:', error)
formData.clinicDiag = '' formData.clinicDiag = ''
} }
} }
@@ -1260,9 +1220,15 @@ function handleSave() {
// 准备保存数据 // 准备保存数据
const prepareSaveData = () => { const prepareSaveData = () => {
// 将执行科室代码赋值给每个检验项目
const labApplyItemList = selectedInspectionItems.value.map(item => ({
...item,
performDeptCode: formData.executeDepartment // 从字典获取的执行科室代码
}))
return { return {
...formData, ...formData,
labApplyItemList: selectedInspectionItems.value, labApplyItemList,
physicalExamination: formData.physicalExam, // 字段名映射:前端 physicalExam -> 后端 physicalExamination
inspectionItemsText: selectedInspectionItems.value.map(item => item.itemName).join('+'), inspectionItemsText: selectedInspectionItems.value.map(item => item.itemName).join('+'),
amount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount, 0), amount: selectedInspectionItems.value.reduce((sum, item) => sum + item.itemAmount, 0),
serviceFee: selectedInspectionItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0), serviceFee: selectedInspectionItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0),
@@ -1305,16 +1271,13 @@ function handleSave() {
ElMessage.success('新申请单号已生成,请点击保存按钮继续,请核对数据'); ElMessage.success('新申请单号已生成,请点击保存按钮继续,请核对数据');
// 不自动保存,等待用户再次点击保存 // 不自动保存,等待用户再次点击保存
} else { } else {
console.debug('生成的申请单号为空,不设置');
isGeneratingNewApplyNo.value = false; isGeneratingNewApplyNo.value = false;
} }
}); });
}).catch((error) => { }).catch((error) => {
// 用户点击取消或其他原因导致的拒绝 // 用户点击取消或其他原因导致的拒绝
if (error !== 'cancel' && error !== 'close') { if (error !== 'cancel' && error !== 'close') {
console.error('MessageBox操作出错:', error);
} }
console.debug('用户取消了重新生成申请单号');
}); });
} else { } else {
// 申请单号不存在,继续保存操作 // 申请单号不存在,继续保存操作
@@ -1326,8 +1289,7 @@ function handleSave() {
const saveData = prepareSaveData(); const saveData = prepareSaveData();
executeSave(saveData); executeSave(saveData);
} }
}).catch((error) => { }).catch(() => {
console.error('检查申请单号时发生错误:', error);
// 如果检查过程出错,仍然继续保存操作,以免影响正常使用 // 如果检查过程出错,仍然继续保存操作,以免影响正常使用
const saveData = prepareSaveData(); const saveData = prepareSaveData();
executeSave(saveData); executeSave(saveData);
@@ -1346,7 +1308,6 @@ const executeSave = (saveData) => {
if (newApplyNo && newApplyNo.trim() !== '') { if (newApplyNo && newApplyNo.trim() !== '') {
formData.applyNo = newApplyNo; formData.applyNo = newApplyNo;
} else { } else {
console.debug('生成的申请单号为空,不设置');
} }
}); });
leftActiveTab.value = 'application' leftActiveTab.value = 'application'
@@ -1357,14 +1318,11 @@ const executeSave = (saveData) => {
ElMessageBox.alert(res.message || '保存失败', '错误', { ElMessageBox.alert(res.message || '保存失败', '错误', {
confirmButtonText: '确定', confirmButtonText: '确定',
type: 'error', type: 'error',
}).catch((error) => { }).catch(() => {
console.error('错误提示框操作出错:', error);
}); });
console.debug(res.message || '保存失败')
} }
}).catch((error) => { }).catch(() => {
// 处理请求失败的其他错误 // 处理请求失败的其他错误
console.error('保存检验申请单时发生错误:', error);
ElMessage.error('保存失败,请稍后重试'); ElMessage.error('保存失败,请稍后重试');
}).finally(() => { }).finally(() => {
saving.value = false saving.value = false
@@ -1460,7 +1418,6 @@ function handleSizeChange(size) {
getInspectionList() getInspectionList()
} }
// 分页页码改变
function handleCurrentChange(page) { function handleCurrentChange(page) {
queryParams.pageNo = page queryParams.pageNo = page
getInspectionList() getInspectionList()
@@ -1471,7 +1428,6 @@ function handleSelectionChange(selection) {
selectedRows.value = selection selectedRows.value = selection
} }
// 打印申请单
function handlePrint(row) { function handlePrint(row) {
// 切换到申请单TAB // 切换到申请单TAB
leftActiveTab.value = 'application' leftActiveTab.value = 'application'
@@ -1515,7 +1471,7 @@ function handleDelete(row) {
ElMessage.error(res.message || '删除失败') ElMessage.error(res.message || '删除失败')
} }
}).catch((error) => { }).catch((error) => {
console.error('删除检验请单异常:', error) console.error('删除检验<EFBFBD><EFBFBD>请单异常:', error)
ElMessage.error('删除异常') ElMessage.error('删除异常')
}) })
}).catch(() => { }).catch(() => {
@@ -1526,73 +1482,88 @@ function handleDelete(row) {
// 单元格点击 - 点击表格行时加载申请单详情 // 单元格点击 - 点击表格行时加载申请单详情
function handleCellClick(row, column) { function handleCellClick(row, column) {
// 点击表格行时,将该申请单的数据加载到表单中 // 点击表格行时,将该申请单的数据加载到表单中
if (row && row.applicationId) { // 使用 applyNo 判断是否有效
if (row && row.applyNo) {
loadApplicationToForm(row); loadApplicationToForm(row);
} }
} }
// 🔧 Bug #269 修复:行点击事件处理 // 行点击事件处理
function handleRowClick(currentRow, oldRow) { function handleRowClick(currentRow, oldRow) {
// 点击表格行时,将该申请单的数据加载到表单中 // 点击表格行时,将该申请单的数据加载到表单中
if (currentRow && currentRow.applicationId) { // 使用 applyNo 判断是否有效
if (currentRow && currentRow.applyNo) {
loadApplicationToForm(currentRow); loadApplicationToForm(currentRow);
} }
} }
// 🔧 Bug #269 修复:提取公共方法加载申请单到表单 // 提取公共方法加载申请单到表单
function loadApplicationToForm(row) { async function loadApplicationToForm(row) {
// 切换到申请单 TAB // 切换到申请单 TAB
leftActiveTab.value = 'application' leftActiveTab.value = 'application'
// 加载表单数据 // 先用列表数据设置基本信息
Object.assign(formData, { Object.assign(formData, {
applicationId: row.applicationId,
applyNo: row.applyNo, applyNo: row.applyNo,
patientName: row.patientName,
medicalrecordNumber: row.medicalrecordNumber,
natureofCost: row.natureofCost || 'self',
applyTime: row.applyTime,
applyDepartment: row.applyDepartment,
applyDocName: row.applyDocName, applyDocName: row.applyDocName,
executeDepartment: row.executeDepartment || 'medical_lab',
clinicDesc: row.clinicDesc,
contraindication: row.contraindication,
clinicDiag: row.clinicDiag,
medicalHistorySummary: row.medicalHistorySummary,
purposeofInspection: row.purposeofInspection,
physicalExam: row.physicalExam,
applyRemark: row.applyRemark,
priorityCode: row.priorityCode || 0, priorityCode: row.priorityCode || 0,
applyStatus: row.applyStatus || 0, // 🔧 Bug #268: 默认为 0 applyStatus: row.applyStatus || 0
needRefund: row.needRefund || false,
needExecute: row.needExecute || false,
inspectionDoctor: row.inspectionDoctor,
inspectionTime: row.inspectionTime,
auditDoctor: row.auditDoctor,
auditTime: row.auditTime,
visitNo: row.visitNo,
applyDocCode: row.applyDocCode,
applyDeptCode: row.applyDeptCode,
specimenName: row.specimenName,
encounterId: row.encounterId,
patientId: row.patientId,
applyOrganizationId: row.applyOrganizationId
}) })
// 🔧 Bug #269 修复:根据检验项目 ID 加载详细的检验项目数据 // 根据申请单号获取完整详情
try {
const res = await getInspectionApplyDetail(row.applyNo)
console.log('申请单详情API返回:', res) // 临时调试日志
if (res.code === 200 && res.data) {
const detail = res.data
// 加载完整的表单数据
Object.assign(formData, {
applicationId: detail.applicationId || null,
applyNo: detail.applyNo,
patientId: detail.patientId,
patientName: detail.patientName,
medicalrecordNumber: detail.medicalrecordNumber,
natureofCost: detail.natureofCost || 'self',
applyTime: detail.applyTime,
applyDepartment: detail.applyDepartment,
applyDocName: detail.applyDocName,
applyDocCode: detail.applyDocCode,
applyDeptCode: detail.applyDeptCode,
applyOrganizationId: detail.applyOrganizationId,
executeDepartment: detail.executeDepartment || '',
clinicDesc: detail.clinicDesc,
contraindication: detail.contraindication,
clinicDiag: detail.clinicDiag,
medicalHistorySummary: detail.medicalHistorySummary,
purposeofInspection: detail.purposeofInspection,
physicalExam: detail.physicalExamination,
applyRemark: detail.applyRemark,
priorityCode: detail.priorityCode || 0,
applyStatus: detail.applyStatus || 0,
needRefund: detail.needRefund || false,
needExecute: detail.needExecute || false,
inspectionDoctor: detail.inspectionDoctor,
inspectionTime: detail.inspectionTime,
auditDoctor: detail.auditDoctor,
auditTime: detail.auditTime,
visitNo: detail.visitNo,
specimenName: detail.specimenName,
encounterId: detail.encounterId
})
// 加载检验项目数据
selectedInspectionItems.value = [] selectedInspectionItems.value = []
if (row.labApplyItemList && row.labApplyItemList.length > 0) { if (detail.labApplyItemList && detail.labApplyItemList.length > 0) {
// 如果后端返回了检验项目列表,直接使用 selectedInspectionItems.value = detail.labApplyItemList.map(item => ({
selectedInspectionItems.value = row.labApplyItemList.map(item => ({
...item, ...item,
itemId: item.itemId || item.id || Math.random().toString(36).substring(2, 11), itemId: item.itemId || item.id || Math.random().toString(36).substring(2, 11),
itemName: item.itemName || item.name || '', itemName: item.itemName || item.name || '',
itemPrice: item.itemPrice || item.price || 0, itemPrice: item.itemPrice || item.price || 0,
itemAmount: item.itemAmount || item.price || 0, itemAmount: item.itemAmount || item.price || 0,
})) }))
} else if (row.itemName || row.inspectionItem) { } else if (detail.inspectionItem || detail.itemName) {
// 如果只有项目名称,尝试从本地分类中查找匹配项 // 如果只有项目名称,尝试从本地分类中查找匹配项
const itemNames = (row.itemName || row.inspectionItem).split(/[+,]/) // 支持多种分隔符 const itemNames = (detail.inspectionItem || detail.itemName).split(/[+,]/)
inspectionCategories.value.forEach(category => { inspectionCategories.value.forEach(category => {
category.items.forEach(item => { category.items.forEach(item => {
if (itemNames.includes(item.itemName)) { if (itemNames.includes(item.itemName)) {
@@ -1601,13 +1572,16 @@ function loadApplicationToForm(row) {
}) })
}) })
} }
}
} catch (error) {
// 如果获取详情失败,至少显示列表中的基本信息
Object.assign(formData, row)
}
// 重置验证错误状态 // 重置验证错误状态
Object.keys(validationErrors).forEach(key => { Object.keys(validationErrors).forEach(key => {
validationErrors[key] = false validationErrors[key] = false
}) })
console.log('已加载申请单到表单:', row.applyNo);
} }
// 监听activeTab变化 // 监听activeTab变化
@@ -1654,6 +1628,13 @@ watch(() => selectedInspectionItems.value, (newVal) => {
} }
}, { deep: true }) }, { deep: true })
// 监听执行科室字典数据,设置默认值为第一个选项
watch(() => inspection_lab_dept.value, (newVal) => {
if (newVal && newVal.length > 0 && !formData.executeDepartment) {
formData.executeDepartment = newVal[0].value
}
}, { immediate: true })
// 组件挂载时预加载检验项目数据不依赖patientInfo // 组件挂载时预加载检验项目数据不依赖patientInfo
onMounted(async () => { onMounted(async () => {
await loadInspectionData() await loadInspectionData()
@@ -2273,7 +2254,6 @@ defineExpose({
line-height: 1; line-height: 1;
} }
/* 自定义消息框样式,确保其显示在最顶层 */
.custom-message-box { .custom-message-box {
z-index: 9999 !important; z-index: 9999 !important;
} }

View File

@@ -79,7 +79,25 @@
</div> </div>
<div class="filter-item"> <div class="filter-item">
<label>用户</label> <label>用户</label>
<select></select> <el-select
v-model="searchParams.user"
placeholder="请选择用户"
style="width: 150px;"
clearable
filterable
remote
:teleported="true"
:remote-method="remoteSearchUser"
:loading="userLoading"
@focus="handleUserFocus"
>
<el-option
v-for="u in userOptions"
:key="u.value"
:label="u.label"
:value="u.value"
/>
</el-select>
</div> </div>
<!-- 操作按钮组 --> <!-- 操作按钮组 -->
@@ -261,9 +279,61 @@ const searchParams = ref({
endDate: getCurrentDate(), endDate: getCurrentDate(),
packageName: '', packageName: '',
packageLevel: '', packageLevel: '',
department: '' department: '',
user: ''
}); });
// 用户下拉选项
const userOptions = ref([])
const userLoading = ref(false)
const allUserOptions = ref([]) // 全量缓存
// 点击时加载个人套餐中的用户值
async function handleUserFocus() {
if (allUserOptions.value.length === 0) {
await loadUserOptions()
}
userOptions.value = allUserOptions.value
}
// 输入时前端模糊过滤
function remoteSearchUser(keyword) {
if (!keyword) {
userOptions.value = allUserOptions.value
} else {
userOptions.value = allUserOptions.value.filter(u => u.label.includes(keyword))
}
}
// 调套餐接口取个人套餐的userId字段去重
async function loadUserOptions() {
try {
userLoading.value = true
const res = await listInspectionPackage({
pageNum: 1,
pageSize: 50,
packageLevel: '个人套餐',
packageCategory: '检验套餐'
})
let list = []
if (res && res.data) {
if (Array.isArray(res.data.rows)) list = res.data.rows
else if (Array.isArray(res.data.records)) list = res.data.records
else if (Array.isArray(res.data)) list = res.data
} else if (Array.isArray(res?.rows)) {
list = res.rows
}
const uniqueUsers = [...new Set(
list.map(item => item.userId).filter(u => u && u.trim())
)]
allUserOptions.value = uniqueUsers.map(u => ({ value: u, label: u }))
} catch (e) {
ElMessage.error('加载用户列表失败')
} finally {
userLoading.value = false
}
}
// 从API加载数据 // 从API加载数据
async function loadData() { async function loadData() {
try { try {
@@ -297,6 +367,9 @@ async function loadData() {
if (searchParams.value.department) { if (searchParams.value.department) {
params.department = searchParams.value.department params.department = searchParams.value.department
} }
if (searchParams.value.user) {
params.userId = searchParams.value.user
}
const response = await listInspectionPackage(params) const response = await listInspectionPackage(params)
@@ -489,9 +562,10 @@ function handleReset() {
endDate: getCurrentDate(), endDate: getCurrentDate(),
packageName: '', packageName: '',
packageLevel: '', packageLevel: '',
department: '' department: '',
user: ''
}; };
currentPage.value = 1; // 重置到第一页 currentPage.value = 1;
loadData() loadData()
} }

View File

@@ -560,15 +560,21 @@
<span class="form-label">服务费</span> <span class="form-label">服务费</span>
<el-input :model-value="serviceFee.toFixed(2)" readonly /> <el-input :model-value="serviceFee.toFixed(2)" readonly />
</div> </div>
<div class="form-item"> <div class="form-item" v-if="selectedLisGroup || !isViewMode">
<span class="form-label">lis分组</span> <span class="form-label">lis分组</span>
<template v-if="isViewMode">
<el-input :model-value="lisGroupList.find(g => g.id === selectedLisGroup)?.groupName || lisGroupList.find(g => g.id === selectedLisGroup)?.lisGroupName || ''" readonly />
</template>
<template v-else>
<el-select <el-select
v-model="selectedLisGroup" :model-value="selectedLisGroup || ''"
placeholder="请选择lis分组" placeholder="请选择lis分组"
style="width: 100%;" style="width: 100%;"
:disabled="isViewMode"
:loading="loadingLisGroup" :loading="loadingLisGroup"
clearable
@change="val => selectedLisGroup = val || undefined"
@visible-change="handleLisGroupVisibleChange" @visible-change="handleLisGroupVisibleChange"
@clear="() => selectedLisGroup = undefined"
> >
<el-option <el-option
v-for="group in lisGroupList" v-for="group in lisGroupList"
@@ -577,6 +583,7 @@
:value="group.id" :value="group.id"
/> />
</el-select> </el-select>
</template>
</div> </div>
<div class="form-item"> <div class="form-item">
<span class="form-label">血量</span> <span class="form-label">血量</span>
@@ -847,7 +854,7 @@ const route = useRoute();
// 存储LIS分组数据 // 存储LIS分组数据
const lisGroupList = ref([]); const lisGroupList = ref([]);
// 选中的LIS分组 // 选中的LIS分组
const selectedLisGroup = ref(''); const selectedLisGroup = ref(undefined);
// LIS分组加载状态 // LIS分组加载状态
const loadingLisGroup = ref(false); const loadingLisGroup = ref(false);
@@ -894,7 +901,7 @@ const getLisGroupList = async () => {
} }
} }
lisGroupList.value = items; lisGroupList.value = items.map(item => ({ ...item, id: Number(item.id) }));
} else { } else {
ElMessage.error('获取LIS分组数据失败'); ElMessage.error('获取LIS分组数据失败');
} }
@@ -1552,20 +1559,10 @@ const deletePackageItem = (index) => {
}; };
// 更新项目金额(考虑折扣 // 更新项目金额(金额 = 数量 × 单价,不应用折扣;折扣只影响套餐总金额
const updateItemAmount = (item) => { const updateItemAmount = (item) => {
// 计算项目原价金额 // 金额 = 数量 × 单价
const originalAmount = (item.quantity || 1) * (item.unitPrice || 0.00); item.amount = parseFloat(((item.quantity || 1) * (item.unitPrice || 0.00)).toFixed(2));
// 应用折扣到项目金额
let discountedAmount = originalAmount;
if (discount.value && !isNaN(parseFloat(discount.value))) {
const discountRate = parseFloat(discount.value) / 100;
discountedAmount = originalAmount * (1 - discountRate);
}
// 更新项目金额
item.amount = parseFloat(discountedAmount.toFixed(2));
// 注意serviceFee 由用户手动输入,不在此处覆盖 // 注意serviceFee 由用户手动输入,不在此处覆盖
@@ -1647,15 +1644,9 @@ const cancelEditItem = (index) => {
// 计算套餐金额和服务费 // 计算套餐金额和服务费
const calculateAmounts = () => { const calculateAmounts = () => {
// 更新每个项目的折扣金额和总金额 // 更新每个项目的金额(金额 = 数量 × 单价,不受折扣影响)和总金额
packageItems.value.forEach(item => { packageItems.value.forEach(item => {
const originalAmount = (item.quantity || 1) * (item.unitPrice || 0.00); item.amount = parseFloat(((item.quantity || 1) * (item.unitPrice || 0.00)).toFixed(2));
let discountedAmount = originalAmount;
if (discount.value && !isNaN(parseFloat(discount.value))) {
const discountRate = parseFloat(discount.value) / 100;
discountedAmount = originalAmount * (1 - discountRate);
}
item.amount = parseFloat(discountedAmount.toFixed(2));
// serviceFee 由用户手动输入,不覆盖;只更新 totalAmount // serviceFee 由用户手动输入,不覆盖;只更新 totalAmount
item.totalAmount = parseFloat(((item.amount) + (item.serviceFee || 0)).toFixed(2)); item.totalAmount = parseFloat(((item.amount) + (item.serviceFee || 0)).toFixed(2));
}); });
@@ -1663,9 +1654,14 @@ const calculateAmounts = () => {
// 汇总各明细行服务费到基本信息服务费(只读展示) // 汇总各明细行服务费到基本信息服务费(只读展示)
serviceFee.value = parseFloat(packageItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0).toFixed(2)); serviceFee.value = parseFloat(packageItems.value.reduce((sum, item) => sum + (item.serviceFee || 0), 0).toFixed(2));
// 套餐总金额 = 各行折扣后金额之和 + 各行服务费之和 // 套餐总金额 = (各行金额之和 + 各行服务费之和) × 折扣比例
const totalAmount = packageItems.value.reduce((sum, item) => sum + (item.amount || 0) + (item.serviceFee || 0), 0); const rawTotal = packageItems.value.reduce((sum, item) => sum + (item.amount || 0) + (item.serviceFee || 0), 0);
packageAmount.value = parseFloat(totalAmount.toFixed(2)); let finalTotal = rawTotal;
if (discount.value && !isNaN(parseFloat(discount.value)) && parseFloat(discount.value) > 0) {
const discountRate = parseFloat(discount.value) / 100; // 80 → 0.8表示八折保留80%
finalTotal = rawTotal * discountRate;
}
packageAmount.value = parseFloat(finalTotal.toFixed(2));
}; };
const itemNameRefs = ref([]); const itemNameRefs = ref([]);
@@ -2019,7 +2015,7 @@ const saveItem = async (item) => {
const submitData = { const submitData = {
busNo: item.code.trim(), busNo: item.code.trim(),
name: item.name.trim(), name: item.name.trim(),
categoryCode: inspectionCategoryCode.value, categoryCode: inspectionCategoryCode.value , // '22' 为检验分类的固定字典值,防止字典未加载时为空
inspectionTypeId: item.inspectionTypeId || null, inspectionTypeId: item.inspectionTypeId || null,
feePackageId: item.feePackageId || null, feePackageId: item.feePackageId || null,
subItemId: item.subItemId || null, subItemId: item.subItemId || null,
@@ -2183,7 +2179,7 @@ const handleSave = () => {
enablePackagePrice: enablePackagePrice.value, enablePackagePrice: enablePackagePrice.value,
packageAmount: packageAmount.value, packageAmount: packageAmount.value,
serviceFee: serviceFee.value, serviceFee: serviceFee.value,
lisGroup: selectedLisGroup.value, // 从下拉框获取 lisGroup: selectedLisGroup.value || null,
bloodVolume: bloodVolume.value, bloodVolume: bloodVolume.value,
remarks: remarks.value, remarks: remarks.value,
orgName: (tenantOptions.value.find(t => t.value === selectedTenantId.value)?.label) || userStore.orgName || '', // 卫生机构 orgName: (tenantOptions.value.find(t => t.value === selectedTenantId.value)?.label) || userStore.orgName || '', // 卫生机构
@@ -2423,13 +2419,13 @@ const savePackageData = async (basicInfo, detailData) => {
// 关闭加载提示 // 关闭加载提示
loading.close(); loading.close();
ElMessage.success('保存成功');
if (isEditMode) { if (isEditMode) {
// 编辑模式:重新加载最新数据,保持在编辑页面 // 编辑模式:提示更新成功并跳转到套餐管理页面
loadInspectionPackage(String(packageId)); ElMessage.success('更新成功');
router.push({ path: '/maintainSystem/Inspection/PackageManagement' });
} else { } else {
// 新增模式:保存成功后重置表单 // 新增模式:保存成功后重置表单
ElMessage.success('保存成功');
doResetForm(); doResetForm();
} }
@@ -2498,7 +2494,7 @@ const doResetForm = () => {
enablePackagePrice.value = true; enablePackagePrice.value = true;
packageAmount.value = 0.00; packageAmount.value = 0.00;
serviceFee.value = 0.00; serviceFee.value = 0.00;
selectedLisGroup.value = ''; selectedLisGroup.value = undefined;
bloodVolume.value = ''; bloodVolume.value = '';
remarks.value = ''; remarks.value = '';
@@ -2522,6 +2518,11 @@ const loadInspectionPackage = async (packageId) => {
background: 'rgba(0, 0, 0, 0.7)', background: 'rgba(0, 0, 0, 0.7)',
}); });
// 确保 lis分组列表已加载否则编辑时下拉框无法显示名称
if (lisGroupList.value.length === 0) {
await getLisGroupList();
}
// 获取基本信息 // 获取基本信息
const basicResponse = await getInspectionPackage(packageId); const basicResponse = await getInspectionPackage(packageId);
if (basicResponse.code !== 200) { if (basicResponse.code !== 200) {
@@ -2551,7 +2552,7 @@ const loadInspectionPackage = async (packageId) => {
enablePackagePrice.value = basicData.enablePackagePrice !== false; enablePackagePrice.value = basicData.enablePackagePrice !== false;
packageAmount.value = parseFloat(basicData.packageAmount || 0); packageAmount.value = parseFloat(basicData.packageAmount || 0);
serviceFee.value = parseFloat(basicData.serviceFee || 0); serviceFee.value = parseFloat(basicData.serviceFee || 0);
selectedLisGroup.value = basicData.lisGroup || ''; selectedLisGroup.value = (basicData.lisGroup != null && basicData.lisGroup !== 0 && basicData.lisGroup !== '0') ? Number(basicData.lisGroup) : undefined;
bloodVolume.value = basicData.bloodVolume || ''; bloodVolume.value = basicData.bloodVolume || '';
remarks.value = basicData.remarks || ''; remarks.value = basicData.remarks || '';