Files
his/openhis-ui-vue3/src/views/maintainSystem/Inspection/PackageManagement.vue

643 lines
17 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="package-management">
<!-- 左侧导航栏 -->
<nav class="sidebar" :class="{ active: sidebarActive }">
<div class="sidebar-item" @click="navigateToTab(0)">检验类型</div>
<div class="sidebar-item" @click="navigateToTab(1)">检验项目</div>
<div class="sidebar-item active" @click="navigateToTab(2)">套餐设置</div>
</nav>
<!-- 主内容区域 -->
<main class="content">
<!-- 导航切换按钮响应式 -->
<div class="menu-toggle" @click="toggleSidebar">
<i class="fas fa-bars"></i>
</div>
<!-- 查询过滤区域 -->
<section class="filter-bar">
<div class="filter-item">
<label>日期</label>
<input type="date" v-model="searchParams.startDate" placeholder="开始日期">
<span></span>
<input type="date" v-model="searchParams.endDate" placeholder="结束日期">
</div>
<div class="filter-item">
<label>卫生机构</label>
<select>
<option>演示医院</option>
</select>
</div>
<div class="filter-item">
<label>套餐名称</label>
<input type="text" v-model="searchParams.packageName" placeholder="套餐名称">
</div>
<div class="filter-item">
<label>套餐级别</label>
<select v-model="searchParams.packageLevel">
<option value="">请选择套餐级别</option>
<option value="全院套餐">全院套餐</option>
<option value="科室套餐">科室套餐</option>
<option value="个人套餐">个人套餐</option>
</select>
</div>
<div class="filter-item">
<label>套餐类别</label>
<select>
<option>检验套餐</option>
</select>
</div>
<div class="filter-item">
<label>科室</label>
<select>
<option value="">请选择科室</option>
<option value="内科">内科</option>
<option value="儿科">儿科</option>
<option value="外科">外科</option>
<option value="妇科">妇科</option>
</select>
</div>
<div class="filter-item">
<label>用户</label>
<select></select>
</div>
<!-- 操作按钮组 -->
<div class="button-group">
<button class="btn btn-search" @click="handleSearch"><i class="fas fa-search" style="margin-right: 6px;"></i>查询</button>
<button class="btn btn-reset" @click="handleReset"><i class="fas fa-redo" style="margin-right: 6px;"></i>重置</button>
<button class="btn btn-primary" @click="handleAdd"><i class="fas fa-plus" style="margin-right: 6px;"></i>新增</button>
<button class="btn btn-export" @click="handleExport"><i class="fas fa-download" style="margin-right: 6px;"></i>导出</button>
<button class="btn btn-copy" @click="returnToPackageSetup"><i class="fas fa-arrow-left" style="margin-right: 6px;"></i>返回</button>
</div>
</section>
<!-- 表格区域 -->
<section class="table-container">
<table>
<thead>
<tr>
<th>ID</th>
<th>卫生机构</th>
<th>日期</th>
<th>套餐名称</th>
<th>套餐类别</th>
<th>套餐级别</th>
<th>科室</th>
<th>用户</th>
<th class="text-right">金额</th>
<th class="text-right">服务费</th>
<th class="text-right">总金额</th>
<th>组合套餐</th>
<th>显示套餐名</th>
<th>启用标志</th>
<th>操作人</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in filteredData" :key="item.id">
<td>{{ item.id }}</td>
<td>{{ item.hospital }}</td>
<td>{{ item.date }}</td>
<td>{{ item.name }}</td>
<td>{{ item.type }}</td>
<td>{{ item.level }}</td>
<td>{{ item.dept || '-' }}</td>
<td>{{ item.user || '-' }}</td>
<td class="text-right">{{ item.amount.toFixed(2) }}</td>
<td class="text-right">{{ item.fee.toFixed(2) }}</td>
<td class="text-right">{{ item.total.toFixed(2) }}</td>
<td><span class="status-tag" :class="item.combined === '是' ? 'status-no' : 'status-yes'">{{ item.combined }}</span></td>
<td><span class="status-tag" :class="item.display === '是' ? 'status-yes' : 'status-no'">{{ item.display }}</span></td>
<td><span class="status-tag" :class="item.enabled === '是' ? 'status-yes' : 'status-no'">{{ item.enabled }}</span></td>
<td>{{ item.operator }}</td>
<td>
<div class="action-icons">
<el-button type="text" @click="handleEdit(item)"><el-icon><Edit /></el-icon></el-button>
<el-button type="text" @click="handleView(item)"><el-icon><View /></el-icon></el-button>
<el-button type="text" @click="handleDelete(item)"><el-icon><Delete /></el-icon></el-button>
</div>
</td>
</tr>
</tbody>
</table>
</section>
<!-- 分页组件 -->
<div class="pagination">
<button class="page-btn">&lt;</button>
<button class="page-btn active">1</button>
<button class="page-btn">2</button>
<button class="page-btn">3</button>
<button class="page-btn">...</button>
<button class="page-btn">10</button>
<button class="page-btn">&gt;</button>
<div class="total-count">总数{{ filteredData.length }}</div>
</div>
</main>
</div>
</template>
<script setup>
import { ref, computed } from 'vue';
import { useRouter } from 'vue-router';
import { Edit, View, Delete } from '@element-plus/icons-vue';
// 创建路由实例
const router = useRouter();
// 侧边栏状态
const sidebarActive = ref(false);
// 表格数据
const tableData = ref([
{id: 2348, hospital: '演示医院', date: '2025-11-17', name: '血脂333', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 40.00, fee: 0.00, total: 40.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
{id: 2341, hospital: '演示医院', date: '2025-10-31', name: '病理检测', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 50.00, fee: 0.00, total: 50.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
{id: 2340, hospital: '演示医院', date: '2025-10-31', name: '肝功能', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 31.00, fee: 0.00, total: 31.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
{id: 2339, hospital: '演示医院', date: '2025-10-31', name: '风湿', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 119.00, fee: 0.00, total: 119.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
{id: 2338, hospital: '演示医院', date: '2025-10-31', name: '尿常规', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 1.00, fee: 0.00, total: 1.00, combined: '否', display: '是', enabled: '是', operator: '徐斌'},
{id: 2297, hospital: '演示医院', date: '2025-04-30', name: '测试', type: '检验套餐', level: '全院套餐', dept: '', user: '', amount: 241.00, fee: 0.00, total: 241.00, combined: '否', display: '是', enabled: '否', operator: '徐斌'},
]);
// 获取当前日期的函数格式为YYYY-MM-DD
function getCurrentDate() {
const today = new Date();
const year = today.getFullYear();
const month = String(today.getMonth() + 1).padStart(2, '0');
const day = String(today.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
// 搜索参数
const searchParams = ref({
startDate: getCurrentDate(),
endDate: getCurrentDate(),
packageName: '',
packageLevel: ''
});
// 过滤后的数据
const filteredData = computed(() => {
return tableData.value.filter(item => {
// 日期筛选
if (searchParams.value.startDate && item.date < searchParams.value.startDate) return false;
if (searchParams.value.endDate && item.date > searchParams.value.endDate) return false;
// 套餐名称筛选
if (searchParams.value.packageName && !item.name.toLowerCase().includes(searchParams.value.packageName.toLowerCase())) return false;
// 套餐级别筛选
if (searchParams.value.packageLevel && item.level !== searchParams.value.packageLevel) return false;
return true;
});
});
// 返回套餐设置主界面
function returnToPackageSetup() {
router.push('/maintainSystem/Inspection?tab=2');
}
// 导航到指定标签页
function navigateToTab(tabIndex) {
router.push(`/maintainSystem/Inspection?tab=${tabIndex}`);
}
// 切换侧边栏
function toggleSidebar() {
sidebarActive.value = !sidebarActive.value;
}
// 处理查询
function handleSearch() {
// 过滤逻辑已在computed属性中实现
}
// 处理重置
function handleReset() {
searchParams.value = {
startDate: getCurrentDate(),
endDate: getCurrentDate(),
packageName: '',
packageLevel: ''
};
}
// 处理新增
function handleAdd() {
router.push('/maintainSystem/Inspection?tab=2');
}
// 处理编辑
function handleEdit(item) {
alert(`准备编辑套餐:${item.name}\n数据已加载至编辑表单套餐设置主界面`);
}
// 处理查看
function handleView(item) {
alert(`准备查看套餐:${item.name}\n数据已加载至查看表单套餐设置主界面`);
}
// 处理删除
function handleDelete(item) {
if (confirm(`确定要删除套餐 "${item.name}" 吗?`)) {
const index = tableData.value.findIndex(i => i.id === item.id);
if (index !== -1) {
tableData.value.splice(index, 1);
alert(`套餐 "${item.name}" 已删除`);
}
}
}
// 处理导出
function handleExport() {
// 获取当前筛选后的数据
const dataToExport = filteredData.value;
// 转换为CSV格式
const csvContent = convertToCSV(dataToExport);
// 创建下载链接
const blob = new Blob([csvContent], { type: 'text/csv;charset=utf-8;' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', `套餐数据_${new Date().toISOString().slice(0,10)}.csv`);
link.style.visibility = 'hidden';
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
// 将数据转换为CSV格式的函数
function convertToCSV(data) {
if (data.length === 0) return '';
// 获取表头
const headers = Object.keys(data[0]);
// 构建CSV内容
let csv = headers.join(',') + '\n';
// 添加数据行
data.forEach(row => {
const values = headers.map(header => {
// 处理可能包含逗号的值
const value = row[header] === null || row[header] === undefined ? '' : row[header];
return `"${value.toString().replace(/"/g, '""')}"`;
});
csv += values.join(',') + '\n';
});
return csv;
}
</script>
<style>
:root {
--background: #FFFFFF;
--primary: #5C8DFF;
--primary-hover: #7DA3FF;
--text-primary: #333333;
--text-secondary: #666666;
--text-disabled: #CCCCCC;
--danger: #FF6B6B;
--border: #E0E0E0;
--header-bg: #F5F5F5;
--row-hover: #FAFAFA;
--table-border: #E8E8E8;
--sidebar-width: 200px;
--content-padding: 24px;
--secondary: #8E8E93;
--secondary-hover: #A7A7AB;
--success: #4CAF50;
--info: #2196F3;
--btn-search: #6c757d;
--btn-reset: #17a2b8;
--btn-add: #28a745;
--btn-export: #17a2b8;
--btn-copy: #6c757d;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'PingFang SC', 'Microsoft YaHei', sans-serif;
}
/* 移除body样式避免影响其他页面 */
.package-management {
display: flex;
height: 100vh;
background-color: var(--background);
color: var(--text-primary);
overflow: hidden;
}
/* 左侧导航栏 */
.sidebar {
width: var(--sidebar-width);
background-color: var(--background);
border-right: 1px solid var(--border);
height: 100%;
display: flex;
flex-direction: column;
}
.sidebar-item {
padding: 16px 24px;
font-size: 14px;
color: var(--text-primary);
cursor: pointer;
transition: all 0.2s;
display: flex;
align-items: center;
}
.sidebar-item:hover {
background-color: #f0f8ff;
}
.sidebar-item.active {
background-color: var(--primary);
color: white;
}
/* 主内容区域 */
.content {
flex: 1;
display: flex;
flex-direction: column;
height: 100%;
overflow: hidden;
}
/* 查询过滤栏 */
.filter-bar {
padding: 16px var(--content-padding);
border-bottom: 1px solid var(--border);
display: flex;
flex-wrap: wrap;
gap: 12px;
align-items: center;
}
.filter-item {
display: flex;
align-items: center;
gap: 8px;
}
.filter-item label {
font-size: 14px;
color: var(--text-secondary);
white-space: nowrap;
}
input, select {
height: 32px;
border-radius: 4px;
border: 1px solid var(--border);
padding: 0 8px;
font-size: 14px;
min-width: 120px;
}
input:focus, select:focus {
outline: none;
border-color: var(--primary);
}
/* 按钮样式 */
.btn {
padding: 6px 16px;
border-radius: 6px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
height: 36px;
display: inline-flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
border: none;
box-shadow: 0 1px 2px rgba(0,0,0,0.05);
min-width: 80px;
}
.btn-primary {
background-color: var(--primary);
color: white;
border: 1px solid var(--primary);
box-shadow: 0 2px 4px rgba(92, 141, 255, 0.2);
}
.btn-text {
background-color: #F5F7FA;
color: var(--secondary);
border: 1px solid var(--border);
}
.btn-search {
background-color: var(--btn-search);
color: white;
}
.btn-reset {
background-color: var(--btn-reset);
color: white;
}
.btn-export {
background-color: var(--btn-export);
color: white;
}
.btn-copy {
background-color: var(--btn-copy);
color: white;
}
.btn-text:hover {
background-color: #EBEEF2;
color: var(--text-primary);
border-color: var(--secondary-hover);
}
.btn-danger {
background-color: var(--danger);
color: white;
}
.btn:hover {
opacity: 0.9;
}
.btn-primary:hover {
background-color: var(--primary-hover);
border-color: var(--primary-hover);
}
.button-group {
display: flex;
gap: 12px;
margin-left: auto;
flex-wrap: wrap;
}
/* 表格区域 */
.table-container {
flex: 1;
overflow: auto;
padding: 0 var(--content-padding) var(--content-padding);
}
table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
th, td {
padding: 8px;
text-align: left;
border-bottom: 1px solid var(--table-border);
}
th {
background-color: var(--header-bg);
font-weight: 500;
position: sticky;
top: 0;
}
tr:hover {
background-color: var(--row-hover);
}
.text-right {
text-align: right;
}
/* 状态标签 */
.status-tag {
padding: 0 8px;
border-radius: 2px;
font-size: 12px;
height: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.status-yes {
background-color: #f6ffed;
border: 1px solid #b7eb8f;
color: #389e0d;
}
.status-no {
background-color: #fff2f0;
border: 1px solid #ffccc7;
color: var(--danger);
}
/* 操作图标 */
.action-icons {
display: flex;
gap: 8px;
}
.action-icons .el-button {
color: var(--danger);
padding: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.action-icons .el-button:hover {
background-color: #fff2f0;
color: var(--danger);
}
/* 分页样式 */
.pagination {
display: flex;
justify-content: center;
align-items: center;
padding: 16px 0;
gap: 8px;
}
.page-btn {
width: 32px;
height: 32px;
border-radius: 4px;
border: 1px solid var(--border);
background-color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.page-btn.active {
background-color: var(--primary);
color: white;
border: none;
}
.total-count {
margin-left: 16px;
font-size: 14px;
color: var(--text-secondary);
}
/* 响应式设计 */
@media (max-width: 1200px) {
.sidebar {
transform: translateX(calc(-1 * var(--sidebar-width)));
position: absolute;
z-index: 100;
transition: transform 0.3s;
}
.sidebar.active {
transform: translateX(0);
}
.menu-toggle {
display: flex;
align-items: center;
justify-content: center;
height: 40px;
width: 40px;
position: absolute;
top: 16px;
left: 16px;
z-index: 101;
cursor: pointer;
background: white;
border: 1px solid var(--border);
border-radius: 4px;
}
.filter-bar {
padding-top: 64px;
}
}
</style>
<style scoped>
/* 移除未使用的图标样式 */
</style>
<style scoped>
/* 移除自动生成的未使用样式 */
</style>