563 lines
30 KiB
HTML
563 lines
30 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||
<title>车主信息查询系统 - 查询</title>
|
||
<!-- 引入Layui CSS -->
|
||
<link rel="stylesheet" href="{{ url_for('static', filename='css/layui.css') }}">
|
||
<!-- 引入Font Awesome -->
|
||
<link href="{{ url_for('static', filename='css/font-awesome.min.css') }}" rel="stylesheet">
|
||
<!-- 引入自定义CSS -->
|
||
<link href="{{ url_for('static', filename='css/custom.css') }}" rel="stylesheet">
|
||
|
||
<!-- 引入Layui JS -->
|
||
<script src="{{ url_for('static', filename='layui.js') }}"></script>
|
||
|
||
<script>
|
||
layui.use(['layer', 'form', 'table'], function(){
|
||
var layer = layui.layer;
|
||
var form = layui.form;
|
||
var table = layui.table;
|
||
});
|
||
</script>
|
||
|
||
<style>
|
||
@keyframes fadeIn {
|
||
from {
|
||
opacity: 0;
|
||
transform: translateY(-10px);
|
||
}
|
||
to {
|
||
opacity: 1;
|
||
transform: translateY(0);
|
||
}
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<!-- 引入统一的顶部导航栏 -->
|
||
{% include 'header.html' %}
|
||
|
||
<!-- 主要内容区域 -->
|
||
<div class="content-container">
|
||
<div class="content-wrapper">
|
||
<div class="card">
|
||
<div class="card-body">
|
||
<!-- 表单已清除 -->
|
||
|
||
<!-- 消息提示区域 -->
|
||
{% if error %}
|
||
<div class="error-message">
|
||
<i class="fa fa-exclamation-circle"></i> {{ error }}
|
||
</div>
|
||
{% endif %}
|
||
{% if success %}
|
||
<div class="success-message">
|
||
<i class="fa fa-check-circle"></i> {{ success }}
|
||
</div>
|
||
{% endif %}
|
||
|
||
<!-- 最近查询记录 -->
|
||
{% if recent_queries %}
|
||
<div class="card">
|
||
<div class="card-header">
|
||
<i class="fa fa-history"></i> 最近查询记录
|
||
<button id="addQueryBtn" class="layui-btn layui-btn-normal" style="
|
||
float: right;
|
||
padding: 6px 16px;
|
||
border-radius: 6px;
|
||
background-color: #009688;
|
||
border-color: #009688;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
color: white;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
gap: 5px;
|
||
">
|
||
<i class="fa fa-plus-circle"></i> 新增查询记录
|
||
</button>
|
||
</div>
|
||
<div class="card-body">
|
||
<table class="layui-table">
|
||
<thead>
|
||
<tr>
|
||
<th>序号</th>
|
||
<th>查询日期</th>
|
||
<th>车牌号</th>
|
||
<th>手机号</th>
|
||
<th>状态</th>
|
||
<th>登录用户</th>
|
||
<th>登录部门</th>
|
||
<th>登录IP</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for query in recent_queries %}
|
||
<tr class="table-hover" data-history-id="{{ query.id }}">
|
||
<td>{{ loop.index }}</td>
|
||
<td>{{ query.query_date }}</td>
|
||
<td>{{ query.plate_number }}</td>
|
||
<td>{{ query.phone }}</td>
|
||
<td>
|
||
<span class="layui-badge
|
||
{% if query.results_count == -1 %}
|
||
layui-bg-orange
|
||
{% elif query.results_count > 0 %}
|
||
layui-bg-green
|
||
{% else %}
|
||
layui-bg-red
|
||
{% endif %}">
|
||
{% if query.results_count == -1 %}
|
||
待查询
|
||
{% else %}
|
||
{{ query.results_count }} 条记录
|
||
{% endif %}
|
||
</span>
|
||
</td>
|
||
<td>{{ query.user_name }}</td>
|
||
<td>{{ query.user_department }}</td>
|
||
<td>{{ query.query_ip }}</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 用于layui增加查询弹窗的隐藏字段 -->
|
||
<input type="hidden" id="add_plate_number">
|
||
<input type="hidden" id="add_phone">
|
||
|
||
<!-- 详情弹窗已使用layui动态生成,此处不再需要静态模态框 -->
|
||
|
||
{% include 'footer.html' %}
|
||
|
||
<!-- 页面JavaScript -->
|
||
<script>
|
||
// 等待DOM加载完成
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
// 获取DOM元素
|
||
var addQueryBtn = document.getElementById('addQueryBtn');
|
||
|
||
// 为查询历史记录行添加单击事件
|
||
var rows = document.querySelectorAll('tr[data-history-id]');
|
||
for (var i = 0; i < rows.length; i++) {
|
||
rows[i].addEventListener('click', function() {
|
||
var historyId = this.getAttribute('data-history-id');
|
||
loadHistoryDetail(historyId);
|
||
});
|
||
// 为了提升用户体验,添加鼠标悬停效果
|
||
rows[i].style.cursor = 'pointer';
|
||
rows[i].style.transition = 'background-color 0.2s ease';
|
||
rows[i].addEventListener('mouseenter', function() {
|
||
this.style.backgroundColor = '#f5f7fa';
|
||
});
|
||
rows[i].addEventListener('mouseleave', function() {
|
||
this.style.backgroundColor = '';
|
||
});
|
||
}
|
||
|
||
// 增加查询按钮点击事件
|
||
addQueryBtn.addEventListener('click', function() {
|
||
// 使用layui创建增加查询记录弹窗,并美化设计
|
||
layer.open({
|
||
type: 1,
|
||
title: '<i class="fa fa-plus-circle"></i> 增加查询记录',
|
||
area: ['520px', '380px'],
|
||
offset: '10%',
|
||
shade: 0.3,
|
||
shadeClose: false,
|
||
anim: 2,
|
||
content: `
|
||
<div class="form-container" style="padding: 24px;">
|
||
|
||
|
||
<!-- 表单主体 -->
|
||
<form class="layui-form">
|
||
<!-- 车牌号输入框 -->
|
||
<div class="form-group" style="margin-bottom: 20px;">
|
||
<label for="layui_add_plate_number" style="display: block; font-size: 14px; color: #333; margin-bottom: 8px; font-weight: 500;">
|
||
<i class="fa fa-id-card-o" style="color: #009688; margin-right: 6px;"></i>车牌号
|
||
</label>
|
||
<div class="input-wrapper" style="position: relative;">
|
||
<input type="text" id="layui_add_plate_number"
|
||
style="
|
||
width: 100%;
|
||
height: 42px;
|
||
padding: 0 12px;
|
||
border: 1px solid #dcdfe6;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
transition: all 0.3s ease;
|
||
box-sizing: border-box;
|
||
"
|
||
placeholder="请输入车牌号(如:京A123456)"
|
||
onfocus="this.style.borderColor='#009688'; this.style.boxShadow='0 0 0 2px rgba(0,150,136,0.2)';"
|
||
onblur="this.style.borderColor='#dcdfe6'; this.style.boxShadow='none';">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 手机号输入框 -->
|
||
<div class="form-group" style="margin-bottom: 24px;">
|
||
<label for="layui_add_phone" style="display: block; font-size: 14px; color: #333; margin-bottom: 8px; font-weight: 500;">
|
||
<i class="fa fa-mobile" style="color: #009688; margin-right: 6px;"></i>手机号
|
||
</label>
|
||
<div class="input-wrapper" style="position: relative;">
|
||
<input type="tel" id="layui_add_phone"
|
||
style="
|
||
width: 100%;
|
||
height: 42px;
|
||
padding: 0 12px;
|
||
border: 1px solid #dcdfe6;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
transition: all 0.3s ease;
|
||
box-sizing: border-box;
|
||
"
|
||
placeholder="请输入手机号(如:13800138001)"
|
||
onfocus="this.style.borderColor='#009688'; this.style.boxShadow='0 0 0 2px rgba(0,150,136,0.2)';"
|
||
onblur="this.style.borderColor='#dcdfe6'; this.style.boxShadow='none';">
|
||
</div>
|
||
<div class="form-tip" style="margin-top: 6px;">
|
||
<i class="fa fa-info-circle" style="color: #909399; font-size: 12px;"></i>
|
||
<span style="color: #909399; font-size: 12px; margin-left: 4px;">提示:请至少输入车牌号或手机号其中一项</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 加载状态 -->
|
||
<div id="layui_addQueryLoading" class="loading-state" style="display: none; flex-direction: column; align-items: center; justify-content: center; padding: 30px 0;">
|
||
<div class="spinner" style="width: 40px; height: 40px; border: 3px solid #f0f0f0; border-top: 3px solid #009688; border-radius: 50%; animation: spin 1s linear infinite;"></div>
|
||
<p style="margin-top: 12px; color: #606266; font-size: 14px;">正在处理...</p>
|
||
</div>
|
||
|
||
<style>
|
||
@keyframes spin {
|
||
0% { transform: rotate(0deg); }
|
||
100% { transform: rotate(360deg); }
|
||
}
|
||
</style>
|
||
</form>
|
||
<style>
|
||
.btn-success {
|
||
background-color: #009688;
|
||
border-color: #009688;
|
||
color: white;
|
||
padding: 8px 20px;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
transition: all 0.3s ease;
|
||
box-shadow: 0 2px 4px rgba(0, 150, 136, 0.2);
|
||
outline: none;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.btn-success:hover {
|
||
background-color: #26a69a;
|
||
border-color: #26a69a;
|
||
box-shadow: 0 4px 8px rgba(0, 150, 136, 0.3);
|
||
}
|
||
|
||
.btn-success:active {
|
||
transform: translateY(1px);
|
||
}
|
||
|
||
.btn-secondary {
|
||
background-color: #f0f2f5;
|
||
border-color: #dcdfe6;
|
||
color: #606266;
|
||
padding: 8px 20px;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
transition: all 0.3s ease;
|
||
outline: none;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.btn-secondary:hover {
|
||
background-color: #e6eaf0;
|
||
border-color: #c0c4cc;
|
||
}
|
||
</style>
|
||
</div>
|
||
`,
|
||
btn: ['保存', '取消'],
|
||
btnAlign: 'c',
|
||
btnClass: ['btn-success', 'btn-secondary'],
|
||
btn1: function(index, layero) {
|
||
const plateNumber = document.getElementById('layui_add_plate_number').value;
|
||
const phone = document.getElementById('layui_add_phone').value;
|
||
|
||
// 验证输入
|
||
if (!plateNumber && !phone) {
|
||
layer.msg('请至少输入车牌号或手机号其中一项', {
|
||
icon: 5,
|
||
anim: 6,
|
||
time: 2000
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 手机号格式验证
|
||
if (phone && !/^1[3-9]\d{9}$/.test(phone)) {
|
||
layer.msg('请输入正确的手机号码', {
|
||
icon: 5,
|
||
anim: 6,
|
||
time: 2000
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 车牌号格式简单验证(可根据实际需求调整)
|
||
if (plateNumber && plateNumber.length < 5) {
|
||
layer.msg('请输入正确的车牌号', {
|
||
icon: 5,
|
||
anim: 6,
|
||
time: 2000
|
||
});
|
||
return false;
|
||
}
|
||
|
||
// 显示加载状态
|
||
document.getElementById('layui_addQueryLoading').style.display = 'flex';
|
||
|
||
// 模拟提交数据
|
||
setTimeout(function() {
|
||
// 创建表单用于提交数据
|
||
var form = document.createElement('form');
|
||
form.method = 'POST';
|
||
form.action = '/query';
|
||
|
||
// 添加车牌号字段
|
||
var plateInput = document.createElement('input');
|
||
plateInput.type = 'hidden';
|
||
plateInput.name = 'plate_number';
|
||
plateInput.value = plateNumber;
|
||
form.appendChild(plateInput);
|
||
|
||
// 添加手机号字段
|
||
var phoneInput = document.createElement('input');
|
||
phoneInput.type = 'hidden';
|
||
phoneInput.name = 'phone';
|
||
phoneInput.value = phone;
|
||
form.appendChild(phoneInput);
|
||
|
||
// 添加标识字段,表示这是从"增加"按钮提交的请求
|
||
var isAddInput = document.createElement('input');
|
||
isAddInput.type = 'hidden';
|
||
isAddInput.name = 'is_add_query';
|
||
isAddInput.value = 'true';
|
||
form.appendChild(isAddInput);
|
||
|
||
// 隐藏加载状态
|
||
document.getElementById('layui_addQueryLoading').style.display = 'none';
|
||
|
||
// 关闭弹窗
|
||
layer.close(index);
|
||
|
||
// 显示成功消息
|
||
layer.msg('查询记录添加成功', {
|
||
icon: 1,
|
||
time: 2000,
|
||
end: function() {
|
||
// 提交表单,将数据发送到服务器
|
||
document.body.appendChild(form);
|
||
form.submit();
|
||
}
|
||
});
|
||
}, 800);
|
||
},
|
||
btn2: function(index, layero) {
|
||
layer.close(index);
|
||
return false;
|
||
}
|
||
});
|
||
});
|
||
|
||
|
||
|
||
// 详情弹窗已使用layui实现,点击背景关闭功能由layui自动处理
|
||
|
||
// 表单提交逻辑已整合到layui弹窗中,不需要单独的表单提交事件
|
||
|
||
|
||
// 加载查询历史详情
|
||
function loadHistoryDetail(historyId) {
|
||
// 创建加载中的弹窗
|
||
const loadingIndex = layer.load(2, {
|
||
shade: [0.3, '#fff'],
|
||
content: '<div style="padding: 20px;"><i class="fa fa-spinner fa-spin mr-2"></i>正在加载详情...</div>',
|
||
shadeClose: false
|
||
});
|
||
|
||
// 发送AJAX请求获取详情
|
||
fetch('/query_history_detail/' + historyId)
|
||
.then(function(response) {
|
||
return response.json();
|
||
})
|
||
.then(function(data) {
|
||
// 关闭加载弹窗
|
||
layer.close(loadingIndex);
|
||
|
||
// 创建详情弹窗内容
|
||
let content = '';
|
||
|
||
// 转义特殊字符以防止XSS攻击
|
||
function escapeHtml(text) {
|
||
const div = document.createElement('div');
|
||
div.textContent = text || '';
|
||
return div.innerHTML;
|
||
}
|
||
|
||
if (data.error) {
|
||
// 显示错误信息
|
||
content = `
|
||
<div class="layui-text" style="text-align: center; padding: 60px 40px;">
|
||
<div style="display: inline-flex; align-items: center; justify-content: center; width: 80px; height: 80px; background-color: #fef0f0; border-radius: 50%; margin-bottom: 20px;">
|
||
<i class="fa fa-exclamation-circle text-red-500 text-4xl"></i>
|
||
</div>
|
||
<p style="color: #666; font-size: 16px;">${data.error}</p>
|
||
</div>
|
||
`;
|
||
} else if (data.car_owners && data.car_owners.length > 0) {
|
||
// 添加查询信息标题
|
||
content = `
|
||
<div class="layui-text" style="padding: 15px;">
|
||
<div class="mb-4 pb-3 border-b border-gray-200">
|
||
|
||
</div>
|
||
<div class="space-y-4" id="carOwnerCards">
|
||
`;
|
||
|
||
// 添加车辆信息卡片
|
||
for (var i = 0; i < data.car_owners.length; i++) {
|
||
var carOwner = data.car_owners[i];
|
||
|
||
content += `
|
||
<div class="bg-white border border-gray-200 rounded-lg shadow-sm">
|
||
<div class="p-3 grid grid-cols-1 gap-2">
|
||
<div class="flex items-center p-2">
|
||
<i class="fa fa-id-card-o text-gray-400 w-8 text-center"></i>
|
||
<span class="text-gray-500 w-20">车牌号:</span>
|
||
<span class="font-medium text-gray-800 flex-1">${escapeHtml(carOwner.plate_number)}</span>
|
||
</div>
|
||
<div class="flex items-center p-2">
|
||
<i class="fa fa-mobile text-gray-400 w-8 text-center"></i>
|
||
<span class="text-gray-500 w-20">手机号:</span>
|
||
<span class="font-medium text-gray-800 flex-1">${escapeHtml(carOwner.phone)}</span>
|
||
</div>
|
||
<div class="flex items-center p-2">
|
||
<i class="fa fa-user text-gray-400 w-8 text-center"></i>
|
||
<span class="text-gray-500 w-20">车主姓名:</span>
|
||
<span class="font-medium text-gray-800 flex-1">${escapeHtml(carOwner.name)}</span>
|
||
</div>
|
||
<div class="flex items-center p-2">
|
||
<i class="fa fa-id-card text-gray-400 w-8 text-center"></i>
|
||
<span class="text-gray-500 w-20">身份证号:</span>
|
||
<span class="font-medium text-gray-800 flex-1">${escapeHtml(carOwner.id_card)}</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
content += `
|
||
</div>
|
||
</div>
|
||
`;
|
||
} else {
|
||
// 显示无结果状态
|
||
content = `
|
||
<div class="layui-text" style="text-align: center; padding: 60px 40px;">
|
||
<div style="display: inline-flex; align-items: center; justify-content: center; width: 80px; height: 80px; background-color: #f5f7fa; border-radius: 50%; margin-bottom: 20px;">
|
||
<i class="fa fa-search text-gray-300 text-4xl"></i>
|
||
</div>
|
||
<p style="color: #666; font-size: 16px; margin-bottom: 8px;">暂无车辆信息</p>
|
||
<p style="color: #909399; font-size: 14px;">该查询条件下未找到相关车辆信息</p>
|
||
</div>
|
||
`;
|
||
}
|
||
|
||
// 打开详情弹窗 - 优化布局和样式
|
||
layer.open({
|
||
type: 1,
|
||
title: '<i class="fa fa-file-text-o"></i> 查询详情',
|
||
area: ['700px', 'auto'], // 使用自适应高度
|
||
offset: '10%',
|
||
shade: [0.3, '#fff'],
|
||
shadeClose: true,
|
||
anim: 2,
|
||
content: content,
|
||
btn: ['关闭'],
|
||
btnAlign: 'c',
|
||
btnClass: ['layui-btn layui-btn-primary'],
|
||
skin: 'layui-layer-molv',
|
||
success: function(layero, index) {
|
||
|
||
}
|
||
});
|
||
})
|
||
.catch(function(error) {
|
||
// 关闭加载弹窗
|
||
layer.close(loadingIndex);
|
||
|
||
// 显示错误弹窗
|
||
layer.open({
|
||
type: 1,
|
||
title: '<i class="fa fa-exclamation-circle"></i> 加载失败',
|
||
area: ['360px', 'auto'],
|
||
offset: '10%',
|
||
shade: 0.3,
|
||
shadeClose: false,
|
||
anim: 2,
|
||
content: `
|
||
<div class="layui-text" style="text-align: center; padding: 30px 20px;">
|
||
<div style="display: inline-flex; align-items: center; justify-content: center; width: 60px; height: 60px; background-color: #fef0f0; border-radius: 50%; margin-bottom: 15px;">
|
||
<i class="fa fa-exclamation-circle text-red-500 text-3xl"></i>
|
||
</div>
|
||
<p style="color: #666; font-size: 14px;">加载详情时发生错误</p>
|
||
<p style="color: #999; font-size: 12px; margin-top: 8px;">请稍后重试</p>
|
||
</div>
|
||
`,
|
||
btn: ['确定'],
|
||
btnAlign: 'c',
|
||
btnClass: ['layui-btn layui-btn-primary'],
|
||
skin: 'layui-layer-molv'
|
||
});
|
||
|
||
console.error('Error loading history detail:', error);
|
||
});
|
||
}
|
||
|
||
// 响应式处理:当窗口大小改变时,重新绑定事件(因为表格可能会重新渲染)
|
||
window.addEventListener('resize', function() {
|
||
// 重新绑定事件到查询历史记录行
|
||
var rows = document.querySelectorAll('tr[data-history-id]');
|
||
for (var i = 0; i < rows.length; i++) {
|
||
var row = rows[i];
|
||
// 先移除旧的事件监听器
|
||
var newRow = row.cloneNode(true);
|
||
row.parentNode.replaceChild(newRow, row);
|
||
|
||
// 添加新的事件监听器
|
||
newRow.addEventListener('click', function() {
|
||
var historyId = this.getAttribute('data-history-id');
|
||
loadHistoryDetail(historyId);
|
||
});
|
||
}
|
||
});
|
||
});
|
||
</script>
|
||
|
||
</body>
|
||
</html> |