From 61cfdecaf6b76acb27478e5901eb0908244e3875 Mon Sep 17 00:00:00 2001
From: sinake <sinake1@qq.com>
Date: 星期四, 15 十月 2026 16:36:54 +0800
Subject: [PATCH] 发票识别
---
ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/HttpUtils.java | 312 ++++++++++++++++++++++++
ruoyi-admin/src/main/resources/application-druid.yml | 12
ruoyi-common/src/main/java/com/ruoyi/common/utils/ChineseUtils.java | 288 ++++++++++++++++++++++
ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java | 133 +++++++++
ruoyi-admin/src/main/resources/application.yml | 1
5 files changed, 736 insertions(+), 10 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
index 005f510..e6364fc 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -1,26 +1,31 @@
package com.ruoyi.web.controller.common;
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.utils.ChineseUtils;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig;
+import com.ruoyi.web.controller.tool.HttpUtils;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.coyote.AbstractProtocol;
+import org.apache.http.HttpResponse;
+import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.management.*;
@@ -28,7 +33,11 @@
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.lang.management.ManagementFactory;
-import java.util.Set;
+import java.math.BigDecimal;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.*;
/**
* 閫氱敤璇锋眰澶勭悊
@@ -42,6 +51,8 @@
@Autowired
private ServerConfig serverConfig;
+ @Value("${appcode}")
+ private String appcode;
/**
* 閫氱敤涓嬭浇璇锋眰
@@ -120,6 +131,120 @@
}
}
+ public String aliOCR(String base64) {
+ String host = "https://mixedmulti.market.alicloudapi.com";
+ String path = "/ocrservice/mixedMultiInvoice";
+ String method = "POST";
+ Map<String, String> headers = new HashMap<String, String>();
+ //鏈�鍚庡湪header涓殑鏍煎紡(涓棿鏄嫳鏂囩┖鏍�)涓篈uthorization:APPCODE 83359fd73fe94948385f570e3c139105
+ headers.put("Authorization", "APPCODE " + appcode);
+ //鏍规嵁API鐨勮姹傦紝瀹氫箟鐩稿搴旂殑Content-Type
+ headers.put("Content-Type", "application/json; charset=UTF-8");
+ Map<String, String> querys = new HashMap<String, String>();
+ String bodys = "{\"img\":\""+base64+"\"}";
+
+
+ try {
+
+ HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
+ System.out.println(response.toString());
+ //鑾峰彇response鐨刡ody
+ String content=EntityUtils.toString(response.getEntity());
+ JSONObject jsonContent=JSONObject.parseObject(content);
+ JSONArray subMsgs=jsonContent.getJSONArray("subMsgs");
+ List<Map<String,Object>> lists=new ArrayList<>();
+ for(Object row: subMsgs){
+ Map<String,Object> tempList=new HashMap<>();
+ JSONObject rowObject=(JSONObject)row;
+ tempList.put("鍙戠エ鍒嗙被",rowObject.getString("type"));
+ JSONObject result=((JSONObject)rowObject.get("result")).getJSONObject("data");
+ for(Map.Entry<String, Object> entry : result.entrySet()){
+ tempList.put(entry.getKey(),entry.getValue());
+ }
+ if(rowObject.getString("type").equals("閾惰鎵垮厬姹囩エ")){
+ BigDecimal totalAmount= ChineseUtils.chineseToNumber(result.getString("绁ㄦ嵁閲戦澶у啓"));
+ tempList.put("鍙戠エ閲戦",totalAmount);
+ }
+ if(rowObject.getString("type").equals("鐏溅绁�")){
+ tempList.put("鍙戠エ閲戦",result.getString("绁ㄤ环"));
+ }
+
+ lists.add(tempList);
+ }
+ System.out.println(content);
+ return JSON.toJSONString(lists);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return "{}";
+ }
+ }
+
+ /**
+ * 閫氱敤涓婁紶璇锋眰
+ */
+ @ApiOperation("testOCR")
+ @PostMapping("/common/testOCR")
+ public AjaxResult testOCR(@RequestBody String fileName) throws Exception {
+ Path filePath= Paths.get(fileName);
+ String base64= Base64.getEncoder().encodeToString( Files.readAllBytes(filePath));
+
+ AjaxResult ajax = AjaxResult.success();
+ ajax.put("OCRList", aliOCR(base64));
+ return ajax;
+ }
+
+ /**
+ * 閫氱敤涓婁紶璇锋眰
+ */
+ @PostMapping("/common/uploadOCR")
+ public AjaxResult uploadOCR(MultipartFile file) throws Exception {
+
+ try {
+ // 涓婁紶鏂囦欢璺緞
+ String filePath = RuoYiConfig.getUploadPath();
+
+ //鍒ゆ柇鏂囦欢鏄惁瀛樺湪
+ String filename = file.getOriginalFilename().trim();
+ String felinamePath = FileUploadUtils.extractFilename(file);
+// String pathFileName = FileUploadUtils.getPathFileName(filePath, s);
+ for (int i=1;i<500;i++) {
+ File file1 = new File(filePath + "/" + felinamePath);
+ boolean exists = file1.exists();
+ if (exists) {
+ int index = filename.lastIndexOf(".");
+ String startStr = filename.substring(0, index);
+ String endStr = filename.substring(index, filename.length());
+
+ String newFilename = startStr + "-" + i + endStr; // your new filename
+ felinamePath = DateUtils.datePath() + "/" + newFilename;
+ String contentType = file.getContentType();
+ byte[] bytes = file.getBytes();
+ file = new MockMultipartFile(newFilename, newFilename, contentType, bytes);
+ }else{
+ break;
+ }
+ }
+ // 涓婁紶骞惰繑鍥炴柊鏂囦欢鍚嶇О
+ String fileName = FileUploadUtils.upload(filePath, file);
+ String url1 = serverConfig.getUrl();
+ log.info("url1鐨勫�紀ld :{}", url1);
+ if (url1.contains("8032")) {
+ //杩欓噷鐨�8032涓嶆槸tomcat鐨勶紝鎵�浠ヨ杞垚tomcat鐨�
+ url1 = url1.replace("8032", "8032/prod-api");
+ }
+ String base64= Base64.getEncoder().encodeToString(file.getBytes());
+
+ log.info("url1鐨勫�糿ew :{}", url1);
+ String url = url1 + fileName;
+ AjaxResult ajax = AjaxResult.success();
+ ajax.put("fileName", fileName);
+ ajax.put("url", url);
+ ajax.put("OCRList", aliOCR(base64));
+ return ajax;
+ } catch (Exception e) {
+ return AjaxResult.error(e.getMessage());
+ }
+ }
// private static void parseUTF(int[] bits) {
// int index = 0;//杩欎釜鎸囬拡鎸囧悜姣忎竴琛屽惊鐜椂鍒椾笅鏍囩殑浣嶇疆锛屼笅涓�琛屽紑濮嬫椂閲嶆柊缃綅0
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/HttpUtils.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/HttpUtils.java
new file mode 100644
index 0000000..55abda0
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/tool/HttpUtils.java
@@ -0,0 +1,312 @@
+package com.ruoyi.web.controller.tool;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
+import org.apache.http.client.methods.HttpDelete;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.methods.HttpPost;
+import org.apache.http.client.methods.HttpPut;
+import org.apache.http.conn.ClientConnectionManager;
+import org.apache.http.conn.scheme.Scheme;
+import org.apache.http.conn.scheme.SchemeRegistry;
+import org.apache.http.conn.ssl.SSLSocketFactory;
+import org.apache.http.entity.ByteArrayEntity;
+import org.apache.http.entity.StringEntity;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+
+public class HttpUtils {
+
+ /**
+ * get
+ *
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doGet(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpGet request = new HttpGet(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * post form
+ *
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @param bodys
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doPost(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys,
+ Map<String, String> bodys)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpPost request = new HttpPost(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ if (bodys != null) {
+ List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
+
+ for (String key : bodys.keySet()) {
+ nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
+ }
+ UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
+ formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
+ request.setEntity(formEntity);
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * Post String
+ *
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @param body
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doPost(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys,
+ String body)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpPost request = new HttpPost(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ if (StringUtils.isNotBlank(body)) {
+ request.setEntity(new StringEntity(body, "utf-8"));
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * Post stream
+ *
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @param body
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doPost(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys,
+ byte[] body)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpPost request = new HttpPost(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ if (body != null) {
+ request.setEntity(new ByteArrayEntity(body));
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * Put String
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @param body
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doPut(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys,
+ String body)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpPut request = new HttpPut(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ if (StringUtils.isNotBlank(body)) {
+ request.setEntity(new StringEntity(body, "utf-8"));
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * Put stream
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @param body
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doPut(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys,
+ byte[] body)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpPut request = new HttpPut(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ if (body != null) {
+ request.setEntity(new ByteArrayEntity(body));
+ }
+
+ return httpClient.execute(request);
+ }
+
+ /**
+ * Delete
+ *
+ * @param host
+ * @param path
+ * @param method
+ * @param headers
+ * @param querys
+ * @return
+ * @throws Exception
+ */
+ public static HttpResponse doDelete(String host, String path, String method,
+ Map<String, String> headers,
+ Map<String, String> querys)
+ throws Exception {
+ HttpClient httpClient = wrapClient(host);
+
+ HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
+ for (Map.Entry<String, String> e : headers.entrySet()) {
+ request.addHeader(e.getKey(), e.getValue());
+ }
+
+ return httpClient.execute(request);
+ }
+
+ private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
+ StringBuilder sbUrl = new StringBuilder();
+ sbUrl.append(host);
+ if (!StringUtils.isBlank(path)) {
+ sbUrl.append(path);
+ }
+ if (null != querys) {
+ StringBuilder sbQuery = new StringBuilder();
+ for (Map.Entry<String, String> query : querys.entrySet()) {
+ if (0 < sbQuery.length()) {
+ sbQuery.append("&");
+ }
+ if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
+ sbQuery.append(query.getValue());
+ }
+ if (!StringUtils.isBlank(query.getKey())) {
+ sbQuery.append(query.getKey());
+ if (!StringUtils.isBlank(query.getValue())) {
+ sbQuery.append("=");
+ sbQuery.append(URLEncoder.encode(query.getValue(), "utf-8"));
+ }
+ }
+ }
+ if (0 < sbQuery.length()) {
+ sbUrl.append("?").append(sbQuery);
+ }
+ }
+
+ return sbUrl.toString();
+ }
+
+ private static HttpClient wrapClient(String host) {
+ HttpClient httpClient = new DefaultHttpClient();
+ if (host.startsWith("https://")) {
+ sslClient(httpClient);
+ }
+
+ return httpClient;
+ }
+
+ private static void sslClient(HttpClient httpClient) {
+ try {
+ SSLContext ctx = SSLContext.getInstance("TLS");
+ X509TrustManager tm = new X509TrustManager() {
+ public X509Certificate[] getAcceptedIssuers() {
+ return null;
+ }
+ public void checkClientTrusted(X509Certificate[] xcs, String str) {
+
+ }
+ public void checkServerTrusted(X509Certificate[] xcs, String str) {
+
+ }
+ };
+ ctx.init(null, new TrustManager[] { tm }, null);
+ SSLSocketFactory ssf = new SSLSocketFactory(ctx);
+ ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
+ ClientConnectionManager ccm = httpClient.getConnectionManager();
+ SchemeRegistry registry = ccm.getSchemeRegistry();
+ registry.register(new Scheme("https", 443, ssf));
+ } catch (KeyManagementException ex) {
+ throw new RuntimeException(ex);
+ } catch (NoSuchAlgorithmException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+}
diff --git a/ruoyi-admin/src/main/resources/application-druid.yml b/ruoyi-admin/src/main/resources/application-druid.yml
index 80c4781..cf4f697 100644
--- a/ruoyi-admin/src/main/resources/application-druid.yml
+++ b/ruoyi-admin/src/main/resources/application-druid.yml
@@ -7,12 +7,12 @@
# 涓诲簱鏁版嵁婧�
master:
# 寮�鍙戠幆澧�
- url: jdbc:mysql://127.0.0.1:3306/opo?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
- username: root
- password: sendohill
-# url: jdbc:mysql://haiershi.a1.luyouxia.net:23844/opo?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
-# username: smartor
-# password: Smartor.2023
+# url: jdbc:mysql://127.0.0.1:3306/opo?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
+# username: root
+# password: sendohill
+ url: jdbc:mysql://haiershi.a1.luyouxia.net:23844/opo?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
+ username: smartor
+ password: Smartor.2023
# 浠庡簱鏁版嵁婧�
slave:
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index a27b896..bc808e3 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -132,6 +132,7 @@
#涓庡崗鍙嬩氦浜掔殑鏂板姛鑳藉紑鍏� 1寮� 2鍏�
newSwitch: 1
+appcode: 07b7e4f573a54d97865abdeb3fc3408e
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ChineseUtils.java b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ChineseUtils.java
index cd1b79e..f43a4da 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/utils/ChineseUtils.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/utils/ChineseUtils.java
@@ -1,6 +1,47 @@
package com.ruoyi.common.utils;
+import java.math.BigDecimal;
+import java.util.HashMap;
+import java.util.Map;
+
public class ChineseUtils {
+ private static final String[] CN_NUM = {
+ "闆�", "澹�", "璐�", "鍙�", "鑲�", "浼�", "闄�", "鏌�", "鎹�", "鐜�"
+ };
+
+ private static final String[] CN_UNIT = {
+ "", "鎷�", "浣�", "浠�"
+ };
+
+ private static final String[] CN_BIG_UNIT = {
+ "", "涓�", "浜�", "鍏�"
+ };
+ private static final Map<Character, Integer> CN_NUM_MAP = new HashMap<>();
+ private static final Map<Character, Integer> CN_UNIT_MAP = new HashMap<>();
+
+ static {
+ for (int i = 0; i < CN_NUM.length; i++) {
+ CN_NUM_MAP.put(CN_NUM[i].charAt(0), i);
+ }
+ CN_NUM_MAP.put('闆�', 0);
+ CN_NUM_MAP.put('涓�', 1);
+ CN_NUM_MAP.put('浜�', 2);
+ CN_NUM_MAP.put('涓�', 3);
+ CN_NUM_MAP.put('鍥�', 4);
+ CN_NUM_MAP.put('浜�', 5);
+ CN_NUM_MAP.put('鍏�', 6);
+ CN_NUM_MAP.put('涓�', 7);
+ CN_NUM_MAP.put('鍏�', 8);
+ CN_NUM_MAP.put('涔�', 9);
+ CN_NUM_MAP.put('涓�', 2);
+
+ CN_UNIT_MAP.put('鎷�', 10);
+ CN_UNIT_MAP.put('浣�', 100);
+ CN_UNIT_MAP.put('浠�', 1000);
+ CN_UNIT_MAP.put('鍗�', 10);
+ CN_UNIT_MAP.put('鐧�', 100);
+ CN_UNIT_MAP.put('鍗�', 1000);
+ }
/**
* 鏍¢獙鏄惁鏄腑鏂�
@@ -23,4 +64,251 @@
return c >= 0x4E00 && c <= 0x9FA5;
}
+ /**
+ * 鏁板瓧閲戦杞腑鏂囧ぇ鍐�
+ * 渚嬪锛�1234.56 -> 澹逛粺璐颁桨鍙佹嬀鑲嗗厓浼嶈闄嗗垎
+ */
+ public static String numberToChinese(BigDecimal amount) {
+ if (amount == null) {
+ throw new IllegalArgumentException("閲戦涓嶈兘涓虹┖");
+ }
+
+ boolean negative = amount.signum() < 0;
+ amount = amount.abs().setScale(2, BigDecimal.ROUND_HALF_UP);
+
+ long integerPart = amount.longValue();
+ int decimalPart = amount.subtract(new BigDecimal(integerPart))
+ .multiply(new BigDecimal(100))
+ .intValue();
+
+ int jiao = decimalPart / 10;
+ int fen = decimalPart % 10;
+
+ StringBuilder sb = new StringBuilder();
+
+ if (negative) {
+ sb.append("璐�");
+ }
+
+ if (integerPart == 0) {
+ sb.append("闆跺厓");
+ } else {
+ sb.append(integerToChinese(integerPart)).append("鍏�");
+ }
+
+ if (jiao == 0 && fen == 0) {
+ sb.append("鏁�");
+ } else {
+ if (jiao > 0) {
+ sb.append(CN_NUM[jiao]).append("瑙�");
+ } else if (fen > 0 && integerPart > 0) {
+ sb.append("闆�");
+ }
+
+ if (fen > 0) {
+ sb.append(CN_NUM[fen]).append("鍒�");
+ }
+ }
+
+ return sb.toString();
+ }
+
+ public static String numberToChinese(double amount) {
+ return numberToChinese(BigDecimal.valueOf(amount));
+ }
+
+ public static String numberToChinese(String amount) {
+ return numberToChinese(new BigDecimal(amount));
+ }
+
+ /**
+ * 鏁存暟閮ㄥ垎杞腑鏂囧ぇ鍐�
+ */
+ private static String integerToChinese(long num) {
+ if (num == 0) {
+ return "闆�";
+ }
+
+ StringBuilder sb = new StringBuilder();
+ int unitIndex = 0;
+ boolean needZero = false;
+
+ while (num > 0) {
+ int section = (int) (num % 10000);
+ if (section != 0) {
+ String sectionStr = sectionToChinese(section);
+ if (needZero || (section < 1000 && sb.length() > 0)) {
+ sb.insert(0, "闆�");
+ }
+ sb.insert(0, sectionStr + CN_BIG_UNIT[unitIndex]);
+ needZero = section < 1000;
+ } else {
+ if (sb.length() > 0 && !sb.toString().startsWith("闆�")) {
+ needZero = true;
+ }
+ }
+ num /= 10000;
+ unitIndex++;
+ }
+
+ String result = sb.toString();
+ result = result.replaceAll("闆�+", "闆�");
+ result = result.replaceAll("闆�$", "");
+ result = result.replaceAll("闆朵竾", "涓�");
+ result = result.replaceAll("闆朵嚎", "浜�");
+ return result;
+ }
+
+ /**
+ * 鍥涗綅浠ュ唴鏁板瓧杞腑鏂�
+ */
+ private static String sectionToChinese(int section) {
+ StringBuilder sb = new StringBuilder();
+ int unit = 1000;
+ boolean zeroFlag = false;
+
+ while (section > 0) {
+ int digit = section / unit;
+ if (digit == 0) {
+ if (sb.length() > 0 && !zeroFlag) {
+ zeroFlag = true;
+ sb.append("闆�");
+ }
+ } else {
+ zeroFlag = false;
+ sb.append(CN_NUM[digit]).append(CN_UNIT[getUnitIndex(unit)]);
+ }
+ section %= unit;
+ unit /= 10;
+ }
+
+ String result = sb.toString();
+ if (result.endsWith("闆�")) {
+ result = result.substring(0, result.length() - 1);
+ }
+ return result;
+ }
+
+ private static int getUnitIndex(int unit) {
+ switch (unit) {
+ case 1000: return 3;
+ case 100: return 2;
+ case 10: return 1;
+ default: return 0;
+ }
+ }
+
+ /**
+ * 涓枃澶у啓閲戦杞暟瀛�
+ * 渚嬪锛氬9浠熻窗浣板弫鎷捐倖鍏冧紞瑙掗檰鍒� -> 1234.56
+ */
+ public static BigDecimal chineseToNumber(String chinese) {
+ if (chinese == null || chinese.trim().isEmpty()) {
+ throw new IllegalArgumentException("涓枃閲戦涓嶈兘涓虹┖");
+ }
+
+ String str = chinese.trim()
+ .replace("鏁�", "")
+ .replace("姝�", "")
+ .replace("浜烘皯甯�", "");
+
+ boolean negative = str.startsWith("璐�");
+ if (negative) {
+ str = str.substring(1);
+ }
+
+ // 鍒嗙鍏冦�佽銆佸垎
+ String integerPartStr;
+ String decimalPartStr = "";
+
+ int yuanIndex = str.indexOf("鍏�");
+ if (yuanIndex >= 0) {
+ integerPartStr = str.substring(0, yuanIndex);
+ String rest = str.substring(yuanIndex + 1);
+
+ int jiaoIndex = rest.indexOf("瑙�");
+ int fenIndex = rest.indexOf("鍒�");
+
+ if (jiaoIndex >= 0) {
+ decimalPartStr += chineseDigitToNumber(rest.substring(0, jiaoIndex)) + "";
+ } else if (fenIndex > 0) {
+ decimalPartStr += "0";
+ }
+
+ if (fenIndex >= 0) {
+ String fenStr = rest.substring(jiaoIndex >= 0 ? jiaoIndex + 1 : 0, fenIndex);
+ decimalPartStr += chineseDigitToNumber(fenStr) + "";
+ } else {
+ if (decimalPartStr.length() == 1) {
+ decimalPartStr += "0";
+ }
+ }
+ } else {
+ // 娌℃湁鈥滃厓鈥濓紝鎸夌函鏁板瓧涓枃澶勭悊
+ integerPartStr = str;
+ }
+
+ long integerPart = chineseIntegerToNumber(integerPartStr);
+
+ if (decimalPartStr.isEmpty()) {
+ decimalPartStr = "00";
+ } else if (decimalPartStr.length() == 1) {
+ decimalPartStr += "0";
+ }
+
+ BigDecimal result = new BigDecimal(integerPart + "." + decimalPartStr);
+ return negative ? result.negate() : result;
+ }
+ /**
+ * 涓枃鏁存暟杞� long
+ */
+ private static long chineseIntegerToNumber(String chinese) {
+ if (chinese == null || chinese.isEmpty() || chinese.equals("闆�")) {
+ return 0;
+ }
+
+ long result = 0;
+ long section = 0;
+ long number = 0;
+
+ for (int i = 0; i < chinese.length(); i++) {
+ char c = chinese.charAt(i);
+
+ if (CN_NUM_MAP.containsKey(c)) {
+ number = CN_NUM_MAP.get(c);
+ } else if (CN_UNIT_MAP.containsKey(c)) {
+ int unit = CN_UNIT_MAP.get(c);
+ if (number == 0) {
+ number = 1;
+ }
+ section += number * unit;
+ number = 0;
+ } else if (c == '涓�') {
+ section += number;
+ result += section * 10000;
+ section = 0;
+ number = 0;
+ } else if (c == '浜�') {
+ section += number;
+ result += section * 100000000;
+ section = 0;
+ number = 0;
+ } else if (c == '鍏�') {
+ section += number;
+ result += section * 1000000000000L;
+ section = 0;
+ number = 0;
+ }
+ }
+
+ return result + section + number;
+ }
+
+ private static int chineseDigitToNumber(String chinese) {
+ if (chinese == null || chinese.isEmpty()) {
+ return 0;
+ }
+ char c = chinese.charAt(0);
+ return CN_NUM_MAP.getOrDefault(c, 0);
+ }
}
--
Gitblit v1.9.3