diff --git a/public/static/tpl/import_site_batch.xlsx b/public/static/tpl/import_site_batch.xlsx index eb5d4459..2022c70d 100644 Binary files a/public/static/tpl/import_site_batch.xlsx and b/public/static/tpl/import_site_batch.xlsx differ diff --git a/src/utils/custom.js b/src/utils/custom.js index d651c726..3dad090a 100644 --- a/src/utils/custom.js +++ b/src/utils/custom.js @@ -4,9 +4,90 @@ import request from '@/utils/request' import dayjs from "dayjs"; /** - * 通用js方法封装处理 - * Copyright (c) 2019 ruoyi + * 解析日期字符串并返回指定格式的日期。 + * + * @param {string|number} dateString - 要解析的日期字符串或 Excel 日期数字。 + * @param {boolean} isDateTime - 是否需要返回日期和时间格式。 + * @returns {string} - 格式化后的日期字符串。 */ +export function parseExcelTime(dateString, isDateTime){ + // 帮助函数:将 Date 对象格式化为 yyyy-MM-dd HH:mm:ss + const formatDateTime = date => { + return dayjs(date).format("YYYY-MM-DD HH:mm:ss"); + }; + + // 帮助函数:将 Date 对象格式化为 yyyy-MM-dd + const formatDate = date => { + return dayjs(date).format("YYYY-MM-DD"); + }; + + // 将非字符串的日期转换为字符串 + if (typeof dateString !== "string") { + dateString = String(dateString); + } + + // 处理包含 "23:59:17" 的日期字符串 + if (dateString.includes("23:59:17")) { + dateString = dayjs(dateString) + .add(isDateTime ? 43 : 1, isDateTime ? "second" : "day") + .format(isDateTime ? "YYYY-MM-DD HH:mm:ss" : "YYYY-MM-DD"); + } + + // 检查日期字符串是否为数字(Excel 日期格式) + if (!isNaN(dateString) && !isNaN(parseFloat(dateString))) { + const excelDate = parseFloat(dateString); + const excelEpoch = new Date(Date.UTC(1899, 11, 30)); + const dayInMs = 24 * 60 * 60 * 1000; + const parsedDate = new Date( + excelEpoch.getTime() + excelDate * dayInMs + ); + return isDateTime + ? formatDateTime(parsedDate) + : formatDate(parsedDate); + } + + // 处理各种日期格式 + let date; + const chineseDateTimeRegex = /^(\d{4})年(\d{1,2})月(\d{1,2})日 (\d{2}):(\d{2}):(\d{2})$/; + const chineseDateRegex = /^(\d{4})年(\d{1,2})月(\d{1,2})日$/; + const chineseMatch = dateString.match(chineseDateTimeRegex); + const chineseDateMatch = dateString.match(chineseDateRegex); + const dotDateRegex = /^(\d{4})\.(\d{1,2})\.(\d{1,2})$/; // 匹配 2024.06.20 格式的正则表达式 + const dotDateMatch = dateString.match(dotDateRegex); + + if (chineseMatch) { + const [_, year, month, day, hour, minute, second] = chineseMatch; + date = new Date(year, month - 1, day, hour, minute, second); + } else if (chineseDateMatch) { + const [_, year, month, day] = chineseDateMatch; + date = new Date(year, month - 1, day); + } else if (dotDateMatch) { + const [_, year, month, day] = dotDateMatch; + date = new Date(year, month - 1, day); + } else { + const slashDateTimeRegex = /^(\d{4})\/(\d{1,2})\/(\d{1,2})( \d{2}:\d{2}:\d{2})?$/; + const slashMatch = dateString.match(slashDateTimeRegex); + if (slashMatch) { + const [_, year, month, day, time] = slashMatch; + date = new Date( + `${year}-${month}-${day}T${time ? time.trim() : "00:00:00"}` + ); + } else { + date = new Date(dateString); + if (!isDateTime) { + date.setUTCHours(0, 0, 0, 0); + } + } + } + + if (isNaN(date.getTime())) { + console.error(`Invalid date object: ${dateString}`); + return dateString; + } + + return isDateTime ? formatDateTime(date) : formatDate(date); +} + // 日期格式化 export function parseTime(time, pattern) { diff --git a/src/views/emis/emisTmsSiteBatch/panel/BatchImportSiteBatch.vue b/src/views/emis/emisTmsSiteBatch/panel/BatchImportSiteBatch.vue index 213af9f2..cd48c4a5 100644 --- a/src/views/emis/emisTmsSiteBatch/panel/BatchImportSiteBatch.vue +++ b/src/views/emis/emisTmsSiteBatch/panel/BatchImportSiteBatch.vue @@ -83,7 +83,11 @@ - + + + @@ -100,10 +104,11 @@ import { listSimpleEmisSupplier } from "@/api/emis/emisSupplier"; import { listEmisTmsSiteBatchDtl, delEmisTmsSiteBatchDtl, addEmisTmsSiteBatchDtl } from "@/api/emis/emisTmsSiteBatchDtl"; import { listEmisWaybill } from "@/api/emis/emisWaybill"; -import { parseTime } from "@/utils/custom"; +import { parseTime,parseExcelTime } from "@/utils/custom"; import {timeDiffTime,timeFormat} from '@/utils/dateUtils' import { formatSearchStr,deepClone } from '@/utils/index' import { result } from "lodash"; +import dayjs from "dayjs"; import XLSX from 'xlsx' import moment from 'moment' @@ -211,7 +216,7 @@ export default { const reader = new FileReader() reader.onload = e => { const data = e.target.result - const workbook = XLSX.read(data, { type: 'array' }) + const workbook = XLSX.read(data, { type: 'array' ,cellDates: true}) const firstSheetName = workbook.SheetNames[0] // firstSheetName // if (!excelTypes.includes(firstSheetName)) { // reject('无法识别当前Excel模板') @@ -272,7 +277,7 @@ export default { transType: element['运输方式'], startSiteCode: element['起始网点'], nextSiteCode: element['下一网点'], - etd: element['发出时间'], + etd: parseExcelTime(element['发出时间'],false), carNo: element['运输号'], destCountry: element['目的国家'], destCountryName: null, diff --git a/src/views/emis/emisTmsSiteBatch/panel/BigBatchListPanel.vue b/src/views/emis/emisTmsSiteBatch/panel/BigBatchListPanel.vue index fc27bae8..c4d2756b 100644 --- a/src/views/emis/emisTmsSiteBatch/panel/BigBatchListPanel.vue +++ b/src/views/emis/emisTmsSiteBatch/panel/BigBatchListPanel.vue @@ -155,6 +155,7 @@ icon="el-icon-download" size="mini" @click="handleExport" + v-hasPermi="['emis:emisTmsSiteBatch:export']" >导出