机具领料模版下载与导入
This commit is contained in:
parent
5a513f49d1
commit
8fa6e994f0
|
|
@ -37,6 +37,8 @@
|
||||||
<input type="text" name="keyWord" placeholder="这里输入物资名称" class="input-large">
|
<input type="text" name="keyWord" placeholder="这里输入物资名称" class="input-large">
|
||||||
<button id='searchBtn' class="btn btn-warning btn-sm" title="过滤" type="button" onclick="getbaseList(1)"><i class="icon-search bigger-110 icon-only"></i></button>
|
<button id='searchBtn' class="btn btn-warning btn-sm" title="过滤" type="button" onclick="getbaseList(1)"><i class="icon-search bigger-110 icon-only"></i></button>
|
||||||
<button id="addBtn" class="btn btn-success btn-sm" title="新增" type="button">新增</button>
|
<button id="addBtn" class="btn btn-success btn-sm" title="新增" type="button">新增</button>
|
||||||
|
<button class="btn btn-fail btn-sm" title="导入模板下载" type="button" onclick="templateDownload()">导入模板下载</button>
|
||||||
|
<button class="btn btn-sm btn-danger" title="批量导入" type="button" onclick="importData()">批量导入</button>
|
||||||
<button class="btn btn-fail btn-sm" title="批量确认" type="button" onclick="batchConfirmation()">批量确认</button>
|
<button class="btn btn-fail btn-sm" title="批量确认" type="button" onclick="batchConfirmation()">批量确认</button>
|
||||||
<button class="btn btn-sm btn-danger" title="批量删除" type="button" onclick="batchDeletion()">批量删除</button>
|
<button class="btn btn-sm btn-danger" title="批量删除" type="button" onclick="batchDeletion()">批量删除</button>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -633,3 +633,175 @@ function backShowChenkStatus(){
|
||||||
})
|
})
|
||||||
return vals;
|
return vals;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导入模板下载功能
|
||||||
|
*/
|
||||||
|
function templateDownload() {
|
||||||
|
// 1. 校验领料时间(与新增/删除逻辑保持一致,非今日不允许下载)
|
||||||
|
if (applyDate !== today) {
|
||||||
|
layer.alert('领料时间不是今天,不允许下载导入模板', {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 构造下载请求(携带必要参数:taskId,保证模板与当前任务关联)
|
||||||
|
var taskId = localStorage.getItem("taskId");
|
||||||
|
var token = $("#token").val(); // 携带令牌,防止重复请求
|
||||||
|
var downloadUrl = bonuspath + '/backstage/receiveDetails/downloadTemplate';
|
||||||
|
|
||||||
|
// 3. 构造隐藏表单提交(解决GET请求参数暴露/大小限制问题,支持POST下载)
|
||||||
|
var $form = $("<form>").attr({
|
||||||
|
"method": "POST",
|
||||||
|
"action": downloadUrl,
|
||||||
|
"target": "_blank" // 新窗口打开,不阻塞当前页面
|
||||||
|
});
|
||||||
|
// 添加请求参数
|
||||||
|
$form.append($("<input>").attr({
|
||||||
|
"type": "hidden",
|
||||||
|
"name": "taskId",
|
||||||
|
"value": taskId
|
||||||
|
}));
|
||||||
|
$form.append($("<input>").attr({
|
||||||
|
"type": "hidden",
|
||||||
|
"name": "token",
|
||||||
|
"value": token
|
||||||
|
}));
|
||||||
|
// 插入页面并提交
|
||||||
|
$("body").append($form);
|
||||||
|
$form.submit();
|
||||||
|
// 提交后移除表单
|
||||||
|
$form.remove();
|
||||||
|
|
||||||
|
// 4. 友好提示
|
||||||
|
layer.msg('正在下载导入模板,请稍后...', {
|
||||||
|
icon: 16,
|
||||||
|
shade: 0.1,
|
||||||
|
time: 1500
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量导入功能
|
||||||
|
*/
|
||||||
|
function importData() {
|
||||||
|
// 1. 校验领料时间(与其他操作逻辑保持一致)
|
||||||
|
if (applyDate !== today) {
|
||||||
|
layer.alert('领料时间不是今天,不允许进行批量导入操作', {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 弹出文件选择层(使用layui/layer实现美观的文件上传界面)
|
||||||
|
layer.open({
|
||||||
|
type: 1,
|
||||||
|
title: ['批量导入物资数据', 'background-color: #438EB9;color:#fff'],
|
||||||
|
shadeClose: false,
|
||||||
|
shade: 0.3,
|
||||||
|
area: ['450px', '220px'],
|
||||||
|
content: '<div style="padding: 20px;">' +
|
||||||
|
' <div class="layui-form-item" style="margin-bottom: 15px;">' +
|
||||||
|
' <label style="display: inline-block; width: 80px; text-align: right; margin-right: 10px;">选择文件:</label>' +
|
||||||
|
' <input type="file" id="importFile" accept=".xlsx,.xls" style="display: inline-block; width: 280px;" />' +
|
||||||
|
' <span style="color: #999; font-size: 12px;">(仅支持xlsx/xls格式)</span>' +
|
||||||
|
' </div>' +
|
||||||
|
' <div style="text-align: center; margin-top: 20px;">' +
|
||||||
|
' <button id="submitImport" class="btn btn-success btn-sm" style="margin-right: 20px;">确认导入</button>' +
|
||||||
|
' <button id="cancelImport" class="btn btn-default btn-sm">取消</button>' +
|
||||||
|
' </div>' +
|
||||||
|
'</div>',
|
||||||
|
success: function(layero, index) {
|
||||||
|
// 3. 取消按钮事件
|
||||||
|
$("#cancelImport").on('click', function() {
|
||||||
|
layer.close(index);
|
||||||
|
// 清空文件选择
|
||||||
|
$("#importFile").val("");
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4. 确认导入按钮事件
|
||||||
|
$("#submitImport").on('click', function() {
|
||||||
|
var file = $("#importFile")[0].files[0];
|
||||||
|
// 4.1 校验文件是否选择
|
||||||
|
if (!file) {
|
||||||
|
layer.tips('请先选择要导入的Excel文件', '#importFile', {
|
||||||
|
tips: [1, '#FF5722'],
|
||||||
|
time: 2000
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.2 校验文件格式
|
||||||
|
var fileName = file.name;
|
||||||
|
var suffix = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
|
||||||
|
if (suffix !== ".xlsx" && suffix !== ".xls") {
|
||||||
|
layer.alert('仅支持导入xlsx/xls格式的Excel文件,请重新选择', {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0
|
||||||
|
});
|
||||||
|
$("#importFile").val("");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.3 构造FormData(用于上传文件)
|
||||||
|
var formData = new FormData();
|
||||||
|
formData.append("importFile", file); // 文件对象
|
||||||
|
formData.append("taskId", localStorage.getItem("taskId")); // 当前任务ID
|
||||||
|
formData.append("token", $("#token").val()); // 令牌
|
||||||
|
// 4.4 显示加载提示
|
||||||
|
var loadIndex = layer.load(2, {
|
||||||
|
shade: [0.3, '#000'],
|
||||||
|
time: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
// 4.5 异步上传文件(使用jQuery Ajax实现文件上传)
|
||||||
|
$.ajax({
|
||||||
|
url: bonuspath + '/backstage/receiveDetails/importData',
|
||||||
|
type: 'POST',
|
||||||
|
data: formData,
|
||||||
|
contentType: false, // 必须设置为false,让浏览器自动处理Content-Type
|
||||||
|
processData: false, // 必须设置为false,不处理表单数据
|
||||||
|
dataType: 'json',
|
||||||
|
success: function(data) {
|
||||||
|
layer.close(loadIndex);
|
||||||
|
layer.close(index);
|
||||||
|
$("#importFile").val("");
|
||||||
|
if (data.resCode === "0000") {
|
||||||
|
layer.alert(data.resMsg, {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0
|
||||||
|
}, function() {
|
||||||
|
getbaseList(1);
|
||||||
|
layer.closeAll();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 拆分错误信息,实现换行展示
|
||||||
|
var errorMsg = data.resMsg.replace(/\n/g, '<br/>');
|
||||||
|
layer.alert(errorMsg, {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0,
|
||||||
|
html: true // 允许展示HTML标签(br换行)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
// 异常处理
|
||||||
|
layer.close(loadIndex);
|
||||||
|
layer.close(index);
|
||||||
|
$("#importFile").val("");
|
||||||
|
layer.alert('导入请求异常,请联系管理员', {
|
||||||
|
skin: 'layui-layer-molv',
|
||||||
|
closeBtn: 0
|
||||||
|
});
|
||||||
|
console.error("导入异常:", error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -306,5 +306,25 @@
|
||||||
LEFT JOIN wf_info_record wir ON wir.SUP_ID = wtr.ID
|
LEFT JOIN wf_info_record wir ON wir.SUP_ID = wtr.ID
|
||||||
WHERE wtr.SUP_ID = #{taskId} and wir.MA_ID
|
WHERE wtr.SUP_ID = #{taskId} and wir.MA_ID
|
||||||
</select>
|
</select>
|
||||||
|
<select id="getMaTypeByNameAndModel" resultType="com.bonus.lease.beans.ReceiveDetailsBean">
|
||||||
|
SELECT
|
||||||
|
mt.ID as maModelId,
|
||||||
|
mt.PARENT_ID as maTypeId,
|
||||||
|
mt2.`NAME`
|
||||||
|
FROM
|
||||||
|
mm_type mt
|
||||||
|
LEFT JOIN mm_type mt2 on mt2.ID=mt.PARENT_ID
|
||||||
|
WHERE
|
||||||
|
mt.`name`=#{maModel}
|
||||||
|
and mt.`level`='4'
|
||||||
|
and mt2.`NAME`=#{maType};
|
||||||
|
</select>
|
||||||
|
<select id="getUserByUserName" resultType="com.bonus.lease.beans.ReceiveDetailsBean">
|
||||||
|
SELECT id as customerSrepId,
|
||||||
|
`NAME` as `name`
|
||||||
|
FROM pm_user
|
||||||
|
WHERE `NAME` = #{customerSrep}
|
||||||
|
and POST_NAME LIKE CONCAT('%', '客服代表', '%')
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
Binary file not shown.
|
|
@ -1,28 +1,46 @@
|
||||||
package com.bonus.lease.controller;
|
package com.bonus.lease.controller;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.net.URLEncoder;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletOutputStream;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.servlet.http.HttpSession;
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
|
import com.bonus.sys.*;
|
||||||
|
import com.bonus.sys.beans.UserBean;
|
||||||
|
//导入POI核心类
|
||||||
|
import org.apache.poi.ss.usermodel.Cell;
|
||||||
|
import org.apache.poi.ss.usermodel.Row;
|
||||||
|
import org.apache.poi.ss.usermodel.Sheet;
|
||||||
|
import org.apache.poi.ss.usermodel.Workbook;
|
||||||
|
import org.apache.poi.ss.usermodel.DateUtil;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import com.bonus.lease.beans.OutStorageBean;
|
import com.bonus.lease.beans.OutStorageBean;
|
||||||
import com.bonus.lease.beans.ReceiveDetailsBean;
|
import com.bonus.lease.beans.ReceiveDetailsBean;
|
||||||
import com.bonus.lease.service.OutStorageService;
|
import com.bonus.lease.service.OutStorageService;
|
||||||
import com.bonus.lease.service.ReceiveDetailsService;
|
import com.bonus.lease.service.ReceiveDetailsService;
|
||||||
import com.bonus.sys.AjaxRes;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.bonus.sys.BaseController;
|
|
||||||
import com.bonus.sys.GlobalConst;
|
|
||||||
import com.bonus.sys.Page;
|
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
@RequestMapping("/backstage/receiveDetails/")
|
@RequestMapping("/backstage/receiveDetails/")
|
||||||
|
|
@ -447,4 +465,315 @@ public class ReceiveDetailsController extends BaseController<ReceiveDetailsBean>
|
||||||
// list.add("是否确认");
|
// list.add("是否确认");
|
||||||
// return list;
|
// return list;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载物资导入模板
|
||||||
|
* @param taskId 任务ID
|
||||||
|
* @param token 令牌
|
||||||
|
* @param request HTTP请求对象(显式声明参数,Spring自动注入)
|
||||||
|
* @param response 响应对象
|
||||||
|
*/
|
||||||
|
@RequestMapping("/downloadTemplate")
|
||||||
|
// 注意:文件下载接口建议移除@ResponseBody,因为要直接写入响应流,无需Spring序列化返回值
|
||||||
|
public void downloadTemplate(String taskId, String token,
|
||||||
|
HttpServletRequest request, // 关键:添加request参数声明
|
||||||
|
HttpServletResponse response) {
|
||||||
|
// 1. 令牌校验(此时request已正常获取,可直接调用getSession())
|
||||||
|
HttpSession session = request.getSession();
|
||||||
|
String sessionToken = (String) session.getAttribute("TOKEN_IN_SESSION");
|
||||||
|
// if (token == null || !token.equals(sessionToken)) {
|
||||||
|
// // 令牌无效处理
|
||||||
|
// try {
|
||||||
|
// response.getWriter().write("令牌无效,请刷新页面重试");
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
// }
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// 2. 模板文件生成/读取(建议将模板放在项目resources/template目录下)
|
||||||
|
String templatePath = "template/机具领料导入模板.xlsx";
|
||||||
|
File templateFile = null;
|
||||||
|
try {
|
||||||
|
// 读取模板文件
|
||||||
|
Resource resource = new ClassPathResource(templatePath);
|
||||||
|
templateFile = resource.getFile();
|
||||||
|
|
||||||
|
// 3. 设置响应头,实现文件下载
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode("物资导入模板.xlsx", "UTF-8"));
|
||||||
|
response.setContentLength((int) templateFile.length());
|
||||||
|
|
||||||
|
// 4. 写入响应流
|
||||||
|
FileInputStream fis = new FileInputStream(templateFile);
|
||||||
|
ServletOutputStream sos = response.getOutputStream();
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int len;
|
||||||
|
while ((len = fis.read(buffer)) != -1) {
|
||||||
|
sos.write(buffer, 0, len);
|
||||||
|
}
|
||||||
|
sos.flush();
|
||||||
|
fis.close();
|
||||||
|
sos.close();
|
||||||
|
|
||||||
|
// // 5. 移除令牌(可选,防止重复下载)
|
||||||
|
// session.removeAttribute("TOKEN_IN_SESSION");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
// 下载失败处理
|
||||||
|
try {
|
||||||
|
response.getWriter().write("模板下载失败,请联系管理员");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping("/importData")
|
||||||
|
@ResponseBody
|
||||||
|
public Map<String, Object> importData(@RequestParam("importFile") MultipartFile importFile,
|
||||||
|
String taskId,
|
||||||
|
String token,
|
||||||
|
HttpSession session) {
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
List<String> errorMsgList = new ArrayList<>();
|
||||||
|
Map<String, Integer> existTypeModelMap = new HashMap<>();
|
||||||
|
List<ReceiveDetailsBean> dataList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 1. 基础校验
|
||||||
|
if (importFile == null || importFile.isEmpty()) {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "请选择要导入的Excel文件");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// // 2. 令牌校验
|
||||||
|
// String sessionToken = (String) session.getAttribute("TOKEN_IN_SESSION");
|
||||||
|
// if (token == null || !token.equals(sessionToken)) {
|
||||||
|
// result.put("resCode", "9999");
|
||||||
|
// result.put("resMsg", "令牌无效,请刷新页面重试");
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
Workbook workbook = null;
|
||||||
|
InputStream inputStream = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 3. 获取文件输入流和文件名
|
||||||
|
inputStream = importFile.getInputStream();
|
||||||
|
String fileName = importFile.getOriginalFilename();
|
||||||
|
if (fileName == null || (!fileName.endsWith(".xls") && !fileName.endsWith(".xlsx"))) {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "仅支持导入.xls或.xlsx格式的Excel文件");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. 创建Workbook(低版本POI兼容)
|
||||||
|
if (fileName.endsWith(".xls")) {
|
||||||
|
workbook = new HSSFWorkbook(inputStream);
|
||||||
|
} else {
|
||||||
|
workbook = new XSSFWorkbook(inputStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 获取工作表
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
if (sheet == null) {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "Excel文件中无有效工作表,请检查");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 遍历数据行
|
||||||
|
int firstRowNum = sheet.getFirstRowNum();
|
||||||
|
int lastRowNum = sheet.getLastRowNum();
|
||||||
|
|
||||||
|
// 只有表头无数据
|
||||||
|
if (firstRowNum == lastRowNum) {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "Excel文件中无有效数据,请检查");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历所有数据行(跳过表头)
|
||||||
|
for (int i = firstRowNum + 2; i <= lastRowNum; i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ReceiveDetailsBean bean = new ReceiveDetailsBean();
|
||||||
|
int excelRowNum = i + 1;
|
||||||
|
StringBuilder rowErrorMsg = new StringBuilder();
|
||||||
|
|
||||||
|
// 低版本POI兼容:手动判断单元格是否为null(无MissingCellPolicy)
|
||||||
|
Cell maTypeCell = row.getCell(0);
|
||||||
|
String maType = getCellStringValue(maTypeCell);
|
||||||
|
bean.setMaType(maType);
|
||||||
|
|
||||||
|
Cell maModelCell = row.getCell(1);
|
||||||
|
String maModel = getCellStringValue(maModelCell);
|
||||||
|
bean.setMaModel(maModel);
|
||||||
|
|
||||||
|
Cell customerSrepCell = row.getCell(2);
|
||||||
|
String customerSrep = getCellStringValue(customerSrepCell);
|
||||||
|
bean.setCustomerSrep(customerSrep);
|
||||||
|
|
||||||
|
Cell machinesNumCell = row.getCell(3);
|
||||||
|
String machinesNum = getCellStringValue(machinesNumCell);
|
||||||
|
bean.setMachinesNum(machinesNum);
|
||||||
|
|
||||||
|
// 7. 原有校验逻辑(完全不变)
|
||||||
|
if (StringHelper.isEmpty(maType)) {
|
||||||
|
rowErrorMsg.append("物资名称为空;");
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(maModel)) {
|
||||||
|
rowErrorMsg.append("规格型号为空;");
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(customerSrep)) {
|
||||||
|
rowErrorMsg.append("客服代表为空;");
|
||||||
|
}
|
||||||
|
if (StringHelper.isEmpty(machinesNum)) {
|
||||||
|
rowErrorMsg.append("机具数量为空;");
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
int machineNum = Integer.parseInt(machinesNum.trim());
|
||||||
|
if (machineNum <= 0) {
|
||||||
|
rowErrorMsg.append("机具数量必须为正整数;");
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
rowErrorMsg.append("机具数量格式错误,必须为正整数;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8. 物资名称+规格型号存在性校验(不变)
|
||||||
|
if (rowErrorMsg.length() == 0) {
|
||||||
|
ReceiveDetailsBean receiveDetailsBean = service.getMaTypeByNameAndModel(bean);
|
||||||
|
if (receiveDetailsBean == null) {
|
||||||
|
rowErrorMsg.append("物资名称或规格型号不存在;");
|
||||||
|
} else {
|
||||||
|
bean.setMaModelId(receiveDetailsBean.getMaModelId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9. 客服代表合法性校验(不变)
|
||||||
|
if (rowErrorMsg.length() == 0) {
|
||||||
|
ReceiveDetailsBean kfBean = service.getUserByUserName(bean);
|
||||||
|
if (kfBean == null) {
|
||||||
|
rowErrorMsg.append("客服代表名称不存在或角色不符;");
|
||||||
|
} else {
|
||||||
|
bean.setCustomerSrep(kfBean.getCustomerSrepId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 10. 数据库重复校验(不变)
|
||||||
|
if (rowErrorMsg.length() == 0) {
|
||||||
|
bean.setTaskId(taskId);
|
||||||
|
List<ReceiveDetailsBean> list = service.findBean(bean);
|
||||||
|
if (list.size() > 0) {
|
||||||
|
rowErrorMsg.append("该物资类型+规格型号已在数据库中存在,请勿重复添加;");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 11. Excel内部重复校验(不变)
|
||||||
|
if (rowErrorMsg.length() == 0) {
|
||||||
|
String typeModelKey = maType.trim() + "_" + maModel.trim();
|
||||||
|
if (existTypeModelMap.containsKey(typeModelKey)) {
|
||||||
|
int firstRowNum2 = existTypeModelMap.get(typeModelKey);
|
||||||
|
rowErrorMsg.append("物资类型+规格型号与第").append(firstRowNum2).append("行重复;");
|
||||||
|
} else {
|
||||||
|
existTypeModelMap.put(typeModelKey, excelRowNum);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 12. 收集错误信息(不变)
|
||||||
|
if (rowErrorMsg.length() > 0) {
|
||||||
|
errorMsgList.add("第" + excelRowNum + "行:" + rowErrorMsg.toString().substring(0, rowErrorMsg.length() - 1));
|
||||||
|
} else {
|
||||||
|
dataList.add(bean);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 13. 错误判断与批量插入(不变)
|
||||||
|
if (!errorMsgList.isEmpty()) {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
StringBuilder allErrorMsg = new StringBuilder("导入失败,存在以下错误:\n");
|
||||||
|
for (String errorMsg : errorMsgList) {
|
||||||
|
allErrorMsg.append(errorMsg).append("\n");
|
||||||
|
}
|
||||||
|
result.put("resMsg", allErrorMsg.toString().trim());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean importSuccess = service.batchImport(dataList, taskId);
|
||||||
|
if (importSuccess) {
|
||||||
|
result.put("resCode", "0000");
|
||||||
|
result.put("resMsg", "批量导入成功,共导入" + dataList.size() + "条数据");
|
||||||
|
} else {
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "批量导入失败,数据库插入异常");
|
||||||
|
}
|
||||||
|
|
||||||
|
// session.removeAttribute("TOKEN_IN_SESSION");
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
result.put("resCode", "9999");
|
||||||
|
result.put("resMsg", "导入异常:" + e.getMessage());
|
||||||
|
} finally {
|
||||||
|
// 关闭资源(不变)
|
||||||
|
try {
|
||||||
|
if (workbook != null) {
|
||||||
|
workbook.close();
|
||||||
|
}
|
||||||
|
if (inputStream != null) {
|
||||||
|
inputStream.close();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 低版本POI兼容的单元格值转换方法(无CellType和MissingCellPolicy依赖)
|
||||||
|
private String getCellStringValue(Cell cell) {
|
||||||
|
if (cell == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String cellValue = "";
|
||||||
|
int cellType = cell.getCellType();
|
||||||
|
|
||||||
|
// 处理公式单元格
|
||||||
|
if (cellType == Cell.CELL_TYPE_FORMULA) {
|
||||||
|
cellType = cell.getCachedFormulaResultType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用低版本POI静态常量判断类型
|
||||||
|
switch (cellType) {
|
||||||
|
case Cell.CELL_TYPE_STRING:
|
||||||
|
cellValue = cell.getStringCellValue().trim();
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_NUMERIC:
|
||||||
|
if (DateUtil.isCellDateFormatted(cell)) {
|
||||||
|
cellValue = cell.getDateCellValue().toString();
|
||||||
|
} else {
|
||||||
|
BigDecimal bigDecimal = new BigDecimal(cell.getNumericCellValue());
|
||||||
|
cellValue = bigDecimal.toString().trim();
|
||||||
|
if (cellValue.endsWith(".0")) {
|
||||||
|
cellValue = cellValue.substring(0, cellValue.lastIndexOf("."));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_BOOLEAN:
|
||||||
|
cellValue = String.valueOf(cell.getBooleanCellValue()).trim();
|
||||||
|
break;
|
||||||
|
case Cell.CELL_TYPE_BLANK:
|
||||||
|
cellValue = "";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cellValue = "";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return cellValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,4 +50,17 @@ public interface ReceiveDetailsDao extends BaseDao<ReceiveDetailsBean> {
|
||||||
|
|
||||||
public int batchDeletion(ReceiveDetailsBean o);
|
public int batchDeletion(ReceiveDetailsBean o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据物资名称和规格型号查询物资
|
||||||
|
* @param bean
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReceiveDetailsBean getMaTypeByNameAndModel(ReceiveDetailsBean bean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户名查询用户
|
||||||
|
* @param bean
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReceiveDetailsBean getUserByUserName(ReceiveDetailsBean bean);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,4 +36,26 @@ public interface ReceiveDetailsService extends BaseService<ReceiveDetailsBean> {
|
||||||
|
|
||||||
public String batchDeletion(ReceiveDetailsBean o);
|
public String batchDeletion(ReceiveDetailsBean o);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据物资名称和规格型号查询物资
|
||||||
|
* @param bean
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReceiveDetailsBean getMaTypeByNameAndModel(ReceiveDetailsBean bean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户名查询用户
|
||||||
|
* @param bean
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
ReceiveDetailsBean getUserByUserName(ReceiveDetailsBean bean);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量导入
|
||||||
|
* @param dataList
|
||||||
|
* @param taskId
|
||||||
|
* @param leasePlanOutId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
boolean batchImport(List<ReceiveDetailsBean> dataList, String taskId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.bonus.lease.service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.google.protobuf.ServiceException;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
@ -24,6 +25,7 @@ import com.bonus.sys.beans.UserBean;
|
||||||
import com.bonus.sys.dao.UserDao;
|
import com.bonus.sys.dao.UserDao;
|
||||||
import com.bonus.wf.beans.TaskRecordBean;
|
import com.bonus.wf.beans.TaskRecordBean;
|
||||||
import com.bonus.wf.dao.TaskRecordDao;
|
import com.bonus.wf.dao.TaskRecordDao;
|
||||||
|
import org.springframework.transaction.interceptor.TransactionAspectSupport;
|
||||||
|
|
||||||
@Service("receiveDetails")
|
@Service("receiveDetails")
|
||||||
public class ReceiveDetailsServiceImp extends BaseServiceImp<ReceiveDetailsBean> implements ReceiveDetailsService {
|
public class ReceiveDetailsServiceImp extends BaseServiceImp<ReceiveDetailsBean> implements ReceiveDetailsService {
|
||||||
|
|
@ -233,4 +235,43 @@ public class ReceiveDetailsServiceImp extends BaseServiceImp<ReceiveDetailsBean>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReceiveDetailsBean getMaTypeByNameAndModel(ReceiveDetailsBean bean) {
|
||||||
|
try {
|
||||||
|
return dao.getMaTypeByNameAndModel(bean);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.toString(), e);
|
||||||
|
return new ReceiveDetailsBean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReceiveDetailsBean getUserByUserName(ReceiveDetailsBean bean) {
|
||||||
|
try {
|
||||||
|
return dao.getUserByUserName(bean);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.toString(), e);
|
||||||
|
return new ReceiveDetailsBean();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public boolean batchImport(List<ReceiveDetailsBean> dataList, String taskId) {
|
||||||
|
try {
|
||||||
|
for (ReceiveDetailsBean bean : dataList) {
|
||||||
|
bean.setTaskId(taskId);
|
||||||
|
int res = dao.insertBean(bean);
|
||||||
|
if (res != 1) {
|
||||||
|
throw new ServiceException("新增类型数据失败");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.toString(), e);
|
||||||
|
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue