Z?h=6HRY)cUizzP;VVr(o<`>VV%%-wpn#PB<3BhyXNqvD+zNP4B7k&TrSiMN1ETc<_I&s+%
z%H4csT|XRrWLi<30Be!ss7Zh3p-i-L;1Z)tbMd@KF+%YKSm}(sS1Y)Jr>J#xy*YP0jDcA=*o8I-aK^eTzXtFG%K*lS4d;nc9vd?
zm+KHO4|Rdz^k%KZVVxUVX?HXoRw`9?LZdKGx7|V^^@gPALm@ZZL+Ye(RooFo`&rE^J-NMAsvqpS!$~meeLF593)v?dyZ%t=X~P
zZHRJzqNg-xrZziH#HM?;!1!TVCzXwgmW-J?BRyM+_QV>sy$j!v_|9t8$j)JEL&`Jl
zQMl?Jo@ZT7wvrY(L${9d7dh26#;$u4aTe~fovW`Jy$&PYUqfqkhA+DoGfP%vR57{3o
zY!5z+*O+z4WySC@vc8ADZk>yzw#HF?pJk&p6JOFQ^vnWL6S}q@`@^et(`R7idX1ad
zj;qhf96Ys6zGV!Dh^o#b0Kkd(ifFgQmsB4y-@C?UZA>NWnYB7BG{71QEwJ_bmGKzT
zb(SpDKDl@`ptsJl
z>WVl@=%yX)5Dv_%=GTZzt#l7%Xt99U<+XgG&ChRFz{RzeN@MfxMSj-(&gvnSk}qg_
z0-${*)vOwsI#^W;t}#`MO5WtTq~!>6!wZ@Cy$Er-o0Dp;6?b82B}RT(3H(9jZgWkD1(
z10G$8
z+Y(5#e`kjkmFUx$jibGrkP;t0;bMoxu|@QT2;~?om3`ib#?y&eI;h!6JeifWzpw-#OYR)I4W|7l2L+-x-j!m7GLJK}tDFXTmLMrq<&v5`Jc?v{3kz
zL|K^oCHNH|>nw1Qzh?!t8XqFl2Mq5gHnC2{6~wgykl0=cZChX)B_3dGj%t}2gHrp5
zwM^j_D5wWeM(0nOjVnYC_NlT3sL|0TIJ&$McE?)Hv{>-bojmnE1Xrpbc;>bsBfFyc
z)K-tqBOW||JE8bp(W(V%-!$|odB-*SP=pF%_6=Ukley`1t`u9Fs{#9a=>I;Q9^U1U
z>Evo?1%7=IkK;#;7G)S(TcbAN_($0#%!08odTg=
zXoVVtB_SI|Tx?*Ii0R%$M)&Lk?x$*z*E!ZBa<3O&($2t3`x%ZJt#Ut4g}Fu{0ctU*
z=GgT0lQWqZ0S;1^S3e)2HGKe{8;iA?etu+Z-B)Q)@{Lpx_DL+~&Xv1VKos*$Ml>xN
zra9fgl?&r-Y4cNGr$_t!_%u_nH|l#?kx%84_tohs{EPw2)u@F>c3mF+0Pl4bsyrK7X`j*;dXNw)+9H#0yB_BsssI22TUQ$2H?=^O>R?42_IPfli<@=2oe4a03C
z*dqPDbG`2t?KC{TR%Hq9g`B?
zY-8+(eJ5G4Tzc4kbu+8f+MeNax${ZOp@sFh{r+s)vE6qYzDr1#{pI!fm~e)$&-Kve
ztGlBf=*3klyDlj}XIFEmQp+>O*YCGGram7hwI_e1mF%ezVY>n~9t=*wETmEHbnTly
z^SI=d4ngs-zvx)u55Jbj>if*I(gQ=vCV5HV4!;zXG8l4Xl^}WW>H2feyy(^xmpfj*
zrp-+)YF%8TKFHK=q(wo6UgeD%qu_bC0vo98K!{vZKT5hI`33g&Jk5d-#h2*t{weyr
z{1IpwG8Pv+QR(-%skvSYLb(+hmq*nRZ_r*B1>7R4F@#To<#T%0fp4&E;BPTLO+5$l
zZoUrPML|lAWHmPw?h$LWb8yzKj5#ABdwNj!bi~tyvI(G;I4s_i6uMV!%_AwZ(SSXgCh~*SS8IeIxm@
z4QE`=PPUg|NCOa5YdIxY7zFh#uJ$x}qHFfN#6A$F9TDV|b2Od8-DTQo6>HbBx_?y(
zPQ5spom|hy36L%Ae&M?^v3Y2=dh8`eOESRsF<30K;}K_;6I8%}q7lEdC&{46RS}3?
z{>3syWL-pG^6i^`5BywI#X~M5zEFu}ek{XYxH-b}s$IOVdvpnR+@)mJZplB;5c#Y_@?}YvvWZ7C5n%Z?F
zjLZy|Z`I4Ip=``Gm)@*(HkGXM?7V=Hbg~!238q)_EWw)||Ky#TynrKL3R7~Vnp@;&
zUN9TB+q+&ozMckCn_{X70Kv*qi|F)acI=Y~Q4@TPRHo6Bp!B%LmCkUydP^(U8@NY~
zxd}a)6IUuK2G}5_lIhbLWEm4tD<@CUvqynjPN$lL*YTX}7aiRPtbT$+7?p2k%b`er
z^(b)oeb=>msu6J+<2351V0bsSqrBxUx<8g}oejMoIp$GVVS*F~;7GFur^ftyIcI?w
zXlT;^L(qw{L@hop$w!=1;)?v1yxjJ9Hr6&=+aNzeayr6gURAUS)RJ+9!HO7{sVTQ%
zZq*nL372UOCJhyXv2v3M)VJJKSc7l5JOjoldce#>=$UetC2RF~x(z@@+GaSomhjBn
z-Hcpv{I3adI$v>C-3T;O48mtxO{+UNiqZ>Z@Jkl;8x2DBrYY0LI+p_Zg{R6jnNSs;
zY|4^YfA0>wMu8;~hC1HrY@Q>Cr@%u*oB59L`(dtkavNLl`+uV
zOwAQ&?O^Hhuwb%}7M1N5!3nzbcSo#kh@%gYj%9{ZQhtmPTa5(Z;NrkEKrW|v-y7kt
zonJ2PHYO^pGGTmlcezBH`n&pj^2vB0fc45v4~xWqVLz
z4;{fy)C>|~W$$Fm$ucglz<*JJg$jBF^EZD)UHgi@vR3T5E(%!4Y5}5*aA(FSE_qKQ1kr^8Gb4(RuJB-)e
zLJL>sN`&;$n_S~%9|n6qhFf0JPhClETt^ooWoFzCD7Vdi`(qDrrh)x@9fBn$92C^!
zUyD!^M@QQSC?nKV98*~_d^79rUt9~aMS}xrl>@1*;!{dwYhArkh=3sL6tI>0eC`fv51UP$y((nS(DF?DgQrNI;X^Au@4aH{$pn3}3W^zhXIY0sEOtwR
z(-yJNuE#0XM*7C%xujny2A=MuiB0=DLuZx7dPKU2
z(+}_-;A{Xxg8E$&x@7YTksA*r0PoaOH%tA;OSA^j_n&JG!K1GhXs*7)u5!zeW5yw7
z0%~@(okER#@Xd?gKGQc*SIwU!7>f?{Fi{=pAX+j7D7kr?G@V`
z2`=K9D=0D+z#c*wbj37rwNWNhAOM%@;SfXwPPU~NCoB?@sns3H
zQA^e1Y|7GNJ@k{?eWlO3SYgMIxO0!0Ib@T_8lAR>fOSa9(>x?{(EalAoQgo!&|zg9
z$or~kp1FN*BJ+l!Ul@(bV#A{8+o!lY$4K8Fi?UzL$w=gU(llg81J;CsLi^VYbM>?{
z|1q`3_3fi(wQ=tvdtO!PcOvx28}7-+PJeo*Xi;WhEs9G50EooL@p3#-OmjVw&X6)qdJ(noGvb
zidW^~#CdK;?p$?C_WlKtjdg1gy=MD9Xzxx`{QH--YE8BHY{!dd1*;e3K`-sl#&>6p
z?nWoT!k{v};DmLCtQ=vxqTn{+DMp;2eeqID^vU_xp>AsS<@14vyzig1MWIj?L9ovTrpBYC!t1sQtUf;&jc$G+Hsge)PO7Z_=WdQymYm24z|U1@uR@m-U*91
zEv|l+_)qVuapuJ9P{R&zn`yLjKh&ZYyg+-zLA1D0rOLsXn^LjSC_fWzE6PR&|9;Pd
z-4@)aGCx!`Cxc43wy2TthVNQ0%^lB%O$}%sX$l@>G_ar9z%S*=wrLwxWu2Uor1Bc}
zcQvpMpmf=>u@-Gc5#MT@j>JBnrjMXZWH9*5x%oxx4-|jcEebCl&+E^&&y2m*#4y6P``3w_gvRHSF?27
zt-Q|T2Di#+(&jvZy@S?5VO-~)i`A%H-6meOwJfow0tV&=1z4NI%rn$~r#c$G$3it!
zHx}n(y`T+DiTR$NM=)(9n^H>9;3=A~V(_=7Z8GJHd;)5`gc)wi8#x({n)Y{`EJY|#
zr>t@cKfX}j+*_t>%Tc#X)azHm#(`v6F(3I%AI)4On7a9R#GLH~h@VWlBdon2J@-l4
zm|57F+IT(7L&D3*%9I26e9_rsD1QFf*n~NagjK4I=(96U$V*YL95^yWXn@e56LmM-
zRez_%dmS-pPQ}-w5&)r;M_(jzX>&t|fkqUnR0DZK);T$Y&lh4dgC`st_
zlk!+CsXSm*kpZ4OwiNblJ?y;Q!5QP#QmsYkp@veSiv+15DMaZl$GaM>+T#qYwKAp|
z6BjL4Co&~*`-Im|MY&?{b!2*4@3
zip9jR1ZHSqD7&?f0&OhtSrGK;r0cis*mYH1)i);@d$mVb0`38ZD6al939EAyt?`GT
z+>B_&gl%HCkq-pgBN7wp(fNF97?S4!;uANqM!4kY4*isgaB`7v_Vo2m^QDp}rQ
zLM^C#uuQ)imwImt&dlaq4i4d-es)jGXZvooUfR>ylNW{?4cncN+C^4)+!Mk3bE;)4
zMU|ZJxDPImls6joJ6k?G&IYLbULzR(SDPro$(t_;Ce-`#J<}Vg(*yToAWz;3>xXGO@F~jD$
z4t&1XU|fS*P9@#+f$Wi4|4E5x&_OTc(k5j{o*O2!#O^AwA!^9zMZUgFYwRl;JNg9G
z+z`$z;l2L}Y}XNcm?9lxV9~WG*`0ZvbZRupNWIJ@HZHzTu2?K~KEnY_1v-
z?XY1RRc%IY%A=))!Oh3L!uQkHH||f7=`UsHJgTsi5sS1prCy5LYx}-tx&5liUKnRn{|K;GuhkQ
z{iLsN6``GEv7P7o=u}#B?U9`=RgC$&%$R&}aRDQ9>*S2vRWsnFa5f*mVt_CsV`24^|{oAmbg3lV1z()%{fMjsoc*yNY-tDxsCM6JgffQf`IFMM!>hjBl
zNwt&4>5-&T6*q$BGoEr#9fJ#rK-Qw1kV<*yUahihvxKO@ol+MRD?wG_L5AuNLnmyS
z+ch4NHlCLj@gT^q701rQO|Ku(uWvA*FQcB5qJhna;zecnh5^#1qrF70f=z^5A!)|U
zxSdcG8X=np-{q%PE@vwxqfSOs)=I7?Nl~+{`lS~bSc=J4D#u6kL%M?5+`&%0kuc;j
zNcN#yKNC@P5nN5Ob-Rbwm|9#q%OB(TTrQpbQ^O&UJuxa#WO9L~IdOEDFsDuMsMOSL
zC}#Cgiie0^_>TJfD00nH0k^TX)o<$0#n<~BV;_rUXTlH%Uxx7nAK}v6YDi|xD=$vZ
z7EicehM(w`H>&B4ah29+R_^UpXq;_)IjB%!Nq9T-RNSIpvockR>N{|@_{nY{|Lh5F
zTLJBMsyG6-!8wd2>`}wj`=BsId~g3YsH*Avuc2M6Ghv{cSO1-ugomtwjezEMf716}
zyr7nQ$Zv}f3LoV!8RiGc^4MY79#)LrL;pjJjWz{$T+C@#7K%LuGatVs`Fk)mcC5~R
zTdSxF_9na{YM7xD?4QU-9hIw(5~oJjU&k}4|*
zd|aRp@oI*5<_&DQc62P+{jwyOoGU)e!LX(tlkR30jT;`|ojcWzasC`0o^KfFCNy~H
zE*o4{Zo!21Tt6^LEo^RGzulQJxldp5X&6=3(6z|e*k)H}%!ppypfvv*s+`?>0DE80
zT7st#mytB^gsIg1zhn6?lJ}qB?6;c+?m=Mu0D+Sba))f}e~LZiPyW3f{TI3lHr=ck
zftP^`qMzFm(i2o=*X(4;XD0;xqI(lUnUIFg`Wh;o$eqdZh#cV@;ae|(i^od4+Jhf*qV`}Z#Jwt2p#?<
zBok#abOKJ1HP8%IC(y)0@;-GGBdlLMFo4V!9gbeD&zM`~mQ<5<(YT2PI@KBF=`*y>
zyjB7JqM8B@PwLB3LNUSDcZ9rLzHdG}w1tczODzs=JQvd;od>%hD#3*o;rf_QH8vOnp0J%W3DSDfcae
zM1h9E`9VPaJZ|u(XCTgjf`%f4TyIJL(N8}+_~*poL&W)69!@Tp6aR`ozZ?BC0zK&b
zG#dJs&W{=Mzl=Rh$)DxH*hBf-iHhIt{duP1LHMUVn!l_4>x9Lh5dC>(;FoqF8@yAlw%u-25+v-%+Y2`CEMYbD)0)
zvIjdqQJVU@+JA(#Kl}NU>HO8tJ%pC|C*JeV9{yxd5+5Oxw`_wTU%uR%W~-+z_|4`=-J@NcR3
m-$(vuGX6pLr`HDlL-$u|URmzZkI9M&IR%3Nk$Xq>p!a`EfKZ$O
literal 0
HcmV?d00001
diff --git a/src/com/bonus/lease/controller/ReceiveDetailsController.java b/src/com/bonus/lease/controller/ReceiveDetailsController.java
index 6afc8d6..a8643ed 100644
--- a/src/com/bonus/lease/controller/ReceiveDetailsController.java
+++ b/src/com/bonus/lease/controller/ReceiveDetailsController.java
@@ -1,28 +1,46 @@
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.HashMap;
import java.util.List;
import java.util.Map;
+import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
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.core.io.ClassPathResource;
+import org.springframework.core.io.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.bonus.lease.beans.OutStorageBean;
import com.bonus.lease.beans.ReceiveDetailsBean;
import com.bonus.lease.service.OutStorageService;
import com.bonus.lease.service.ReceiveDetailsService;
-import com.bonus.sys.AjaxRes;
-import com.bonus.sys.BaseController;
-import com.bonus.sys.GlobalConst;
-import com.bonus.sys.Page;
+import org.springframework.web.multipart.MultipartFile;
@Controller
@RequestMapping("/backstage/receiveDetails/")
@@ -447,4 +465,315 @@ public class ReceiveDetailsController extends BaseController
// list.add("是否确认");
// 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 importData(@RequestParam("importFile") MultipartFile importFile,
+ String taskId,
+ String token,
+ HttpSession session) {
+ Map result = new HashMap<>();
+ List errorMsgList = new ArrayList<>();
+ Map existTypeModelMap = new HashMap<>();
+ List 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 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;
+ }
}
diff --git a/src/com/bonus/lease/dao/ReceiveDetailsDao.java b/src/com/bonus/lease/dao/ReceiveDetailsDao.java
index be4c5bb..e89da60 100644
--- a/src/com/bonus/lease/dao/ReceiveDetailsDao.java
+++ b/src/com/bonus/lease/dao/ReceiveDetailsDao.java
@@ -50,4 +50,17 @@ public interface ReceiveDetailsDao extends BaseDao {
public int batchDeletion(ReceiveDetailsBean o);
+ /**
+ * 根据物资名称和规格型号查询物资
+ * @param bean
+ * @return
+ */
+ ReceiveDetailsBean getMaTypeByNameAndModel(ReceiveDetailsBean bean);
+
+ /**
+ * 根据用户名查询用户
+ * @param bean
+ * @return
+ */
+ ReceiveDetailsBean getUserByUserName(ReceiveDetailsBean bean);
}
diff --git a/src/com/bonus/lease/service/ReceiveDetailsService.java b/src/com/bonus/lease/service/ReceiveDetailsService.java
index eacb1c1..372935e 100644
--- a/src/com/bonus/lease/service/ReceiveDetailsService.java
+++ b/src/com/bonus/lease/service/ReceiveDetailsService.java
@@ -36,4 +36,26 @@ public interface ReceiveDetailsService extends BaseService {
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 dataList, String taskId);
}
diff --git a/src/com/bonus/lease/service/ReceiveDetailsServiceImp.java b/src/com/bonus/lease/service/ReceiveDetailsServiceImp.java
index 9a000c3..bd7ab00 100644
--- a/src/com/bonus/lease/service/ReceiveDetailsServiceImp.java
+++ b/src/com/bonus/lease/service/ReceiveDetailsServiceImp.java
@@ -2,6 +2,7 @@ package com.bonus.lease.service;
import java.util.List;
+import com.google.protobuf.ServiceException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
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.wf.beans.TaskRecordBean;
import com.bonus.wf.dao.TaskRecordDao;
+import org.springframework.transaction.interceptor.TransactionAspectSupport;
@Service("receiveDetails")
public class ReceiveDetailsServiceImp extends BaseServiceImp implements ReceiveDetailsService {
@@ -233,4 +235,43 @@ public class ReceiveDetailsServiceImp extends BaseServiceImp
}
}
+ @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 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;
+ }
+ }
+
}