912 lines
40 KiB
HTML
912 lines
40 KiB
HTML
<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"></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"></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> |