Files
swiftadmin/app/admin/view/pdm_partlist/index.html
2025-05-03 08:52:41 +08:00

912 lines
40 KiB
HTML
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.
<include file="/public/header" />
<!-- // 重定位Style -->
<style>
.layui-card-header.layadmin-card-header-auto {
border-bottom: 0px;
padding-bottom: 0px;
}
.layui-card-header h5 {
font-size: 16px;
}
#layui-dic_group {
padding-bottom: 25px;
}
#layui-dic_group .layui-table-view .layui-table {
width: 100%;
}
#layui-dic_group table thead tr:first-child i {
display: none;
}
@media screen and (max-width: 1200px) {
.layui-table-tool-temp .layui-btn {
height: 30px;
line-height: 30px;
padding: 0 10px;
font-size: 12px;
}
.layui-table-tool-temp .layui-btn:nth-last-child(3) {
display: none;
}
}
</style>
<div class="layui-col-md4">
<div class="layui-fluid">
<div class="layui-card">
<div class="layui-card-header layadmin-card-header-auto" style="padding-bottom: 5px">
<div class="layui-inline layui-hide" id="toolbar">
<!-- // 打开添加页面 -->
<button class="layui-btn icon-btn" lay-open="add" data-title="{:__('添加BOM')}" data-area="600px"
data-url="#editforms_bom" callback="edit">
<i class="layui-icon layui-icon-add-1"></i>{:__('添加')}
</button>
<!-- // 修改页面 -->
<button class="layui-btn icon-btn" lay-open="edit" data-title="{:__('修改BOM')}" data-area="600px"
data-url="#editforms_bom" callback="edit">
<i class="layui-icon layui-icon-edit"></i>{:__('修改')}
</button>
<!-- // 删除所有 -->
<button class="layui-btn icon-btn layui-btn-danger" lay-batch="" data-table="lay-tableGroup"
data-url="{:url('/PdmPartlist/del')}">
<i class="layui-icon layui-icon-delete"></i>{:__('删除')}
</button>
</div>
</div>
<div class="layui-card-body" id="layui-dic_group">
<!-- // 创建字典组实例 -->
<table id="lay-tableGroup" lay-filter="lay-tableGroup"></table>
</div>
</div>
</div>
</div>
<div class="layui-col-md8" >
<!-- // 展示数据 -->
<div class="layui-fluid">
<div class="layui-card">
<!-- // 默认操作按钮 -->
<div class="layui-card-header layadmin-card-header-auto ">
<div class="layui-form">
<!-- // 自定义搜索参数 -->
<div id="laytable-search" class="layui-form-item">
<div class="layui-inline">
<div class="layui-form-label">{:__('Partnumber')}</div>
<div class="layui-input-inline ">
<input name="partnumber" class="layui-input" type="text" placeholder="{:__('Partnumber')}" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">{:__('Purchasecode')}</label>
<div class="layui-input-inline ">
<input name="purchasecode" class="layui-input" type="text" placeholder="{:__('Purchasecode')}" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">{:__('Value')}</label>
<div class="layui-input-inline ">
<input name="value" class="layui-input" type="text" placeholder="{:__('Value')}" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">{:__('MPN')}</label>
<div class="layui-input-inline ">
<input name="mpn" class="layui-input" type="text" placeholder="{:__('MPN')}" />
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">{:__('Reference')}</label>
<div class="layui-input-inline ">
<input name="reference" class="layui-input" type="text" placeholder="{:__('Reference')}" />
</div>
</div>
</div>
<div class="layui-form-item">
<!-- <div class="layui-inline">
<div class="layui-input-inline">
<select name="status">
<option value="">{:__('按状态查询')}</option>
<option value="2" >{:__('正常')}</option>
<option value="1" >{:__('关闭')}</option>
</select>
</div>
</div> -->
<div class="layui-inline">
<div class="layui-input-inline ">
<input name="keyword" class="layui-input" type="text" placeholder="{:__('关键字搜索')}" />
</div>
</div>
<div class="layui-inline">
<!-- // 默认搜索 -->
<button class="layui-btn icon-btn" lay-filter="formSearch" lay-submit><i
class="layui-icon layui-icon-search"></i>{:__('搜索')}</button>
<!-- // 打开添加页面 -->
<button class="layui-btn icon-btn" lay-open="" data-title="{:__('添加BOM项')}"
data-area="600px" data-url="#editforms">
<i class="layui-icon layui-icon-add-1"></i>{:__('添加')}
</button>
<!-- // 删除所有 -->
<button class="layui-btn icon-btn layui-btn-danger" lay-batch data-table="lay-tableList"
data-url="{:url('/PdmPartlist/del')}">
<i class="layui-icon layui-icon-delete"></i>{:__('删除')}
</button>
<!-- 自定义导出按钮 -->
<button id="exportExcel" class="layui-btn layui-btn-primary">
<i class="layui-icon layui-icon-export"></i> {:__('导出 Excel')}
</button>
<button type="button" class="layui-btn" id="uploadExcelBtn">
<i class="layui-icon">&#xe67c;</i> {:__('导入Excel')}
</button>
<input type="file" id="excelFileInput" accept=".xls,.xlsx" style="display: none;" />
<button id="syncButton" class="layui-btn" style="display: none;">
<i class="layui-icon">&#xe67c;</i>{:__('同步到数据库')}
</button>
</div>
</div>
</div>
</div>
<!-- // 创建数据实例 -->
<table id="lay-tableList" lay-filter="lay-tableList"></table>
<table class="layui-hide" id="dataTable" lay-filter="dataTableFilter"></table>
</div>
</div>
</div>
<script type="text/html" id="toolbarDemo">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-sm" lay-event="export" lay-filter="dataTableFilter" >导出数据</button>
</div>
</script>
<!-- // 添加编辑数据 -->
<section id="editforms_bom" class="layui-hide">
<div class="layui-fluid layui-bg-white">
<form class="layui-form layui-form-fixed" lay-filter="editforms_bom">
<input type="text" name="id" hidden="">
<input type="text" class="pid" name="pid" value="{$pid}" hidden="">
<!-- <div class="layui-form-item">
<label class="layui-form-label">{:__('Item')}</label>
<div class="layui-input-block">
<input name="item" placeholder="{:__('请输入item')}" type="text" class="layui-input" lay-verify="" />
</div>
</div> -->
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('BOM编码')}</label>
<div class="layui-input-block">
<input name="partnumber" placeholder="{:__('请输入BOM编码')}" type="text" class="layui-input" lay-verify="required" />
</div>
</div>
<!-- <div class="layui-form-item">
<label class="layui-form-label">{:__('位号')}</label>
<div class="layui-input-block">
<input name="reference" placeholder="{:__('请输入位号')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('用量')}</label>
<div class="layui-input-block">
<input name="quantity" placeholder="{:__('请输入用量')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('单位')}</label>
<div class="layui-input-block">
<input name="unit" placeholder="{:__('请输入单位')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('排序号')}</label>
<div class="layui-input-block">
<input name="sort" placeholder="{:__('默认自动生成')}" type="number" class="layui-input" />
</div>
</div> -->
<div class="layui-form-item">
<label class="layui-form-label">{:__('BOM备注')}</label>
<div class="layui-input-block">
<textarea name="content" id="content" style="min-height: 80px;" placeholder="{:__('请输入BOM备注')}"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-footer layui-form-item layui-center">
<button class="layui-btn layui-btn-primary" type="button"
sa-event="closePageDialog">{:__('取消')}</button>
<button class="layui-btn" lay-add="{:url('/PdmPartlist/add')}" lay-edit="{:url('/PdmPartlist/edit')}"
lay-filter="submitPage" lay-submit>{:__('提交')}</button>
</div>
</form>
</div>
</section>
<!-- // 添加编辑数据 -->
<section id="editforms" class="layui-hide">
<div class="layui-fluid layui-bg-white">
<form class="layui-form layui-form-fixed" lay-filter="editforms">
<input type="text" name="id" hidden="">
<input type="text" class="pid" name="pid" value="{$pid}" hidden="">
<div class="layui-form-item">
<label class="layui-form-label">{:__('Item')}</label>
<div class="layui-input-block">
<input name="item" placeholder="{:__('请输入item')}" type="text" class="layui-input"
lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span style="color: red; ">* </span>{:__('BOM编码')}</label>
<div class="layui-input-block">
<input name="partnumber" placeholder="{:__('请输入BOM编码')}" type="text" class="layui-input"
lay-verify="required" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('位号')}</label>
<div class="layui-input-block">
<input name="reference" placeholder="{:__('请输入位号')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('用量')}</label>
<div class="layui-input-block">
<input name="quantity" placeholder="{:__('请输入用量')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('单位')}</label>
<div class="layui-input-block">
<input name="unit" placeholder="{:__('请输入单位')}" class="layui-input" lay-verify="" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('排序号')}</label>
<div class="layui-input-block">
<input name="sort" placeholder="{:__('默认自动生成')}" type="number" class="layui-input" />
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">{:__('BOM备注')}</label>
<div class="layui-input-block">
<textarea name="content" id="content" style="min-height: 80px;" placeholder="{:__('请输入BOM备注')}"
class="layui-textarea"></textarea>
</div>
</div>
<div class="layui-footer layui-form-item layui-center">
<button class="layui-btn layui-btn-primary" type="button"
sa-event="closePageDialog">{:__('取消')}</button>
<button class="layui-btn" lay-add="{:url('/PdmPartlist/add')}" lay-edit="{:url('/PdmPartlist/edit')}"
lay-filter="submitPage" lay-submit>{:__('提交')}</button>
</div>
</form>
</div>
</section>
<!-- // 列表编辑框 -->
<script type="text/html" id="tableBar">
<a class="layui-table-text" data-title="{:__('编辑BOM项')}" data-url="#editforms" data-area="600px" lay-event="edit" >{:__('编辑')}</a>
<div class="layui-divider layui-divider-vertical"></div>
<a class="layui-table-text" data-url="{:url('/PdmPartlist/del')}?id={{d.id}}" lay-event="del" >{:__('删除')}</a>
</script>
<script type="text/html" id="tableButton"></script>
<!-- 在页面底部(通常在 </body> 标签之前)引入 SheetJS 库 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>
<include file="/public/footer" />
<script>
layui.use(['admin', 'jquery', 'table', 'form'], function () {
let admin = layui.admin;
let $ = layui.jquery;
let table = layui.table;
let form = layui.form;
// let count = {$count|default=300};
let bomname ="";
let bomid = "";
// 定义表格URL
let tableURL = "{:url('/PdmPartlist/index')}";
// 字典类表格
let isClass = table.render({
elem: "#lay-tableGroup"
, url: tableURL + "?pid=0"
, toolbar: '#toolbar'
, defaultToolbar: []
, page: true
, limit: 18
, cols: [[
{ type: 'radio', align: 'left' },
{ field: 'id', title: '{:__("ID")}' },
{ field: 'partnumber', align: 'center', title: '{:__("BOM编码")}' },
// { field: 'reference', align: 'center', title: '{:__("位号")}' },
{ field: 'content', align: 'center', title: '{:__("备注")}' },
]]
,done: function(res, curr, count) {
if (res.data.length > 0) {
// 获取第一行数据
// let firstRow = res.data[0];
let data = table.checkStatus('lay-tableGroup').data;
let ids = [];
// console.log('data:'+ JSON.stringify(data));
// 处理选中行的数据
handleSelectedRow(data);
for (const key in data) {
ids.push(data[key].id);
bomid = data[key].id;
bomname = data[key].partnumber;
}
let url = tableURL + '?pid=' + ids.join(',');
table.reloadData('lay-tableList', {
url: url
});
// // 重新加载关联表格数据
// let ids = res.data.map(item => item.id);
// let url = tableURL + '?pid=' + ids.join(',');
// table.reload('lay-tableList', {
// url: url,
// where: { pid: ids.join(',') } // 传递必要的参数
// });
// 模拟点击第一行的 radio
setTimeout(function(){
let firstRadio = $('tr.layui-table-body tbody tr').first().find('.layui-form-radio');
firstRadio.addClass('layui-form-radioed');
firstRadio.find('input[type="radio"]').prop('checked', true).trigger('change');
}, 100); // 延迟以确保 DOM 渲染完成
console.log('bomid:'+bomid+',bomname:'+bomname);
}
}
})
// 基础表格
let isTable = table.render({
elem: "#lay-tableList"
, url: tableURL
,toolbar: '#tableButton'
// ,defaultToolbar: ['filter', 'exports', 'print', 'search']
,defaultToolbar: ['filter', 'print', 'search']
, cellMinWidth: 80
, page: true
//, page: false
, limit: 18
, cols: [[
{type: 'checkbox'},
// {field: 'id', align: 'center',sort: true,width: 80, title: 'ID'},
{ field: 'item', align: 'center', width: 40,title: '{:__("Item")}' },
{ field: 'partnumber', align: 'left', width: 180,title: '{:__("Partnumber")}' },
{ field: 'parttype', align: 'left', width: 100,title: '{:__("Parttype")}' },
{ field: 'purchasecode', align: 'left', width: 160,title: '{:__("Purchasecode")}' },
{ field: 'value', align: 'left', width: 100,title: '{:__("Value")}' },
{ field: 'description', align: 'left', width: 200,title: '{:__("Description")}' },
{ field: 'mpn', align: 'left', width: 150,title: '{:__("MPN")}' },
{ field: 'mfg', align: 'left', width: 150,title: '{:__("MFG")}' },
{ field: 'footprint', align: 'left', width: 150,title: '{:__("Footprint")}' },
{ field: 'manufacture', align: 'left', width: 120,title: '{:__("Manufacture")}' },
{ field: 'reference', align: 'left',width: 250, title: '{:__("位号")}' },
// {field: 'sort', align: 'center', width: 135, title: '{:__("排序号")}'},
{ field: 'quantity', align: 'center', width: 100, title: '{:__("Quantity")}' },
{ field: 'unit', align: 'center', width: 80, title: '{:__("Unit")}' },
{ field: 'content', align: 'left', title: '{:__("Remark")}' },
// {field: 'create_time', align: 'center', width: 180,title: '{:__("创建时间")}'},
{ align: 'center', toolbar: '#tableBar', width: 135, fixed:'right', title: '{:__("操作")}' },
]]
})
// 定义处理选中行数据的函数
function handleSelectedRow(row) {
$('#editforms').find('.pid').attr('value', row.id);
$('#editforms_bom').find('.pid').attr('value', row.id);
}
// 表格选择行事件
table.on('radio(lay-tableGroup)', function (obj) {
let data = table.checkStatus('lay-tableGroup').data;
let ids = [];
if (data.length) {
for (const key in data) {
ids.push(data[key].id);
}
let url = tableURL + '?pid=' + ids.join(',');
table.reloadData('lay-tableList', {
url: url
});
// 获取最后点击
if (obj.checked === true) {
handleSelectedRow(obj.data);
bomname = obj.data.partnumber;
bomid = obj.data.id;
console.log('bomid:'+bomid+',bomname:'+bomname);
}
}
});
// 自定义导出按钮点击事件
document.getElementById('exportExcel').addEventListener('click', function () {
// 确认用户希望导出全部数据
layer.confirm('确定导出所有数据到 Excel 吗?', { icon: 3, title: '导出确认' }, function(index){
layer.close(index);
exportAllDataToExcel();
});
});
function isValidFilename(name) {
// 正则匹配非法字符
const invalidChars = /[\\/:*?"<>|]/;
return !invalidChars.test(name);
}
// 自定义导出功能
function exportAllDataToExcel(){
// 获取当前的过滤条件例如pid
let selectedData = table.checkStatus('lay-tableGroup').data;
let pid = selectedData.length ? selectedData[0].id : 0;
// 异步获取所有数据(不分页)
layer.msg('异步获取所有数据不分页超时限制30s');
// 显示加载层
const loadingIndex = layer.load(1, { shade: [0.3, '#fff'] });
$.ajax({
url: tableURL + "?pid=" + pid + "&export=1", // 后端需要根据 'export=1' 返回所有数据
type: 'POST',
dataType: 'json',
timeout: 30000,
success: function(res){
if(res.code === 200){
// layer.msg('获取数据总数: ' + res.data.length);
let data = res.data;
if(data.length === 0){
layer.msg('没有数据可导出,BOM ID:'+bomid+'BOMname:'+bomname);
// 解析完成后关闭加载层
layer.close(loadingIndex);
return;
}
// 转换数据为 SheetJS 格式
// layer.msg('转换数据为 SheetJS 格式');
let worksheetData = data.map(row => {
return {
'Item': row.item,
'Partnumber': row.partnumber,
'Parttype': row.parttype,
'Purchasecode': row.purchasecode,
'Value': row.value,
'Description': row.description,
'MPN': row.mpn,
'MFG': row.mfg,
'Footprint': row.footprint,
'Manufacture': row.manufacture,
'Reference': row.reference,
'Quantity': row.quantity,
'Unit': row.unit,
'Remark': row.content,
// 添加其他需要导出的字段
};
});
// 创建工作簿和工作表
// layer.msg('创建工作簿和工作表');
let worksheet = XLSX.utils.json_to_sheet(worksheetData);
let workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "BOM数据");
// 解析完成后关闭加载层
layer.close(loadingIndex);
// 默认文件名
const defaultFilename = bomname+" BOM_Export_" + new Date().toISOString().slice(0,10);
// 弹出提示框让用户输入文件名
layer.prompt({
title: '请输入导出文件名',
formType: 0, // 0 = 输入框, 1 = 密码框, 2 = 多行文本
value: defaultFilename,
area: ['800px', '200px'] // 设置提示框的宽度和高度
// area: ['50%', '30%'] // 宽度为50%高度为30%
}, function(value, index, elem){
// 确保文件名不为空
if(!value.trim()){
layer.msg('文件名不能为空');
return;
}
if(!isValidFilename(value.trim())){
layer.msg('文件名包含非法字符');
return;
}
// 确定文件名,添加 .xlsx 后缀
const filename = value.trim() + ".xlsx";
layer.msg('生成 Excel 文件并下载,文件名:' + filename);
// 生成并下载 Excel 文件
XLSX.writeFile(workbook, filename);
layer.close(index); // 关闭提示框
});
} else {
layer.msg('获取数据失败,状态码:' + res.code);
// 解析完成后关闭加载层
layer.close(loadingIndex);
}
},
error: function(xhr, status, error){
layer.msg('数据获取失败,请稍后重试: ' + error);
// 解析完成后关闭加载层
layer.close(loadingIndex);
}
});
}
// 全局回调函数
admin.callback.edit = function (clickthis, colletction, config) {
let status = true;
let action = clickthis.attr('lay-open');
let data = table.checkStatus('lay-tableGroup').data;
if (action === 'edit') {
status = false;
form.val('editforms', data[0]);
form.val('editforms_bom', data[0]);
}
form.on("submit(submitPage)", function (post) {
let pageThat = $(this),
_pageUrl = !status ? pageThat.attr('lay-edit') : pageThat.attr('lay-add');
post.field.pid = 0;
// 开始POST提交数据
$.post(_pageUrl,
post.field, function (res) {
if (res.code === 200) {
table.reloadData('lay-tableGroup');
table.reloadData('lay-tableList');
// 关闭当前窗口
layer.msg(res.msg);
layer.close(colletction.index);
pageThat.attr("disabled", true);
}
else {
layui.show.error(res.msg);
}
}, 'json');
return false;
})
}
let jsonData = [];
// 定义字段映射对象
const fieldMapping = {
'Item': 'item',
'Partnumber': 'partnumber',
'Parttype': 'parttype',
'Purchasecode': 'purchasecode',
'Value': 'value',
'Description': 'description',
'MPN': 'mpn',
'MFG': 'mfg',
'Footprint': 'footprint',
'Manufacture': 'manufacture',
'Reference': 'reference',
'Quantity': 'quantity',
'Unit': 'unit',
'Remark': 'content'
// 添加其他需要映射的字段
};
// 逆向转换函数
function reverseTransform(data, mapping) {
return data.map(row => {
const originalRow = {};
for (const [exportKey, originalKey] of Object.entries(mapping)) {
originalRow[originalKey] = row[exportKey];
}
return originalRow;
});
}
//当用户点击上传按钮时,触发隐藏的文件输入:
document.getElementById('uploadExcelBtn').addEventListener('click', function(){
document.getElementById('excelFileInput').click();
});
document.getElementById('excelFileInput').addEventListener('change', function(event){
// 显示加载层
const loadingIndex = layer.load(1, { shade: [0.3, '#fff'] });
const file = event.target.files[0];
if(!file){
layer.close(loadingIndex);
return;
}
const reader = new FileReader();
reader.onload = function(e){
try {
const data = e.target.result;
let workbook;
try {
workbook = XLSX.read(data, { type: 'binary' });
} catch (error) {
layer.msg('读取 Excel 文件失败,请检查文件格式。');
return;
}
// 假设导入第一个工作表
const firstSheetName = workbook.SheetNames[0];
const worksheet = workbook.Sheets[firstSheetName];
// 将工作表转换为 JSON
jsonData = XLSX.utils.sheet_to_json(worksheet, { defval: '' });
if(jsonData.length === 0){
layer.msg('Excel 文件中没有数据。');
layer.close(loadingIndex);
return;
}
// 在渲染之前进行验证
if(!validateData(jsonData)){
layer.close(loadingIndex);
return;
}
layer.msg('Excel 文件数据读取成功,渲染数据表。');
// 渲染数据到表格
renderDataTable(jsonData);
// 显示同步按钮
document.getElementById('syncButton').style.display = 'inline-block';
} catch (error) {
layer.msg('读取 Excel 文件失败,请检查文件格式。');
} finally {
// 解析完成后关闭加载层
layer.close(loadingIndex);
}
};
reader.onerror = function(){
layer.msg('文件读取出现错误。');
layer.close(loadingIndex);
};
// 读取文件为二进制字符串
reader.readAsBinaryString(file);
});
// 同步数据到数据库
document.getElementById('syncButton').addEventListener('click', function(){
if(jsonData.length === 0){
layer.msg('没有可同步的数据。');
return;
}
// 显示加载层
const loadingIndex = layer.load(1, { shade: [0.3, '#fff'] });
let syncurl = "{:url('/PdmPartlist/sync')}?bomid="+bomid;
// fetch(syncurl
// , {
// method: 'POST'
// ,headers: { 'Content-Type': 'application/json' }
// ,body: JSON.stringify({ data: jsonData })
// })
// .then(response => response.json())
// .then(data => {
// layer.msg('dddd'.data);
// if(data.success){
// layer.msg('数据同步成功!');
// } else {
// layer.msg('同步失败: ' + data.message);
// }
// })
// .catch(error => {
// console.error('错误:', error);
// layer.msg('同步过程中发生错误');
// })
// .finally(() => {
// layer.close(loadingIndex);
// });
// 应用逆向转换
const originalData = reverseTransform(jsonData, fieldMapping);
// console.log(originalData);
console.log(JSON.stringify({ data: originalData }));
syncData(syncurl, originalData);
});
function syncData(url, jsonData, retries = 3, retryDelay = 1000) {
let attempt = 0;
let loadingIndex;
attempt++;
// 显示加载指示器
loadingIndex = layer.load(1, { shade: [0.1, '#fff'] });
$.ajax({
url: url,
// method: 'POST', // 使用 method 替代 type
type: 'POST',
dataType: 'json', // 预期服务器返回 JSON
contentType: 'application/json', // 发送的数据为 JSON
data: JSON.stringify({ data: jsonData }), // 序列化数据
timeout: 30000, // 设置超时时间30秒
})
.done(function(res) {
if (res.code === 200) {
layer.msg('更新数据成功: ' + res.msg);
} else {
layer.msg('更新失败: ' + res.msg);
}
})
.fail(function(jqXHR, textStatus, errorThrown) {
if (textStatus === 'timeout') {
if (attempt < retries) {
layer.msg(`请求超时,正在进行第 ${attempt} 次重试...`);
setTimeout(makeRequest, retryDelay);
} else {
layer.msg('请求超时,请稍后重试。');
}
} else if (jqXHR.status === 0) {
layer.msg('网络错误,请检查您的网络连接。');
} else if (jqXHR.status >= 500) {
layer.msg('服务器错误,请稍后再试。');
} else if (jqXHR.status === 404) {
layer.msg('请求的资源未找到 (404)。');
} else if (jqXHR.status === 401) {
layer.msg('未授权,请登录。');
// 可选:重定向到登录页
window.location.href = '/login';
} else {
layer.msg('数据获取失败,请稍后重试: ' + errorThrown);
}
// 可选:在控制台打印错误详情以便调试
console.error('AJAX 错误:', jqXHR.responseText);
})
.always(function() {
// 关闭加载指示器
layer.close(loadingIndex);
});
}
function renderDataTable(data){
// 提取表头(即对象的键)
const tableHeaders = Object.keys(data[0]).map(key => ({
field: key,
title: key,
sort: true, // 可根据需要设置是否可排序
// 可以根据需要添加其他属性,如宽度、对齐方式等
}));
// 渲染 LayUI 表格
// table.reloadData('lay-tableList', {
// data: data
// });
// 表格基本配置
table.render({
elem: '#dataTable',
data: data,
// cols: [tableHeaders],
cols: [tableHeaders.map(header => ({
field: header.field,
title: header.title,
width: 150, // 设置指定宽度如150px
// cellMinWidth:150,
sort: header.sort
}))],
toolbar: '#toolbarDemo', // 绑定工具栏模板
page: true, // 是否显示分页
limit: 20, // 默认每页显示数量
height: 'full-200', // 设置表格高度,根据需要调整
id: 'dataTableReload'
});
// 监听工具栏
table.on('toolbar(dataTableFilter)', function(obj){
if(obj.event === 'export'){
layer.msg('Excel dataTableFilter export');
exportTableData(data); // 定义导出函数
layer.msg('Excel dataTableFilter export end');
}
});
}
function validateData(data){
// 示例:确保每行都有 "Item" 和 "Quantity" 字段
for(let i = 0; i < data.length; i++){
const row = data[i];
if(!row.hasOwnProperty('Item') || !row.hasOwnProperty('Quantity')){
layer.msg(`${i+1} 行缺少必填字段。`);
return false;
}
// 可以添加更多的验证逻辑,如数据类型、值范围等
}
layer.msg(`数据校验成功。`);
return true;
}
// (可选)导出表格数据为 Excel
function exportTableData(data){
layer.msg('Excel dataTableFilter --');
// 使用 SheetJS 将数据转换为工作表
const worksheet = XLSX.utils.json_to_sheet(data);
const workbook = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(workbook, worksheet, "导出数据");
// 生成 Excel 文件并下载
const filename = "导出数据_" + new Date().toISOString().slice(0,10) + ".xlsx";
XLSX.writeFile(workbook, filename);
}
});
</script>