2024-06-06 14:18:42 +08:00
|
|
|
{% load static %}
|
|
|
|
|
|
|
|
<div id="uploadModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="uploadModalLabel" aria-hidden="true">
|
|
|
|
<div class="modal-dialog" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<form id="upload-form" method="post" enctype="multipart/form-data">
|
|
|
|
{% csrf_token %}
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="uploadModalLabel">上传Excel文件</h5>
|
|
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<!-- 上传表单 -->
|
|
|
|
<input type="file" name="excel_file" class="form-control" id="inputFile" hidden accept=".xlsx">
|
|
|
|
<label class="btn btn-outline-primary" for="inputFile">选择文件</label>
|
|
|
|
<span id="file-chosen" style="font-size: 12px; margin-left: 10px;">未选择文件</span>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<button type="button" class="btn btn-secondary" onclick="#!" id="downloadExcelBtn">下载填报模板</button>
|
|
|
|
<button type="button" class="btn btn-primary" id="uploadBtn">上传Excel</button>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<div id="excelPreviewModal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="excelPreviewModalTitle" aria-hidden="true">
|
|
|
|
<div class="modal-dialog modal-dialog-centered modal-xl" role="document">
|
|
|
|
<div class="modal-content">
|
|
|
|
<form id="preview-form" method="post">
|
|
|
|
{% csrf_token %}
|
|
|
|
<div class="modal-header">
|
|
|
|
<h5 class="modal-title" id="excelPreviewModalTitle">上传文件预览</h5>
|
|
|
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
|
|
|
</div>
|
|
|
|
<div class="modal-body">
|
|
|
|
<div style="overflow-x: auto;">
|
|
|
|
<table id="form-input-table" class="table table-striped table-bordered nowrap">
|
|
|
|
<thead></thead>
|
|
|
|
<tbody></tbody>
|
|
|
|
</table>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="modal-footer">
|
|
|
|
<div id="pagination">
|
|
|
|
<span id="totalData" class="mx-2"></span>
|
|
|
|
<span id="pageInfo" class="mx-2"></span>
|
|
|
|
<button id="prevPage" class="btn btn-secondary" type="button">上一页</button>
|
|
|
|
<button id="nextPage" class="btn btn-secondary" type="button">下一页</button>
|
|
|
|
</div>
|
|
|
|
<div id="actions">
|
|
|
|
<button id="saveButton" type="button" class="btn btn-primary">保存</button>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<script>
|
2024-06-06 22:44:07 +08:00
|
|
|
var excel_upload_config = {{ excel_upload_config|safe }};
|
|
|
|
var model_config = "{{ model_config }}";
|
2024-06-06 14:18:42 +08:00
|
|
|
|
|
|
|
$(document).ready(function () {
|
|
|
|
|
|
|
|
// 获取 CSRF 令牌
|
|
|
|
function getCookie(name) {
|
|
|
|
let cookieValue = null;
|
|
|
|
if (document.cookie && document.cookie !== '') {
|
|
|
|
const cookies = document.cookie.split(';');
|
|
|
|
for (let i = 0; i < cookies.length; i++) {
|
|
|
|
const cookie = cookies[i].trim();
|
|
|
|
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
|
|
|
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cookieValue;
|
|
|
|
}
|
|
|
|
const csrftoken = getCookie('csrftoken');
|
|
|
|
|
|
|
|
// 每页显示的行数
|
|
|
|
var rowsPerPage = 10;
|
|
|
|
// 当前页码
|
|
|
|
var currentPage = 1;
|
|
|
|
// 用于存储所有表格数据的全局变量
|
|
|
|
var tableData = [];
|
|
|
|
// 用于存储完整数据的全局变量
|
|
|
|
var fullTableData = [];
|
|
|
|
|
|
|
|
// 处理上传按钮的点击事件
|
|
|
|
$('#downloadExcelBtn').on('click', function() {
|
|
|
|
window.location.href = excel_upload_config.template_url;
|
|
|
|
});
|
|
|
|
|
|
|
|
// 当上传模态框显示时,清空文件输入框和文件名显示
|
|
|
|
$('#uploadModal').on('show.bs.modal', function () {
|
|
|
|
$('#inputFile').val('');
|
|
|
|
$('#file-chosen').text('未选择文件');
|
|
|
|
});
|
|
|
|
|
|
|
|
// 当选择文件变化时,更新文件名显示
|
|
|
|
$('#inputFile').on('change', function () {
|
|
|
|
var fileName = $(this).val().split('\\').pop();
|
|
|
|
$('#file-chosen').text(fileName || '未选择文件');
|
|
|
|
});
|
|
|
|
|
|
|
|
// 处理上传按钮的点击事件
|
|
|
|
$('#uploadBtn').on('click', function () {
|
|
|
|
var formData = new FormData($('#upload-form')[0]);
|
2024-06-06 22:44:07 +08:00
|
|
|
formData.append(('model_config'), model_config);
|
2024-06-06 14:18:42 +08:00
|
|
|
|
|
|
|
// 隐藏上传模态框
|
|
|
|
{#$('#uploadModal').modal('hide');#}
|
|
|
|
// 检查是否有文件被选中
|
|
|
|
if ($('#inputFile').get(0).files.length === 0) {
|
|
|
|
alert("没有文件选中");
|
|
|
|
$('#uploadModal').modal('show');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// 使用Ajax发送文件到后端解析
|
|
|
|
$.ajax({
|
|
|
|
url: '{{ excel_upload_config.parse_url }}',
|
|
|
|
type: 'POST',
|
|
|
|
data: formData,
|
|
|
|
headers: {'X-CSRFToken': csrftoken},
|
|
|
|
contentType: false,
|
|
|
|
processData: false,
|
|
|
|
success: function (response) {
|
|
|
|
// 隐藏上传模态框
|
|
|
|
$('#uploadModal').modal('hide');
|
|
|
|
|
|
|
|
// 获取表头和表体的jQuery对象
|
|
|
|
var tableHead = $('#form-input-table thead');
|
|
|
|
var tableBody = $('#form-input-table tbody');
|
|
|
|
|
|
|
|
// 清空现有的表头和表体内容
|
|
|
|
tableHead.empty();
|
|
|
|
tableBody.empty();
|
|
|
|
|
|
|
|
// 使用从服务器返回的数据来构造表头
|
|
|
|
var headerRow = $('<tr>');
|
|
|
|
headerRow.append($('<th>').text('序号'));
|
2024-06-06 23:46:12 +08:00
|
|
|
$.each(Object.values(response.fields_map), function (index, column) {
|
2024-06-06 14:18:42 +08:00
|
|
|
headerRow.append($('<th>').text(column));
|
|
|
|
});
|
|
|
|
tableHead.append(headerRow);
|
|
|
|
|
|
|
|
// 存储数据以进行分页
|
2024-06-06 23:46:12 +08:00
|
|
|
tableData = response.table_data;
|
2024-06-06 14:18:42 +08:00
|
|
|
fullTableData = tableData.slice();
|
|
|
|
|
|
|
|
// 初始化分页信息
|
|
|
|
currentPage = 1;
|
|
|
|
updateTable();
|
|
|
|
|
|
|
|
// 显示数据预览模态框
|
|
|
|
$('#excelPreviewModal').modal('show');
|
|
|
|
},
|
|
|
|
error: function (xhr, status, error) {
|
|
|
|
// 默认错误消息
|
|
|
|
var errorMsg = "解析Excel文件失败。";
|
|
|
|
|
|
|
|
// 尝试获取服务器返回的错误消息
|
|
|
|
if (xhr.responseJSON && xhr.responseJSON.error) {
|
|
|
|
errorMsg = xhr.responseJSON.error;
|
|
|
|
}
|
|
|
|
|
|
|
|
// 显示错误消息
|
|
|
|
alert(errorMsg);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
// 更新表格内容以显示当前页的数据
|
|
|
|
function updateTable() {
|
|
|
|
var tableBody = $('#form-input-table tbody');
|
|
|
|
tableBody.empty();
|
|
|
|
|
|
|
|
var fields_preview_config = {{ excel_upload_config.fields_preview_config|safe }};
|
|
|
|
var startIndex = (currentPage - 1) * rowsPerPage;
|
|
|
|
var endIndex = startIndex + rowsPerPage;
|
|
|
|
var pageData = tableData.slice(startIndex, endIndex);
|
|
|
|
|
|
|
|
$.each(pageData, function (index, rowData) {
|
|
|
|
var row = $('<tr>');
|
|
|
|
row.append($('<td>').text(startIndex + index + 1));
|
|
|
|
|
|
|
|
var cellIndex = 0;
|
|
|
|
|
|
|
|
$.each(fields_preview_config, function (key, field) {
|
|
|
|
var cellElement;
|
|
|
|
var cellValue = rowData[key] || '';
|
|
|
|
|
|
|
|
if (field.type === 'text') {
|
|
|
|
cellElement = $('<input>').attr({
|
|
|
|
style: "width: " + field.width,
|
|
|
|
type: 'text',
|
|
|
|
class: 'form-control',
|
|
|
|
id: key,
|
|
|
|
name: key,
|
|
|
|
value: cellValue,
|
|
|
|
}).on('change', function() {
|
|
|
|
rowData[key] = $(this).val();
|
|
|
|
fullTableData[startIndex + index][key] = $(this).val();
|
|
|
|
});
|
|
|
|
} else if (field.type === 'select') {
|
|
|
|
cellElement = $('<select>').attr({
|
|
|
|
style: "width: " + field.width,
|
|
|
|
class: 'form-control',
|
|
|
|
id: key,
|
|
|
|
name: key,
|
|
|
|
}).on('change', function() {
|
|
|
|
rowData[key] = $(this).val();
|
|
|
|
fullTableData[startIndex + index][key] = $(this).val();
|
|
|
|
});
|
|
|
|
$.each(field.options, function (optionIndex, optionValue) {
|
|
|
|
var optionElement = $('<option>').val(optionValue).text(optionValue);
|
|
|
|
if (String(cellValue) === String(optionValue)) {
|
|
|
|
optionElement.attr('selected', 'selected');
|
|
|
|
}
|
|
|
|
cellElement.append(optionElement);
|
|
|
|
});
|
|
|
|
} else if (field.type === 'date') {
|
|
|
|
cellElement = $('<input>').attr({
|
|
|
|
style: "width: " + field.width,
|
|
|
|
type: 'date',
|
|
|
|
class: 'form-control',
|
|
|
|
id: key,
|
|
|
|
name: key,
|
|
|
|
value: cellValue,
|
|
|
|
}).on('change', function() {
|
|
|
|
rowData[key] = $(this).val();
|
|
|
|
fullTableData[startIndex + index][key] = $(this).val();
|
|
|
|
});
|
|
|
|
} else if (field.type === 'month') {
|
|
|
|
cellElement = $('<input>').attr({
|
|
|
|
style: "width: " + field.width,
|
|
|
|
type: 'month',
|
|
|
|
class: 'form-control',
|
|
|
|
id: key,
|
|
|
|
name: key,
|
|
|
|
value: cellValue,
|
|
|
|
}).on('change', function() {
|
|
|
|
rowData[key] = $(this).val();
|
|
|
|
fullTableData[startIndex + index][key] = $(this).val();
|
|
|
|
});
|
|
|
|
} else if (field.type === 'number') {
|
|
|
|
cellElement = $('<input>').attr({
|
|
|
|
style: "width: " + field.width,
|
|
|
|
type: 'number',
|
|
|
|
class: 'form-control',
|
|
|
|
id: key,
|
|
|
|
name: key,
|
|
|
|
value: cellValue,
|
|
|
|
}).on('change', function() {
|
|
|
|
rowData[key] = $(this).val();
|
|
|
|
fullTableData[startIndex + index][key] = $(this).val();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
var td = $('<td>').append(cellElement);
|
|
|
|
row.append(td);
|
|
|
|
|
|
|
|
cellIndex++;
|
|
|
|
});
|
|
|
|
|
|
|
|
tableBody.append(row);
|
|
|
|
});
|
|
|
|
|
|
|
|
$('#totalData').text('数据总数: ' + tableData.length);
|
|
|
|
$('#pageInfo').text('第 ' + currentPage + ' 页, 共 ' + Math.ceil(tableData.length / rowsPerPage) + ' 页');
|
|
|
|
}
|
|
|
|
|
|
|
|
// 处理上一页按钮的点击事件
|
|
|
|
$('#prevPage').on('click', function () {
|
|
|
|
if (currentPage > 1) {
|
|
|
|
currentPage--;
|
|
|
|
updateTable();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// 处理下一页按钮的点击事件
|
|
|
|
$('#nextPage').on('click', function () {
|
|
|
|
if (currentPage < Math.ceil(tableData.length / rowsPerPage)) {
|
|
|
|
currentPage++;
|
|
|
|
updateTable();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// 处理保存按钮的点击事件
|
|
|
|
$('#saveButton').on('click', function() {
|
2024-06-06 23:46:12 +08:00
|
|
|
var modelConfig = "{{ model_config }}";
|
2024-06-06 14:18:42 +08:00
|
|
|
var saveDataUrl = excel_upload_config.save_url;
|
|
|
|
|
|
|
|
// 构建发送到后端的数据对象
|
|
|
|
var postData = {
|
2024-06-06 23:46:12 +08:00
|
|
|
model_config: modelConfig,
|
2024-06-06 14:18:42 +08:00
|
|
|
table_data: fullTableData
|
|
|
|
};
|
|
|
|
|
|
|
|
// 发送AJAX请求到后端保存数据
|
|
|
|
$.ajax({
|
|
|
|
url: saveDataUrl,
|
|
|
|
method: 'POST',
|
|
|
|
contentType: 'application/json',
|
|
|
|
data: JSON.stringify(postData),
|
|
|
|
headers: {'X-CSRFToken': csrftoken},
|
|
|
|
success: function(response) {
|
|
|
|
$('#excelPreviewModal').modal('hide');
|
2024-06-06 23:46:12 +08:00
|
|
|
showAlert('success', '数据保存成功');
|
2024-06-06 14:18:42 +08:00
|
|
|
location.reload();
|
|
|
|
},
|
|
|
|
error: function(xhr, status, error) {
|
2024-06-06 23:46:12 +08:00
|
|
|
showAlert('danger', '数据保存失败');
|
2024-06-06 14:18:42 +08:00
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|