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

1044 lines
31 KiB
Vue
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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="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('调用删除APIID:', 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>