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

This commit is contained in:
wangjian963
2026-05-08 17:46:51 +08:00
15 changed files with 527 additions and 14 deletions

View File

@@ -0,0 +1,20 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "/root/.openclaw/workspace/his-repo/logs/.2c17bf7b4e92189ae54ef8e767273ceaeb613314-audit.json",
"files": [
{
"date": 1778128585254,
"name": "/root/.openclaw/workspace/his-repo/logs/application-2026-05-07.log",
"hash": "2ec545aad5feb57a45e48b0a980690b3b9ef6b90e57204f6c3dfb1c7f2fd4d95"
},
{
"date": 1778200962650,
"name": "/root/.openclaw/workspace/his-repo/logs/application-2026-05-08.log",
"hash": "cf50ef7b8aa656efb0a209a252219fea97a437ff9020b1b8770788f1ba51303e"
}
],
"hashType": "sha256"
}

View File

@@ -0,0 +1,20 @@
{
"keep": {
"days": true,
"amount": 14
},
"auditLog": "/root/.openclaw/workspace/his-repo/logs/.9c2086cba7d24dcd050254bba93c4693957f894e-audit.json",
"files": [
{
"date": 1778128585256,
"name": "/root/.openclaw/workspace/his-repo/logs/error-2026-05-07.log",
"hash": "84a811bf9cf76799b49d36df79427471c8e0cfaa1bd359422d69091b06a64f87"
},
{
"date": 1778200962653,
"name": "/root/.openclaw/workspace/his-repo/logs/error-2026-05-08.log",
"hash": "83b015957301572a67ea6fb41a65dfe5aa357831ca361155629630c6e9ef68bd"
}
],
"hashType": "sha256"
}

View File

@@ -106,6 +106,7 @@ public class CheckMethodAppServiceImpl implements ICheckMethodAppService {
if (ObjectUtil.isNotEmpty(m.getPackageName())) { if (ObjectUtil.isNotEmpty(m.getPackageName())) {
CheckPackage pkg = packageMap.get(m.getPackageName()); CheckPackage pkg = packageMap.get(m.getPackageName());
if (pkg != null) { if (pkg != null) {
dto.setPackageId(pkg.getId());
dto.setPackagePrice(pkg.getPackagePrice()); dto.setPackagePrice(pkg.getPackagePrice());
dto.setServiceFee(pkg.getServiceFee()); dto.setServiceFee(pkg.getServiceFee());
} }

View File

@@ -220,6 +220,36 @@ public class CheckTypeController extends BaseController {
return AjaxResult.success(result); return AjaxResult.success(result);
} }
/**
* 查询检查套餐明细,用于医生站已选择套餐展开显示
*/
@GetMapping({ "/package/{packageId}/details", "/check-package/{packageId}/details" })
public AjaxResult getPackageDetails(@PathVariable Long packageId) {
List<CheckPackageDetail> details = checkPackageDetailService.list(
new LambdaQueryWrapper<CheckPackageDetail>()
.eq(CheckPackageDetail::getPackageId, packageId)
.orderByAsc(CheckPackageDetail::getOrderNum)
.orderByAsc(CheckPackageDetail::getId));
List<Map<String, Object>> result = details.stream().map(d -> {
Map<String, Object> item = new LinkedHashMap<>();
item.put("id", d.getId());
item.put("packageId", d.getPackageId());
item.put("itemCode", d.getItemCode());
item.put("itemName", d.getItemName());
item.put("name", d.getItemName());
item.put("quantity", d.getQuantity());
item.put("unit", d.getUnit());
item.put("unitPrice", d.getUnitPrice());
item.put("price", d.getUnitPrice());
item.put("amount", d.getAmount());
item.put("orderNum", d.getOrderNum());
return item;
}).collect(Collectors.toList());
return AjaxResult.success(result);
}
/** 套餐级别文字映射 */ /** 套餐级别文字映射 */
private String parseLevelText(String level) { private String parseLevelText(String level) {
if ("1".equals(level)) if ("1".equals(level))

View File

@@ -31,6 +31,9 @@ public class CheckMethodDto {
/* 套餐名称 */ /* 套餐名称 */
private String packageName; private String packageName;
/* 套餐ID */
private Long packageId;
/* 套餐价格 - Bug #384修复通过packageName匹配CheckPackage获取 */ /* 套餐价格 - Bug #384修复通过packageName匹配CheckPackage获取 */
private BigDecimal packagePrice; private BigDecimal packagePrice;

View File

@@ -25,7 +25,9 @@ public interface ISurgeryAppService {
* @param plannedTimeEnd 计划结束时间 * @param plannedTimeEnd 计划结束时间
* @return 手术列表 * @return 手术列表
*/ */
IPage<SurgeryDto> getSurgeryPage(SurgeryDto surgeryDto, Integer pageNo, Integer pageSize, String plannedTimeStart, String plannedTimeEnd); IPage<SurgeryDto> getSurgeryPage(SurgeryDto surgeryDto, Integer pageNo, Integer pageSize,
String plannedTimeStart, String plannedTimeEnd,
String createTimeStart, String createTimeEnd);
/** /**
* 根据ID查询手术详情 * 根据ID查询手术详情

View File

@@ -108,7 +108,9 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
* @return 手术列表 * @return 手术列表
*/ */
@Override @Override
public IPage<SurgeryDto> getSurgeryPage(SurgeryDto surgeryDto, Integer pageNo, Integer pageSize, String plannedTimeStart, String plannedTimeEnd) { public IPage<SurgeryDto> getSurgeryPage(SurgeryDto surgeryDto, Integer pageNo, Integer pageSize,
String plannedTimeStart, String plannedTimeEnd,
String createTimeStart, String createTimeEnd) {
QueryWrapper<SurgeryDto> queryWrapper = HisQueryUtils.buildQueryWrapper(surgeryDto, null, QueryWrapper<SurgeryDto> queryWrapper = HisQueryUtils.buildQueryWrapper(surgeryDto, null,
new HashSet<String>() {{ new HashSet<String>() {{
add("surgery_no"); add("surgery_no");
@@ -149,6 +151,34 @@ public class SurgeryAppServiceImpl implements ISurgeryAppService {
} }
} }
// 申请时间范围(创建时间 create_time查询用于“手术申请查询”弹窗
if (createTimeStart != null && !createTimeStart.isEmpty()) {
try {
LocalDateTime startDateTime = LocalDateTime.parse(createTimeStart, DateTimeFormatter.ISO_DATE_TIME);
queryWrapper.ge("create_time", startDateTime);
} catch (Exception e) {
try {
LocalDateTime startDateTime = LocalDateTime.parse(createTimeStart + "T00:00:00", DateTimeFormatter.ISO_DATE_TIME);
queryWrapper.ge("create_time", startDateTime);
} catch (Exception ex) {
log.error("解析创建开始时间失败: {}", createTimeStart, ex);
}
}
}
if (createTimeEnd != null && !createTimeEnd.isEmpty()) {
try {
LocalDateTime endDateTime = LocalDateTime.parse(createTimeEnd, DateTimeFormatter.ISO_DATE_TIME);
queryWrapper.le("create_time", endDateTime);
} catch (Exception e) {
try {
LocalDateTime endDateTime = LocalDateTime.parse(createTimeEnd + "T23:59:59", DateTimeFormatter.ISO_DATE_TIME);
queryWrapper.le("create_time", endDateTime);
} catch (Exception ex) {
log.error("解析创建结束时间失败: {}", createTimeEnd, ex);
}
}
}
queryWrapper.orderByDesc("create_time"); queryWrapper.orderByDesc("create_time");
return surgeryAppMapper.getSurgeryPage(new Page<>(pageNo, pageSize), queryWrapper); return surgeryAppMapper.getSurgeryPage(new Page<>(pageNo, pageSize), queryWrapper);
} }

View File

@@ -40,9 +40,12 @@ public class SurgeryController {
@RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo, @RequestParam(value = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize, @RequestParam(value = "pageSize", defaultValue = "10") Integer pageSize,
@RequestParam(value = "plannedTimeStart", required = false) String plannedTimeStart, @RequestParam(value = "plannedTimeStart", required = false) String plannedTimeStart,
@RequestParam(value = "plannedTimeEnd", required = false) String plannedTimeEnd) { @RequestParam(value = "plannedTimeEnd", required = false) String plannedTimeEnd,
@RequestParam(value = "createTimeStart", required = false) String createTimeStart,
@RequestParam(value = "createTimeEnd", required = false) String createTimeEnd) {
// 将时间范围参数传递给服务层 // 将时间范围参数传递给服务层
IPage<SurgeryDto> page = surgeryAppService.getSurgeryPage(surgeryDto, pageNo, pageSize, plannedTimeStart, plannedTimeEnd); IPage<SurgeryDto> page = surgeryAppService.getSurgeryPage(surgeryDto, pageNo, pageSize,
plannedTimeStart, plannedTimeEnd, createTimeStart, createTimeEnd);
return R.ok(page); return R.ok(page);
} }

View File

@@ -912,7 +912,9 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
ChargeItem chargeItem; ChargeItem chargeItem;
// 新增 + 修改 // 新增 + 修改
// 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来
// 🔧 BugFix #454: 排除删除操作避免误入insertOrUpdateList
List<AdviceSaveDto> insertOrUpdateList = medicineList.stream() List<AdviceSaveDto> insertOrUpdateList = medicineList.stream()
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()))
.filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType())
|| DbOpType.UPDATE.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())
|| e.getRequestId() != null)) || e.getRequestId() != null))
@@ -1358,7 +1360,9 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
ChargeItem chargeItem; ChargeItem chargeItem;
// 新增 + 修改 // 新增 + 修改
// 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来
// 🔧 BugFix #454: 排除删除操作避免误入insertOrUpdateList
List<AdviceSaveDto> insertOrUpdateList = deviceList.stream() List<AdviceSaveDto> insertOrUpdateList = deviceList.stream()
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()))
.filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType())
|| DbOpType.UPDATE.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())
|| e.getRequestId() != null)) || e.getRequestId() != null))
@@ -1673,7 +1677,9 @@ public class DoctorStationAdviceAppServiceImpl implements IDoctorStationAdviceAp
ChargeItem chargeItem; ChargeItem chargeItem;
// 新增 + 修改 // 新增 + 修改
// 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来 // 🔧 BugFix: 如果 requestId 不为空说明是已存在的医嘱,需要更新,即使 dbOpType 不匹配也应该包含进来
// 🔧 BugFix #454: 排除删除操作避免误入insertOrUpdateList触发执行科室校验
List<AdviceSaveDto> insertOrUpdateList = activityList.stream() List<AdviceSaveDto> insertOrUpdateList = activityList.stream()
.filter(e -> !DbOpType.DELETE.getCode().equals(e.getDbOpType()))
.filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType()) .filter(e -> (DbOpType.INSERT.getCode().equals(e.getDbOpType())
|| DbOpType.UPDATE.getCode().equals(e.getDbOpType()) || DbOpType.UPDATE.getCode().equals(e.getDbOpType())
|| e.getRequestId() != null)) || e.getRequestId() != null))

View File

@@ -13,6 +13,33 @@ export function listOperatingRoom(query) {
}) })
} }
/**
* 查询诊疗项目列表(用于诊疗子项检索)
* @param {Object} query - 查询参数
* @returns {Promise} 请求结果
*/
export function listMedicalItems(query) {
return request({
url: '/clinical-manage/medical-item/list',
method: 'get',
params: query
})
}
/**
* 查询医嘱类型列表
* @param {Object} query - 查询参数
* @returns {Promise} 请求结果
*/
export function listAdviceTypes(query) {
return request({
url: '/clinical-manage/advice-type/list',
method: 'get',
params: query
})
}
```
/** /**
* 查询手术室详细 * 查询手术室详细
* @param {Long} id - 手术室ID * @param {Long} id - 手术室ID

View File

@@ -393,12 +393,24 @@ function openSaveImplementDepartment(row) {
editImplementDepartment(params).then((res) => { editImplementDepartment(params).then((res) => {
data.isAdding = false; // 允许新增下一行 data.isAdding = false; // 允许新增下一行
proxy.$modal.msgSuccess('保存成功!'); proxy.$modal.msgSuccess('保存成功!');
// 确保选中项在 filteredOptions 中,使 el-select 能正确显示名称
const savedItem = allImplementDepartmentList.value.find(i => i.value === row.activityDefinitionId);
if (savedItem && !row.filteredOptions.some(o => o.value === row.activityDefinitionId)) {
row.filteredOptions.push(savedItem);
}
getList();
}); });
} else { } else {
delete params.id; delete params.id;
addImplementDepartment(params).then((res) => { addImplementDepartment(params).then((res) => {
data.isAdding = false; // 允许新增下一行 data.isAdding = false; // 允许新增下一行
proxy.$modal.msgSuccess('保存成功!'); proxy.$modal.msgSuccess('保存成功!');
// 确保选中项在 filteredOptions 中,使 el-select 能正确显示名称
const savedItem = allImplementDepartmentList.value.find(i => i.value === row.activityDefinitionId);
if (savedItem && !row.filteredOptions.some(o => o.value === row.activityDefinitionId)) {
row.filteredOptions.push(savedItem);
}
getList();
}); });
} }
} }

View File

@@ -164,6 +164,20 @@
/> />
</el-form-item> </el-form-item>
</el-col> </el-col>
<!--执行时间-->
<el-col :span="8">
<el-form-item label="执行时间" style="margin-bottom: 4px">
<el-date-picker
v-model="formData.executeTime"
type="datetime"
placeholder="选择执行时间"
size="small"
format="YYYY-MM-DD HH:mm:ss"
value-format="YYYY-MM-DD HH:mm:ss"
style="width: 100%"
/>
</el-form-item>
</el-col>
<!--申请科室--> <!--申请科室-->
<el-col :span="8"> <el-col :span="8">
<el-form-item label="申请科室" required style="margin-bottom: 4px"> <el-form-item label="申请科室" required style="margin-bottom: 4px">
@@ -293,6 +307,34 @@
</el-col> </el-col>
</el-row> </el-row>
<!-- 标本类型申请类型 -->
<el-row :gutter="12" style="margin-bottom: 0">
<el-col :span="12">
<el-form-item label="标本类型" style="margin-bottom: 4px">
<el-select v-model="formData.specimenName" placeholder="请选择标本类型" size="small" style="width: 100%">
<el-option label="血液" value="血液" />
<el-option label="尿液" value="尿液" />
<el-option label="粪便" value="粪便" />
<el-option label="痰液" value="痰液" />
<el-option label="咽拭子" value="咽拭子" />
<el-option label="脑脊液" value="脑脊液" />
<el-option label="胸腹水" value="胸腹水" />
<el-option label="关节液" value="关节液" />
<el-option label="分泌物" value="分泌物" />
<el-option label="其他" value="其他" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="申请类型" style="margin-bottom: 4px">
<el-radio-group v-model="formData.applicationType" size="small">
<el-radio :value="0">普通</el-radio>
<el-radio :value="1" border type="warning">急诊</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<!-- 检验项目和备注 --> <!-- 检验项目和备注 -->
<el-row :gutter="12" style="margin-bottom: 0"> <el-row :gutter="12" style="margin-bottom: 0">
<el-col :span="12"> <el-col :span="12">
@@ -925,7 +967,9 @@ const formData = reactive({
applyDocCode: '', applyDocCode: '',
applyDeptCode: '', applyDeptCode: '',
specimenName: '血液', specimenName: '血液',
encounterId: '' encounterId: '',
executeTime: null,
applicationType: 0
}) })
// 表单引用 // 表单引用
@@ -1329,13 +1373,13 @@ const getInspectionList = () => {
// 如果返回的是分页对象 {records: [...], total: 100} // 如果返回的是分页对象 {records: [...], total: 100}
if (Array.isArray(res.data.records)) { if (Array.isArray(res.data.records)) {
// 直接使用后端返回的数据(后端已按申请单返回,无需合并) // 直接使用后端返回的数据(后端已按申请单返回,无需合并)
inspectionList.value = res.data.records inspectionList.value = mergeInspectionApplyRecords(res.data.records)
total.value = res.data.total || res.data.records.length total.value = res.data.total || res.data.records.length
} }
// 如果返回的是普通数组 // 如果返回的是普通数组
else if (Array.isArray(res.data)) { else if (Array.isArray(res.data)) {
// 直接使用后端返回的数据 // 合并同一个申请单的明细
inspectionList.value = res.data inspectionList.value = mergeInspectionApplyRecords(res.data)
total.value = res.data.length total.value = res.data.length
} }
// 如果返回的是其他对象结构 // 如果返回的是其他对象结构
@@ -1476,6 +1520,8 @@ const resetForm = async () => {
visitNo: '', visitNo: '',
specimenName: '血液', specimenName: '血液',
encounterId: props.patientInfo.encounterId || '', encounterId: props.patientInfo.encounterId || '',
executeTime: null,
applicationType: 0,
}) })
selectedInspectionItems.value = [] selectedInspectionItems.value = []
@@ -1911,7 +1957,9 @@ const loadApplicationToForm = async (row) => {
auditTime: detail.auditTime, auditTime: detail.auditTime,
visitNo: detail.visitNo, visitNo: detail.visitNo,
specimenName: detail.specimenName, specimenName: detail.specimenName,
encounterId: detail.encounterId encounterId: detail.encounterId,
executeTime: detail.executeTime || null,
applicationType: detail.applicationType ?? 0
}) })
// 加载检验项目数据 // 加载检验项目数据

View File

@@ -17,8 +17,11 @@
</el-tab-pane> </el-tab-pane>
<!-- <el-tab-pane label="医技报告" name="fourth">Task</el-tab-pane> --> <!-- <el-tab-pane label="医技报告" name="fourth">Task</el-tab-pane> -->
<el-tab-pane label="检验申请" name="test"> <el-tab-pane label="检验申请" name="test">
<TestApplication ref="testApplicationRef" /> <TestApplication ref="testApplicationRef" :show-status-column="true" />
</el-tab-pane> </el-tab-pane>
```vue
```
<el-tab-pane label="检查申请" name="examine"> <el-tab-pane label="检查申请" name="examine">
<ExamineApplication ref="examineApplicationRef" /> <ExamineApplication ref="examineApplicationRef" />
</el-tab-pane> </el-tab-pane>

View File

@@ -990,7 +990,7 @@ function selectRow(rowValue, index) {
form.purchaseinventoryList[index].ybNo = rowValue.ybNo; form.purchaseinventoryList[index].ybNo = rowValue.ybNo;
// #439 fix: 不清空sourceLocationId保留handleAddRow设置的仓库ID // #439 fix: 不清空sourceLocationId保留handleAddRow设置的仓库ID
if (!form.purchaseinventoryList[index].sourceLocationId) { if (!form.purchaseinventoryList[index].sourceLocationId) {
form.purchaseinventoryList[index].sourceLocationId = ''; form.purchaseinventoryList[index].sourceLocationId = receiptHeaderForm.headerLocationId || '';
} }
getPharmacyCabinetList().then((res) => { getPharmacyCabinetList().then((res) => {
purposeTypeListOptions.value = res.data; purposeTypeListOptions.value = res.data;

View File

@@ -58,6 +58,312 @@
</el-form> </el-form>
<el-row :gutter="10" class="mb8"> <el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['surgical:schedule:add']">
新增
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate" v-hasPermi="['surgical:schedule:edit']">
修改
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete" v-hasPermi="['surgical:schedule:remove']">
删除
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<el-table v-loading="loading" :data="scheduleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="手术单号" align="center" prop="operCode" />
<el-table-column label="患者姓名" align="center" prop="patientName" />
<el-table-column label="性别" align="center" prop="sex" :formatter="sexFormat" />
<el-table-column label="年龄" align="center" prop="age" />
<el-table-column label="申请科室" align="center" prop="applyDeptName" />
<el-table-column label="安排时间" align="center" prop="scheduleDate" width="180">
<template #default="scope">
{{ parseTime(scope.row.scheduleDate, '{y}-{m}-{d} {h}:{i}') }}
</template>
</el-table-column>
<el-table-column label="手术名称" align="center" prop="operationName" />
<el-table-column label="手术医师" align="center" prop="surgeonName" />
<el-table-column label="麻醉方法" align="center" prop="anesthesiaMethod" :formatter="anesthesiaMethodFormat" />
<el-table-column label="外请专家姓名" align="center" prop="expertName" />
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template #default="scope">
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['surgical:schedule:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['surgical:schedule:remove']">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改门诊手术安排对话框 -->
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
<el-form ref="scheduleRef" :model="form" :rules="rules" label-width="120px">
<el-row>
<el-col :span="12">
<el-form-item label="手术单号" prop="operCode">
<el-input v-model="form.operCode" placeholder="请输入手术单号" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="患者姓名" prop="patientName">
<el-input v-model="form.patientName" placeholder="请输入患者姓名" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="性别" prop="sex">
<el-select v-model="form.sex" placeholder="请选择性别">
<el-option label="男" value="1" />
<el-option label="女" value="2" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="年龄" prop="age">
<el-input v-model="form.age" placeholder="请输入年龄" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="申请科室" prop="applyDeptId">
<el-select v-model="form.applyDeptId" placeholder="请选择申请科室" @change="handleApplyDeptChange">
<el-option
v-for="dept in deptList"
:key="dept.id"
:label="dept.name"
:value="dept.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="安排时间" prop="scheduleDate">
<el-date-picker
v-model="form.scheduleDate"
type="datetime"
placeholder="选择安排时间"
format="YYYY-MM-DD HH:mm"
value-format="YYYY-MM-DD HH:mm:ss"
/>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="手术名称" prop="operationName">
<el-input v-model="form.operationName" placeholder="请输入手术名称" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手术医师" prop="surgeonId">
<el-select v-model="form.surgeonId" placeholder="请选择手术医师">
<el-option
v-for="doctor in doctorList"
:key="doctor.id"
:label="doctor.name"
:value="doctor.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="麻醉方法" prop="anesthesiaMethod">
<el-select v-model="form.anesthesiaMethod" placeholder="请选择麻醉方法">
<el-option
v-for="item in anesthesiaMethodOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="外请专家姓名" prop="expertId">
<el-select v-model="form.expertId" placeholder="请选择外请专家">
<el-option
v-for="expert in expertList"
:key="expert.id"
:label="expert.name"
:value="expert.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="麻醉医师" prop="anesthetistId">
<el-select v-model="form.anesthetistId" placeholder="请选择麻醉医师">
<el-option
v-for="doctor in anesthetistList"
:key="doctor.id"
:label="doctor.name"
:value="doctor.id"
/>
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="手术室" prop="operatingRoomId">
<el-select v-model="form.operatingRoomId" placeholder="请选择手术室">
<el-option
v-for="room in operatingRoomList"
:key="room.id"
:label="room.roomName"
:value="room.id"
/>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="SurgicalSchedule">
import { listSurgicalSchedule, getSurgicalSchedule, delSurgicalSchedule, addSurgicalSchedule, updateSurgicalSchedule } from "@/api/surgical/surgicalSchedule";
import { listDept } from "@/api/system/dept";
import { listDoctorByDeptId } from "@/api/system/doctor";
import { listExpert } from "@/api/surgical/expert";
import { listOperatingRoom } from "@/api/surgical/operatingRoom";
const { proxy } = getCurrentInstance();
const { userStore } = useUserStore();
const scheduleList = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
const deptList = ref([]);
const doctorList = ref([]);
const anesthetistList = ref([]);
const expertList = ref([]);
const operatingRoomList = ref([]);
const anesthesiaMethodOptions = ref([
{ value: '01', label: '全身麻醉' },
{ value: '02', label: '局部麻醉' },
{ value: '03', label: '椎管内麻醉' },
{ value: '04', label: '复合麻醉' }
]);
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
operCode: null,
patientName: null,
applyDeptId: null,
scheduleDateRange: [],
},
rules: {
operCode: [
{ required: true, message: "手术单号不能为空", trigger: "blur" }
],
patientName: [
{ required: true, message: "患者姓名不能为空", trigger: "blur" }
],
sex: [
{ required: true, message: "性别不能为空", trigger: "change" }
],
age: [
{ required: true, message: "年龄不能为空", trigger: "blur" }
],
applyDeptId: [
{ required: true, message: "申请科室不能为空", trigger: "change" }
],
scheduleDate: [
{ required: true, message: "安排时间不能为空", trigger: "change" }
],
operationName: [
{ required: true, message: "手术名称不能为空", trigger: "blur" }
],
surgeonId: [
{ required: true, message: "手术医师不能为空", trigger: "change" }
],
anesthesiaMethod: [
{ required: true, message: "麻醉方法不能为空", trigger: "change" }
]
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询门诊手术安排列表 */
function getList() {
loading.value = true;
listSurgicalSchedule(queryParams.value).then(response => {
scheduleList.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
/** 取消按钮 */
function cancel() {
open.value = false;
reset();
}
/** 表单重置 */
function reset() {
form.value = {
id: null,
operCode: null,
patientName: null,
sex: null,
age: null,
applyDeptId: null,
scheduleDate: null,
operationName: null,
surgeonId: null,
anesthesiaMethod: null,
expertId: null,
anesthetistId: null,
operatingRoomId: null,
remark: null
};
proxy.$refs["scheduleRef"].resetFields();
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery()utter="10" class="mb8">
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="primary" plain icon="Plus" @click="handleAdd"> 新增手术安排 </el-button> <el-button type="primary" plain icon="Plus" @click="handleAdd"> 新增手术安排 </el-button>
</el-col> </el-col>
@@ -1113,12 +1419,14 @@ function loadOrgList() {
const records = res.data?.records || res.data || [] const records = res.data?.records || res.data || []
orgList.value = records.map(item => ({ id: item.id, name: item.tenantName || item.name })) orgList.value = records.map(item => ({ id: item.id, name: item.tenantName || item.name }))
} else { } else {
proxy.$modal.msgError('获取卫生机构列表失败') // 权限不足时静默降级不弹窗阻断Bug #441
console.warn('卫生机构列表加载失败(可能无权限):', res.message || res.code)
orgList.value = [] orgList.value = []
} }
}) })
.catch(() => { .catch((err) => {
proxy.$modal.msgError('获取卫生机构列表失败') // 网络错误或权限拒绝:静默降级
console.warn('卫生机构列表加载失败:', err?.message || err)
orgList.value = [] orgList.value = []
}) })
} }