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

This commit is contained in:
2026-02-25 12:58:45 +08:00
5 changed files with 502 additions and 470 deletions

View File

@@ -1,375 +1,376 @@
<template>
<div class="appoinmentmanage-container">
<div class="appoinmentmanage-header">
<h2 class="appoinmentmanage-title">科室排班管理</h2>
</div>
<div class="appoinmentmanage-content">
<!-- 查询条件 -->
<div class="query-condition">
<el-select v-model="queryParams.orgName" placeholder="全部机构" class="query-select" clearable @change="handleOrgChange">
<el-option label="全部机构" value=""></el-option>
<el-option v-for="org in organizationOptions" :key="org.id || org.code" :label="org.name || org.orgName" :value="org.name || org.orgName"></el-option>
</el-select>
<el-select v-model="queryParams.deptName" placeholder="全部科室" class="query-select">
<el-option label="全部科室" value=""></el-option>
<el-option v-for="dept in departmentOptions" :key="dept.id || dept.code" :label="dept.name || dept.deptName" :value="dept.name || dept.deptName"></el-option>
</el-select>
<el-button type="primary" @click="handleQuery" class="query-button">查询</el-button>
<el-button @click="handleReset" class="reset-button">重置</el-button>
<el-button type="success" @click="handleAppointmentSetting" class="appointment-setting-button">预约设置</el-button>
<div class="appoinmentmanage-wrapper">
<div class="appoinmentmanage-container">
<div class="appoinmentmanage-header">
<h2 class="appoinmentmanage-title">科室排班管理</h2>
</div>
<!-- 科室列表 -->
<div class="dept-table-container">
<el-table :data="deptList" border style="width: 100%" class="centered-table">
<!-- 添加空状态提示 -->
<template #empty>
<div style="padding: 20px 0;">
<el-icon><DocumentRemove /></el-icon>
<span style="margin-left: 8px;">暂无数据</span>
</div>
</template>
<!-- 适配常见的后端字段名 -->
<el-table-column prop="id" label="ID" width="150"></el-table-column>
<el-table-column prop="orgName" label="卫生机构" width="350">
<template #default="scope">
{{ scope.row.orgName || scope.row.organizationName || scope.row.org || '' }}
</template>
</el-table-column>
<el-table-column prop="deptName" label="科室名称" width="350">
<template #default="scope">
{{ scope.row.deptName || scope.row.departmentName || scope.row.name || '' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" width="400">
<template #default="scope">
{{ scope.row.remark || scope.row.description || scope.row.note || '' }}
</template>
</el-table-column>
<el-table-column prop="status" label="作废标志">
<template #default="scope">
<el-tag :type="(scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? 'success' : 'danger'">
{{ (scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? '有效' : '无效' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="350" fixed="right">
<template #default="scope">
<el-button type="primary" size="small" @click="handleEdit(scope.row)">
<el-icon><EditPen /></el-icon>
</el-button>
<el-button type="info" size="small" @click="handleView(scope.row)">
<el-icon><View /></el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="pagination.currentPage"
v-model:page-size="pagination.pageSize"
:page-sizes="[10, 20, 30, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
<div class="appoinmentmanage-content">
<!-- 查询条件 -->
<div class="query-condition">
<el-select v-model="queryParams.orgName" placeholder="全部机构" class="query-select" clearable @change="handleOrgChange">
<el-option label="全部机构" value=""></el-option>
<el-option v-for="org in organizationOptions" :key="org.id || org.code" :label="org.name || org.orgName" :value="org.name || org.orgName"></el-option>
</el-select>
<el-select v-model="queryParams.deptName" placeholder="全部科室" class="query-select">
<el-option label="全部科室" value=""></el-option>
<el-option v-for="dept in departmentOptions" :key="dept.id || dept.code" :label="dept.name || dept.deptName" :value="dept.name || dept.deptName"></el-option>
</el-select>
<el-button type="primary" @click="handleQuery" class="query-button">查询</el-button>
<el-button @click="handleReset" class="reset-button">重置</el-button>
<el-button type="success" @click="handleAppointmentSetting" class="appointment-setting-button">预约设置</el-button>
</div>
</div>
</div>
</div>
<!-- 预约设置弹窗 -->
<el-dialog
v-model="appointmentSettingDialog"
title="预约设置"
width="400px"
center
:close-on-click-modal="false"
:close-on-press-escape="false"
top="50%"
:before-close="handleAppointmentSettingCancel"
>
<el-form label-position="top" :model="appointmentSettingForm">
<el-form-item label="取消预约时间类型">
<el-select v-model="appointmentSettingForm.cancelAppointmentType" placeholder="请选择" style="width: 200px">
<el-option label="年" value="年"></el-option>
<el-option label="月" value="月"></el-option>
<el-option label="日" value="日"></el-option>
</el-select>
</el-form-item>
<el-form-item label="取消预约次数">
<el-input-number
v-model="appointmentSettingForm.cancelAppointmentCount"
:min="0"
:step="1"
placeholder="请输入"
></el-input-number>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="handleAppointmentSettingCancel">取消</el-button>
<el-button type="primary" @click="handleAppointmentSettingConfirm">确定</el-button>
</div>
</template>
</el-dialog>
<!-- 医生排班弹窗 -->
<el-dialog
v-model="scheduleDialogVisible"
:title="scheduleDialogTitle"
width="90%"
:close-on-click-modal="false"
top="20px"
fullscreen
>
<div class="doctorschedule-content">
<!-- 筛选条件 -->
<div class="filter-condition">
<span class="filter-label">卫生机构</span>
<el-input v-model="displayedInstitutionName" class="filter-select" disabled></el-input>
<span class="filter-label">科室名称</span>
<el-select v-model="filterParams.deptName" class="filter-select" disabled>
<el-option :label="filterParams.deptName" :value="filterParams.deptName"></el-option>
</el-select>
<span class="filter-label">开始日期</span>
<el-date-picker
v-model="filterParams.startDate"
type="date"
placeholder="选择日期"
class="filter-date-picker"
/>
<span class="filter-label">排班类型</span>
<div class="radio-group">
<el-radio v-model="filterParams.appointmentType" label="普通" @change="handleAppointmentTypeChange">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家" @change="handleAppointmentTypeChange">专家</el-radio>
</div>
</div>
<!-- 排班表格 -->
<div class="schedule-table-container">
<!-- 按日期分组显示排班 -->
<div v-for="(dateGroup, index) in groupedSchedule" :key="index" class="daily-schedule">
<div class="daily-header">
<span class="date-text">{{ dateGroup.date }}</span>
<span class="weekday-text">{{ dateGroup.weekday }}</span>
</div>
<el-table :data="dateGroup.items" border style="width: 100%" class="schedule-table">
<el-table-column prop="timeSlot" label="时段" width="100"></el-table-column>
<el-table-column prop="doctorName" :label="filterParams.appointmentType === '专家' ? '专家' : '医生'" width="150">
<!-- 科室列表 -->
<div class="dept-table-container">
<el-table :data="deptList" border style="width: 100%" class="centered-table">
<!-- 添加空状态提示 -->
<template #empty>
<div style="padding: 20px 0;">
<el-icon><DocumentRemove /></el-icon>
<span style="margin-left: 8px;">暂无数据</span>
</div>
</template>
<!-- 适配常见的后端字段名 -->
<el-table-column prop="id" label="ID" width="150"></el-table-column>
<el-table-column prop="orgName" label="卫生机构" width="350">
<template #default="scope">
<el-select
v-model="scope.row.doctorId"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
:key="`doctor-${filterParams.appointmentType}-${scope.row.id}`"
@change="(selectedId) => handleDoctorChange(selectedId, scope.row)"
>
<el-option
v-for="doctor in getDoctorOptions(filterParams.appointmentType)"
:key="doctor.id"
:label="doctor.label"
:value="String(doctor.id)"
></el-option>
</el-select>
{{ scope.row.orgName || scope.row.organizationName || scope.row.org || '' }}
</template>
</el-table-column>
<el-table-column prop="room" label="诊室" width="100">
<el-table-column prop="deptName" label="科室名称" width="350">
<template #default="scope">
<el-select
v-model="scope.row.room"
placeholder="请选择"
filterable
:remote-method="searchClinicRooms"
class="inline-select"
:disabled="!isEditMode"
>
<el-option
v-for="room in filteredClinicRoomOptions"
:key="room.id"
:label="room.label"
:value="room.value"
></el-option>
</el-select>
{{ scope.row.deptName || scope.row.departmentName || scope.row.name || '' }}
</template>
</el-table-column>
<el-table-column prop="startTime" label="开始时间" width="120">
<el-table-column prop="remark" label="备注" width="400">
<template #default="scope">
<el-time-picker
v-model="scope.row.startTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择开始时间"
:disabled="!isEditMode"
class="time-picker"
/>
{{ scope.row.remark || scope.row.description || scope.row.note || '' }}
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="120">
<el-table-column prop="status" label="作废标志">
<template #default="scope">
<el-time-picker
v-model="scope.row.endTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择结束时间"
:disabled="!isEditMode"
class="time-picker"
/>
<el-tag :type="(scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? 'success' : 'danger'">
{{ (scope.row.status === 1 || scope.row.status === true || scope.row.status === '1') ? '有效' : '无效' }}
</el-tag>
</template>
</el-table-column>
<el-table-column prop="maxNumber" label="限号数量" width="80">
<el-table-column label="操作" width="350" fixed="right">
<template #default="scope">
<el-input
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="record" label="号源记录" width="80">
<template #default="scope">
<el-icon
@click="handleViewRecord(scope.row)"
class="record-icon"
title="查看号源记录"
>
<View />
</el-icon>
</template>
</el-table-column>
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
<template #default="scope">
<el-select
v-model="scope.row.appointmentItem"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
@change="handleAppointmentItemChange(scope.row)"
>
<el-option
v-for="item in registrationItemOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100">
<template #default="scope">
<span>{{ scope.row.registrationFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="clinicItem" label="诊查项目" width="150">
<template #default="scope">
<el-select
v-model="scope.row.clinicItem"
placeholder="请选择诊查项目"
class="inline-select"
:disabled="!isEditMode"
@change="handleClinicItemChange(scope.row)"
>
<el-option
v-for="item in clinicItemOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100">
<template #default="scope">
<span>{{ scope.row.treatmentFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="online" label="线上" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.online" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopClinic" label="停诊" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.stopClinic" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopReason" label="停诊原因" width="150">
<template #default="scope">
<el-input
v-model="scope.row.stopReason"
:placeholder="scope.row.stopClinic ? '请输入停诊原因' : ''"
class="inline-input"
:disabled="!isEditMode || !scope.row.stopClinic"
></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="scope">
<el-button
type="primary"
size="small"
@click="handleAddSchedule(scope.row)"
:disabled="!isEditMode"
>
添加
<el-button type="primary" size="small" @click="handleEdit(scope.row)">
<el-icon><EditPen /></el-icon>
</el-button>
<el-button
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
:disabled="!isEditMode"
>
删除
<el-button type="info" size="small" @click="handleView(scope.row)">
<el-icon><View /></el-icon>
</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<div class="pagination-container">
<el-pagination
v-model:current-page="pagination.currentPage"
v-model:page-size="pagination.pageSize"
:page-sizes="[10, 20, 30, 50]"
layout="total, sizes, prev, pager, next, jumper"
:total="pagination.total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-buttons">
<el-button type="primary" @click="handleSave" :disabled="!isEditMode">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
</div>
</div>
<!-- 号源记录对话框 -->
<!-- 预约设置弹窗 -->
<el-dialog
v-model="recordDialogVisible"
title="号源记录"
width="30%"
:close-on-click-modal="true"
v-model="appointmentSettingDialog"
title="预约设置"
width="400px"
center
:close-on-click-modal="false"
:close-on-press-escape="false"
top="50%"
:before-close="handleAppointmentSettingCancel"
>
<div class="appointment-records">
<div class="record-item" v-for="record in appointmentRecords" :key="record.index">
<span class="record-time">{{ record.time }}</span>
</div>
</div>
<el-form label-position="top" :model="appointmentSettingForm">
<el-form-item label="取消预约时间类型">
<el-select v-model="appointmentSettingForm.cancelAppointmentType" placeholder="请选择" style="width: 200px">
<el-option label="年" value="年"></el-option>
<el-option label="月" value="月"></el-option>
<el-option label="日" value="日"></el-option>
</el-select>
</el-form-item>
<el-form-item label="取消预约次数">
<el-input-number
v-model="appointmentSettingForm.cancelAppointmentCount"
:min="0"
:step="1"
placeholder="请输入"
></el-input-number>
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button @click="recordDialogVisible = false">确定</el-button>
<el-button @click="handleAppointmentSettingCancel">取消</el-button>
<el-button type="primary" @click="handleAppointmentSettingConfirm">确定</el-button>
</div>
</template>
</el-dialog>
</el-dialog>
<!-- 医生排班弹窗 -->
<el-dialog
v-model="scheduleDialogVisible"
:title="scheduleDialogTitle"
width="90%"
:close-on-click-modal="false"
top="20px"
fullscreen
>
<div class="doctorschedule-content">
<!-- 筛选条件 -->
<div class="filter-condition">
<span class="filter-label">卫生机构</span>
<el-input v-model="displayedInstitutionName" class="filter-select" disabled></el-input>
<span class="filter-label">科室名称</span>
<el-select v-model="filterParams.deptName" class="filter-select" disabled>
<el-option :label="filterParams.deptName" :value="filterParams.deptName"></el-option>
</el-select>
<span class="filter-label">开始日期</span>
<el-date-picker
v-model="filterParams.startDate"
type="date"
placeholder="选择日期"
class="filter-date-picker"
/>
<span class="filter-label">排班类型</span>
<div class="radio-group">
<el-radio v-model="filterParams.appointmentType" label="普通" @change="handleAppointmentTypeChange">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家" @change="handleAppointmentTypeChange">专家</el-radio>
</div>
</div>
<!-- 排班表格 -->
<div class="schedule-table-container">
<!-- 按日期分组显示排班 -->
<div v-for="(dateGroup, index) in groupedSchedule" :key="index" class="daily-schedule">
<div class="daily-header">
<span class="date-text">{{ dateGroup.date }}</span>
<span class="weekday-text">{{ dateGroup.weekday }}</span>
</div>
<el-table :data="dateGroup.items" border style="width: 100%" class="schedule-table">
<el-table-column prop="timeSlot" label="时段" width="100"></el-table-column>
<el-table-column prop="doctorName" :label="filterParams.appointmentType === '专家' ? '专家' : '医生'" width="150">
<template #default="scope">
<el-select
v-model="scope.row.doctorId"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
:key="`doctor-${filterParams.appointmentType}-${scope.row.id}`"
@change="(selectedId) => handleDoctorChange(selectedId, scope.row)"
>
<el-option
v-for="doctor in getDoctorOptions(filterParams.appointmentType)"
:key="doctor.id"
:label="doctor.label"
:value="String(doctor.id)"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="room" label="诊室" width="100">
<template #default="scope">
<el-select
v-model="scope.row.room"
placeholder="请选择"
filterable
:remote-method="searchClinicRooms"
class="inline-select"
:disabled="!isEditMode"
>
<el-option
v-for="room in filteredClinicRoomOptions"
:key="room.id"
:label="room.label"
:value="room.value"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="startTime" label="开始时间" width="120">
<template #default="scope">
<el-time-picker
v-model="scope.row.startTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择开始时间"
:disabled="!isEditMode"
class="time-picker"
/>
</template>
</el-table-column>
<el-table-column prop="endTime" label="结束时间" width="120">
<template #default="scope">
<el-time-picker
v-model="scope.row.endTime"
type="time"
format="HH:mm"
value-format="HH:mm"
placeholder="选择结束时间"
:disabled="!isEditMode"
class="time-picker"
/>
</template>
</el-table-column>
<el-table-column prop="maxNumber" label="限号数量" width="80">
<template #default="scope">
<el-input
v-model="scope.row.maxNumber"
type="number"
:disabled="!isEditMode"
/>
</template>
</el-table-column>
<el-table-column prop="record" label="号源记录" width="80">
<template #default="scope">
<el-icon
@click="handleViewRecord(scope.row)"
class="record-icon"
title="查看号源记录"
>
<View />
</el-icon>
</template>
</el-table-column>
<el-table-column prop="appointmentItem" label="挂号项目" width="120">
<template #default="scope">
<el-select
v-model="scope.row.appointmentItem"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
@change="handleAppointmentItemChange(scope.row)"
>
<el-option
v-for="item in registrationItemOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100">
<template #default="scope">
<span>{{ scope.row.registrationFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="clinicItem" label="诊查项目" width="150">
<template #default="scope">
<el-select
v-model="scope.row.clinicItem"
placeholder="请选择诊查项目"
class="inline-select"
:disabled="!isEditMode"
@change="handleClinicItemChange(scope.row)"
>
<el-option
v-for="item in clinicItemOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100">
<template #default="scope">
<span>{{ scope.row.treatmentFee || '0' }}</span>
</template>
</el-table-column>
<el-table-column prop="online" label="线上" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.online" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopClinic" label="停诊" width="60">
<template #default="scope">
<el-checkbox v-model="scope.row.stopClinic" :disabled="!isEditMode"></el-checkbox>
</template>
</el-table-column>
<el-table-column prop="stopReason" label="停诊原因" width="150">
<template #default="scope">
<el-input
v-model="scope.row.stopReason"
:placeholder="scope.row.stopClinic ? '请输入停诊原因' : ''"
class="inline-input"
:disabled="!isEditMode || !scope.row.stopClinic"
></el-input>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="scope">
<el-button
type="primary"
size="small"
@click="handleAddSchedule(scope.row)"
:disabled="!isEditMode"
>
添加
</el-button>
<el-button
type="danger"
size="small"
@click="handleDeleteSchedule(scope.row)"
:disabled="!isEditMode"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!-- 底部操作按钮 -->
<div class="bottom-buttons">
<el-button type="primary" @click="handleSave" :disabled="!isEditMode">确定</el-button>
<el-button @click="handleCancel">取消</el-button>
</div>
</div>
<!-- 号源记录对话框 -->
<el-dialog
v-model="recordDialogVisible"
title="号源记录"
width="30%"
:close-on-click-modal="true"
>
<div class="appointment-records">
<div class="record-item" v-for="record in appointmentRecords" :key="record.index">
<span class="record-time">{{ record.time }}</span>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="recordDialogVisible = false">确定</el-button>
</div>
</template>
</el-dialog>
</el-dialog>
</div>
</template>
<script setup name="AppoinmentManage">
<script setup name="DeptManage">
import {computed, onMounted, ref, watch} from 'vue'
import { getDeptAppthoursList } from '@/api/appoinmentmanage/deptappthoursManage'
import {useRouter} from 'vue-router'
@@ -806,30 +807,23 @@ const fetchOrganizationList = async () => {
// 获取科室列表(通用方法)
const fetchDeptList = async (apiFunction) => {
try {
// 复制查询参数,避免修改原始参数
// 复制查询参数
const params = {
...queryParams.value,
pageNo: pagination.value.currentPage,
pageNum: pagination.value.currentPage, // 修正为 pageNum
pageSize: pagination.value.pageSize
};
// 并行获取科室列表和科室时间配置
// 同时获取配置数据,分页大小与主列表保持一致
// 这样既解决了 9999 导致的性能问题,又保证了当前显示行的数据完整性
const [deptRes, configRes] = await Promise.all([
apiFunction(params),
getDeptAppthoursList({ pageNum: 1, pageSize: 9999 })
getDeptAppthoursList({
pageNum: pagination.value.currentPage,
pageSize: pagination.value.pageSize
})
]);
// 创建科室名称到机构名称的映射
const institutionMap = new Map();
if (configRes.code === 200) {
const configRecords = configRes.data?.records || configRes.rows || [];
configRecords.forEach(config => {
if (config.department && config.institution) {
institutionMap.set(config.department, config.institution);
}
});
}
if (deptRes.code === 200) {
let dataList = [];
let totalCount = 0;
@@ -837,12 +831,14 @@ const fetchDeptList = async (apiFunction) => {
if (actualData && actualData.code === 200 && actualData.msg) {
actualData = actualData.data;
}
if (actualData && actualData.content) {
dataList = actualData.content;
totalCount = actualData.totalElements || 0;
} else if (actualData && actualData.records) {
// 提取主数据列表
if (actualData && actualData.records) {
dataList = actualData.records;
totalCount = actualData.total || 0;
} else if (actualData && actualData.content) {
dataList = actualData.content;
totalCount = actualData.totalElements || 0;
} else if (Array.isArray(actualData)) {
dataList = actualData;
totalCount = actualData.length;
@@ -854,38 +850,38 @@ const fetchDeptList = async (apiFunction) => {
totalCount = Array.isArray(actualData) ? actualData.length : 0;
}
// 提取并映射配置数据
const configs = configRes?.data?.records || configRes?.rows || configRes?.data || [];
const configMap = new Map();
if (Array.isArray(configs)) {
configs.forEach(c => {
// 假设通过机构+科室名进行匹配或者通过ID取决于后端模型
const key = `${c.institution}-${c.department}`;
configMap.set(key, c);
});
}
if (apiFunction === getRegisterOrganizations) {
deptList.value = dataList.map(org => ({
id: org.id,
orgName: institutionMap.get(org.name) || org.name,
deptName: org.name,
name: org.name,
remark: org.remark || org.intro,
status: org.activeFlag === 1,
registerFlag: org.registerFlag
}));
deptList.value = dataList.map(org => {
const key = `${org.orgName || org.organizationName || org.org || ''}-${org.name}`;
const config = configMap.get(key);
return {
id: org.id,
orgName: org.orgName || org.organizationName || org.name,
deptName: org.name,
name: org.name,
remark: org.remark || org.intro,
// 优先使用配置中的状态,作为补充
status: config ? config.activeFlag !== 0 : (org.activeFlag === 1),
registerFlag: config ? config.registerFlag : org.registerFlag
};
});
} else {
deptList.value = dataList;
}
// 如果后端没有处理筛选,才进行前端筛选
// 但要注意,这样会影响分页准确性,理想情况下应由后端处理
pagination.value.total = totalCount;
// 仅当前端分页时才进行过滤
if (queryParams.value.orgName && queryParams.value.orgName !== '') {
deptList.value = deptList.value.filter(
org => org.orgName === queryParams.value.orgName
);
pagination.value.total = deptList.value.length; // 更新总数为过滤后的数量
}
if (queryParams.value.deptName && queryParams.value.deptName !== '') {
deptList.value = deptList.value.filter(
org => org.deptName && org.deptName.includes(queryParams.value.deptName)
);
pagination.value.total = deptList.value.length; // 更新总数为过滤后的数量
}
} else {
ElMessage.error(deptRes.msg || '获取科室列表失败');
}
@@ -1637,7 +1633,10 @@ const handleCurrentChange = (current) => {
const fetchDepartmentOptions = async () => {
try {
// 使用当前查询参数进行过滤
const params = {}
const params = {
pageNum: 1,
pageSize: 100 // 下拉菜单加载较多数据以供选择
}
if (queryParams.value.deptName) {
params.name = queryParams.value.deptName
}
@@ -1700,18 +1699,16 @@ const fetchDepartmentOptions = async () => {
}
}
// 页面加载时获取科室列表
// 页面加载时获取初始化数据
onMounted(async () => {
// 同时加载卫生机构列表和科室列表
await Promise.all([
fetchOrganizationList(), // 加载卫生机构列表
getDeptList() // 加载科室列表
])
// 优化:合并初始化请求,减少并发
await fetchOrganizationList() // 该函数内部已包含 getRegisterOrganizations 调用
await getDeptList()
// 延迟加载科室选项,避免阻塞主列表加载
// 延迟加载非核心选项
setTimeout(() => {
fetchDepartmentOptions()
}, 0)
}, 300)
})
</script>

View File

@@ -277,7 +277,7 @@
:show-overflow-tooltip="true"
>
<template #default="scope">
<span>{{ scope.row.purchasePrice?.toFixed(3) + ' 元' }}</span>
<span>{{ Number(scope.row.purchasePrice || 0).toFixed(3) + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column
@@ -290,7 +290,7 @@
:show-overflow-tooltip="true"
>
<template #default="scope">
<span>{{ scope.row.salePrice?.toFixed(3) + ' 元' }}</span>
<span>{{ Number(scope.row.salePrice || 0).toFixed(3) + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column
@@ -303,7 +303,7 @@
:show-overflow-tooltip="true"
>
<template #default="scope">
<span>{{ scope.row.totalPurchasePrice?.toFixed(3) + ' 元' }}</span>
<span>{{ Number(scope.row.totalPurchasePrice || 0).toFixed(3) + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column
@@ -316,7 +316,7 @@
:show-overflow-tooltip="true"
>
<template #default="scope">
<span>{{ scope.row.totalSalePrice?.toFixed(3) + ' 元' }}</span>
<span>{{ Number(scope.row.totalSalePrice || 0).toFixed(3) + ' 元' }}</span>
</template>
</el-table-column>
<el-table-column
@@ -671,8 +671,13 @@ function getList() {
total.value = res.data.total;
});
productPageTotal(params).then((res) => {
salePriceTotal.value = res.data.purchasePriceStatistics;
priceTotal.value = res.data.salePriceStatistics;
// 使用 Number() 强制转换,解决字符串问题
// 使用 || 0 解决 null/undefined 问题
const purchasePrice = res.data?.purchasePriceStatistics;
const salePrice = res.data?.salePriceStatistics;
salePriceTotal.value = Number(purchasePrice || 0);
priceTotal.value = Number(salePrice || 0);
});
}