ThOcrServiceImpl.java 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964
  1. package nc.impl.th;
  2. import java.io.BufferedOutputStream;
  3. import java.io.BufferedReader;
  4. import java.io.ByteArrayOutputStream;
  5. import java.io.DataOutputStream;
  6. import java.io.File;
  7. import java.io.FileInputStream;
  8. import java.io.FileNotFoundException;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. import java.io.InputStreamReader;
  12. import java.io.OutputStreamWriter;
  13. import java.net.HttpURLConnection;
  14. import java.net.URL;
  15. import java.text.SimpleDateFormat;
  16. import java.util.ArrayList;
  17. import java.util.Date;
  18. import java.util.HashMap;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.UUID;
  22. import java.io.FileOutputStream;
  23. import nc.bs.dao.BaseDAO;
  24. import nc.bs.dao.DAOException;
  25. import nc.bs.framework.common.InvocationInfoProxy;
  26. import nc.bs.framework.common.NCLocator;
  27. import nc.bs.framework.common.RuntimeEnv;
  28. import nc.itf.uap.IUAPQueryBS;
  29. import nc.jdbc.framework.processor.ArrayListProcessor;
  30. import nc.jdbc.framework.processor.BeanListProcessor;
  31. import nc.jdbc.framework.processor.ColumnProcessor;
  32. import nc.jdbc.framework.processor.MapProcessor;
  33. import nc.log.NcLog;
  34. import nc.vo.bd.defdoc.DefdocVO;
  35. import nc.vo.pu.m25.entity.InvoiceItemVO;
  36. import nc.vo.pu.m25.entity.InvoiceVO;
  37. import nc.vo.pub.BusinessException;
  38. import nc.bs.pub.filesystem.IFileSystemService;
  39. import nc.itf.uap.IVOPersistence;
  40. import org.apache.commons.codec.digest.DigestUtils;
  41. import org.apache.commons.httpclient.HttpClient;
  42. import org.apache.commons.httpclient.methods.PostMethod;
  43. import org.apache.commons.httpclient.methods.RequestEntity;
  44. import org.apache.commons.httpclient.methods.StringRequestEntity;
  45. import org.bouncycastle.jce.provider.symmetric.Skipjack.Mac;
  46. import com.alibaba.fastjson.JSONArray;
  47. import com.alibaba.fastjson.JSONObject;
  48. import nc.itf.bd.defdoc.IDefdocService;
  49. import nc.itf.th.IThOcrService;
  50. import nc.pub.toolkits.Toolkits;
  51. import nc.th.redistoken.RedisTokenManager;
  52. import nc.vo.pub.filesystem.NCFileNode;
  53. import nc.vo.pub.lang.UFDouble;
  54. import nc.vo.pubapp.pattern.pub.SqlBuilder;
  55. import nc.vo.th.ocr.OCRInvoiceVO;
  56. import weaver.fna.invoice.utils.InvoiceCloudAESUtil;
  57. /**
  58. * OCR接口实现
  59. * @author Administrator
  60. *
  61. */
  62. public class ThOcrServiceImpl implements IThOcrService{
  63. private IVOPersistence IVOPersistence = (IVOPersistence) NCLocator.getInstance().lookup(IVOPersistence.class);
  64. private IUAPQueryBS iuap=(IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName());
  65. private String aesKey = "w34xx413y2x23w4y";
  66. private static String appId="1438490100786012161";
  67. private static String secret="80c8664aa7a444049b8ed49ed5095561";
  68. private static String cid="1438490101547343873";
  69. private String upurl="https://up.mypiaojia.com/api/invoiceApi/file/uploadFileSpilit";
  70. private String inverurl="https://api.mypiaojia.com/api/invoiceApi/invoice/ocr";
  71. //发票验伪地址
  72. private String person_local_valid = "https://api.mypiaojia.com/api/invoiceApi/invoice/person_local_valid";
  73. //发票锁定地址
  74. private String ec_comm = "https://api.mypiaojia.com/api/invoiceApi/invoice/ec_comm";
  75. //获取token地址
  76. private String buildToken="https://api.mypiaojia.com/api/invoiceApi/token/buildToken";
  77. //获取发票云发票地址
  78. private String sync_rt = "https://api.mypiaojia.com/api/invoiceApi/invoice/sync_rt";
  79. public String[] insert(ArrayList<?> arrlist) throws BusinessException {
  80. return this.IVOPersistence.insertVOList(arrlist);
  81. }
  82. @Override
  83. /**
  84. * 获取token
  85. */
  86. public String getToken(String billmaker) throws Exception {
  87. NcLog.info("=======获取token开始=======");
  88. //redis中获取用户token
  89. String userToken ="";
  90. try {
  91. userToken = RedisTokenManager.getToken(billmaker);
  92. }catch(Exception e){
  93. // Redis 连接异常,执行相应的异常处理操作
  94. e.printStackTrace();
  95. throw new Exception(e.getMessage()+"请检查redis服务器是否启动!");
  96. }
  97. //token为空
  98. if(Toolkits.isEmpty(userToken)){
  99. //调用OCR接口
  100. userToken=getOcrToken(billmaker);
  101. //保存到redis,设置失效时间36000秒
  102. RedisTokenManager.setTokenTTL(billmaker,36000, userToken);
  103. }
  104. NcLog.info("=======token======="+userToken);
  105. NcLog.info("=======获取token结束=======");
  106. return userToken;
  107. }
  108. /**
  109. * 上传发票
  110. * @throws Exception
  111. */
  112. public String uploadInvoice(String token,String vdef17,String invoicename) throws Exception {
  113. NcLog.info("=======上传发票开始=======");
  114. File file=new File(RuntimeEnv.getInstance().getNCHome()
  115. +File.separator +"uploadfile" + File.separator+ vdef17+File.separator+invoicename);
  116. String resmsg=httpFilePost(upurl,token,file);
  117. String id="";
  118. if(null!=resmsg&&resmsg.indexOf("uploading")!=-1){
  119. JSONObject json = JSONObject.parseObject(resmsg);
  120. JSONObject data=json.getJSONObject("data");
  121. if(null!=data){
  122. id=data.getString("id");
  123. }else{
  124. throw new Exception(json.toString());
  125. }
  126. }
  127. return resmsg;
  128. }
  129. /**
  130. * OCR识别
  131. * @throws Exception
  132. */
  133. @Override
  134. public String ocrIdentification(String token,String data) throws Exception {
  135. // TODO 自动生成的方法存根
  136. NcLog.info("=======发票OCR识别开始=======");
  137. JSONObject jsondata = JSONObject.parseObject(data);
  138. JSONObject jsonobject = new JSONObject();
  139. jsonobject.put("image_index", jsondata.getJSONObject("data").getString("id"));
  140. jsonobject.put("fileTypeStr", jsondata.getJSONObject("data").getString("fileType"));
  141. jsonobject.put("flag", "13");
  142. jsonobject.put("is_save", "0");
  143. jsonobject.put("is_sync", "1");
  144. jsonobject.put("ocrMap","");
  145. jsonobject.put("operate_type",0);
  146. String json = doPost(inverurl,token,jsonobject.toString());
  147. NcLog.info("发票OCR识别返回json"+json);
  148. return json;
  149. }
  150. @Override
  151. public void InvoiceCheck(String token,String fid)
  152. throws Exception {
  153. NcLog.info("=======发票查验识别开始=======");
  154. JSONObject jsonobject = new JSONObject();
  155. jsonobject.put("id", fid);
  156. jsonobject.put("fid", fid);
  157. jsonobject.put("ic_cut", "0");
  158. jsonobject.put("operate_type","0");
  159. JSONObject req_base = new JSONObject();
  160. req_base.put("trace", fid);
  161. req_base.put("dev", "1");
  162. jsonobject.put("req_base",req_base);
  163. JSONObject json = JSONObject.parseObject(doPost(person_local_valid,token,jsonobject.toString()));
  164. NcLog.info("发票查验返回json"+json);
  165. JSONObject data=json.getJSONObject("data");
  166. if(data == null) {
  167. String msg=json.getJSONObject("actionMsg").getString("message");
  168. throw new Exception(msg);
  169. }
  170. }
  171. /**
  172. * OCR识别数据保存数据库
  173. * @throws BusinessException
  174. */
  175. public void insertOCRdataInfo(ArrayList<OCRInvoiceVO> vos) throws BusinessException {
  176. insert(vos);
  177. }
  178. public String getOcrToken(String userid) throws Exception{
  179. HttpClient httpClient = new HttpClient();
  180. httpClient.getHttpConnectionManager().getParams().setConnectionTimeout(5000);
  181. httpClient.getHttpConnectionManager().getParams().setSoTimeout(5000);
  182. PostMethod postMethod = new PostMethod(buildToken);
  183. postMethod.setRequestHeader("content-type", "application/json");
  184. postMethod.setRequestHeader("appkey", appId);
  185. Map<String,String> oamap = QueryOAUserid(userid);
  186. long l = System.currentTimeMillis();
  187. Map<String, Object> map = new HashMap<String, Object>();
  188. map.put("role", 1);
  189. map.put("name", oamap.get("lastname"));
  190. map.put("userId", oamap.get("id"));//OA用户体系的用户id 2108
  191. map.put("cid", cid);
  192. String s1 = JSONObject.toJSONString(map);
  193. String s2 = s1 + "&time=" + l + "&secret="+secret;
  194. byte[] requestBodyBytes = s2.getBytes("UTF-8");
  195. String newMd5 = DigestUtils.md5Hex(requestBodyBytes);
  196. String s4 = s1 + "&time=" + l + "&md5=" + newMd5;
  197. RequestEntity entity = new StringRequestEntity (s4 ,"application/json" ,"UTF-8");
  198. postMethod.setRequestEntity(entity);
  199. httpClient.executeMethod(postMethod);
  200. String responseMsg = postMethod.getResponseBodyAsString().trim();
  201. //返回结果{"data":"WEAPPe8Ke9pFzz9fbZ3qCcN6itq1zLHCKOgPmXHz6uIg8eOg","actionMsg":{"code":0,"message":"执行成功"}}
  202. // System.out.println("返回结果"+ responseMsg);
  203. JSONObject json = JSONObject.parseObject(responseMsg);
  204. String token=json.getString("data");
  205. String status=json.getString("status");
  206. //保存token返回值到日志文件里
  207. NcLog.info("token:"+token);
  208. if(token == null){
  209. throw new BusinessException(responseMsg);
  210. }
  211. return token;
  212. }
  213. public String httpFilePost(String uploadUrl,String token, File file) throws Exception {
  214. //File file = new File(file);
  215. String LINEND = "\r\n";
  216. String boundary = UUID.randomUUID().toString();
  217. FileInputStream fileInputStream = new FileInputStream(file);
  218. URL url = new URL(uploadUrl);
  219. HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
  220. httpURLConnection.setDoInput(true);
  221. httpURLConnection.setUseCaches(false);
  222. httpURLConnection.setDoOutput(true);
  223. httpURLConnection.setRequestMethod("POST");
  224. httpURLConnection.setRequestProperty("connection", "keep-alive");
  225. httpURLConnection.setRequestProperty("Charsert", "UTF-8");
  226. httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
  227. httpURLConnection.setRequestProperty("token", token);
  228. httpURLConnection.setRequestProperty("Accept","*/*");
  229. DataOutputStream outStream = new DataOutputStream(httpURLConnection.getOutputStream());
  230. StringBuilder stringBuilder = new StringBuilder();
  231. stringBuilder.append("--").append(boundary).append(LINEND);
  232. stringBuilder.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + LINEND);
  233. stringBuilder.append("Content-Type: " + HttpURLConnection.guessContentTypeFromName(file.getName()) + LINEND);
  234. stringBuilder.append("Content-Transfer-Encoding: binary"+ LINEND);
  235. stringBuilder.append(LINEND);
  236. // outStream.write(stringBuilder.toString().getBytes());
  237. outStream.writeUTF(stringBuilder.toString());
  238. InputStream is = new FileInputStream(file);
  239. byte[] buffer = new byte[1024];
  240. int len = 0;
  241. while ((len = is.read(buffer)) != -1){
  242. outStream.write(buffer, 0, len);
  243. }
  244. is.close();
  245. outStream.write(LINEND.getBytes());
  246. byte[] end_data = ("--" + boundary + "--" + LINEND).getBytes();
  247. outStream.write(end_data);
  248. outStream.flush();
  249. fileInputStream.close();
  250. String response = readStream(httpURLConnection.getInputStream());
  251. outStream.close();
  252. httpURLConnection.disconnect();
  253. NcLog.info("发票上传返回json:"+response);
  254. return response;
  255. }
  256. private String readStream(InputStream inputStream) throws IOException {
  257. ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
  258. byte[] buffer = new byte[1024];
  259. int bytesRead;
  260. while ((bytesRead = inputStream.read(buffer)) != -1) {
  261. outputStream.write(buffer, 0, bytesRead);
  262. }
  263. byte[] bytes = outputStream.toByteArray();
  264. String result = new String(bytes, "UTF-8");
  265. outputStream.close();
  266. return result;
  267. }
  268. public String doPost(String pathUrl, String token,String data) throws Exception{
  269. OutputStreamWriter out = null;
  270. BufferedReader br = null;
  271. String result = "";
  272. try {
  273. URL url = new URL(pathUrl);
  274. //打开和url之间的连接
  275. HttpURLConnection conn = (HttpURLConnection) url.openConnection();
  276. //设定请求的方法为"POST",默认是GET
  277. //post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内。
  278. conn.setRequestMethod("POST");
  279. //设置30秒连接超时
  280. conn.setConnectTimeout(30000);
  281. //设置30秒读取超时
  282. conn.setReadTimeout(30000);
  283. // 设置是否向httpUrlConnection输出,因为这个是post请求,参数要放在http正文内,因此需要设为true, 默认情况下是false;
  284. conn.setDoOutput(true);
  285. // 设置是否从httpUrlConnection读入,默认情况下是true;
  286. conn.setDoInput(true);
  287. // Post请求不能使用缓存
  288. conn.setUseCaches(false);
  289. //设置通用的请求属性
  290. conn.setRequestProperty("accept", "*/*");
  291. conn.setRequestProperty("connection", "Keep-Alive"); //维持长链接
  292. conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
  293. conn.setRequestProperty("token", token);
  294. //连接,从上述url.openConnection()至此的配置必须要在connect之前完成,
  295. conn.connect();
  296. /**
  297. * 下面的三句代码,就是调用第三方http接口
  298. */
  299. //获取URLConnection对象对应的输出流
  300. //此处getOutputStream会隐含的进行connect(即:如同调用上面的connect()方法,所以在开发中不调用上述的connect()也可以)。
  301. out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
  302. //发送请求参数即数据
  303. out.write(data);
  304. //flush输出流的缓冲
  305. out.flush();
  306. /**
  307. * 下面的代码相当于,获取调用第三方http接口后返回的结果
  308. */
  309. //获取URLConnection对象对应的输入流
  310. InputStream is = conn.getInputStream();
  311. //构造一个字符流缓存
  312. br = new BufferedReader(new InputStreamReader(is,"UTF-8"));
  313. String str = "";
  314. while ((str = br.readLine()) != null){
  315. result += str;
  316. }
  317. // System.out.println(result);
  318. /* JSONObject json = JSONObject.parseObject(result);
  319. //获取主要数据
  320. JSONObject datajson = json.getJSONObject("data");
  321. System.out.println("datajson===="+datajson.toString());
  322. JSONArray infosjson = datajson.getJSONArray("infos");
  323. System.out.println("infosjson===="+infosjson.toString());
  324. for (Object infos : infosjson) {
  325. JSONObject infosObject =(JSONObject)infos;
  326. String total=infosObject.getJSONObject("info").getJSONObject("comm_info").getJSONObject("price").getString("total");
  327. System.out.println("total===="+total);
  328. }*/
  329. //关闭流
  330. is.close();
  331. //断开连接,disconnect是在底层tcp socket链接空闲时才切断,如果正在被其他线程使用就不切断。
  332. conn.disconnect();
  333. }catch (Exception e) {
  334. throw new Exception(e);
  335. }finally {
  336. try {
  337. if (out != null){
  338. out.close();
  339. }
  340. if (br != null){
  341. br.close();
  342. }
  343. } catch (IOException e) {
  344. throw new Exception(e);
  345. }
  346. }
  347. return result;
  348. }
  349. /**
  350. *
  351. * 发票保存到文件夹里
  352. * vdef17 发票主键
  353. * fileName 发票名
  354. * file 选中的发票
  355. * @throws IOException
  356. */
  357. public String saveUploadFile(String vdef17,String fileName,byte[] bytes) throws Exception {
  358. /* NcLog.info("=====发票保存开始=====");
  359. String filepath = RuntimeEnv.getInstance().getNCHome()
  360. +File.separator +"uploadfile" + File.separator+ vdef17; // 文件保存的路径
  361. NcLog.info("文件保存的路径:"+filepath);
  362. NcLog.info("原文件路径:"+file.getPath());
  363. File folder = new File(filepath);
  364. if(!folder.exists() && !folder.isDirectory()){
  365. folder.mkdirs();
  366. }
  367. String newFileName = filepath + File.separator + fileName;
  368. NcLog.info("文件保存新路径:"+newFileName);
  369. FileOutputStream outputStream = new FileOutputStream(newFileName);
  370. NcLog.info("=====FileOutputStream=====");
  371. FileInputStream fis = new FileInputStream(file);
  372. byte[] buffer = new byte[1024];
  373. int len;
  374. NcLog.info("=====读取发票信息开始=====");
  375. while ((len = fis.read(buffer)) != -1) {
  376. outputStream.write(buffer, 0, len);
  377. }
  378. NcLog.info("=====读取发票信息结束=====");
  379. outputStream.close();
  380. fis.close();
  381. NcLog.info("=====发票保存结束=====");*/
  382. // byte[] bs = Base64.decode(file.trim());
  383. NcLog.info("=====发票保存开始=====");
  384. // NcLog.info("=====bytes:"+bytes.length+"=====");
  385. String filepath = RuntimeEnv.getInstance().getNCHome()
  386. +File.separator +"uploadfile" + File.separator+ vdef17; // 文件保存的文件夹
  387. String newFileName = filepath + File.separator + fileName;
  388. NcLog.info("文件保存新路径:"+newFileName);
  389. String savefilepath=SaveTempFile(filepath,newFileName,bytes);
  390. // Upload(vdef17,savefilepath,newFileName,InvocationInfoProxy.getInstance().getUserId());
  391. return savefilepath;
  392. }
  393. /**
  394. * 保存文件
  395. *
  396. * @param filepath 文件夹路径
  397. * @param fileName 文件名路径
  398. * @param bs 文件流
  399. * @return 返回文件保存的路径
  400. * @throws Exception
  401. */
  402. public String SaveTempFile(String filepath,String fileName,byte[] bytes) throws Exception {
  403. FileOutputStream fos = null;
  404. BufferedOutputStream bos=null;
  405. try {
  406. File folder = new File(filepath);
  407. if(!folder.exists() && !folder.isDirectory()){
  408. folder.mkdirs();
  409. }
  410. fos = new FileOutputStream(fileName);
  411. bos = new BufferedOutputStream(fos);
  412. bos.write(bytes);
  413. } catch (FileNotFoundException e1) {
  414. // TODO 自动生成的 catch 块
  415. e1.printStackTrace();
  416. NcLog.info("保存发票FileNotFoundException异常:"+e1.getMessage());
  417. throw new Exception("保存发票FileNotFoundException异常:"+e1.getMessage());
  418. } catch (IOException e) {
  419. // TODO 自动生成的 catch 块
  420. e.printStackTrace();
  421. NcLog.info("保存发票IOException异常:"+e.getMessage());
  422. throw new Exception("保存发票IOException异常:"+e.getMessage());
  423. }finally {
  424. if (bos != null) {
  425. try {
  426. bos.close();
  427. } catch (IOException e) {
  428. e.printStackTrace();
  429. NcLog.info("关闭bos流异常:"+e.getMessage());
  430. throw new Exception("关闭bos流异常:"+e.getMessage());
  431. }
  432. }
  433. }
  434. if (fos != null) {
  435. try {
  436. fos.close();
  437. } catch (IOException e) {
  438. e.printStackTrace();
  439. NcLog.info("关闭fos流异常:"+e.getMessage());
  440. throw new Exception("关闭fos流异常:"+e.getMessage());
  441. }
  442. }
  443. return filepath;
  444. }
  445. /**
  446. * NC文件上传
  447. * @param parentPath 单据主键pk_jkbx
  448. * @param newFile 文件路径
  449. * @param filename 文件名
  450. * @param user_code 创建人
  451. * @return 0表示上传成功,-1表示失败
  452. * @throws BusinessException
  453. * @throws IOException
  454. */
  455. public int Upload(String parentPath, String filepath, String filename,String user_code) throws BusinessException, IOException {
  456. NcLog.info("============防止重复上传相同名称的附件开始============");
  457. QueryFile(parentPath, filename);
  458. NcLog.info("============防止重复上传相同名称的附件结束============");
  459. File file = new File(filepath);
  460. NcLog.info("文件路径file:"+file.getPath());
  461. Long fileLen = file.length();
  462. String creator = user_code;
  463. NCFileNode node = null;
  464. InputStream fileinput = null;
  465. try {
  466. fileinput = new FileInputStream(file);
  467. NcLog.info("FileInputStream:"+fileinput);
  468. IFileSystemService service = (IFileSystemService) NCLocator
  469. .getInstance().lookup(IFileSystemService.class);
  470. NcLog.info("接口service开始:"+service);
  471. node = service.createNewFileNodeWithStream(parentPath, filename,
  472. creator, fileinput, fileLen);
  473. NcLog.info("接口service结束:"+node);
  474. } catch (FileNotFoundException e) {
  475. e.printStackTrace();
  476. NcLog.info("FileNotFoundException保存失败:"+e.getMessage());
  477. throw new FileNotFoundException();
  478. } catch (IOException e) {
  479. e.printStackTrace();
  480. NcLog.info("IOException保存失败:"+e.getMessage());
  481. throw new IOException();
  482. } catch (BusinessException e) {
  483. e.printStackTrace();
  484. NcLog.info("BusinessException保存失败:"+e.getMessage());
  485. throw new BusinessException();
  486. } finally {
  487. try {
  488. fileinput.close();
  489. } catch (IOException e) {
  490. e.printStackTrace();
  491. }
  492. }
  493. if (node == null) {
  494. NcLog.info("-1表示失败:"+"【"+-1+"】");
  495. return -1;
  496. }
  497. NcLog.info("0表示上传成功:"+"【"+0+"】");
  498. return 0;
  499. }
  500. /**
  501. * 防止重复上传相同名称的附件
  502. *
  503. * @param parentPath
  504. * 单据主键
  505. * @param filename
  506. * 文件名
  507. * @throws BusinessException
  508. */
  509. public void QueryFile(String parentPath, String filename) throws BusinessException {
  510. try {
  511. String path = parentPath + "/" + filename;
  512. IUAPQueryBS iuap= (IUAPQueryBS) NCLocator.getInstance().lookup(IUAPQueryBS.class.getName());
  513. String sql = "select filepath from sm_pub_filesystem where filepath = '"
  514. + path + "'";
  515. @SuppressWarnings("unchecked")
  516. List<Object[]> filelist = (List<Object[]>) iuap.executeQuery(sql,
  517. new ArrayListProcessor());
  518. if (filelist != null && filelist.size() > 0) {// 如果有附件,则先删除
  519. IFileSystemService service = (IFileSystemService) NCLocator
  520. .getInstance().lookup(IFileSystemService.class);
  521. String[] arg = new String[] { path };
  522. service.deleteNCFileNodes(arg);
  523. }
  524. } catch (DAOException e) {
  525. e.printStackTrace();
  526. NcLog.info("=====DAOException防止重复上传相同名称的附件====="+e.getMessage());
  527. throw new DAOException();
  528. } catch (BusinessException e) {
  529. e.printStackTrace();
  530. NcLog.info("=====BusinessException防止重复上传相同名称的附件====="+e.getMessage());
  531. throw new BusinessException();
  532. }
  533. }
  534. /**
  535. * 获取home路径
  536. */
  537. public String getNCHomePath() {
  538. return RuntimeEnv.getInstance().getNCHome();
  539. }
  540. /**
  541. * 删除home里对应的发票
  542. */
  543. public Boolean deleteFile(String filepath) {
  544. NcLog.info("=====删除home里对应的发票开始=====");
  545. //删除home发票文件夹里的对应发票 add by ZTH
  546. String deletefilepath = RuntimeEnv.getInstance().getNCHome()
  547. +File.separator +"uploadfile" + File.separator+ filepath; // 文件保存的路径
  548. File file = new File(deletefilepath);
  549. Boolean bo= file.delete();
  550. NcLog.info("=====删除home里对应的发票结束=====");
  551. return bo;
  552. }
  553. /**
  554. * 由于删除太慢,改成自定义档案数据停用
  555. * @throws BusinessException
  556. */
  557. public DefdocVO[] enablestateDate(String filepath,String[] filname) throws BusinessException {
  558. NcLog.info("=====改成自定义档案数据停用开始=====");
  559. DefdocVO[] deletevos=QryDefdocvoInfo(filname[1]);
  560. IDefdocService idefservice = NCLocator.getInstance().lookup(IDefdocService.class);
  561. DefdocVO defvo =deletevos[0];
  562. defvo.setAttributeValue("enablestate", 3);//停用
  563. DefdocVO[] defdocVOs= idefservice.updateDefdocs(InvocationInfoProxy.getInstance().getGroupId(),deletevos);
  564. NcLog.info("=====改成自定义档案数据停用结束=====");
  565. return defdocVOs;
  566. }
  567. private DefdocVO[] QryDefdocvoInfo(String name){
  568. String sql = "select * from bd_defdoc where nvl(dr, 0) = 0 and pk_defdoclist="
  569. + "(select pk_defdoclist from bd_defdoclist where code='OCRTHNC' and nvl(dr,0)=0) and memo='" + name + "' ";
  570. ArrayList<Object> arrayvos=null;
  571. try {
  572. arrayvos=(ArrayList<Object>) iuap.executeQuery(sql, new BeanListProcessor(DefdocVO.class));
  573. } catch (BusinessException e) {
  574. // TODO 自动生成的 catch 块
  575. e.printStackTrace();
  576. }
  577. if (arrayvos==null) {
  578. return new DefdocVO[0];
  579. }else {
  580. return arrayvos.toArray(new DefdocVO[0]);
  581. }
  582. }
  583. /**
  584. * 获取"+vdef17+"文件夹下所有发票名
  585. */
  586. public List<String> getInvoiceInfo(String vdef17) {
  587. String filepath = RuntimeEnv.getInstance().getNCHome()
  588. +File.separator +"uploadfile" + File.separator+ vdef17; // 文件保存的路径
  589. List<String> filewjlis=getFileNames(filepath);
  590. return filewjlis;
  591. }
  592. /**
  593. * 得到文件名称
  594. *
  595. * @param path 路径
  596. * @return {@link List}<{@link String}>
  597. */
  598. private List<String> getFileNames(String path) {
  599. File file = new File(path);
  600. if (!file.exists()) {
  601. return null;
  602. }
  603. List<String> fileNames = new ArrayList<String>();
  604. return getFileNames(file, fileNames);
  605. }
  606. /**
  607. * 得到文件名称
  608. *
  609. * @param file 文件
  610. * @param fileNames 文件名
  611. * @return {@link List}<{@link String}>
  612. */
  613. private List<String> getFileNames(File file, List<String> fileNames) {
  614. File[] files = file.listFiles();
  615. for (File f : files) {
  616. if (f.isDirectory()) {
  617. getFileNames(f, fileNames);
  618. } else {
  619. fileNames.add(f.getName());
  620. }
  621. }
  622. return fileNames;
  623. }
  624. @Override
  625. public void UpdateInvoiceStatus(String status, InvoiceVO[] vos) throws Exception {
  626. //T提交——1 S收回——0 //Y审批通过——2 //R驳回
  627. for (InvoiceVO invoiceVO : vos) {
  628. //没有发票不传发票云
  629. if(invoiceVO.getParentVO().getVdef17() == null) {
  630. continue;
  631. }
  632. NcLog.info("=======锁定发票、修改开始=======");
  633. Map<String,String> oamap = QueryOAUserid(invoiceVO.getParent().getAttributeValue("billmaker").toString());
  634. InvoiceItemVO[] arrInvoiceItemVO = (InvoiceItemVO[]) invoiceVO.getChildren(InvoiceItemVO.class);
  635. List<Map<Object, Object>> listMapVbdef20 = new ArrayList<Map<Object, Object>>();
  636. List<String> listVbdef20 = new ArrayList<String>();
  637. for (InvoiceItemVO invoiceItemVO : arrInvoiceItemVO) {
  638. if(invoiceItemVO.getVbdef20() != null && !"".equals(invoiceItemVO.getVbdef20())) {
  639. String[] arrVbdef20 = invoiceItemVO.getVbdef20().split(",");
  640. for(String Vbdef20 : arrVbdef20) {
  641. //当前单据该发票价税合计,无税金额,税额
  642. UFDouble norigtaxmny = invoiceItemVO.getNorigtaxmny();
  643. UFDouble norigmny = invoiceItemVO.getNorigmny();
  644. UFDouble ntax = invoiceItemVO.getNtax();
  645. StringBuffer sql1 = new StringBuffer();
  646. sql1.append("SELECT");
  647. sql1.append(" shortname2,");
  648. sql1.append(" shortname,");
  649. sql1.append(" shortname3");
  650. sql1.append(" FROM");
  651. sql1.append(" bd_defdoc");
  652. sql1.append(" WHERE");
  653. sql1.append(" pk_defdoc = '"+Vbdef20+"'");
  654. Map<String,String> mapdb = (Map<String, String>) iuap.executeQuery(sql1.toString(), new MapProcessor());
  655. //该发票价税合计
  656. UFDouble shortname2 = new UFDouble(mapdb.get("shortname2"));
  657. //该发票无税金额
  658. UFDouble shortname = new UFDouble(mapdb.get("shortname"));
  659. //该发票税额
  660. UFDouble shortname3 = new UFDouble(mapdb.get("shortname3"));
  661. //审批的情况下
  662. if("Y".equals(status)){
  663. int index = invoiceItemVO.getVbdef16().indexOf("—");
  664. //去掉拼接时间戳
  665. String code = index == -1 ? invoiceItemVO.getVbdef16() : invoiceItemVO.getVbdef16().substring(0, index);
  666. //查询该发票已使用价税合计,无税金额,税额
  667. StringBuffer sql = new StringBuffer();
  668. sql.append("SELECT");
  669. sql.append(" SUM( po_invoice_b.norigtaxmny ) as norigtaxmny,");
  670. sql.append(" SUM( po_invoice_b.norigmny ) as norigmny,");
  671. sql.append(" SUM( po_invoice_b.ntax ) as ntax");
  672. sql.append(" FROM");
  673. sql.append(" po_invoice po_invoice");
  674. sql.append(" LEFT JOIN po_invoice_b po_invoice_b ON po_invoice.pk_invoice = po_invoice_b.pk_invoice ");
  675. sql.append(" WHERE");
  676. sql.append(" po_invoice.fbillstatus <> '0' ");
  677. sql.append(" AND po_invoice.fbillstatus <> '1' ");
  678. sql.append(" AND po_invoice.vbillcode <> '"+invoiceVO.getParentVO().getVbillcode()+"'");
  679. sql.append(" AND po_invoice_b.vbdef20 IN ( SELECT pk_defdoc FROM bd_defdoc WHERE code LIKE '"+code+"%' )");
  680. sql.append(" AND nvl(po_invoice.dr,0) = 0");
  681. sql.append(" AND nvl(po_invoice_b.dr,0) = 0");
  682. Map<String,String> mappo = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
  683. //价税合计
  684. Object objectNorigtaxmny = mappo.get("norigtaxmny");
  685. //无税金额
  686. Object objectNorigmny = mappo.get("norigmny");
  687. //税额
  688. Object objectNtax = mappo.get("ntax");
  689. UFDouble sumNorigtaxmny = new UFDouble(objectNorigtaxmny == null ? 0.00 : Double.valueOf(objectNorigtaxmny.toString()));
  690. UFDouble sumNorigmny = new UFDouble(objectNorigmny == null ? 0.00 : Double.valueOf(objectNorigmny.toString()));
  691. UFDouble sumNtax = new UFDouble(objectNtax == null ? 0.00 : Double.valueOf(objectNtax.toString()));
  692. if(sumNorigtaxmny.add(norigtaxmny).compareTo(shortname2)>0) {
  693. throw new Exception("行:"+invoiceItemVO.getCrowno()+"发票可用余额不足!差:"+(sumNorigtaxmny.add(norigtaxmny)).sub(shortname2));
  694. }
  695. if(sumNorigmny.add(norigmny).compareTo(shortname)>0) {
  696. throw new Exception("行:"+invoiceItemVO.getCrowno()+"无税金额大于发票可用金额!差:"+(sumNorigmny.add(norigmny)).sub(shortname));
  697. }
  698. if(sumNtax.add(ntax).compareTo(shortname3)>0) {
  699. throw new Exception("行:"+invoiceItemVO.getCrowno()+"税额大于发票可用税额!差:"+(sumNtax.add(ntax)).sub(shortname3));
  700. }
  701. }
  702. StringBuffer sql2 = new StringBuffer();
  703. sql2.append("SELECT");
  704. sql2.append(" name5");
  705. sql2.append(" FROM");
  706. sql2.append(" bd_defdoc ");
  707. sql2.append(" WHERE");
  708. sql2.append(" pk_defdoc = '"+Vbdef20+"'");
  709. String name5 = (String) iuap.executeQuery(sql2.toString(), new ColumnProcessor());
  710. Map<Object, Object> map = new HashMap<Object, Object>();
  711. map.put("norigtaxmny", norigtaxmny.toString());
  712. map.put("name5",name5);
  713. listMapVbdef20.add(map);
  714. listVbdef20.add(name5);
  715. }
  716. }
  717. }
  718. if(listMapVbdef20.size() > 0) {
  719. JSONObject bodyJson = new JSONObject();
  720. //发票云团队id
  721. bodyJson.put("cid", cid);
  722. //userId报销人id(OA)
  723. bodyJson.put("userId", oamap.get("id"));
  724. //userId报销人id(OA)
  725. bodyJson.put("flag", "3");
  726. //发票云发票ID数组
  727. bodyJson.put("fids", listVbdef20.toArray());
  728. NcLog.info("发票锁定返回json:"+UpdateInvoiceOCR(bodyJson.toString()));
  729. //0 未报销 1 报销中 2已报销
  730. String sreim = "0";
  731. if("Y".equals(status)) {
  732. sreim = "2";
  733. }else if("T".equals(status)) {
  734. sreim = "1";
  735. }
  736. JSONObject bodyJson1 = new JSONObject();
  737. bodyJson1.put("cid", cid);
  738. bodyJson1.put("userId", oamap.get("id"));
  739. bodyJson1.put("flag", "2");
  740. bodyJson1.put("sreim",sreim);
  741. JSONArray arrinfos = new JSONArray();
  742. for (Map<Object, Object> map : listMapVbdef20) {
  743. long date = System.currentTimeMillis()/ 1000;
  744. JSONObject bodyJson2 = new JSONObject();
  745. bodyJson2.put("dataid", invoiceVO.getParent().getAttributeValue("pk_invoice"));
  746. bodyJson2.put("number", invoiceVO.getParent().getAttributeValue("pk_invoice"));
  747. bodyJson2.put("amount", map.get("norigtaxmny"));
  748. bodyJson2.put("uid", oamap.get("id"));
  749. bodyJson2.put("date",Long.toString(date));
  750. bodyJson2.put("name", invoiceVO.getParent().getAttributeValue("pk_invoice"));
  751. bodyJson2.put("fid", map.get("name5"));
  752. bodyJson2.put("cid", cid);
  753. arrinfos.add(bodyJson2);
  754. }
  755. bodyJson1.put("infos", arrinfos);
  756. NcLog.info("发票锁定修改返回json:"+UpdateInvoiceOCR(bodyJson1.toString()));
  757. }
  758. }
  759. }
  760. /**
  761. *
  762. * @param content
  763. * @throws Exception
  764. */
  765. private String UpdateInvoiceOCR(String bodyJson) throws Exception {
  766. String content = InvoiceCloudAESUtil.startAssemble(aesKey, secret, bodyJson);
  767. HttpClient httpClient = new HttpClient();
  768. PostMethod postMethod = new PostMethod(ec_comm);
  769. postMethod.setRequestHeader("content-type", "application/json");
  770. postMethod.setRequestHeader("appkey", appId);
  771. RequestEntity entity = new StringRequestEntity (content ,"application/json" ,"UTF-8");
  772. postMethod.setRequestEntity(entity);
  773. httpClient.executeMethod(postMethod);
  774. String responseMsg = postMethod.getResponseBodyAsString().trim();
  775. JSONObject json = JSONObject.parseObject(responseMsg);
  776. String data=json.getString("data");
  777. if(data == null) {
  778. throw new BusinessException(responseMsg);
  779. }
  780. return json.toJSONString();
  781. }
  782. /**
  783. * 从发票云获取发票
  784. */
  785. @Override
  786. public JSONObject SelectORCInvoice(String token) throws Exception{
  787. NcLog.info("=======发票云获取发票开始=======");
  788. JSONObject jsonobject = new JSONObject();
  789. jsonobject.put("tag", "1");
  790. jsonobject.put("sreim", "0");
  791. jsonobject.put("mask", "281474976710655");
  792. jsonobject.put("mext", "4031");
  793. jsonobject.put("page_size", "9999");
  794. jsonobject.put("start_pos", "0");
  795. JSONArray sorts = new JSONArray();
  796. jsonobject.put("sorts", sorts);
  797. String json = doPost(sync_rt,token,jsonobject.toString());
  798. NcLog.info("发票云获取发票返回json:"+json.toString());
  799. return JSONObject.parseObject(json);
  800. }
  801. /**
  802. * 将发票数据存储关联表
  803. */
  804. @Override
  805. public void addORC(Map<String,String> map) throws Exception {
  806. // 组装新增SQL语句
  807. InvocationInfoProxy.getInstance().getUserDataSource();
  808. StringBuilder insertSQL = new StringBuilder("INSERT INTO ocr_defdoc VALUES (");
  809. insertSQL.append("'").append(map.get("KYHSJE")).append("', ");
  810. insertSQL.append("'").append(map.get("KYWSJE")).append("', ");
  811. insertSQL.append("'").append(map.get("JYSE")).append("', ");
  812. insertSQL.append("'").append(map.get("FPXZ")).append("', ");
  813. insertSQL.append("'").append(map.get("NUMBERID")).append("', ");
  814. insertSQL.append("'").append(map.get("VDEF17")).append("') ");
  815. new BaseDAO().executeUpdate(insertSQL.toString());
  816. }
  817. /**
  818. * 删除发票关联表数据
  819. *
  820. */
  821. @Override
  822. public void deleteORC(String number,String vdef17,int type) throws Exception {
  823. String[] arrNumber = number.split(",");
  824. StringBuilder deleteSQL = new StringBuilder("DELETE FROM ocr_defdoc");
  825. deleteSQL.append(" WHERE");
  826. deleteSQL.append(" vdef17 = '"+vdef17+"'");
  827. //注意发票识别的信息number没有时间戳,发票云获取的信息有时间戳
  828. //0本地上传 1发票获取
  829. if(type == 1) {
  830. if(arrNumber.length == 1) {
  831. deleteSQL.append(" AND SUBSTR(NUMBERID, 1, INSTR(NUMBERID, '—')-1) = '"+arrNumber[0].toString()+"'");
  832. }else {
  833. SqlBuilder sqlb = new SqlBuilder();
  834. sqlb.append("SUBSTR(NUMBERID, 1, INSTR(NUMBERID, '—')-1)", arrNumber);
  835. deleteSQL.append(" AND "+sqlb.toString());
  836. }
  837. }else {
  838. if(arrNumber.length == 1) {
  839. deleteSQL.append(" AND NUMBERID = '"+arrNumber[0].toString()+"'");
  840. }else {
  841. SqlBuilder sqlb = new SqlBuilder();
  842. sqlb.append("NUMBERID", arrNumber);
  843. deleteSQL.append(" AND "+sqlb.toString());
  844. }
  845. }
  846. new BaseDAO().executeUpdate(deleteSQL.toString());
  847. }
  848. private Map<String,String> QueryOAUserid(String cuserid) throws Exception {
  849. StringBuffer sql = new StringBuffer();
  850. sql.append("SELECT");
  851. sql.append(" oa_user.id,");
  852. sql.append(" oa_user.lastname");
  853. sql.append(" FROM");
  854. sql.append(" sm_user sm_user");
  855. sql.append(" left join oa_user oa_user on sm_user.pk_psndoc = TRIM(oa_user.outkey)");
  856. sql.append(" WHERE");
  857. sql.append(" sm_user.cuserid = '"+cuserid+"'");
  858. Map<String,String> map = (Map<String, String>) iuap.executeQuery(sql.toString(), new MapProcessor());
  859. if(map.get("id") == null) {
  860. throw new Exception("获取oaid失败,请检查用户和人员是否关联!");
  861. }
  862. return map;
  863. }
  864. }