页面上导航栏搜索栏显示不全bug

This commit is contained in:
2025-12-17 17:23:31 +08:00
parent b27542ba6d
commit 515f03a5cd
6 changed files with 1317 additions and 743 deletions

View File

@@ -85,14 +85,6 @@ function resolvePath(routePath, routeQuery) {
if (isExternal(props.basePath)) {
return props.basePath
}
// 特殊处理门诊医生站路径,确保路径正确
if (routePath === '/doctorstation' || routePath === 'doctorstation') {
if (routeQuery) {
let query = JSON.parse(routeQuery);
return { path: '/doctorstation', query: query }
}
return '/doctorstation'
}
if (routeQuery) {
let query = JSON.parse(routeQuery);
return { path: getNormalPath(props.basePath + '/' + routePath), query: query }

View File

@@ -1,13 +1,13 @@
<template>
<div
:class="{ 'has-logo': showLogo }"
:style="{
backgroundColor:
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
}"
>
:class="{ 'has-logo': showLogo }"
:style="{
backgroundColor:
sideTheme === 'theme-dark' ? variables.menuBackground : variables.menuLightBackground,
}"
class="sidebar-layout"
>
<!-- <logo v-if="showLogo" :collapse="isCollapse" /> -->
<!-- <el-scrollbar :class="sideTheme" wrap-class="scrollbar-wrapper"> -->
<el-menu
:default-active="activeMenu"
:collapse="isCollapse"
@@ -27,7 +27,6 @@
:base-path="route.path"
/>
</el-menu>
<!-- </el-scrollbar> -->
<navbar @setLayout="setLayout" class="navbar-container" />
<settings ref="settingRef" />
</div>
@@ -40,7 +39,7 @@ import variables from '@/assets/styles/variables.module.scss';
import useAppStore from '@/store/modules/app';
import useSettingsStore from '@/store/modules/settings';
import usePermissionStore from '@/store/modules/permission';
import { computed } from 'vue';
import { computed, ref } from 'vue';
import { useRoute } from 'vue-router';
import { Navbar, Settings } from '@/layout/components';
@@ -71,27 +70,27 @@ function setLayout() {
</script>
<style lang="scss" scoped>
.scrollbar-wrapper {
overflow-x: auto !important;
width: 100%;
}
/* 移除滚动条样式 */
.el-menu--horizontal {
display: flex !important;
justify-content: center !important;
border-bottom: none !important;
background-color: transparent !important;
min-width: auto;
flex-wrap: nowrap;
overflow: hidden !important;
white-space: nowrap;
& > .el-menu-item,
& > .el-sub-menu {
height: 50px;
line-height: 50px;
color: #fff;
padding: 0 20px !important;
padding: 0 15px !important;
font-size: 14px;
min-width: 120px !important;
border: 1px solid red !important;
min-width: auto !important;
white-space: nowrap;
}
:deep(.svg-icon) {
@@ -101,6 +100,7 @@ function setLayout() {
:deep(.el-sub-menu__title) {
padding-right: 25px !important;
white-space: nowrap;
}
:deep(.el-sub-menu__icon-arrow) {
@@ -113,7 +113,20 @@ function setLayout() {
}
/* 水平布局,并与 Navbar 正确配合 */
div {
.sidebar-layout {
display: flex;
flex-direction: row;
align-items: center;
height: 50px;
padding: 0;
width: 100%;
& > .el-menu {
flex: 1;
height: 50px;
min-width: 0;
}
&.has-logo {
display: flex;
flex-direction: row;
@@ -121,12 +134,6 @@ div {
height: 50px;
padding: 0;
width: 100%;
& > .el-scrollbar {
flex: 1;
height: 50px;
min-width: 0;
}
}
}
</style>

View File

@@ -25,22 +25,7 @@ import Layout from '@/layout'
// 公共路由 - 所有用户均可访问的路由
export const constantRoutes = [
// 门诊医生站路由
// {
// path: '/doctorstation',
// component: Layout,
// redirect: '/doctorstation',
// name: 'DoctorStation',
// meta: { title: '门诊医生站', icon: 'doctorstation' },
// children: [
// {
// path: '',
// component: () => import('@/views/doctorstation/index.vue'),
// name: 'DoctorStationIndex',
// meta: { title: '门诊医生站', icon: 'doctorstation' }
// }
// ]
// },
// 重定向路由
{
path: '/redirect',
@@ -101,316 +86,316 @@ export const constantRoutes = [
]
},
// 套餐管理相关路由 - 添加到公共路由确保始终可用
// {
// path: '/maintainSystem/Inspection/PackageManagement',
// component: Layout,
// hidden: true,
// children: [
// {
// path: '',
// component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
// name: 'DirectPackageManagement',
// meta: { title: '套餐管理' }
// }
// ]
// },
{
path: '/maintainSystem/Inspection/PackageManagement',
component: Layout,
hidden: true,
children: [
{
path: '',
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
name: 'DirectPackageManagement',
meta: { title: '套餐管理' }
}
]
},
// 预约管理直接访问路由 - 兼容外部系统访问
// {
// path: '/reservationRecord2/appoinmentmanage',
// component: Layout,
// hidden: true,
// children: [
// {
// path: '',
// component: () => import('@/views/appoinmentmanage/clinicRoom/index.vue'),
// name: 'DirectClinicRoom',
// meta: { title: '门诊出诊医生诊室设置' }
// }
// ]
// }
{
path: '/reservationRecord2/appoinmentmanage',
component: Layout,
hidden: true,
children: [
{
path: '',
component: () => import('@/views/appoinmentmanage/clinicRoom/index.vue'),
name: 'DirectClinicRoom',
meta: { title: '门诊出诊医生诊室设置' }
}
]
}
]
// 动态路由 - 基于用户权限动态加载的路由
export const dynamicRoutes = [
// 基础管理路由
// {
// path: '/basicmanage',
// component: Layout,
// redirect: '/basicmanage/invoice-management',
// name: 'BasicManage',
// meta: { title: '基础管理', icon: 'component' },
// children: [
// {
// path: 'invoice-management',
// component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
// name: 'invoice-management',
// meta: { title: '发票管理' }
// }
// ]
// },
// 兼容系统业务管理路径的发票管理路由
// {
// path: '/system/ywgz',
// component: Layout,
// redirect: '/system/ywgz/InvoiceManagement',
// hidden: true,
// children: [
// {
// path: 'InvoiceManagement',
// component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
// name: 'SystemInvoiceManagement',
// meta: { title: '发票管理' }
// }
// ]
// },
{
path: '/basicmanage',
component: Layout,
redirect: '/basicmanage/invoice-management',
name: 'BasicManage',
meta: { title: '基础管理', icon: 'component' },
children: [
{
path: 'invoice-management',
component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
name: 'invoice-management',
meta: { title: '发票管理' }
}
]
},
// 兼容系统业务管理路径的发票管理路由
{
path: '/system/ywgz',
component: Layout,
redirect: '/system/ywgz/InvoiceManagement',
hidden: true,
children: [
{
path: 'InvoiceManagement',
component: () => import('@/views/basicmanage/InvoiceManagement/index.vue'),
name: 'SystemInvoiceManagement',
meta: { title: '发票管理' }
}
]
},
// 维护系统路由
// {
// path: '/maintainSystem',
// component: Layout,
// redirect: '/maintainSystem/chargeConfig',
// name: 'MaintainSystem',
// meta: { title: '维护系统', icon: 'system' },
// children: [
// {
// path: '',
// redirect: 'chargeConfig',
// name: 'MaintainSystemIndex' // 添加名称以解决警告
// },
// {
// path: 'chargeConfig', // 收费配置路由
// component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
// name: 'ChargeConfig',
// meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
// },
// {
// path: 'Inspection', // 检验管理路由
// component: () => import('@/views/maintainSystem/Inspection/index.vue'),
// name: 'Inspection',
// meta: { title: '检验管理', icon: 'inspection' },
// children: [
// {
// path: 'PackageManagement', // 套餐管理路由
// component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
// name: 'PackageManagement',
// meta: { title: '套餐管理' }
// }
// ]
// }
// ]
// },
{
path: '/maintainSystem',
component: Layout,
redirect: '/maintainSystem/chargeConfig',
name: 'MaintainSystem',
meta: { title: '维护系统', icon: 'system' },
children: [
{
path: '',
redirect: 'chargeConfig',
name: 'MaintainSystemIndex' // 添加名称以解决警告
},
{
path: 'chargeConfig', // 收费配置路由
component: () => import('@/views/maintainSystem/chargeConfig/index.vue'),
name: 'ChargeConfig',
meta: { title: '挂号收费系统参数维护', icon: 'config', permissions: ['maintainSystem:chargeConfig:list'] }
},
{
path: 'Inspection', // 检验管理路由
component: () => import('@/views/maintainSystem/Inspection/index.vue'),
name: 'Inspection',
meta: { title: '检验管理', icon: 'inspection' },
children: [
{
path: 'PackageManagement', // 套餐管理路由
component: () => import('@/views/maintainSystem/Inspection/PackageManagement.vue'),
name: 'PackageManagement',
meta: { title: '套餐管理' }
}
]
}
]
},
// 系统管理路由
// {
// path: '/system',
// component: Layout,
// redirect: '/system/user',
// name: 'System',
// meta: { title: '系统管理', icon: 'system' },
// children: [
// {
// path: 'user', // 用户管理路由
// component: () => import('@/views/system/user/index.vue'),
// name: 'User',
// meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
// },
// {
// path: 'role', // 角色管理路由
// component: () => import('@/views/system/role/index.vue'),
// name: 'Role',
// meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
// },
// {
// path: 'menu', // 菜单管理路由
// component: () => import('@/views/system/menu/index.vue'),
// name: 'Menu',
// meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
// },
// {
// path: 'dept', // 部门管理路由
// component: () => import('@/views/system/dept/index.vue'),
// name: 'Dept',
// meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
// },
// {
// path: 'post', // 岗位管理路由
// component: () => import('@/views/system/post/index.vue'),
// name: 'Post',
// meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
// },
// {
// path: 'dict', // 字典管理路由
// component: () => import('@/views/system/dict/index.vue'),
// name: 'Dict',
// meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
// },
// {
// path: 'config', // 参数配置路由
// component: () => import('@/views/system/config/index.vue'),
// name: 'Config',
// meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
// },
// {
// path: 'notice', // 通知公告路由
// component: () => import('@/views/system/notice/index.vue'),
// name: 'Notice',
// meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
// },
// {
// path: 'tenant', // 租户管理路由
// component: () => import('@/views/system/tenant/index.vue'),
// name: 'Tenant',
// meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
// }
// ]
// },
{
path: '/system',
component: Layout,
redirect: '/system/user',
name: 'System',
meta: { title: '系统管理', icon: 'system' },
children: [
{
path: 'user', // 用户管理路由
component: () => import('@/views/system/user/index.vue'),
name: 'User',
meta: { title: '用户管理', icon: 'user', permissions: ['system:user:list'] }
},
{
path: 'role', // 角色管理路由
component: () => import('@/views/system/role/index.vue'),
name: 'Role',
meta: { title: '角色管理', icon: 'role', permissions: ['system:role:list'] }
},
{
path: 'menu', // 菜单管理路由
component: () => import('@/views/system/menu/index.vue'),
name: 'Menu',
meta: { title: '菜单管理', icon: 'menu', permissions: ['system:menu:list'] }
},
{
path: 'dept', // 部门管理路由
component: () => import('@/views/system/dept/index.vue'),
name: 'Dept',
meta: { title: '部门管理', icon: 'dept', permissions: ['system:dept:list'] }
},
{
path: 'post', // 岗位管理路由
component: () => import('@/views/system/post/index.vue'),
name: 'Post',
meta: { title: '岗位管理', icon: 'post', permissions: ['system:post:list'] }
},
{
path: 'dict', // 字典管理路由
component: () => import('@/views/system/dict/index.vue'),
name: 'Dict',
meta: { title: '字典管理', icon: 'dict', permissions: ['system:dict:list'] }
},
{
path: 'config', // 参数配置路由
component: () => import('@/views/system/config/index.vue'),
name: 'Config',
meta: { title: '参数配置', icon: 'config', permissions: ['system:config:list'] }
},
{
path: 'notice', // 通知公告路由
component: () => import('@/views/system/notice/index.vue'),
name: 'Notice',
meta: { title: '通知公告', icon: 'notice', permissions: ['system:notice:list'] }
},
{
path: 'tenant', // 租户管理路由
component: () => import('@/views/system/tenant/index.vue'),
name: 'Tenant',
meta: { title: '租户管理', icon: 'tenant', permissions: ['system:tenant:list'] }
}
]
},
// 租户用户设置路由
// {
// path: '/system/tenant-user',
// component: Layout,
// hidden: true,
// permissions: ['*:*:*'],
// children: [
// {
// path: 'set/:tenantId(\\d+)',
// component: () => import('@/views/system/tenant/setUser'),
// name: 'SetUser',
// meta: { title: '所属用户', activeMenu: '/system/tenant' }
// }
// ]
// },
// // 租户合同管理路由
// {
// path: '/system/tenant-contract',
// component: Layout,
// hidden: true,
// permissions: ['*:*:*'],
// children: [
// {
// path: 'set/:tenantId(\\d+)',
// component: () => import('@/views/system/tenant/setContract'),
// name: 'SetContract',
// meta: { title: '合同管理', activeMenu: '/system/tenant' }
// }
// ]
// },
// // 用户角色分配路由
// {
// path: '/system/user-auth',
// component: Layout,
// hidden: true,
// permissions: ['system:user:edit'],
// children: [
// {
// path: 'role/:userId(\\d+)',
// component: () => import('@/views/system/user/authRole'),
// name: 'AuthRole',
// meta: { title: '分配角色', activeMenu: '/system/user' }
// }
// ]
// },
// // 角色用户分配路由
// {
// path: '/system/role-auth',
// component: Layout,
// hidden: true,
// permissions: ['system:role:edit'],
// children: [
// {
// path: 'user/:roleId(\\d+)',
// component: () => import('@/views/system/role/authUser'),
// name: 'AuthUser',
// meta: { title: '分配用户', activeMenu: '/system/role' }
// }
// ]
// },
// // 字典数据路由
// {
// path: '/system/dict-data',
// component: Layout,
// hidden: true,
// permissions: ['system:dict:list'],
// children: [
// {
// path: 'index/:dictId(\\d+)',
// component: () => import('@/views/system/dict/data'),
// name: 'Data',
// meta: { title: '字典数据', activeMenu: '/system/dict' }
// }
// ]
// },
{
path: '/system/tenant-user',
component: Layout,
hidden: true,
permissions: ['*:*:*'],
children: [
{
path: 'set/:tenantId(\\d+)',
component: () => import('@/views/system/tenant/setUser'),
name: 'SetUser',
meta: { title: '所属用户', activeMenu: '/system/tenant' }
}
]
},
// 租户合同管理路由
{
path: '/system/tenant-contract',
component: Layout,
hidden: true,
permissions: ['*:*:*'],
children: [
{
path: 'set/:tenantId(\\d+)',
component: () => import('@/views/system/tenant/setContract'),
name: 'SetContract',
meta: { title: '合同管理', activeMenu: '/system/tenant' }
}
]
},
// 用户角色分配路由
{
path: '/system/user-auth',
component: Layout,
hidden: true,
permissions: ['system:user:edit'],
children: [
{
path: 'role/:userId(\\d+)',
component: () => import('@/views/system/user/authRole'),
name: 'AuthRole',
meta: { title: '分配角色', activeMenu: '/system/user' }
}
]
},
// 角色用户分配路由
{
path: '/system/role-auth',
component: Layout,
hidden: true,
permissions: ['system:role:edit'],
children: [
{
path: 'user/:roleId(\\d+)',
component: () => import('@/views/system/role/authUser'),
name: 'AuthUser',
meta: { title: '分配用户', activeMenu: '/system/role' }
}
]
},
// 字典数据路由
{
path: '/system/dict-data',
component: Layout,
hidden: true,
permissions: ['system:dict:list'],
children: [
{
path: 'index/:dictId(\\d+)',
component: () => import('@/views/system/dict/data'),
name: 'Data',
meta: { title: '字典数据', activeMenu: '/system/dict' }
}
]
},
// 系统监控路由
// {
// path: '/monitor',
// component: Layout,
// redirect: '/monitor/operlog',
// name: 'Monitor',
// meta: { title: '系统监控', icon: 'monitor' },
// children: [
// {
// path: 'operlog', // 操作日志路由
// component: () => import('@/views/monitor/operlog/index.vue'),
// name: 'Operlog',
// meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
// },
// {
// path: 'logininfor', // 登录日志路由
// component: () => import('@/views/monitor/logininfor/index.vue'),
// name: 'Logininfor',
// meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
// },
// {
// path: 'job', // 定时任务路由
// component: () => import('@/views/monitor/job/index.vue'),
// name: 'Job',
// meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
// }
// ]
// },
{
path: '/monitor',
component: Layout,
redirect: '/monitor/operlog',
name: 'Monitor',
meta: { title: '系统监控', icon: 'monitor' },
children: [
{
path: 'operlog', // 操作日志路由
component: () => import('@/views/monitor/operlog/index.vue'),
name: 'Operlog',
meta: { title: '操作日志', icon: 'operlog', permissions: ['monitor:operlog:list'] }
},
{
path: 'logininfor', // 登录日志路由
component: () => import('@/views/monitor/logininfor/index.vue'),
name: 'Logininfor',
meta: { title: '登录日志', icon: 'logininfor', permissions: ['monitor:logininfor:list'] }
},
{
path: 'job', // 定时任务路由
component: () => import('@/views/monitor/job/index.vue'),
name: 'Job',
meta: { title: '定时任务', icon: 'job', permissions: ['monitor:job:list'] }
}
]
},
// 系统工具路由
// {
// path: '/tool',
// component: Layout,
// redirect: '/tool/gen',
// name: 'Tool',
// meta: { title: '系统工具', icon: 'tool' },
// children: [
// {
// path: 'gen', // 代码生成路由
// component: () => import('@/views/tool/gen/index.vue'),
// name: 'Gen',
// meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
// }
// ]
// },
{
path: '/tool',
component: Layout,
redirect: '/tool/gen',
name: 'Tool',
meta: { title: '系统工具', icon: 'tool' },
children: [
{
path: 'gen', // 代码生成路由
component: () => import('@/views/tool/gen/index.vue'),
name: 'Gen',
meta: { title: '代码生成', icon: 'gen', permissions: ['tool:gen:list'] }
}
]
},
// 定时任务日志路由
// {
// path: '/monitor/job-log',
// component: Layout,
// hidden: true,
// permissions: ['monitor:job:list'],
// children: [
// {
// path: 'index/:jobId(\\d+)',
// component: () => import('@/views/monitor/job/log'),
// name: 'JobLog',
// meta: { title: '调度日志', activeMenu: '/monitor/job' }
// }
// ]
// },
{
path: '/monitor/job-log',
component: Layout,
hidden: true,
permissions: ['monitor:job:list'],
children: [
{
path: 'index/:jobId(\\d+)',
component: () => import('@/views/monitor/job/log'),
name: 'JobLog',
meta: { title: '调度日志', activeMenu: '/monitor/job' }
}
]
},
// 代码生成编辑路由
// {
// path: '/tool/gen-edit',
// component: Layout,
// hidden: true,
// permissions: ['tool:gen:edit'],
// children: [
// {
// path: 'index/:tableId(\\d+)',
// component: () => import('@/views/tool/gen/editTable'),
// name: 'GenEdit',
// meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
// }
// ]
// }
{
path: '/tool/gen-edit',
component: Layout,
hidden: true,
permissions: ['tool:gen:edit'],
children: [
{
path: 'index/:tableId(\\d+)',
component: () => import('@/views/tool/gen/editTable'),
name: 'GenEdit',
meta: { title: '修改生成配置', activeMenu: '/tool/gen' }
}
]
}
]
// 合并常量路由和动态路由,确保所有路由都能被访问

View File

@@ -315,7 +315,7 @@ const generateWeekSchedule = (startDate) => {
//
const initData = () => {
// ID
const deptId = route.params.deptId
const deptId = route.query.deptId
console.log('科室ID:', deptId)
//
@@ -405,7 +405,7 @@ onMounted(() => {
//
watch(
() => [route.params.deptId, route.query.mode],
() => [route.query.deptId, route.query.mode],
() => {
initData()
},
@@ -601,10 +601,12 @@ watch(
/* 隐藏数字输入框的增减按钮 */
:deep(.el-input__inner[type="number"]) {
appearance: textfield;
-moz-appearance: textfield;
}
:deep(.el-input__inner[type="number"])::-webkit-outer-spin-button,
:deep(.el-input__inner[type="number"])::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
margin: 0;
}

View File

@@ -0,0 +1,985 @@
<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">
<el-option label="全部机构" value=""></el-option>
<el-option label="中联医院" value="中联医院"></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 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>
</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-select v-model="filterParams.orgName" class="filter-select" disabled>
<el-option :label="filterParams.orgName" :value="filterParams.orgName"></el-option>
</el-select>
<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="普通">普通</el-radio>
<el-radio v-model="filterParams.appointmentType" label="专家">专家</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="医生" width="120">
<template #default="scope">
<el-select
v-model="scope.row.doctorName"
placeholder="请选"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="张医生" value="张医生"></el-option>
<el-option label="李医生" value="李医生"></el-option>
<el-option label="王医生" value="王医生"></el-option>
<el-option label="赵医生" value="赵医生"></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="请选"
class="inline-select"
:disabled="!isEditMode"
>
<el-option label="诊室1" value="诊室1"></el-option>
<el-option label="诊室2" value="诊室2"></el-option>
<el-option label="诊室3" value="诊室3"></el-option>
<el-option label="诊室4" value="诊室4"></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"
>
<el-option label="挂号费 50" value="挂号费 50"></el-option>
<el-option label="一般诊疗费 10" value="一般诊疗费 10"></el-option>
<el-option label="主任医师 27" value="主任医师 27"></el-option>
<el-option label="副主任 15" value="副主任 15"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="registrationFee" label="挂号费(元)" width="100"></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"
>
<el-option label="常规诊查" value="常规诊查"></el-option>
<el-option label="专科诊查" value="专科诊查"></el-option>
<el-option label="特殊诊查" value="特殊诊查"></el-option>
<el-option label="专家诊查" value="专家诊查"></el-option>
</el-select>
</template>
</el-table-column>
<el-table-column prop="treatmentFee" label="诊疗费(元)" width="100"></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>
</template>
<script setup name="AppoinmentManage">
import { ref, onMounted, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElDialog, ElSelect, ElOption, ElInput, ElForm, ElFormItem, ElMessageBox } from 'element-plus'
import { EditPen, View, DocumentRemove } from '@element-plus/icons-vue'
import { listDept, searchDept } from '@/api/appoinmentmanage/dept'
import { getLocationTree } from '@/views/charge/outpatientregistration/components/outpatientregistration'
// 查询参数
const queryParams = ref({
orgName: '',
deptName: ''
})
// 科室选项列表
const departmentOptions = ref([])
// 科室列表
const deptList = ref([])
// 分页参数
const pagination = ref({
currentPage: 1,
pageSize: 10,
total: 0
})
// 预约设置弹窗
const appointmentSettingDialog = ref(false)
// 预约设置表单数据
const appointmentSettingForm = ref({
cancelAppointmentType: '年',
cancelAppointmentCount: 0
})
// 医生排班相关数据
// 排班弹窗可见性
const scheduleDialogVisible = ref(false)
// 排班弹窗标题
const scheduleDialogTitle = ref('')
// 当前操作模式edit/view
const currentMode = ref('edit')
// 当前选中的科室
const currentDept = ref(null)
// 筛选参数
const filterParams = ref({
orgName: '演示医院',
deptName: '测试内科',
startDate: new Date('2025-12-01'),
appointmentType: '普通'
})
// 排班列表数据
const scheduleList = ref([])
// 号源记录对话框相关
const recordDialogVisible = ref(false)
const currentRow = ref(null)
const appointmentRecords = ref([])
// 计算属性 - 是否为编辑模式
const isEditMode = computed(() => {
return currentMode.value === 'edit'
})
// 按日期分组的排班数据
const groupedSchedule = computed(() => {
// 按日期分组
const groups = {}
scheduleList.value.forEach(item => {
if (!groups[item.date]) {
groups[item.date] = {
date: item.date,
weekday: item.weekday,
items: []
}
}
groups[item.date].items.push(item)
})
// 转换为数组
return Object.values(groups)
})
// 获取科室列表(通用方法)
const fetchDeptList = async (apiFunction) => {
try {
const res = await apiFunction({
...queryParams.value,
pageNo: pagination.value.currentPage,
pageSize: pagination.value.pageSize
})
console.log('后端返回的数据:', res)
if (res.code === 200) {
// 适配不同的后端数据结构
let dataList = []
let totalCount = 0
// 首先检查是否存在嵌套的data结构
let actualData = res.data
// 处理嵌套data结构用户提供的格式
if (actualData && actualData.code === 200 && actualData.msg) {
actualData = actualData.data
}
// 检查是否是标准分页结构 (Spring Boot Page)
if (actualData && actualData.content) {
// Spring Boot Page结构使用content字段
dataList = actualData.content
totalCount = actualData.totalElements || 0
} else if (actualData && actualData.records) {
// 自定义分页结构使用records字段
dataList = actualData.records
totalCount = actualData.total || 0
} else if (Array.isArray(actualData)) {
// 直接返回数组
dataList = actualData
totalCount = actualData.length
} else if (actualData && actualData.list) {
// 其他可能的列表字段名
dataList = actualData.list
totalCount = actualData.total || actualData.list.length
} else {
// 默认处理
dataList = actualData || []
totalCount = Array.isArray(actualData) ? actualData.length : 0
}
deptList.value = dataList
pagination.value.total = totalCount
console.log('处理后的数据列表:', deptList.value)
console.log('总记录数:', pagination.value.total)
} else {
ElMessage.error(res.msg || '获取科室列表失败')
}
} catch (error) {
console.error('获取科室列表失败:', error)
ElMessage.error('获取科室列表失败')
}
}
// 获取科室列表(默认列表)
const getDeptList = async () => {
await fetchDeptList(listDept)
}
// 查询
const handleQuery = () => {
pagination.value.currentPage = 1
fetchDeptList(searchDept)
}
// 重置
const handleReset = () => {
queryParams.value = {
orgName: '',
deptName: ''
}
pagination.value.currentPage = 1
getDeptList()
}
// 预约设置弹窗显示
const handleAppointmentSetting = () => {
appointmentSettingDialog.value = true
}
// 预约设置确定
const handleAppointmentSettingConfirm = () => {
// 这里可以添加表单验证和提交逻辑
console.log('预约设置提交:', appointmentSettingForm.value)
ElMessage.success('预约设置保存成功')
appointmentSettingDialog.value = false
}
// 预约设置取消
const handleAppointmentSettingCancel = () => {
appointmentSettingDialog.value = false
}
// 路由和导航
const router = useRouter()
// 生成一周排班数据
const generateWeekSchedule = (startDate) => {
const days = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六']
const timeSlots = [
{ label: '上午', startTime: '08:00', endTime: '12:00' },
{ label: '下午', startTime: '14:30', endTime: '18:00' }
]
const schedule = []
// 生成一周7天的数据
for (let i = 0; i < 7; i++) {
const currentDate = new Date(startDate)
currentDate.setDate(startDate.getDate() + i)
const dateStr = currentDate.toISOString().split('T')[0]
const weekday = days[currentDate.getDay()]
// 每个时间段生成一条记录
timeSlots.forEach(slot => {
schedule.push({
id: `${dateStr}-${slot.label}`,
date: dateStr,
weekday: weekday,
timeSlot: slot.label,
startTime: slot.startTime,
endTime: slot.endTime,
doctorName: '',
room: '',
maxNumber: '',
appointmentItem: '',
registrationFee: '',
clinicItem: '',
treatmentFee: '',
online: true,
stopClinic: false,
stopReason: ''
})
})
}
return schedule
}
// 编辑
const handleEdit = (row) => {
// 设置当前科室和模式
currentDept.value = row
currentMode.value = 'edit'
scheduleDialogTitle.value = `编辑科室排班 - ${row.name || row.deptName}`
// 动态设置筛选参数
filterParams.value.orgName = row.orgName || '中联医院'
filterParams.value.deptName = row.name || row.deptName
// 生成排班数据
scheduleList.value = generateWeekSchedule(filterParams.value.startDate)
// 显示排班弹窗
scheduleDialogVisible.value = true
}
// 查看
const handleView = (row) => {
// 设置当前科室和模式
currentDept.value = row
currentMode.value = 'view'
scheduleDialogTitle.value = `查看科室排班 - ${row.name || row.deptName}`
// 动态设置筛选参数
filterParams.value.orgName = row.orgName || '中联医院'
filterParams.value.deptName = row.name || row.deptName
// 生成排班数据
scheduleList.value = generateWeekSchedule(filterParams.value.startDate)
// 显示排班弹窗
scheduleDialogVisible.value = true
}
// 添加排班
const handleAddSchedule = (row) => {
ElMessage.info('添加排班功能待实现')
}
// 删除排班
const handleDeleteSchedule = (row) => {
ElMessage.info('删除排班功能待实现')
}
// 计算号源记录
const calculateAppointmentRecords = (row) => {
const { startTime, endTime, maxNumber } = row
// 将时间转换为分钟数
const [startHour, startMinute] = startTime.split(':').map(Number)
const [endHour, endMinute] = endTime.split(':').map(Number)
const startTotalMinutes = startHour * 60 + startMinute
const endTotalMinutes = endHour * 60 + endMinute
// 计算总时长和间隔
const totalDuration = endTotalMinutes - startTotalMinutes
const interval = Math.floor(totalDuration / maxNumber)
// 生成号源记录
const records = []
for (let i = 0; i < maxNumber; i++) {
const minutes = startTotalMinutes + i * interval
const hour = Math.floor(minutes / 60).toString().padStart(2, '0')
const minute = (minutes % 60).toString().padStart(2, '0')
records.push({
index: i + 1,
time: `${hour}:${minute}`
})
}
return records
}
// 查看号源记录
const handleViewRecord = (row) => {
// 验证开始时间、结束时间和限号数量
if (!row.startTime || !row.endTime || !row.maxNumber) {
ElMessageBox.confirm('请先设置开始时间、结束时间和限号数量', '', {
confirmButtonText: '确定',
type: 'warning',
showCancelButton: false
})
return
}
// 计算号源记录
currentRow.value = row
appointmentRecords.value = calculateAppointmentRecords(row)
recordDialogVisible.value = true
}
// 保存排班
const handleSave = () => {
ElMessage.success('排班保存成功')
scheduleDialogVisible.value = false
}
// 取消操作
const handleCancel = () => {
scheduleDialogVisible.value = false
}
// 分页大小变化
const handleSizeChange = (size) => {
pagination.value.pageSize = size
getDeptList()
}
// 当前页码变化
const handleCurrentChange = (current) => {
pagination.value.currentPage = current
getDeptList()
}
// 获取门诊挂号的就诊科室数据
const getDepartmentOptions = async () => {
try {
const response = await getLocationTree()
if (response.code === 200) {
// 适配不同的后端数据结构
let actualData = response.data
// 处理嵌套data结构
if (actualData && actualData.code === 200 && actualData.msg) {
actualData = actualData.data
}
// 确保数据是数组格式
if (Array.isArray(actualData)) {
departmentOptions.value = actualData
} else if (actualData && actualData.records) {
departmentOptions.value = actualData.records
} else if (actualData && actualData.content) {
departmentOptions.value = actualData.content
} else if (actualData && actualData.list) {
departmentOptions.value = actualData.list
} else {
departmentOptions.value = []
}
} else {
console.error('获取科室列表失败:', response.msg)
departmentOptions.value = []
}
} catch (error) {
console.error('获取科室列表失败:', error)
departmentOptions.value = []
}
}
// 页面加载时获取科室列表
onMounted(() => {
getDeptList()
getDepartmentOptions()
})
</script>
<style scoped lang="scss">
.appoinmentmanage-container {
width: 100%;
height: 100%;
padding: 20px;
background-color: #f5f7fa;
}
.appoinmentmanage-header {
margin-bottom: 20px;
}
.appoinmentmanage-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin: 0;
}
.appoinmentmanage-content {
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.query-condition {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 16px;
}
.query-select {
width: 200px;
}
.query-button, .reset-button, .appointment-setting-button {
min-width: 100px;
}
.dept-table-container {
width: 100%;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
/* 表格居中样式 */
.centered-table {
:deep(.el-table__header-wrapper th.el-table__cell),
:deep(.el-table__body-wrapper td.el-table__cell) {
text-align: center;
}
}
/* 医生排班样式 */
.doctorschedule-content {
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.filter-condition {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 16px;
}
.filter-label {
font-weight: 500;
white-space: nowrap;
}
.filter-select {
width: 150px;
}
.filter-date-picker {
width: 200px;
}
.radio-group {
display: flex;
align-items: center;
gap: 10px;
}
.schedule-table-container {
margin-bottom: 20px;
width: 100%;
overflow-x: auto;
}
.daily-schedule {
margin-bottom: 20px;
border: 1px solid #ebeef5;
border-radius: 4px;
overflow: hidden;
width: 100%;
}
.daily-header {
background-color: #f5f7fa;
padding: 10px 15px;
border-bottom: 1px solid #ebeef5;
display: flex;
align-items: center;
gap: 15px;
font-size: 16px;
font-weight: 600;
}
.date-text {
color: #333;
}
.weekday-text {
color: #606266;
font-weight: normal;
}
.schedule-table {
width: 100% !important;
min-width: 100% !important;
:deep(.el-table__header-wrapper) {
width: 100% !important;
border-top: none;
}
:deep(.el-table__body-wrapper) {
width: 100% !important;
}
:deep(.el-table__header-wrapper th.el-table__cell),
:deep(.el-table__body-wrapper td.el-table__cell) {
text-align: center;
padding: 8px 0;
}
/* 确保表格容器填满 */
:deep(.el-table__inner-wrapper) {
width: 100% !important;
}
/* 确保表格本身填满 */
:deep(.el-table__body) {
width: 100% !important;
}
/* 确保表格列正确分配宽度 */
:deep(.el-table__header) {
width: 100% !important;
}
:deep(.el-table__header tr),
:deep(.el-table__body tr) {
width: 100% !important;
}
/* 确保表格容器的最小宽度与内容匹配 */
:deep(.el-table) {
width: 100% !important;
min-width: 100% !important;
}
}
.inline-select {
width: 100%;
}
.inline-input {
width: 100%;
}
.time-picker {
width: 100%;
}
.record-icon {
font-size: 18px;
color: #409eff;
cursor: pointer;
transition: color 0.2s;
}
.record-icon:hover {
color: #66b1ff;
}
.bottom-buttons {
display: flex;
justify-content: flex-end;
gap: 16px;
}
/* 号源记录对话框样式 */
.appointment-records {
max-height: 300px;
overflow-y: auto;
padding: 10px 0;
}
.record-item {
padding: 8px 0;
border-bottom: 1px solid #f0f0f0;
}
.record-item:last-child {
border-bottom: none;
}
.record-time {
font-size: 16px;
color: #333;
}
.dialog-footer {
text-align: center;
}
/* 隐藏数字输入框的增减按钮 */
:deep(.el-input__inner[type="number"]) {
appearance: textfield;
-moz-appearance: textfield;
}
:deep(.el-input__inner[type="number"])::-webkit-outer-spin-button,
:deep(.el-input__inner[type="number"])::-webkit-inner-spin-button {
appearance: none;
-webkit-appearance: none;
margin: 0;
}
</style>
<style scoped>
/* 确保弹窗内容区占满宽度 */
:deep(.el-dialog__body) {
padding: 20px;
}
</style>

View File

@@ -1,397 +0,0 @@
<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">
<el-option label="全部机构" value=""></el-option>
<el-option label="中联医院" value="中联医院"></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 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>
</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>
</template>
<script setup name="AppoinmentManage">
import { ref, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElDialog, ElSelect, ElOption, ElInput, ElForm, ElFormItem } from 'element-plus'
import { EditPen, View, DocumentRemove } from '@element-plus/icons-vue'
import { listDept, searchDept } from '@/api/appoinmentmanage/dept'
import { getLocationTree } from '@/views/charge/outpatientregistration/components/outpatientregistration'
// 查询参数
const queryParams = ref({
orgName: '',
deptName: ''
})
// 科室选项列表
const departmentOptions = ref([])
// 科室列表
const deptList = ref([])
// 分页参数
const pagination = ref({
currentPage: 1,
pageSize: 10,
total: 0
})
// 预约设置弹窗
const appointmentSettingDialog = ref(false)
// 预约设置表单数据
const appointmentSettingForm = ref({
cancelAppointmentType: '年',
cancelAppointmentCount: 0
})
// 获取科室列表(通用方法)
const fetchDeptList = async (apiFunction) => {
try {
const res = await apiFunction({
...queryParams.value,
pageNo: pagination.value.currentPage,
pageSize: pagination.value.pageSize
})
console.log('后端返回的数据:', res)
if (res.code === 200) {
// 适配不同的后端数据结构
let dataList = []
let totalCount = 0
// 首先检查是否存在嵌套的data结构
let actualData = res.data
// 处理嵌套data结构用户提供的格式
if (actualData && actualData.code === 200 && actualData.msg) {
actualData = actualData.data
}
// 检查是否是标准分页结构 (Spring Boot Page)
if (actualData && actualData.content) {
// Spring Boot Page结构使用content字段
dataList = actualData.content
totalCount = actualData.totalElements || 0
} else if (actualData && actualData.records) {
// 自定义分页结构使用records字段
dataList = actualData.records
totalCount = actualData.total || 0
} else if (Array.isArray(actualData)) {
// 直接返回数组
dataList = actualData
totalCount = actualData.length
} else if (actualData && actualData.list) {
// 其他可能的列表字段名
dataList = actualData.list
totalCount = actualData.total || actualData.list.length
} else {
// 默认处理
dataList = actualData || []
totalCount = Array.isArray(actualData) ? actualData.length : 0
}
deptList.value = dataList
pagination.value.total = totalCount
console.log('处理后的数据列表:', deptList.value)
console.log('总记录数:', pagination.value.total)
} else {
ElMessage.error(res.msg || '获取科室列表失败')
}
} catch (error) {
console.error('获取科室列表失败:', error)
ElMessage.error('获取科室列表失败')
}
}
// 获取科室列表(默认列表)
const getDeptList = async () => {
await fetchDeptList(listDept)
}
// 查询
const handleQuery = () => {
pagination.value.currentPage = 1
fetchDeptList(searchDept)
}
// 重置
const handleReset = () => {
queryParams.value = {
orgName: '',
deptName: ''
}
pagination.value.currentPage = 1
getDeptList()
}
// 预约设置弹窗显示
const handleAppointmentSetting = () => {
appointmentSettingDialog.value = true
}
// 预约设置确定
const handleAppointmentSettingConfirm = () => {
// 这里可以添加表单验证和提交逻辑
console.log('预约设置提交:', appointmentSettingForm.value)
ElMessage.success('预约设置保存成功')
appointmentSettingDialog.value = false
}
// 预约设置取消
const handleAppointmentSettingCancel = () => {
appointmentSettingDialog.value = false
}
// 路由和导航
const router = useRouter()
// 编辑
const handleEdit = (row) => {
// 导航到医生排班页面传递科室ID和编辑模式
router.push({
path: `/appoinmentmanage/doctorschedule/${row.id}`,
query: { mode: 'edit' }
})
}
// 查看
const handleView = (row) => {
// 导航到医生排班页面传递科室ID和查看模式
router.push({
path: `/appoinmentmanage/doctorschedule/${row.id}`,
query: { mode: 'view' }
})
}
// 分页大小变化
const handleSizeChange = (size) => {
pagination.value.pageSize = size
getDeptList()
}
// 当前页码变化
const handleCurrentChange = (current) => {
pagination.value.currentPage = current
getDeptList()
}
// 获取门诊挂号的就诊科室数据
const getDepartmentOptions = async () => {
try {
const response = await getLocationTree()
if (response.code === 200) {
// 适配不同的后端数据结构
let actualData = response.data
// 处理嵌套data结构
if (actualData && actualData.code === 200 && actualData.msg) {
actualData = actualData.data
}
// 确保数据是数组格式
if (Array.isArray(actualData)) {
departmentOptions.value = actualData
} else if (actualData && actualData.records) {
departmentOptions.value = actualData.records
} else if (actualData && actualData.content) {
departmentOptions.value = actualData.content
} else if (actualData && actualData.list) {
departmentOptions.value = actualData.list
} else {
departmentOptions.value = []
}
} else {
console.error('获取科室列表失败:', response.msg)
departmentOptions.value = []
}
} catch (error) {
console.error('获取科室列表失败:', error)
departmentOptions.value = []
}
}
// 页面加载时获取科室列表
onMounted(() => {
getDeptList()
getDepartmentOptions()
})
</script>
<style scoped lang="scss">
.appoinmentmanage-container {
width: 100%;
height: 100%;
padding: 20px;
background-color: #f5f7fa;
}
.appoinmentmanage-header {
margin-bottom: 20px;
}
.appoinmentmanage-title {
font-size: 20px;
font-weight: 600;
color: #333;
margin: 0;
}
.appoinmentmanage-content {
background-color: #fff;
border-radius: 8px;
padding: 20px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
.query-condition {
display: flex;
align-items: center;
margin-bottom: 20px;
gap: 16px;
}
.query-select {
width: 200px;
}
.query-button, .reset-button, .appointment-setting-button {
min-width: 100px;
}
.dept-table-container {
width: 100%;
}
.pagination-container {
margin-top: 20px;
display: flex;
justify-content: flex-end;
}
/* 表格居中样式 */
.centered-table {
:deep(.el-table__header-wrapper th.el-table__cell),
:deep(.el-table__body-wrapper td.el-table__cell) {
text-align: center;
}
}
</style>
<style scoped>
/* 确保弹窗内容区占满宽度 */
:deep(.el-dialog__body) {
padding: 20px;
}
</style>