|
@@ -1081,4 +1081,305 @@ $(document).ready(() => {
|
|
|
ledgerSpread.refresh();
|
|
|
materialSpread.refresh();
|
|
|
}
|
|
|
+
|
|
|
+ // 导入功能
|
|
|
+ // 上传图片
|
|
|
+ $('#upload-list').click(function () {
|
|
|
+ // if (materialChecklistData.length === 0) {
|
|
|
+ // toastr.error('请选择调差清单再导入。');
|
|
|
+ // return
|
|
|
+ // }
|
|
|
+ $(this).siblings('input').trigger('click');
|
|
|
+ });
|
|
|
+ $('#upload-list-file').change(function () {
|
|
|
+ const file = this.files[0];
|
|
|
+ const ext = file.name.toLowerCase().split('.').splice(-1)[0];
|
|
|
+ const imgStr = /(xls|xlsx|json|XLS|XLSX|JSON)$/;
|
|
|
+ if (!imgStr.test(ext)) {
|
|
|
+ toastr.error('请导入正确格式的json或excel文件。');
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const fileReader = new FileReader();
|
|
|
+ fileReader.onload = async function(ev) {
|
|
|
+ try{
|
|
|
+ const data = ev.target.result;
|
|
|
+ let tree = [];
|
|
|
+ resetExport();
|
|
|
+ $('#okedit').modal('show');
|
|
|
+ setProgress($('#export-progress'), 30);
|
|
|
+ if (/(xls|xlsx|XLS|XLSX)$/.test(ext)) {
|
|
|
+ const workbook = XLSX.read(data, {type: 'binary'}); // 以二进制流方式读取得到整份excel表格对象
|
|
|
+ const jsonData = transExcel(XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]], { defval: null }));
|
|
|
+ if (!(jsonData[0] && jsonData[0].code !== undefined && jsonData[0].code !== null &&
|
|
|
+ jsonData[0].b_code !== undefined && jsonData[0].name !== undefined &&
|
|
|
+ jsonData[0].unit !== undefined && jsonData[0].unit_price !== undefined)) {
|
|
|
+ throw 'excel必须按指定格式内容上传';
|
|
|
+ }
|
|
|
+ tree = _.filter(jsonData, function (item) {
|
|
|
+ return item.code !== null;
|
|
|
+ });
|
|
|
+ for (const [i,t] of tree.entries()) {
|
|
|
+ const jIndex1 = _.findIndex(jsonData, { code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price });
|
|
|
+ if (i + 1 < tree.length) {
|
|
|
+ const jIndex2 = _.findIndex(jsonData, { code: tree[i+1].code, name: tree[i+1].name, unit: tree[i+1].unit, unit_price: tree[i+1].unit_price });
|
|
|
+ t.children = jsonData.slice(jIndex1 + 1, jIndex2);
|
|
|
+ } else {
|
|
|
+ t.children = jsonData.slice(jIndex1 + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const ascii = jschardet.detect(data.substring(0, 10000));
|
|
|
+ iconv.skipDecodeWarning = true
|
|
|
+ tree = JSON.parse(iconv.decode(data, ascii.encoding));// 需要转码,否则前端处理中文会出现乱码
|
|
|
+ }
|
|
|
+ stopProgress($('#export-progress'));
|
|
|
+ $('#bill-detail').show();
|
|
|
+ setProgress($('#bill-progress'), 30);
|
|
|
+ // 导入先生成materialCheckList,再生成materialBillsData,最后生成materialListData
|
|
|
+ console.log(tree, gclGatherData, materialChecklistData, materialBillsData);
|
|
|
+ const pushChecklist = [];
|
|
|
+ const pushBillsData = [];
|
|
|
+ const needPushTree = [];
|
|
|
+ // 分析materialCheckList和tree,找出相同的清单并插入对应不存在的工料
|
|
|
+ for (const t of tree) {
|
|
|
+ const order = _.findIndex(gclGatherData, { b_code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
|
|
|
+ const mlOrder = _.findIndex(materialChecklistData, { b_code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
|
|
|
+ if (mlOrder === -1 && order !== -1 && _.findIndex(pushChecklist, { b_code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null}) === -1) {
|
|
|
+ pushChecklist.push({
|
|
|
+ b_code: gclGatherData[order].b_code,
|
|
|
+ name: gclGatherData[order].name,
|
|
|
+ unit: gclGatherData[order].unit,
|
|
|
+ unit_price: gclGatherData[order].unit_price,
|
|
|
+ quantity: gclGatherData[order].quantity ? gclGatherData[order].quantity : null,
|
|
|
+ total_price: gclGatherData[order].total_price ? gclGatherData[order].total_price : null,
|
|
|
+ had_bills: 0,
|
|
|
+ });
|
|
|
+ } else if (mlOrder === -1 && order === -1) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ needPushTree.push(t);
|
|
|
+ for (const c of t.children) {
|
|
|
+ const mbOrder = _.findIndex(materialBillsData, { code: c.b_code, name: c.name, unit: c.unit });
|
|
|
+ if (c.b_code !== null && mbOrder === -1 && _.findIndex(pushBillsData, { code: c.b_code, name: c.name, unit: c.unit }) === -1) {
|
|
|
+ pushBillsData.push({
|
|
|
+ code: c.b_code,
|
|
|
+ name: c.name,
|
|
|
+ unit: c.unit
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ console.log(pushChecklist, pushBillsData);
|
|
|
+ // stopProgress($('#bill-progress'));
|
|
|
+ // await pushListData(needPushTree);
|
|
|
+ // 先上传需要生成的清单及工料
|
|
|
+ if (pushChecklist.length > 0 || pushBillsData.length > 0) {
|
|
|
+ postData(window.location.pathname + '/save', { type:'exportCB', addChecklist: pushChecklist, addBillsList: pushBillsData }, async function (result) {
|
|
|
+ // materialListData = result;
|
|
|
+ materialChecklistData = result.materialChecklistData;
|
|
|
+ materialBillsData = result.materialBillsData;
|
|
|
+ materialStageBillsData = result.materialStageBillsData;
|
|
|
+ stopProgress($('#bill-progress'));
|
|
|
+ await pushListData(needPushTree);
|
|
|
+ }, function () {
|
|
|
+ stop = true;
|
|
|
+ clearInterval(interval);
|
|
|
+ setTimeout(function () { $('#okedit').modal('hide') }, 1000);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ stopProgress($('#bill-progress'));
|
|
|
+ await pushListData(needPushTree);
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.log(error);
|
|
|
+ toastr.error(error);
|
|
|
+ stop = true;
|
|
|
+ clearInterval(interval);
|
|
|
+ setTimeout(function () { $('#okedit').modal('hide') }, 1000);
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 分析jsondata,得出每个清单间工料数量,生成新的树结构数组
|
|
|
+
|
|
|
+ // let persons = []; // 存储获取到的数据
|
|
|
+ // // 表格的表格范围,可用于判断表头是否数量是否正确
|
|
|
+ // let fromTo = '';
|
|
|
+ // // 遍历每张表读取
|
|
|
+ // for (const sheet in workbook.Sheets) {
|
|
|
+ // if (workbook.Sheets.hasOwnProperty(sheet)) {
|
|
|
+ // fromTo = workbook.Sheets[sheet]['!ref'];
|
|
|
+ // console.log(fromTo);
|
|
|
+ // persons = persons.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
|
|
|
+ // // break; // 如果只取第一张表,就取消注释这行
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // console.log(persons);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 以二进制方式打开文件
|
|
|
+ fileReader.readAsBinaryString(file);
|
|
|
+ $('#upload-list-file').val('');
|
|
|
+ });
|
|
|
+
|
|
|
+ function sleep(millisecond) {
|
|
|
+ return new Promise(resolve => {
|
|
|
+ setTimeout(() => {
|
|
|
+ resolve()
|
|
|
+ }, millisecond)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ let value = 0;
|
|
|
+ let interval;
|
|
|
+ let stop = false;
|
|
|
+ function setProgress(_this, time = 50) {
|
|
|
+ interval = setInterval(function () {
|
|
|
+ if (value < 100) {
|
|
|
+ value = parseInt(value) + 1;
|
|
|
+ _this.css("width", value + "%").text(value + "%");
|
|
|
+ } else if (value === 100) {
|
|
|
+ value = parseInt(value) + 1;
|
|
|
+ value = 30;
|
|
|
+ }
|
|
|
+ }, time);
|
|
|
+ }
|
|
|
+
|
|
|
+ function resetExport() {
|
|
|
+ resetProgress($('#export-progress'));
|
|
|
+ $('#bill-detail').hide();
|
|
|
+ resetProgress($('#bill-progress'));
|
|
|
+ $('#list-detail').hide();
|
|
|
+ resetProgress($('#list-progress'));
|
|
|
+ }
|
|
|
+
|
|
|
+ function resetProgress(_this) {
|
|
|
+ _this.removeClass('bg-success');
|
|
|
+ _this.css("width", "0%").text("0%").attr('aria-valuenow', '0');
|
|
|
+ }
|
|
|
+
|
|
|
+ function stopProgress(_this) {
|
|
|
+ if (interval) {
|
|
|
+ _this.addClass('bg-success');
|
|
|
+ _this.css("width", "100%").text("100%");
|
|
|
+ value = 0;
|
|
|
+ stop = true;
|
|
|
+ clearInterval(interval);
|
|
|
+ interval = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ async function pushListData(tree = []) {
|
|
|
+ console.log(tree);
|
|
|
+ if (tree.length > 0) {
|
|
|
+ for (const [i,t] of tree.entries()) {
|
|
|
+ $('#list-detail').find('b').text(t.code);
|
|
|
+ resetProgress($('#list-progress'));
|
|
|
+ if (!interval) {
|
|
|
+ $('#list-detail').show();
|
|
|
+ setProgress($('#list-progress'), 30);
|
|
|
+ }
|
|
|
+ const mbList = [];
|
|
|
+ for (const mb of t.children) {
|
|
|
+ const mbInfo = _.find(materialBillsData, { code: mb.b_code, name: mb.name, unit: mb.unit });
|
|
|
+ if (mbInfo) {
|
|
|
+ const num = parseFloat(mb.quantity);
|
|
|
+ if (num < 0 || !/^\d+(\.\d{1,6})?$/.test(num)) {
|
|
|
+ // toastr.warning('已保留6位小数');
|
|
|
+ mb.quantity = ZhCalc.round(num, 6);
|
|
|
+ }
|
|
|
+ mbList.push({ id: mbInfo.id, quantity: mb.quantity });
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const gclIndex = _.findIndex(gclGatherData, { b_code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
|
|
|
+ const gcl = gclGatherData[gclIndex].leafXmjs;
|
|
|
+ const ms_id = isStageSelf ? materialStageData[0].id : null;
|
|
|
+ // const index = materialChecklistData.indexOf(select);
|
|
|
+ const datas = [];
|
|
|
+ for (const xmj of gcl) {
|
|
|
+ const notx = findNotJoinLeafXmj(xmj);
|
|
|
+ const data = {
|
|
|
+ xmj_id: xmj.id,
|
|
|
+ gcl_id: xmj.gcl_id,
|
|
|
+ mx_id: xmj.mx_id !== undefined ? xmj.mx_id : '',
|
|
|
+ gather_qty: xmj.gather_qty,
|
|
|
+ is_join: notx === undefined ? 1 : 0,
|
|
|
+ };
|
|
|
+ if (ms_id) data.ms_id = ms_id;
|
|
|
+ datas.push(data);
|
|
|
+ }
|
|
|
+ if (isStageSelf) {
|
|
|
+ // 取所有的gclGatherData才行,然后获取下的值
|
|
|
+ const gclData = gclGatherData[gclIndex];
|
|
|
+ for (const [index, ms] of materialStageData.entries()) {
|
|
|
+ if (ms.id !== ms_id) {
|
|
|
+ const gclOther = _.find(gclGatherListData[index], { b_code: gclData.b_code, name: gclData.name, unit: gclData.unit, unit_price: gclData.unit_price });
|
|
|
+ if (gclOther) {
|
|
|
+ const leafXmjs = gclOther.leafXmjs.filter(item => item.gather_qty !== null && item.gather_qty !== undefined);
|
|
|
+ for (const xmj of leafXmjs) {
|
|
|
+ const notx = findNotJoinLeafXmj(xmj);
|
|
|
+ const data = {
|
|
|
+ xmj_id: xmj.id,
|
|
|
+ gcl_id: xmj.gcl_id,
|
|
|
+ mx_id: xmj.mx_id ? xmj.mx_id : '',
|
|
|
+ gather_qty: xmj.gather_qty,
|
|
|
+ is_join: notx === undefined ? 1 : 0,
|
|
|
+ ms_id: ms.id,
|
|
|
+ };
|
|
|
+ datas.push(data);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 上传到数据库
|
|
|
+ const select = _.find(materialChecklistData, { b_code: t.code, name: t.name, unit: t.unit, unit_price: t.unit_price ? parseFloat(t.unit_price) : null });
|
|
|
+ console.log(select, datas, mbList);
|
|
|
+ if (select) {
|
|
|
+ await postData(window.location.pathname + '/save', {type: 'adds', checklist: { id: select.id, had_bills: 1 }, postData: {xmjs: datas, mbIds: mbList, export: true}}, function (result) {
|
|
|
+ // materialListData = result;
|
|
|
+ select.had_bills = 1;
|
|
|
+ gclList = result;
|
|
|
+ stopProgress($('#list-progress'));
|
|
|
+ if (i+1 === tree.length) {
|
|
|
+ toastr.success('导入成功');
|
|
|
+ setTimeout(function () { $('#okedit').modal('hide') }, 2000);
|
|
|
+ showSjsData();
|
|
|
+ }
|
|
|
+
|
|
|
+ }, function () {
|
|
|
+ stop = true;
|
|
|
+ clearInterval(interval);
|
|
|
+ setTimeout(function () { $('#okedit').modal('hide') }, 1000);
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ stopProgress($('#list-progress'));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ function transExcel(results) {
|
|
|
+ const mapInfo = {
|
|
|
+ '清单编号': 'code',
|
|
|
+ '工料编号': 'b_code',
|
|
|
+ '名称': 'name',
|
|
|
+ '单位': 'unit',
|
|
|
+ '单价': 'unit_price',
|
|
|
+ '单位耗量': 'quantity',
|
|
|
+ };
|
|
|
+ return results.map(zhObj => {
|
|
|
+ const enObj = {}
|
|
|
+ const zhKeys = Object.keys(zhObj);
|
|
|
+
|
|
|
+ zhKeys.forEach(zhKey => {
|
|
|
+ const enKey = mapInfo[zhKey];
|
|
|
+
|
|
|
+ enObj[enKey] = zhObj[zhKey];
|
|
|
+ });
|
|
|
+
|
|
|
+ return enObj
|
|
|
+ })
|
|
|
+ }
|
|
|
});
|