1044 lines
31 KiB
Vue
1044 lines
31 KiB
Vue
<template>
|
||
<div class="inspection-container">
|
||
<!-- 左侧导航 -->
|
||
<div class="side-nav">
|
||
<div
|
||
v-for="(navItem, index) in navItems"
|
||
:key="index"
|
||
class="nav-item"
|
||
:class="{ active: activeNav === index }"
|
||
@click="activeNav = index"
|
||
>
|
||
{{ navItem }}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右侧主内容 -->
|
||
<div class="main-content">
|
||
<!-- 检验类型页面 -->
|
||
<template v-if="activeNav === 0">
|
||
<div class="header-actions">
|
||
<button class="add-new-btn" @click="addNewRow">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
新增
|
||
</button>
|
||
</div>
|
||
<div class="table-container">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>行</th>
|
||
<th>*大类编码</th>
|
||
<th>*大类项目名称</th>
|
||
<th>*执行科室</th>
|
||
<th>序号</th>
|
||
<th>备注</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="(row, index) in tableData"
|
||
:key="row.id"
|
||
:class="{ 'editing': editingRowId === row.id }"
|
||
>
|
||
<td>{{ index + 1 }}</td>
|
||
<td>
|
||
<template v-if="editingRowId === row.id">
|
||
<input v-model="row.code" type="text" :style="inputStyle">
|
||
</template>
|
||
<template v-else>
|
||
{{ row.code }}
|
||
</template>
|
||
</td>
|
||
<td>
|
||
<template v-if="editingRowId === row.id">
|
||
<input v-model="row.name" type="text" :style="inputStyle">
|
||
</template>
|
||
<template v-else>
|
||
{{ row.name }}
|
||
</template>
|
||
</td>
|
||
<td>
|
||
<template v-if="editingRowId === row.id">
|
||
<select v-model="row.department" :style="inputStyle">
|
||
<option
|
||
v-for="dept in departments"
|
||
:key="dept"
|
||
:value="dept"
|
||
>
|
||
{{ dept }}
|
||
</option>
|
||
</select>
|
||
</template>
|
||
<template v-else>
|
||
{{ row.department }}
|
||
</template>
|
||
</td>
|
||
<td>
|
||
<template v-if="editingRowId === row.id">
|
||
<input v-model="row.sortOrder" type="text" :style="inputStyle">
|
||
</template>
|
||
<template v-else>
|
||
{{ row.sortOrder }}
|
||
</template>
|
||
</td>
|
||
<td>
|
||
<template v-if="editingRowId === row.id">
|
||
<input v-model="row.remark" type="text" :style="inputStyle">
|
||
</template>
|
||
<template v-else>
|
||
{{ row.remark }}
|
||
</template>
|
||
</td>
|
||
<td class="action-cell">
|
||
<div
|
||
class="action-btn confirm-btn"
|
||
@click="handleConfirm(row)"
|
||
>
|
||
<svg v-if="editingRowId === row.id" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<polyline points="20 6 9 17 4 12"></polyline>
|
||
</svg>
|
||
<span v-else>✓</span>
|
||
</div>
|
||
<div
|
||
v-if="editingRowId !== row.id"
|
||
class="action-btn edit-btn"
|
||
@click="handleEdit(row)"
|
||
>
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
|
||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
|
||
</svg>
|
||
</div>
|
||
<div
|
||
v-if="editingRowId !== row.id"
|
||
class="action-btn add-btn"
|
||
@click="handleAdd(row, index)"
|
||
>
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
</div>
|
||
<div
|
||
class="action-btn delete-btn"
|
||
@click="handleDelete(row.id)"
|
||
>
|
||
<svg v-if="editingRowId === row.id" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<line x1="18" y1="6" x2="6" y2="18"></line>
|
||
<line x1="6" y1="6" x2="18" y2="18"></line>
|
||
</svg>
|
||
<span v-else>×</span>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 页码区域 -->
|
||
<div class="pagination">
|
||
<div class="page-btn">上一页</div>
|
||
<div class="page-btn active">1</div>
|
||
<div class="page-btn">2</div>
|
||
<div class="page-btn">3</div>
|
||
<div class="page-btn">下一页</div>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 检验项目页面 -->
|
||
<template v-else-if="activeNav === 1">
|
||
<div class="page-header">
|
||
<h2>检验项目管理</h2>
|
||
</div>
|
||
<div class="header-actions">
|
||
<button class="add-new-btn" @click="addNewItem">
|
||
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<line x1="12" y1="5" x2="12" y2="19"></line>
|
||
<line x1="5" y1="12" x2="19" y2="12"></line>
|
||
</svg>
|
||
新增检验项目
|
||
</button>
|
||
</div>
|
||
<div class="table-container">
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th>行</th>
|
||
<th>*项目编码</th>
|
||
<th>*项目名称</th>
|
||
<th>*检验类型</th>
|
||
<th>*执行科室</th>
|
||
<th>单位</th>
|
||
<th>价格</th>
|
||
<th>医保编码</th>
|
||
<th>状态</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr
|
||
v-for="(item, index) in inspectionItems"
|
||
:key="item.id"
|
||
>
|
||
<td>{{ index + 1 }}</td>
|
||
<td>{{ item.code }}</td>
|
||
<td>{{ item.name }}</td>
|
||
<td>{{ item.typeName }}</td>
|
||
<td>{{ item.department }}</td>
|
||
<td>{{ item.unit }}</td>
|
||
<td>{{ item.price }}</td>
|
||
<td>{{ item.ybNo || '-' }}</td>
|
||
<td>{{ item.status ? '启用' : '禁用' }}</td>
|
||
<td class="action-cell">
|
||
<div class="action-btn edit-btn" @click="editItem(item)">
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"></path>
|
||
<path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"></path>
|
||
</svg>
|
||
</div>
|
||
<div class="action-btn delete-btn" @click="deleteItem(item.id)">
|
||
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
||
<polyline points="3 6 5 6 21 6"></polyline>
|
||
<path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path>
|
||
<line x1="10" y1="11" x2="10" y2="17"></line>
|
||
<line x1="14" y1="11" x2="14" y2="17"></line>
|
||
</svg>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
|
||
<!-- 页码区域 -->
|
||
<div class="pagination">
|
||
<div class="page-btn">上一页</div>
|
||
<div class="page-btn active">1</div>
|
||
<div class="page-btn">2</div>
|
||
<div class="page-btn">3</div>
|
||
<div class="page-btn">下一页</div>
|
||
</div>
|
||
</template>
|
||
|
||
<!-- 套餐设置页面 -->
|
||
<template v-else-if="activeNav === 2">
|
||
<!-- 顶部操作栏 -->
|
||
<div class="top-bar">
|
||
<div class="action-group">
|
||
<button class="btn btn-icon" @click="refreshPage">
|
||
<i>↻</i> 刷新
|
||
</button>
|
||
<button class="btn btn-success" @click="handlePackageManagement">套餐管理</button>
|
||
</div>
|
||
<button class="btn btn-lg">保存</button>
|
||
</div>
|
||
|
||
<!-- 表单区域 -->
|
||
<div class="form-section">
|
||
<div class="section-title">基本信息</div>
|
||
<div class="form-grid">
|
||
<div class="form-item">
|
||
<span class="form-label">套餐类别</span>
|
||
<select class="form-control form-select">
|
||
<option value="1" selected>检验套餐</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="form-item">
|
||
<span class="form-label">套餐级别</span>
|
||
<select class="form-control form-select" id="packageLevel" v-model="packageLevel" @change="handlePackageLevelChange">
|
||
<option value="">请选择套餐级别</option>
|
||
<option value="全院套餐">全院套餐</option>
|
||
<option value="科室套餐">科室套餐</option>
|
||
<option value="个人套餐">个人套餐</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-item" id="departmentContainer" v-show="packageLevel === '科室套餐'">
|
||
<span class="form-label">科室</span>
|
||
<select class="form-control form-select" id="departmentSelect">
|
||
<option value="">请选择科室</option>
|
||
<option value="内科">内科</option>
|
||
<option value="外科">外科</option>
|
||
<option value="儿科">儿科</option>
|
||
<option value="妇产科">妇产科</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-item" id="userContainer" v-show="packageLevel === '个人套餐'">
|
||
<span class="form-label">用户</span>
|
||
<select class="form-control form-select" id="userSelect">
|
||
<option value="">请选择用户</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label"><span style="color:red">*</span>套餐名称</span>
|
||
<input type="text" class="form-control" id="packageNameInput" placeholder="输入套餐名称" required>
|
||
<div class="error-message" id="packageNameError" style="color: #ff4d4f; font-size: 12px; margin-top: 4px; display: none;">套餐名称不能为空</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">卫生机构</span>
|
||
<input type="text" class="form-control" value="演示医院" readonly>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">套餐金额</span>
|
||
<input type="text" class="form-control" style="width: 120px;" value="45.00" id="packageAmountInput">
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">折扣 %</span>
|
||
<input type="text" class="form-control">
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">制单人</span>
|
||
<input type="text" class="form-control" readonly value="张三">
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">是否停用</span>
|
||
<div class="radio-group">
|
||
<label class="radio-item">
|
||
<input type="radio" name="status" checked> 启用
|
||
</label>
|
||
<label class="radio-item">
|
||
<input type="radio" name="status"> 停用
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">显示套餐名</span>
|
||
<div class="radio-group">
|
||
<label class="radio-item">
|
||
<input type="radio" name="show_name" checked> 是
|
||
</label>
|
||
<label class="radio-item">
|
||
<input type="radio" name="show_name"> 否
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">生成服务费</span>
|
||
<div class="radio-group">
|
||
<label class="radio-item">
|
||
<input type="radio" name="fee_generation" checked> 是
|
||
</label>
|
||
<label class="radio-item">
|
||
<input type="radio" name="fee_generation"> 否
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">套餐价格</span>
|
||
<div class="radio-group">
|
||
<label class="radio-item">
|
||
<input type="radio" name="price_enabled" checked> 启用
|
||
</label>
|
||
<label class="radio-item">
|
||
<input type="radio" name="price_enabled"> 不启用
|
||
</label>
|
||
</div>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">备注</span>
|
||
<input type="text" class="form-control" placeholder>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">服务费</span>
|
||
<input type="text" class="form-control">
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">lis分组</span>
|
||
<select class="form-control form-select">
|
||
<option value="">请选择lis分组</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-item">
|
||
<span class="form-label">血量</span>
|
||
<input type="text" class="form-control">
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 表格区域 -->
|
||
<div class="table-container">
|
||
<div class="table-header">
|
||
<div class="table-title">检验套餐明细</div>
|
||
<div>
|
||
<button class="action-btn" title="添加项目" id="addItemBtn">+</button>
|
||
</div>
|
||
</div>
|
||
|
||
<table class="data-table">
|
||
<thead>
|
||
<tr>
|
||
<th style="width: 40px;">行</th>
|
||
<th style="width: 250px;">项目名称/规格</th>
|
||
<th>剂量</th>
|
||
<th>途径</th>
|
||
<th>频次</th>
|
||
<th>天数</th>
|
||
<th>数量</th>
|
||
<th>单位</th>
|
||
<th>单价</th>
|
||
<th>金额</th>
|
||
<th>服务费</th>
|
||
<th>总金额</th>
|
||
<th>产地</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr v-for="(item, index) in packageItems" :key="index">
|
||
<td>{{ index + 1 }}</td>
|
||
<td>{{ item.name }}</td>
|
||
<td>{{ item.dosage }}</td>
|
||
<td>{{ item.route }}</td>
|
||
<td>{{ item.frequency }}</td>
|
||
<td>{{ item.days }}</td>
|
||
<td>{{ item.quantity }}</td>
|
||
<td>{{ item.unit }}</td>
|
||
<td>{{ item.unitPrice }}</td>
|
||
<td>{{ item.amount }}</td>
|
||
<td>{{ item.serviceFee }}</td>
|
||
<td>{{ item.totalAmount }}</td>
|
||
<td>{{ item.origin }}</td>
|
||
<td>
|
||
<div class="table-actions">
|
||
<div class="action-btn" title="编辑">✏️</div>
|
||
<div class="action-btn" title="删除">🗑️</div>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</template>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, onMounted } from 'vue';
|
||
import { ElMessage } from 'element-plus';
|
||
import { useRouter } from 'vue-router';
|
||
import request from '@/utils/request';
|
||
import { listInspectionType, addInspectionType, updateInspectionType, delInspectionType } from '@/api/system/inspectionType';
|
||
|
||
// 创建路由实例
|
||
const router = useRouter();
|
||
|
||
// 导航数据
|
||
const navItems = ref(['检验类型', '检验项目', '套餐设置']);
|
||
const activeNav = ref(0);
|
||
|
||
// 检验类型数据
|
||
const tableData = ref([]);
|
||
|
||
// 获取检验类型列表 - 从后端API获取
|
||
const getInspectionTypeList = () => {
|
||
listInspectionType().then(data => {
|
||
// 确保数据结构与前端使用的一致,处理后端返回的AjaxResult格式
|
||
// 后端返回的数据格式: {code: 200, msg: "查询成功", data: [检验类型列表]}
|
||
const inspectionTypeList = data.data || [];
|
||
const formattedData = inspectionTypeList.map(item => ({
|
||
...item,
|
||
// 将后端返回的order字段映射到前端使用的sortOrder字段
|
||
sortOrder: item.order
|
||
}));
|
||
// 过滤掉已逻辑删除的记录(validFlag为0)
|
||
tableData.value = formattedData.filter(item => item.validFlag === 1);
|
||
}).catch(error => {
|
||
console.error('获取检验类型列表失败:', error);
|
||
});
|
||
};
|
||
const editingRowId = ref(null);
|
||
const inputStyle = { width: '100%', height: '28px', padding: '0 4px', border: '1px solid #d9d9d9', borderRadius: '2px' };
|
||
const departments = ref(['检验科', '病理科', '放射科', '超声科']);
|
||
|
||
// 检验项目数据
|
||
const inspectionItems = ref([
|
||
{ id: 1, code: 'ITEM001', name: '白细胞计数', typeName: '血常规', department: '检验科', unit: '10^9/L', price: 15.00, ybNo: 'Y001', status: true },
|
||
{ id: 2, code: 'ITEM002', name: '红细胞计数', typeName: '血常规', department: '检验科', unit: '10^12/L', price: 15.00, ybNo: 'Y002', status: true },
|
||
{ id: 3, code: 'ITEM003', name: '总蛋白', typeName: '生化检查', department: '检验科', unit: 'g/L', price: 20.00, ybNo: 'Y003', status: true }
|
||
]);
|
||
|
||
// 套餐相关数据
|
||
const packageLevel = ref('');
|
||
const packageItems = ref([
|
||
{ name: '血常规(五分类)', dosage: '项/人', route: '项/人', frequency: '', days: '', quantity: 1, unit: '项', unitPrice: 15.00, amount: 15.00, serviceFee: 0.00, totalAmount: 15.00, origin: '' },
|
||
{ name: '总IgE测定', dosage: '项/人', route: '项/人', frequency: '', days: '', quantity: 1, unit: '项', unitPrice: 30.00, amount: 30.00, serviceFee: 0.00, totalAmount: 30.00, origin: '' }
|
||
]);
|
||
|
||
// 检验类型相关方法
|
||
const addNewRow = () => {
|
||
const newRow = { id: Date.now(), code: '', name: '', department: departments.value[0], sortOrder: tableData.value.length + 1, remark: '' };
|
||
tableData.value.push(newRow);
|
||
editingRowId.value = newRow.id;
|
||
};
|
||
|
||
const handleEdit = (row) => {
|
||
editingRowId.value = row.id;
|
||
};
|
||
|
||
const handleConfirm = (row) => {
|
||
// 准备提交给后端的数据,保留sortOrder字段名,后端会自动映射到数据库的order字段
|
||
const submitData = {
|
||
...row,
|
||
// 确保sortOrder字段存在且为数字类型
|
||
sortOrder: row.sortOrder ? Number(row.sortOrder) : 0
|
||
};
|
||
|
||
console.log('原始row数据:', row);
|
||
console.log('提交前的submitData:', submitData);
|
||
|
||
// 验证必填字段
|
||
if (!submitData.code || submitData.code.trim() === '') {
|
||
alert('检验类型编码不能为空');
|
||
return;
|
||
}
|
||
|
||
if (!submitData.name || submitData.name.trim() === '') {
|
||
alert('检验类型名称不能为空');
|
||
return;
|
||
}
|
||
|
||
if (!submitData.department || submitData.department.trim() === '') {
|
||
alert('执行科室不能为空');
|
||
return;
|
||
}
|
||
|
||
// 检查是否是已知的重复编码
|
||
if (submitData.code.trim() === '21') {
|
||
alert('检验类型编码21已存在,请使用其他编码');
|
||
return;
|
||
}
|
||
|
||
// 输出调试信息
|
||
console.log('原始code值:', submitData.code, '长度:', submitData.code.length);
|
||
|
||
// 去除code字段的前后空格,确保唯一性验证准确
|
||
submitData.code = submitData.code.trim();
|
||
|
||
console.log('去除空格后的code值:', submitData.code, '长度:', submitData.code.length);
|
||
console.log('准备提交的数据:', submitData);
|
||
|
||
// 区分新增和更新操作
|
||
if (row.id.toString().length > 10) { // 新增的临时ID
|
||
// 新增数据时移除临时ID,让后端自动生成主键
|
||
const { id, ...newData } = submitData;
|
||
console.log('删除ID后的newData:', newData);
|
||
|
||
addInspectionType(newData).then(response => {
|
||
console.log('新增成功响应:', response);
|
||
getInspectionTypeList();
|
||
}).catch(error => {
|
||
console.error('新增检验类型失败:', error);
|
||
if (error.response && error.response.data) {
|
||
alert('新增失败: ' + error.response.data.msg);
|
||
} else {
|
||
alert('新增失败,请重试');
|
||
}
|
||
});
|
||
} else { // 更新操作
|
||
// 更新数据时保留ID
|
||
console.log('更新时的submitData:', submitData);
|
||
|
||
updateInspectionType(submitData).then(response => {
|
||
console.log('更新成功响应:', response);
|
||
getInspectionTypeList();
|
||
}).catch(error => {
|
||
console.error('更新检验类型失败:', error);
|
||
if (error.response && error.response.data) {
|
||
alert('更新失败: ' + error.response.data.msg);
|
||
} else {
|
||
alert('更新失败,请重试');
|
||
}
|
||
});
|
||
}
|
||
|
||
editingRowId.value = null;
|
||
};
|
||
|
||
const handleAdd = (row, index) => {
|
||
const newRow = { id: Date.now(), code: '', name: '', department: row.department, sortOrder: row.sortOrder + 0.5, remark: '' };
|
||
tableData.value.splice(index + 1, 0, newRow);
|
||
editingRowId.value = newRow.id;
|
||
};
|
||
|
||
const handleDelete = (id) => {
|
||
console.log('删除按钮被点击,原始ID:', id, '类型:', typeof id);
|
||
|
||
// 确保ID是数字类型
|
||
const numericId = Number(id);
|
||
console.log('转换后的ID:', numericId, '类型:', typeof numericId);
|
||
|
||
// 判断是否为临时ID(临时ID是通过Date.now()生成的,值很大,通常大于2000000000000)
|
||
const isTemporaryId = numericId > 2e12;
|
||
console.log('是否为临时ID:', isTemporaryId, '判断阈值:', 2e12);
|
||
|
||
if (!isTemporaryId) { // 真实数据库ID
|
||
console.log('调用删除API,ID:', numericId, 'API路径:', `/system/inspection-type/${numericId}`);
|
||
delInspectionType(numericId).then(response => {
|
||
console.log('删除成功,响应:', response);
|
||
ElMessage.success('删除成功');
|
||
getInspectionTypeList();
|
||
}).catch(error => {
|
||
console.error('删除检验类型失败:', error);
|
||
ElMessage.error('删除失败: ' + (error.response?.data?.msg || '未知错误'));
|
||
if (error.response) {
|
||
console.error('响应状态:', error.response.status);
|
||
console.error('响应数据:', error.response.data);
|
||
} else if (error.request) {
|
||
console.error('请求发送但未收到响应:', error.request);
|
||
} else {
|
||
console.error('请求配置错误:', error.message);
|
||
}
|
||
});
|
||
} else {
|
||
// 删除临时新增的行
|
||
console.log('删除临时行,ID:', numericId);
|
||
tableData.value = tableData.value.filter(row => Number(row.id) !== numericId);
|
||
ElMessage.success('删除成功');
|
||
}
|
||
};
|
||
|
||
// 检验项目相关方法
|
||
const addNewItem = () => {
|
||
console.log('新增检验项目');
|
||
};
|
||
|
||
const editItem = (item) => {
|
||
console.log('编辑检验项目', item);
|
||
};
|
||
|
||
const deleteItem = (id) => {
|
||
console.log('删除检验项目', id);
|
||
};
|
||
|
||
// 套餐相关方法
|
||
const handlePackageLevelChange = () => {
|
||
console.log('套餐级别变更为:', packageLevel.value);
|
||
};
|
||
|
||
const handlePackageManagement = () => {
|
||
// 跳转到套餐管理页面
|
||
router.push({
|
||
path: '/maintainSystem/Inspection/PackageManagement'
|
||
});
|
||
};
|
||
|
||
const refreshPage = () => {
|
||
getInspectionTypeList();
|
||
};
|
||
|
||
// 页面加载时获取数据
|
||
onMounted(() => {
|
||
getInspectionTypeList();
|
||
// 检查URL参数,如果有tab参数则切换到对应导航项
|
||
const query = router.currentRoute.value.query;
|
||
if (query.tab === '0' || query.tab === '1' || query.tab === '2') {
|
||
activeNav.value = parseInt(query.tab);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
/* 基础样式重置 */
|
||
* {
|
||
margin: 0;
|
||
padding: 0;
|
||
box-sizing: border-box;
|
||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||
}
|
||
|
||
/* 整体布局 */
|
||
.inspection-container {
|
||
display: flex;
|
||
width: 100%;
|
||
height: 100vh;
|
||
background-color: #f5f7fa;
|
||
}
|
||
|
||
/* 左侧导航 */
|
||
.side-nav {
|
||
width: 200px;
|
||
background-color: #fff;
|
||
box-shadow: 1px 0 5px rgba(0, 0, 0, 0.05);
|
||
padding: 20px 0;
|
||
}
|
||
|
||
.nav-item {
|
||
height: 40px;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 20px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
color: #333;
|
||
}
|
||
|
||
.nav-item:hover {
|
||
background-color: #f0f7ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.nav-item.active {
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
}
|
||
|
||
/* 右侧主内容 */
|
||
.main-content {
|
||
flex: 1;
|
||
padding: 20px;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
/* 页面标题 */
|
||
.page-header {
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.page-header h2 {
|
||
font-size: 18px;
|
||
font-weight: 600;
|
||
color: #333;
|
||
}
|
||
|
||
/* 头部操作按钮 */
|
||
.header-actions {
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.add-new-btn {
|
||
height: 32px;
|
||
padding: 0 16px;
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
border: none;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.add-new-btn:hover {
|
||
background-color: #40a9ff;
|
||
}
|
||
|
||
/* 表格容器 */
|
||
.table-container {
|
||
background-color: #fff;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
||
overflow: hidden;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
/* 数据表格 */
|
||
.data-table {
|
||
width: 100%;
|
||
border-collapse: collapse;
|
||
}
|
||
|
||
.data-table th,
|
||
.data-table td {
|
||
height: 36px;
|
||
padding: 0 12px;
|
||
text-align: left;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.data-table th {
|
||
background-color: #fafafa;
|
||
font-weight: 600;
|
||
color: #333;
|
||
white-space: nowrap;
|
||
}
|
||
|
||
.data-table tr:hover {
|
||
background-color: #fafafa;
|
||
}
|
||
|
||
.data-table tr.editing {
|
||
background-color: #f0f7ff;
|
||
box-shadow: 0 0 0 1px #1890ff;
|
||
}
|
||
|
||
/* 操作列 */
|
||
.action-cell {
|
||
display: flex;
|
||
gap: 8px;
|
||
align-items: center;
|
||
}
|
||
|
||
.action-btn {
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 4px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
color: #666;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.action-btn:hover {
|
||
background-color: #f5f5f5;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.confirm-btn:hover {
|
||
background-color: #f6ffed;
|
||
color: #52c41a;
|
||
}
|
||
|
||
.edit-btn:hover {
|
||
background-color: #e6f7ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.add-btn:hover {
|
||
background-color: #e6f7ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.delete-btn:hover {
|
||
background-color: #fff2f0;
|
||
color: #ff4d4f;
|
||
}
|
||
|
||
/* 分页 */
|
||
.pagination {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
gap: 8px;
|
||
margin-top: 20px;
|
||
}
|
||
|
||
.page-btn {
|
||
padding: 6px 12px;
|
||
border: 1px solid #d9d9d9;
|
||
border-radius: 4px;
|
||
cursor: pointer;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.page-btn:hover {
|
||
border-color: #1890ff;
|
||
color: #1890ff;
|
||
}
|
||
|
||
.page-btn.active {
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
border-color: #1890ff;
|
||
}
|
||
|
||
/* 套餐设置样式 */
|
||
.top-bar {
|
||
height: 48px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
padding: 0 16px;
|
||
border-bottom: 1px solid #e8e8e8;
|
||
background: #fff;
|
||
margin-bottom: 16px;
|
||
gap: 16px;
|
||
}
|
||
|
||
.action-group {
|
||
display: flex;
|
||
gap: 12px;
|
||
}
|
||
|
||
.btn {
|
||
height: 32px;
|
||
padding: 0 16px;
|
||
border-radius: 4px;
|
||
font-weight: 500;
|
||
font-size: 14px;
|
||
display: inline-flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
cursor: pointer;
|
||
border: none;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.btn-icon {
|
||
padding: 0 12px;
|
||
}
|
||
|
||
.btn-icon i {
|
||
margin-right: 4px;
|
||
}
|
||
|
||
.btn-primary {
|
||
background-color: #1890ff;
|
||
color: #fff;
|
||
}
|
||
|
||
.btn-success {
|
||
background-color: #00b27a;
|
||
color: #fff;
|
||
}
|
||
|
||
.btn-lg {
|
||
height: 36px;
|
||
padding: 0 24px;
|
||
font-size: 14px;
|
||
background-color: #0fb26d;
|
||
color: white;
|
||
transition: all 0.2s;
|
||
}
|
||
|
||
.btn-lg:hover {
|
||
background-color: #0d9d5f;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.btn-lg:active {
|
||
transform: translateY(1px);
|
||
}
|
||
|
||
/* 表单区域 */
|
||
.form-section {
|
||
background: #fff;
|
||
border-radius: 4px;
|
||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
||
padding: 16px;
|
||
margin-bottom: 16px;
|
||
}
|
||
|
||
.section-title {
|
||
font-weight: 700;
|
||
font-size: 14px;
|
||
margin-bottom: 16px;
|
||
padding-bottom: 8px;
|
||
border-bottom: 1px solid #f0f0f0;
|
||
}
|
||
|
||
.form-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(4, 1fr);
|
||
gap: 16px;
|
||
}
|
||
|
||
.form-item {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.form-label {
|
||
width: 80px;
|
||
text-align: right;
|
||
padding-right: 12px;
|
||
color: #666;
|
||
flex-shrink: 0;
|
||
}
|
||
|
||
.form-control {
|
||
flex: 1;
|
||
height: 32px;
|
||
border: 1px solid #d9d9d9;
|
||
border-radius: 4px;
|
||
padding: 0 8px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.form-control:focus {
|
||
outline: none;
|
||
border-color: #1890ff;
|
||
box-shadow: 0 0 0 2px rgba(24, 144, 255, 0.2);
|
||
}
|
||
|
||
.form-select {
|
||
width: 100%;
|
||
background: white;
|
||
appearance: none;
|
||
}
|
||
|
||
.radio-group {
|
||
display: flex;
|
||
gap: 16px;
|
||
}
|
||
|
||
.radio-item {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 4px;
|
||
}
|
||
|
||
/* 表格头部 */
|
||
.table-header {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
margin-bottom: 16px;
|
||
padding: 16px;
|
||
}
|
||
|
||
.table-title {
|
||
font-weight: 700;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* 表格内操作按钮 */
|
||
.table-actions {
|
||
display: flex;
|
||
gap: 8px;
|
||
}
|
||
|
||
/* 编辑模式行样式 */
|
||
.data-table tr.editing {
|
||
background-color: #f0f7ff;
|
||
box-shadow: 0 0 0 1px #1890ff;
|
||
}
|
||
|
||
/* 响应式设计 */
|
||
@media (max-width: 1200px) {
|
||
.form-grid {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.inspection-container {
|
||
flex-direction: column;
|
||
}
|
||
|
||
.side-nav {
|
||
width: 100%;
|
||
padding: 10px 0;
|
||
}
|
||
|
||
.nav-item {
|
||
height: 36px;
|
||
padding: 0 16px;
|
||
}
|
||
|
||
.main-content {
|
||
padding: 10px;
|
||
}
|
||
|
||
.form-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.table-container {
|
||
overflow-x: auto;
|
||
}
|
||
|
||
.data-table {
|
||
min-width: 1000px;
|
||
}
|
||
}
|
||
</style> |