From b394cc6d13b6ca8ac08e6fe33936a69680c0d82e Mon Sep 17 00:00:00 2001
From: RuicyWu <1063154311@qq.com>
Date: Tue, 21 Apr 2026 20:04:59 +0800
Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
.../org/chenyon/assets/AssetsController.java | 20 +
.../chenyon/assets/AssetsQueryService.java | 25 +-
.../assets/vo/AssetsPageQueryCondition.java | 47 ++
.../java/org/chenyon/assets/vo/AssetsVo.java | 24 +-
.../java/org/chenyon/bill/BillController.java | 38 ++
.../java/org/chenyon/bill/BillService.java | 9 +
.../org/chenyon/bill/BillStatusUpdateVo.java | 15 +
.../java/org/chenyon/bill/UnpaidBillVo.java | 41 ++
.../java/org/chenyon/constants/OaApiUrl.java | 12 +
.../contract/ContractQueryCondition.java | 18 +
.../org/chenyon/contract/ContractService.java | 28 +-
.../chenyon/fallback/FallbackController.java | 4 +-
.../java/org/chenyon/file/AttachmentVo.java | 22 +
.../chenyon/file/OaFileHandlerService.java | 47 +-
.../org/chenyon/file/OaFileLocalSubRef.java | 9 +
.../chenyon/location/IpLocationService.java | 27 +-
.../chenyon/location/LocateController.java | 54 +-
.../java/org/chenyon/message/Message.java | 28 +
.../chenyon/message/MessageController.java | 17 +-
.../java/org/chenyon/message/MessageDao.xml | 4 +-
.../message/MessageQueryCondition.java | 18 +
.../org/chenyon/message/MessageService.java | 38 +-
.../java/org/chenyon/message/MessageVo.java | 38 ++
.../org/chenyon/message/SubcribeMsgMode.java | 7 +
.../chenyon/message/SubscribeMsgSender.java | 6 +
.../message/WeAppMiniProgramMsgSender.java | 111 ++++
.../java/org/chenyon/notice/NoticeVo.java | 8 +-
.../java/org/chenyon/oa/OaAssetService.java | 10 +
.../java/org/chenyon/oa/OaBillService.java | 5 +
.../java/org/chenyon/oa/OaNoticeService.java | 16 +-
.../java/org/chenyon/oa/SeeyonHttpClient.java | 11 +-
.../java/org/chenyon/oa/asset/OaAssetsVo.java | 43 +-
.../org/chenyon/oa/notice/OaNoticeVo.java | 111 ++++
.../java/org/chenyon/pay/CreateOrderResp.java | 28 +
src/main/java/org/chenyon/pay/Goods.java | 30 +-
.../java/org/chenyon/pay/LocalKvRedis.java | 76 +++
src/main/java/org/chenyon/pay/Order.java | 52 --
.../java/org/chenyon/pay/OrderService.java | 240 +++++++++
src/main/java/org/chenyon/pay/OrderVo.java | 80 +++
src/main/java/org/chenyon/pay/SubOrder.java | 20 +
src/main/java/org/chenyon/pay/TmHttpUtil.java | 190 +++++++
.../java/org/chenyon/pay/TmPayService.java | 51 +-
.../org/chenyon/pay/TmPaySignatureUtils.java | 69 +++
.../java/org/chenyon/pay/TmTokenService.java | 133 +++++
.../org/chenyon/pay/UnifiedOrderRequest.java | 45 +-
src/main/java/org/chenyon/pay/WeAppOrder.java | 86 +++
.../java/org/chenyon/pay/WeAppOrderDao.java | 8 +
.../java/org/chenyon/pay/WeAppOrderDao.xml | 13 +
.../java/org/chenyon/pay/WeAppSubOrder.java | 56 ++
.../org/chenyon/pay/WeAppSubOrderDao.java | 15 +
.../java/org/chenyon/pay/WeAppSubOrderDao.xml | 7 +
.../org/chenyon/pay/shopcar/GoodsInfo.java | 32 ++
.../chenyon/pay/shopcar/MiniPayRequest.java | 58 +++
.../chenyon/pay/shopcar/RetCommParams.java | 16 +
.../java/org/chenyon/pay/shopcar/SatInfo.java | 105 ++++
.../shopcar/ShopCarOrderCreateRequest.java | 493 ++++++++++++++++++
.../pay/shopcar/ShopCarOrderQueryRequest.java | 79 +++
.../chenyon/pay/shopcar/TmPayOrderRespVo.java | 23 +
.../chenyon/pay/shopcar/TmPayResponse.java | 22 +
.../java/org/chenyon/pay/shopcar/VaFld.java | 81 +++
.../potential/PotentialController.java | 17 +-
.../org/chenyon/potential/ViewRecordVo.java | 9 +
.../reservation/ReservateController.java | 2 +-
.../org/chenyon/user/LoginController.java | 17 +
src/main/java/org/chenyon/user/UserDao.java | 3 +-
src/main/java/org/chenyon/user/UserDao.xml | 5 +-
.../java/org/chenyon/user/UserService.java | 17 +-
src/main/java/org/chenyon/user/UserVo.java | 9 +
.../java/org/chenyon/vr/VrDataController.java | 29 ++
.../java/org/chenyon/vr/VrDataService.java | 45 ++
src/main/java/org/chenyon/vr/VrDataVo.java | 33 ++
src/main/java/org/chenyon/vr/VrSpace.java | 61 +++
src/main/java/org/chenyon/vr/Vrhotspot.java | 40 ++
.../chenyon/pay/TmPayTokenServiceTest.java | 27 +
75 files changed, 3143 insertions(+), 192 deletions(-)
create mode 100644 src/main/java/org/chenyon/bill/BillStatusUpdateVo.java
create mode 100644 src/main/java/org/chenyon/bill/UnpaidBillVo.java
create mode 100644 src/main/java/org/chenyon/file/AttachmentVo.java
create mode 100644 src/main/java/org/chenyon/message/SubcribeMsgMode.java
create mode 100644 src/main/java/org/chenyon/message/SubscribeMsgSender.java
create mode 100644 src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java
create mode 100644 src/main/java/org/chenyon/pay/CreateOrderResp.java
create mode 100644 src/main/java/org/chenyon/pay/LocalKvRedis.java
delete mode 100644 src/main/java/org/chenyon/pay/Order.java
create mode 100644 src/main/java/org/chenyon/pay/OrderService.java
create mode 100644 src/main/java/org/chenyon/pay/OrderVo.java
create mode 100644 src/main/java/org/chenyon/pay/TmHttpUtil.java
create mode 100644 src/main/java/org/chenyon/pay/TmPaySignatureUtils.java
create mode 100644 src/main/java/org/chenyon/pay/TmTokenService.java
create mode 100644 src/main/java/org/chenyon/pay/WeAppOrder.java
create mode 100644 src/main/java/org/chenyon/pay/WeAppOrderDao.java
create mode 100644 src/main/java/org/chenyon/pay/WeAppOrderDao.xml
create mode 100644 src/main/java/org/chenyon/pay/WeAppSubOrder.java
create mode 100644 src/main/java/org/chenyon/pay/WeAppSubOrderDao.java
create mode 100644 src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml
create mode 100644 src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/RetCommParams.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/SatInfo.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/ShopCarOrderCreateRequest.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/ShopCarOrderQueryRequest.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java
create mode 100644 src/main/java/org/chenyon/pay/shopcar/VaFld.java
create mode 100644 src/main/java/org/chenyon/vr/VrDataController.java
create mode 100644 src/main/java/org/chenyon/vr/VrDataService.java
create mode 100644 src/main/java/org/chenyon/vr/VrDataVo.java
create mode 100644 src/main/java/org/chenyon/vr/VrSpace.java
create mode 100644 src/main/java/org/chenyon/vr/Vrhotspot.java
create mode 100644 src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java
diff --git a/pom.xml b/pom.xml
index 5adc37a..6bd4ef8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,7 +55,7 @@
com.maxmind.geoip2
geoip2
- 2.12.0
+ 2.15.0
org.lionsoul
diff --git a/src/main/java/org/chenyon/assets/AssetsController.java b/src/main/java/org/chenyon/assets/AssetsController.java
index c935b33..d3cf862 100644
--- a/src/main/java/org/chenyon/assets/AssetsController.java
+++ b/src/main/java/org/chenyon/assets/AssetsController.java
@@ -63,4 +63,24 @@ public class AssetsController {
return ResultMessage.success(new AssetsVo());
}
+ @GetMapping("/getBizZones")
+ public ResultMessage getBizZones() {
+ try {
+ return ResultMessage.success(assetsQueryService.getBizZones());
+ }catch (Exception e) {
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success(new ArrayList<>());
+ }
+
+ @GetMapping("/getFeatures")
+ public ResultMessage getFeatures() {
+ try {
+ return ResultMessage.success(assetsQueryService.getFeatures());
+ }catch (Exception e) {
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success(new ArrayList<>());
+ }
+
}
diff --git a/src/main/java/org/chenyon/assets/AssetsQueryService.java b/src/main/java/org/chenyon/assets/AssetsQueryService.java
index 203c42b..d2982eb 100644
--- a/src/main/java/org/chenyon/assets/AssetsQueryService.java
+++ b/src/main/java/org/chenyon/assets/AssetsQueryService.java
@@ -45,8 +45,9 @@ public class AssetsQueryService {
assetsVo.setAssetsName(oaAssetsVo.getAssetsName());
assetsVo.setDetailImgs(oaFileHandlerService.getUrls(true,oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(),"AssetsDetailImg",oaAssetsVo.getDetailImg()));
assetsVo.setVrImgs(oaFileHandlerService.getUrls(true,oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(),"AssetsVrImg",oaAssetsVo.getVrImg()));
- if(assetsVo.getDetailImgs() != null && assetsVo.getDetailImgs().size() > 1) {
- assetsVo.setCoverImgUrl(assetsVo.getDetailImgs().get(0));
+ List assetsCoverImg = oaFileHandlerService.getUrls(true, oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(), "AssetsCoverImg", oaAssetsVo.getCoverImg());
+ if(assetsCoverImg != null && assetsCoverImg.size() >= 1) {
+ assetsVo.setCoverImgUrl(assetsCoverImg.get(0));
}
assetsVoList.add(assetsVo);
}
@@ -54,6 +55,14 @@ public class AssetsQueryService {
return pageResult;
}
+ public List getBizZones() throws Exception {
+ return oaAssetService.getBizZones();
+ }
+
+ public List getFeatures() throws Exception {
+ return oaAssetService.getFeatures();
+ }
+
public AssetsVo getAssetsById(String id) throws Exception {
OaAssetsVo oaAssetsVo = oaAssetService.queryAssetsDetail(id);
AssetsVo assetsVo = new AssetsVo();
@@ -76,12 +85,20 @@ public class AssetsQueryService {
assetsVo.setLongitude(oaAssetsVo.getLongitude());
assetsVo.setLayout(oaAssetsVo.getLayout());
assetsVo.setUnitNo(oaAssetsVo.getUnitNo());
+ assetsVo.setOrientation(oaAssetsVo.getOrientation());
+ assetsVo.setBizZone(oaAssetsVo.getBizZone());
+ List features = oaAssetsVo.getFeatures() == null ? new ArrayList<>() : oaAssetsVo.getFeatures();
+ if(oaAssetsVo.getRenovationStatus() != null) {
+ features.add(oaAssetsVo.getRenovationStatus());
+ }
+ assetsVo.setFeatures(features);
assetsVo.setManagerName(oaAssetsVo.getManagerName());
assetsVo.setManagerPhone(oaAssetsVo.getManagerPhone());
assetsVo.setDetailImgs(oaFileHandlerService.getUrls(true,oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(),"AssetsDetailImg",oaAssetsVo.getDetailImg()));
assetsVo.setVrImgs(oaFileHandlerService.getUrls(true,oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(),"AssetsVrImg",oaAssetsVo.getVrImg()));
- if(assetsVo.getDetailImgs() != null) {
- assetsVo.setCoverImgUrl(assetsVo.getDetailImgs().get(0));
+ List assetsCoverImg = oaFileHandlerService.getUrls(true, oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(), "AssetsCoverImg", oaAssetsVo.getCoverImg());
+ if(assetsCoverImg != null && assetsCoverImg.size() >= 1) {
+ assetsVo.setCoverImgUrl(assetsCoverImg.get(0));
}
return assetsVo;
}
diff --git a/src/main/java/org/chenyon/assets/vo/AssetsPageQueryCondition.java b/src/main/java/org/chenyon/assets/vo/AssetsPageQueryCondition.java
index 4bfc8bb..ebd81f6 100644
--- a/src/main/java/org/chenyon/assets/vo/AssetsPageQueryCondition.java
+++ b/src/main/java/org/chenyon/assets/vo/AssetsPageQueryCondition.java
@@ -2,6 +2,8 @@ package org.chenyon.assets.vo;
import org.rcy.framework.api.entity.PageQueryRequest;
+import java.util.List;
+
public class AssetsPageQueryCondition extends PageQueryRequest {
private String assetsNo;//资产编号
@@ -13,6 +15,11 @@ public class AssetsPageQueryCondition extends PageQueryRequest {
private String assetsName;//资产名称
private String cusNo; //客商编码
private String keyWord; //关键字
+ private String bizZone; //商圈
+ private String rentFeeRange;
+ private String layout;
+ private String renovationStatus; //装修状态
+ private String features; //特点
public String getAssetsType() {
return assetsType;
@@ -85,4 +92,44 @@ public class AssetsPageQueryCondition extends PageQueryRequest {
public void setKeyWord(String keyWord) {
this.keyWord = keyWord;
}
+
+ public String getRentFeeRange() {
+ return rentFeeRange;
+ }
+
+ public void setRentFeeRange(String rentFeeRange) {
+ this.rentFeeRange = rentFeeRange;
+ }
+
+ public String getLayout() {
+ return layout;
+ }
+
+ public void setLayout(String layout) {
+ this.layout = layout;
+ }
+
+ public String getBizZone() {
+ return bizZone;
+ }
+
+ public void setBizZone(String bizZone) {
+ this.bizZone = bizZone;
+ }
+
+ public String getRenovationStatus() {
+ return renovationStatus;
+ }
+
+ public void setRenovationStatus(String renovationStatus) {
+ this.renovationStatus = renovationStatus;
+ }
+
+ public String getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(String features) {
+ this.features = features;
+ }
}
diff --git a/src/main/java/org/chenyon/assets/vo/AssetsVo.java b/src/main/java/org/chenyon/assets/vo/AssetsVo.java
index 5d889d2..58ae7eb 100644
--- a/src/main/java/org/chenyon/assets/vo/AssetsVo.java
+++ b/src/main/java/org/chenyon/assets/vo/AssetsVo.java
@@ -24,10 +24,12 @@ public class AssetsVo implements Serializable {
private String unitNo; //单元号
private String floorNo; //楼层号
private String roomNo; //房间号
- private Boolean hasLift;//有无电梯
+ private String hasLift;//有无电梯
private String layout; //户型
private String orientation; //朝向
private String assetsAddress; //资产地址
+ private String bizZone; //商圈
+ private List features; //特色
public String getManagerName() {
return managerName;
@@ -165,11 +167,11 @@ public class AssetsVo implements Serializable {
this.roomNo = roomNo;
}
- public Boolean getHasLift() {
+ public String getHasLift() {
return hasLift;
}
- public void setHasLift(Boolean hasLift) {
+ public void setHasLift(String hasLift) {
this.hasLift = hasLift;
}
@@ -196,4 +198,20 @@ public class AssetsVo implements Serializable {
public void setAssetsAddress(String assetsAddress) {
this.assetsAddress = assetsAddress;
}
+
+ public String getBizZone() {
+ return bizZone;
+ }
+
+ public void setBizZone(String bizZone) {
+ this.bizZone = bizZone;
+ }
+
+ public List getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List features) {
+ this.features = features;
+ }
}
diff --git a/src/main/java/org/chenyon/bill/BillController.java b/src/main/java/org/chenyon/bill/BillController.java
index 73f17e0..e3ac995 100644
--- a/src/main/java/org/chenyon/bill/BillController.java
+++ b/src/main/java/org/chenyon/bill/BillController.java
@@ -1,5 +1,7 @@
package org.chenyon.bill;
+import org.chenyon.pay.OrderService;
+import org.chenyon.pay.OrderVo;
import org.chenyon.user.LoginCheck;
import org.chenyon.user.UserContext;
import org.rcy.framework.api.entity.PageResult;
@@ -17,6 +19,8 @@ public class BillController {
@Autowired
private BillService billService;
+ @Autowired
+ private OrderService orderService;
@LoginCheck
@PostMapping("/pageQueryContractBill")
@@ -95,4 +99,38 @@ public class BillController {
}
return ResultMessage.success(0);
}
+
+ @LoginCheck
+ @PostMapping("/pay")
+ public ResultMessage payBill(@RequestBody OrderVo orderVo) {
+ try {
+ UserContext userContext = UserContext.get();
+ if(userContext == null || userContext.getCusNo() == null) {
+ return ResultMessage.error();
+ }
+ orderVo.setPayer(userContext.getCusNo());
+ orderVo.setPayerOpenId(userContext.getOpenId());
+ orderVo.setPayStatus("unpaid");
+ orderVo.setPayerName(userContext.getUsername());
+ return ResultMessage.success(orderService.createOrder(orderVo));
+ }catch (Exception e) {
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success(0);
+ }
+
+ @LoginCheck
+ @GetMapping("/updateRentBillStatus")
+ public ResultMessage updateRentBillStatus() {
+ try {
+ UserContext userContext = UserContext.get();
+ if(userContext == null || userContext.getCusNo() == null) {
+ return ResultMessage.success(0);
+ }
+ return ResultMessage.success(billService.countUnpayWaeBills(userContext.getCusNo()));
+ }catch (Exception e) {
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success(0);
+ }
}
diff --git a/src/main/java/org/chenyon/bill/BillService.java b/src/main/java/org/chenyon/bill/BillService.java
index 8c2794c..3972b67 100644
--- a/src/main/java/org/chenyon/bill/BillService.java
+++ b/src/main/java/org/chenyon/bill/BillService.java
@@ -3,6 +3,7 @@ package org.chenyon.bill;
import org.chenyon.oa.OaBillService;
import org.chenyon.oa.bill.OaBillVo;
import org.chenyon.oa.bill.OaPayRecordVo;
+import org.chenyon.pay.OrderService;
import org.rcy.framework.api.entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -15,6 +16,8 @@ public class BillService {
@Autowired
private OaBillService oaBillService;
+ @Autowired
+ private OrderService orderService;
public PageResult pageQueryContractBill(BillQueryCondition condition) throws Exception {
return oaBillService.pageQueryContractBill(condition);
@@ -39,4 +42,10 @@ public class BillService {
return oaBillService.countUnpayWaeBills(params);
}
+ public String getBillPayReceiver(String billNo,String bizType) throws Exception {
+ Map params = new HashMap<>();
+ params.put("billNo",billNo);
+ params.put("bizType",bizType);
+ return oaBillService.getBillPayReceiver(params);
+ }
}
diff --git a/src/main/java/org/chenyon/bill/BillStatusUpdateVo.java b/src/main/java/org/chenyon/bill/BillStatusUpdateVo.java
new file mode 100644
index 0000000..1e0a6e6
--- /dev/null
+++ b/src/main/java/org/chenyon/bill/BillStatusUpdateVo.java
@@ -0,0 +1,15 @@
+package org.chenyon.bill;
+
+import java.util.List;
+
+public class BillStatusUpdateVo {
+ private List billIds;
+
+ public List getBillIds() {
+ return billIds;
+ }
+
+ public void setBillIds(List billIds) {
+ this.billIds = billIds;
+ }
+}
diff --git a/src/main/java/org/chenyon/bill/UnpaidBillVo.java b/src/main/java/org/chenyon/bill/UnpaidBillVo.java
new file mode 100644
index 0000000..0c30b7c
--- /dev/null
+++ b/src/main/java/org/chenyon/bill/UnpaidBillVo.java
@@ -0,0 +1,41 @@
+package org.chenyon.bill;
+
+public class UnpaidBillVo {
+
+ private String billNo;
+ private String payee;
+ private String amount;
+ private String bizType;
+
+ public String getBillNo() {
+ return billNo;
+ }
+
+ public void setBillNo(String billNo) {
+ this.billNo = billNo;
+ }
+
+ public String getPayee() {
+ return payee;
+ }
+
+ public void setPayee(String payee) {
+ this.payee = payee;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public String getBizType() {
+ return bizType;
+ }
+
+ public void setBizType(String bizType) {
+ this.bizType = bizType;
+ }
+}
diff --git a/src/main/java/org/chenyon/constants/OaApiUrl.java b/src/main/java/org/chenyon/constants/OaApiUrl.java
index 911a350..9f4b5f6 100644
--- a/src/main/java/org/chenyon/constants/OaApiUrl.java
+++ b/src/main/java/org/chenyon/constants/OaApiUrl.java
@@ -21,6 +21,14 @@ public final class OaApiUrl {
* 查询资产详情
*/
public static final String QUERY_ASSETS_DETAIL = "/assets/detail";
+ /**
+ * 获取所有商圈信息
+ */
+ public static final String QUERY_ALL_BIZZONE = "/assets/getBizZones";
+ /**
+ * 获取所有商圈信息
+ */
+ public static final String QUERY_ALL_FEATURE = "/assets/getFeatures";
/**
* 分页查询合同
*/
@@ -61,6 +69,10 @@ public final class OaApiUrl {
* 统计未缴租金账单数
*/
public static final String COUNT_UNPAY_RENT_BILLS = "/bill/countUnpay/rent";
+ /**
+ * 获取账单收款方
+ */
+ public static final String BILL_PAY_RECEIVER = "/bill/payreceiver";
/**
* 统计未缴水电费账单数
*/
diff --git a/src/main/java/org/chenyon/contract/ContractQueryCondition.java b/src/main/java/org/chenyon/contract/ContractQueryCondition.java
index eaa48a9..2ff32c7 100644
--- a/src/main/java/org/chenyon/contract/ContractQueryCondition.java
+++ b/src/main/java/org/chenyon/contract/ContractQueryCondition.java
@@ -9,6 +9,8 @@ public class ContractQueryCondition extends PageQueryRequest {
private String formmainId;
private String signStatus;
private String signWay;
+ private String startDate;
+ private String endDate;
public String getCusNo() {
return cusNo;
@@ -49,4 +51,20 @@ public class ContractQueryCondition extends PageQueryRequest {
public void setSignWay(String signWay) {
this.signWay = signWay;
}
+
+ public String getStartDate() {
+ return startDate;
+ }
+
+ public void setStartDate(String startDate) {
+ this.startDate = startDate;
+ }
+
+ public String getEndDate() {
+ return endDate;
+ }
+
+ public void setEndDate(String endDate) {
+ this.endDate = endDate;
+ }
}
diff --git a/src/main/java/org/chenyon/contract/ContractService.java b/src/main/java/org/chenyon/contract/ContractService.java
index a5a805f..42fe190 100644
--- a/src/main/java/org/chenyon/contract/ContractService.java
+++ b/src/main/java/org/chenyon/contract/ContractService.java
@@ -61,9 +61,9 @@ public class ContractService {
if(oaContractVo.getAssetsVos() != null) {
List assetsVos = oaContractVo.getAssetsVos();
OaAssetsVo assetsVo = assetsVos.get(0);
- List assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
- if(assetsDetailImgs != null) {
- contractVo.setCoverImgUrl(assetsDetailImgs.get(0));
+ List assetsCoverImg = oaFileHandlerService.getUrls(true, assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsCoverImg", assetsVo.getCoverImg());
+ if(assetsCoverImg != null && assetsCoverImg.size() >= 1) {
+ contractVo.setCoverImgUrl(assetsCoverImg.get(0));
}
}
contractVo.setSignStatus(convertSignStatus(contractVo.getSignStatus()));
@@ -82,6 +82,16 @@ public class ContractService {
for (OaContractVo oaContractVo : oaContractVos) {
ContractVo contractVo = new ContractVo();
BeanUtils.copyProperties(oaContractVo, contractVo);
+ if(oaContractVo.getAssetsVos() != null) {
+ List contractAssetsVos = new ArrayList<>();
+ for (OaAssetsVo assetsVo : oaContractVo.getAssetsVos()) {
+ ContractAssetsVo contractAssetsVo = new ContractAssetsVo();
+ contractAssetsVo.setAssetsNo(assetsVo.getAssetsNo());
+ contractAssetsVo.setAssetsName(assetsVo.getAssetsName());
+ contractAssetsVos.add(contractAssetsVo);
+ }
+ contractVo.setAssetsInfos(contractAssetsVos);
+ }
contractVos.add(contractVo);
}
return contractVos;
@@ -93,7 +103,7 @@ public class ContractService {
condition.setPageNo(pageNo);
condition.setPageSize(pageSize);
OaAssetsVo assetsVo = oaContractService.pageQueryContractAssets(condition);
- List assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
+ List assetsCoverImgs = oaFileHandlerService.getUrls(true, assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsCoverImg", assetsVo.getCoverImg());
ContractAssetsVo assetsInfo = new ContractAssetsVo();
BeanUtils.copyProperties(assetsVo, assetsInfo);
RentFeeInfo rentFeeInfo = new RentFeeInfo();
@@ -101,8 +111,8 @@ public class ContractService {
rentFeeInfo.setRentFee(Double.parseDouble(assetsVo.getRentFee()));
}
assetsInfo.setFeeInfo(rentFeeInfo);
- if(assetsDetailImgs != null) {
- assetsInfo.setCover(assetsDetailImgs.get(0));
+ if(assetsCoverImgs != null) {
+ assetsInfo.setCover(assetsCoverImgs.get(0));
}
return assetsInfo;
}
@@ -122,7 +132,7 @@ public class ContractService {
BeanUtils.copyProperties(oaContractVo, contractVo);
List assetsVos = oaContractVo.getAssetsVos();
OaAssetsVo assetsVo = assetsVos.get(0);
- List assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
+ List assetsCoverImgs = oaFileHandlerService.getUrls(true, assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsCoverImg", assetsVo.getCoverImg());
List eContractUrl = oaFileHandlerService.getUrls(false,cusNo,oaContractVo.getContractNo(),oaContractVo.getFormId(),"eContractFile",oaContractVo.geteContractFile());
ContractAssetsVo assetsInfo = new ContractAssetsVo();
BeanUtils.copyProperties(assetsVo, assetsInfo);
@@ -131,8 +141,8 @@ public class ContractService {
rentFeeInfo.setRentFee(Double.parseDouble(assetsVo.getRentFee()));
}
assetsInfo.setFeeInfo(rentFeeInfo);
- if(assetsDetailImgs != null) {
- assetsInfo.setCover(assetsDetailImgs.get(0));
+ if(assetsCoverImgs != null) {
+ assetsInfo.setCover(assetsCoverImgs.get(0));
}
if(eContractUrl != null) {
contractVo.seteContractUrl(eContractUrl.get(0));
diff --git a/src/main/java/org/chenyon/fallback/FallbackController.java b/src/main/java/org/chenyon/fallback/FallbackController.java
index c8c0730..cb3f446 100644
--- a/src/main/java/org/chenyon/fallback/FallbackController.java
+++ b/src/main/java/org/chenyon/fallback/FallbackController.java
@@ -1,7 +1,5 @@
package org.chenyon.fallback;
-import org.chenyon.discharge.DisChargeApplyQueryCondition;
-import org.chenyon.discharge.DisChargeApplyVo;
import org.chenyon.oa.OaFallBackService;
import org.chenyon.user.LoginCheck;
import org.chenyon.user.UserContext;
@@ -57,7 +55,7 @@ public class FallbackController {
try {
UserContext userContext = UserContext.get();
if(userContext == null || userContext.getCusNo() == null) {
- return ResultMessage.success("您还未实名");
+ return ResultMessage.error("您还未实名");
}
submitVo.setCusNo(userContext.getCusNo());
submitVo.setTenantType(userContext.getUserType().equals("0") ? "个人" : "单位");
diff --git a/src/main/java/org/chenyon/file/AttachmentVo.java b/src/main/java/org/chenyon/file/AttachmentVo.java
new file mode 100644
index 0000000..a5c4151
--- /dev/null
+++ b/src/main/java/org/chenyon/file/AttachmentVo.java
@@ -0,0 +1,22 @@
+package org.chenyon.file;
+
+public class AttachmentVo {
+ private String fileName;
+ private String fileUrl;
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
+
+ public String getFileUrl() {
+ return fileUrl;
+ }
+
+ public void setFileUrl(String fileUrl) {
+ this.fileUrl = fileUrl;
+ }
+}
diff --git a/src/main/java/org/chenyon/file/OaFileHandlerService.java b/src/main/java/org/chenyon/file/OaFileHandlerService.java
index 2eead7c..57baca9 100644
--- a/src/main/java/org/chenyon/file/OaFileHandlerService.java
+++ b/src/main/java/org/chenyon/file/OaFileHandlerService.java
@@ -8,9 +8,7 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
import java.util.stream.Collectors;
@Service
@@ -46,14 +44,38 @@ public class OaFileHandlerService {
oaFileLocalRefVo.setSubRefIds(oaFileVo.getSubRefIds());
oaFileLocalRefVo.setViewPublic(viewPublic);
oaFileLocalRefVo.setOwner(owner);
- return refLocalUrl(oaFileLocalRefVo);
+ Map map = refLocalUrl(oaFileLocalRefVo);
+ return new ArrayList<>(map.keySet());
+ }
+
+ public List getAttachmentUrls(Boolean viewPublic,String owner,String bizId, String formId, String oaFieldFlag, OaFileVo oaFileVo){
+ if(bizId == null || formId == null || oaFieldFlag == null || oaFileVo == null) {
+ return null;
+ }
+ OaFileLocalRefVo oaFileLocalRefVo = new OaFileLocalRefVo();
+ oaFileLocalRefVo.setBizId(bizId);
+ oaFileLocalRefVo.setOaFormId(formId);
+ oaFileLocalRefVo.setOaFieldFlag(oaFieldFlag);
+ oaFileLocalRefVo.setRefId(oaFileVo.getMainRefId());
+ oaFileLocalRefVo.setSubRefIds(oaFileVo.getSubRefIds());
+ oaFileLocalRefVo.setViewPublic(viewPublic);
+ oaFileLocalRefVo.setOwner(owner);
+ Map map = refLocalUrl(oaFileLocalRefVo);
+ List attachmentVos = new ArrayList<>();
+ for (String key : map.keySet()) {
+ AttachmentVo attachmentVo = new AttachmentVo();
+ attachmentVo.setFileUrl(key);
+ attachmentVo.setFileName(map.get(key));
+ attachmentVos.add(attachmentVo);
+ }
+ return attachmentVos;
}
public List getUrls(Boolean viewPublic,String bizId, String formId, String oaFieldFlag, OaFileVo oaFileVo){
return getUrls(viewPublic,null,bizId,formId,oaFieldFlag,oaFileVo);
}
- public List refLocalUrl(OaFileLocalRefVo oaFileLocalRefVo) {
+ public Map refLocalUrl(OaFileLocalRefVo oaFileLocalRefVo) {
OaFileFindCondition condition1 = new OaFileFindCondition();
condition1.setBizId(oaFileLocalRefVo.getBizId());
condition1.setOaFormId(oaFileLocalRefVo.getOaFormId());
@@ -64,7 +86,7 @@ public class OaFileHandlerService {
List subRefInfos = oaFileLocalSubRefDao.findFileInfoByMainRefId(localRefDb.getRefId());
//先删除旧的
Set subRefSet = oaFileLocalRefVo.getSubRefIds().stream().collect(Collectors.toSet());
- List nSubUrls = new ArrayList<>();
+ Map nSubUrls = new HashMap<>();
for (OaFileLocalSubRef subRefInfo : subRefInfos) {
if (!subRefSet.contains(subRefInfo.getRefId())) {
//删除子表
@@ -77,7 +99,7 @@ public class OaFileHandlerService {
tempFile.delete();
}
}else {
- nSubUrls.add(subRefInfo.getUrl());
+ nSubUrls.put(subRefInfo.getUrl(),subRefInfo.getFileName());
}
}
Set dbSubRefSet = subRefInfos.stream().map(s -> s.getRefId()).collect(Collectors.toSet());
@@ -89,7 +111,7 @@ public class OaFileHandlerService {
return nSubUrls;
}
//附件信息完全删除
- List ncSubUrls = new ArrayList<>();
+ Map ncSubUrls = new HashMap<>();
List subRefIds = oaFileLocalRefVo.getSubRefIds();
for (String subRefId : subRefIds) {
try {
@@ -113,17 +135,20 @@ public class OaFileHandlerService {
return ncSubUrls;
}
- private void reBuildSubRef(String bizType,String subRefId, String mainRefId, Boolean isPublic, String owner, List nSubUrls) {
+ private void reBuildSubRef(String bizType,String subRefId, String mainRefId, Boolean isPublic, String owner, Map nSubUrls) {
//新增
OaFileLocalSubRef oaFileLocalSubRef = new OaFileLocalSubRef();
oaFileLocalSubRef.setRefId(subRefId);
oaFileLocalSubRef.setMainRefId(mainRefId);
//调OA接口写入文件
try {
- String subUrl = seeyonHttpClient.downloadFile(bizType,OaApiUrl.FILE_DOWNLOAD,subRefId, isPublic, owner);
+ Map resMap = seeyonHttpClient.downloadFile(bizType, OaApiUrl.FILE_DOWNLOAD, subRefId, isPublic, owner);
+ String subUrl = resMap.get("url");
+ String oriFileName = resMap.get("fileName");
oaFileLocalSubRef.setUrl(subUrl);
+ oaFileLocalSubRef.setFileName(oriFileName);
oaFileLocalSubRefDao.save(oaFileLocalSubRef);
- nSubUrls.add(subUrl);
+ nSubUrls.put(subUrl,oriFileName);
} catch (Exception e) {
}
diff --git a/src/main/java/org/chenyon/file/OaFileLocalSubRef.java b/src/main/java/org/chenyon/file/OaFileLocalSubRef.java
index 42832c4..be212fe 100644
--- a/src/main/java/org/chenyon/file/OaFileLocalSubRef.java
+++ b/src/main/java/org/chenyon/file/OaFileLocalSubRef.java
@@ -11,6 +11,7 @@ public class OaFileLocalSubRef extends BaseEntity {
private String refId;
private String url;
private String mainRefId;
+ private String fileName;
public String getRefId() {
return refId;
@@ -35,4 +36,12 @@ public class OaFileLocalSubRef extends BaseEntity {
public void setMainRefId(String mainRefId) {
this.mainRefId = mainRefId;
}
+
+ public String getFileName() {
+ return fileName;
+ }
+
+ public void setFileName(String fileName) {
+ this.fileName = fileName;
+ }
}
diff --git a/src/main/java/org/chenyon/location/IpLocationService.java b/src/main/java/org/chenyon/location/IpLocationService.java
index 6d8d800..54b93ab 100644
--- a/src/main/java/org/chenyon/location/IpLocationService.java
+++ b/src/main/java/org/chenyon/location/IpLocationService.java
@@ -1,25 +1,20 @@
package org.chenyon.location;
-import org.rcy.framework.utils.net.HttpRequestUtils;
-import org.rcy.framework.utils.net.HttpResponse;
+import com.maxmind.geoip2.DatabaseReader;
+import com.maxmind.geoip2.model.CityResponse;
import org.springframework.stereotype.Service;
+import java.io.File;
+import java.net.InetAddress;
+
@Service
public class IpLocationService {
- private static final String API = "https://apis.map.qq.com/ws/location/v1/ip";
-
- public String getLocationByIP(String ip) {
- String key = "CQPBZ-R543L-ZCZPH-E5CPI-KMUF6-VRBGE";
- String url = API + "?ip=" + ip + "&key=" + key;
- try {
- HttpResponse response = HttpRequestUtils.sendGet(url, null);
- if(response.getCode() == 200) {
- return response.getRespStr();
- }
- }catch (Exception e) {
-
- }
- return null;
+ public String getLocationByIP(String ip) throws Exception {
+ File database = new File("/usr/local/localfile/GeoLite2-City.mmdb");
+ DatabaseReader reader = new DatabaseReader.Builder(database).build();
+ InetAddress ipAddress = InetAddress.getByName(ip);
+ CityResponse response = reader.city(ipAddress);
+ return response.getCity().getName();
}
}
diff --git a/src/main/java/org/chenyon/location/LocateController.java b/src/main/java/org/chenyon/location/LocateController.java
index 57fc2f7..48afa27 100644
--- a/src/main/java/org/chenyon/location/LocateController.java
+++ b/src/main/java/org/chenyon/location/LocateController.java
@@ -1,6 +1,8 @@
package org.chenyon.location;
import org.rcy.framework.api.entity.ResultMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@@ -12,17 +14,55 @@ import java.io.IOException;
@RestController
@RequestMapping("/location")
public class LocateController {
+
+ private static final Logger log = LoggerFactory.getLogger(LocateController.class);
+
@Autowired
private IpLocationService ipLocationService;
@GetMapping("/getRealCity")
public ResultMessage getRealCity(HttpServletRequest request) throws IOException {
-// String ip = "";
-// String locationJson = ipLocationService.getLocationByIP(ip);
-// JsonNode root = JsonUtils.parseTree(locationJson);
-// JsonNode adInfo = root.path("result").path("ad_info");
-// String city = adInfo.path("city").asText();
-// return ResultMessage.success(city != null ? city : "未知城市");
- return ResultMessage.success("宜昌");
+ try {
+ String ip = getClientIp(request);
+ String city = ipLocationService.getLocationByIP(ip);
+ return ResultMessage.success(city != null ? city : "未知城市");
+ }catch (Exception e){
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success("宜昌市");
+ }
+
+ public String getClientIp(HttpServletRequest request) {
+ String ip;
+ // 1. X-Forwarded-For
+ ip = request.getHeader("X-Forwarded-For");
+ if (isValid(ip)) {
+ // 多级代理:取第一个
+ return ip.split(",")[0].trim();
+ }
+ // 2. X-Real-IP
+ ip = request.getHeader("X-Real-IP");
+ if (isValid(ip)) {
+ return ip;
+ }
+ // 3. 其他兼容头
+ String[] headers = {
+ "Proxy-Client-IP",
+ "WL-Proxy-Client-IP",
+ "HTTP_CLIENT_IP",
+ "HTTP_X_FORWARDED_FOR"
+ };
+ for (String header : headers) {
+ ip = request.getHeader(header);
+ if (isValid(ip)) {
+ return ip;
+ }
+ }
+ // 4. 最后兜底
+ return request.getRemoteAddr();
+ }
+
+ private boolean isValid(String ip) {
+ return ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip);
}
}
diff --git a/src/main/java/org/chenyon/message/Message.java b/src/main/java/org/chenyon/message/Message.java
index aed7975..8b407c5 100644
--- a/src/main/java/org/chenyon/message/Message.java
+++ b/src/main/java/org/chenyon/message/Message.java
@@ -4,6 +4,7 @@ import org.rcy.framework.api.entity.BaseEntity;
import javax.persistence.Entity;
import javax.persistence.Table;
+import java.util.Map;
@Entity
@Table(name = "MESSAGE")
@@ -15,6 +16,9 @@ public class Message extends BaseEntity {
private String messageReceiver;
private String bizId;
private Boolean hasRead = false;
+ private SubcribeMsgMode subscribeMsgMode;
+ private Map templateValue;
+ private String messageText;
public MessageType getMessageType() {
return messageType;
@@ -71,4 +75,28 @@ public class Message extends BaseEntity {
public void setHasRead(Boolean hasRead) {
this.hasRead = hasRead;
}
+
+ public SubcribeMsgMode getSubscribeMsgMode() {
+ return subscribeMsgMode;
+ }
+
+ public void setSubscribeMsgMode(SubcribeMsgMode subscribeMsgMode) {
+ this.subscribeMsgMode = subscribeMsgMode;
+ }
+
+ public Map getTemplateValue() {
+ return templateValue;
+ }
+
+ public void setTemplateValue(Map templateValue) {
+ this.templateValue = templateValue;
+ }
+
+ public String getMessageText() {
+ return messageText;
+ }
+
+ public void setMessageText(String messageText) {
+ this.messageText = messageText;
+ }
}
diff --git a/src/main/java/org/chenyon/message/MessageController.java b/src/main/java/org/chenyon/message/MessageController.java
index a0697d0..5b7565d 100644
--- a/src/main/java/org/chenyon/message/MessageController.java
+++ b/src/main/java/org/chenyon/message/MessageController.java
@@ -2,13 +2,19 @@ package org.chenyon.message;
import org.chenyon.user.LoginCheck;
import org.chenyon.user.UserContext;
+import org.chenyon.wx.AesException;
import org.rcy.framework.api.entity.PageResult;
import org.rcy.framework.api.entity.ResultMessage;
+import org.rcy.framework.utils.aes.AESUtils;
+import org.rcy.framework.utils.string.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.xml.parsers.ParserConfigurationException;
+
@RestController
@RequestMapping("/message")
public class MessageController {
@@ -74,7 +80,16 @@ public class MessageController {
@PostMapping("/sendMessage")
- public ResultMessage sendMessage(@RequestBody MessageVo vo){
+ public ResultMessage sendMessage(@RequestBody MessageVo vo, HttpServletRequest request) throws Exception {
+ String internalToken = request.getHeader("internalToken");
+ if(StringUtils.isBlank(internalToken)) {
+ return ResultMessage.error("无权限");
+ }
+ String decrypt = AESUtils.decrypt(internalToken, "rent*123");
+ if(!"oa".equals(decrypt)){
+ return ResultMessage.error("无权限");
+ }
+ messageService.send(vo);
return ResultMessage.success();
}
}
diff --git a/src/main/java/org/chenyon/message/MessageDao.xml b/src/main/java/org/chenyon/message/MessageDao.xml
index 5c67895..6f10619 100644
--- a/src/main/java/org/chenyon/message/MessageDao.xml
+++ b/src/main/java/org/chenyon/message/MessageDao.xml
@@ -25,7 +25,9 @@
AND messageReceiver = #{messageReceiver}
-
+
+ AND hasRead = #{hasRead}
+
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/message/MessageQueryCondition.java b/src/main/java/org/chenyon/message/MessageQueryCondition.java
index 4e2098d..8cd2703 100644
--- a/src/main/java/org/chenyon/message/MessageQueryCondition.java
+++ b/src/main/java/org/chenyon/message/MessageQueryCondition.java
@@ -5,6 +5,8 @@ import org.rcy.framework.api.entity.PageQueryRequest;
public class MessageQueryCondition extends PageQueryRequest {
private String messageReceiver;
+ private Boolean hasRead;
+ private String bizId;
public String getMessageReceiver() {
return messageReceiver;
@@ -13,4 +15,20 @@ public class MessageQueryCondition extends PageQueryRequest {
public void setMessageReceiver(String messageReceiver) {
this.messageReceiver = messageReceiver;
}
+
+ public Boolean getHasRead() {
+ return hasRead;
+ }
+
+ public void setHasRead(Boolean hasRead) {
+ this.hasRead = hasRead;
+ }
+
+ public String getBizId() {
+ return bizId;
+ }
+
+ public void setBizId(String bizId) {
+ this.bizId = bizId;
+ }
}
diff --git a/src/main/java/org/chenyon/message/MessageService.java b/src/main/java/org/chenyon/message/MessageService.java
index 4dd62bd..4e1573d 100644
--- a/src/main/java/org/chenyon/message/MessageService.java
+++ b/src/main/java/org/chenyon/message/MessageService.java
@@ -1,7 +1,6 @@
package org.chenyon.message;
import org.chenyon.wx.AesException;
-import org.chenyon.wx.WXBizMsgCrypt;
import org.rcy.framework.api.entity.PageResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -16,6 +15,8 @@ public class MessageService {
@Autowired
private MessageDao messageDao;
+ @Autowired
+ private List subscribeMsgSenders;
public MessageVo detail(Long id) {
@@ -38,6 +39,7 @@ public class MessageService {
public Integer countUnread(String cusNo){
MessageQueryCondition messageQueryCondition = new MessageQueryCondition();
messageQueryCondition.setMessageReceiver(cusNo);
+ messageQueryCondition.setHasRead(false);
Long count = messageDao.countCondition(messageQueryCondition);
return count.intValue();
}
@@ -53,21 +55,23 @@ public class MessageService {
public void send(MessageVo messageVo) throws AesException, ParserConfigurationException {
// 消息入库
- //
- String urlSend = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
-
-
- // 需要加密的明文
- String encodingAesKey = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFG";
- String token = "pamtest";
- String timestamp = "1409304348";
- String nonce = "xxxxxx";
- String appId = "wxb11529c136998cb6";
- String replyMsg = " 中文1407743423";
-
- WXBizMsgCrypt pc = new WXBizMsgCrypt(token, encodingAesKey, appId);
- String mingwen = pc.encryptMsg(replyMsg, timestamp, nonce);
- System.out.println("加密后: " + mingwen);
-
+ Message message = new Message();
+ message.setMessageType(MessageType.valueOf(messageVo.getMessageType()));
+ message.setMessageContent(messageVo.getMessageContent());
+ message.setMessageTime(messageVo.getMessageTime());
+ message.setMessageReceiver(messageVo.getMessageReceiver());
+ message.setBizId(messageVo.getBizId());
+ message.setSubscribeMsgMode(SubcribeMsgMode.valueOf(messageVo.getSubscribeMsgMode()));
+ message.setTitle(messageVo.getTitle());
+ message.setHasRead(false);
+ message.setTemplateValue(messageVo.getTemplateValue());
+ message.setMessageText(messageVo.getMessageText());
+ messageDao.save(message);
+ //发送订阅消息
+ for (SubscribeMsgSender subscribeMsgSender : subscribeMsgSenders) {
+ if(subscribeMsgSender.support(messageVo) && Boolean.TRUE.equals(messageVo.getSendSubscribeMsg())){
+ subscribeMsgSender.sendSubscribeMsg(messageVo);
+ }
+ }
}
}
diff --git a/src/main/java/org/chenyon/message/MessageVo.java b/src/main/java/org/chenyon/message/MessageVo.java
index 69e181e..72fccc8 100644
--- a/src/main/java/org/chenyon/message/MessageVo.java
+++ b/src/main/java/org/chenyon/message/MessageVo.java
@@ -1,14 +1,20 @@
package org.chenyon.message;
+import java.util.Map;
+
public class MessageVo {
private String id;
private String title;
private String messageType;
private String messageContent;
+ private String messageText;
private String messageTime;
private String messageReceiver;
private String bizId;
private Boolean hasRead;
+ private Boolean sendSubscribeMsg;
+ private String subscribeMsgMode;
+ private Map templateValue;
public String getMessageType() {
return messageType;
@@ -73,4 +79,36 @@ public class MessageVo {
public void setHasRead(Boolean hasRead) {
this.hasRead = hasRead;
}
+
+ public Boolean getSendSubscribeMsg() {
+ return sendSubscribeMsg;
+ }
+
+ public void setSendSubscribeMsg(Boolean sendSubscribeMsg) {
+ this.sendSubscribeMsg = sendSubscribeMsg;
+ }
+
+ public String getSubscribeMsgMode() {
+ return subscribeMsgMode;
+ }
+
+ public void setSubscribeMsgMode(String subscribeMsgMode) {
+ this.subscribeMsgMode = subscribeMsgMode;
+ }
+
+ public String getMessageText() {
+ return messageText;
+ }
+
+ public void setMessageText(String messageText) {
+ this.messageText = messageText;
+ }
+
+ public Map getTemplateValue() {
+ return templateValue;
+ }
+
+ public void setTemplateValue(Map templateValue) {
+ this.templateValue = templateValue;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/message/SubcribeMsgMode.java b/src/main/java/org/chenyon/message/SubcribeMsgMode.java
new file mode 100644
index 0000000..3fc2eaa
--- /dev/null
+++ b/src/main/java/org/chenyon/message/SubcribeMsgMode.java
@@ -0,0 +1,7 @@
+package org.chenyon.message;
+
+public enum SubcribeMsgMode {
+ WEAPPMINIPROGRAM,
+ SMS,
+ EMAIL,;
+}
diff --git a/src/main/java/org/chenyon/message/SubscribeMsgSender.java b/src/main/java/org/chenyon/message/SubscribeMsgSender.java
new file mode 100644
index 0000000..7d34a06
--- /dev/null
+++ b/src/main/java/org/chenyon/message/SubscribeMsgSender.java
@@ -0,0 +1,6 @@
+package org.chenyon.message;
+
+public interface SubscribeMsgSender {
+ void sendSubscribeMsg(MessageVo messageVo);
+ Boolean support(MessageVo messageVo);
+}
diff --git a/src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java b/src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java
new file mode 100644
index 0000000..40df76e
--- /dev/null
+++ b/src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java
@@ -0,0 +1,111 @@
+package org.chenyon.message;
+
+import org.chenyon.user.UserService;
+import org.chenyon.user.UserVo;
+import org.chenyon.wx.WXBizMsgCrypt;
+import org.chenyon.wx.WeChatAccessTokenService;
+import org.rcy.framework.utils.json.JsonUtils;
+import org.rcy.framework.utils.net.HttpRequestUtils;
+import org.rcy.framework.utils.net.HttpResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.Map;
+
+@Component
+public class WeAppMiniProgramMsgSender implements SubscribeMsgSender{
+
+ private static final Logger log = LoggerFactory.getLogger(WeAppMiniProgramMsgSender.class);
+
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private WeChatAccessTokenService weChatAccessTokenService;
+
+ @Override
+ public void sendSubscribeMsg(MessageVo messageVo) {
+ try {
+ if(messageVo == null || messageVo.getMessageReceiver() == null){
+ return;
+ }
+ UserVo userVo = userService.getByCusNo(messageVo.getMessageReceiver());
+ //用户未开启推送则不发送
+ if(userVo == null || !Boolean.TRUE.equals(userVo.getSubscribeMsg())){
+ return;
+ }
+ String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + weChatAccessTokenService.getAccessToken();
+ Map params = new HashMap<>();
+ params.put("touser",userVo.getOpenId());
+ params.put("template_id",getTemplateId(messageVo.getMessageType()));
+ params.put("page",getForwardPage(messageVo.getMessageType()));
+ params.put("miniprogram_state","formal");
+ params.put("lang","zh_CN");
+ params.put("data",getPushData(messageVo));
+ HttpResponse response = HttpRequestUtils.sendPost(url, JsonUtils.convertJson(params), null);
+ Map respMap = JsonUtils.parseObject(response.getRespStr(), Map.class);
+ if (respMap.get("errcode") != null) {
+ log.error("推送消息到小程序失败");
+ }
+ }catch (Exception e) {
+ log.error("推送消息到小程序失败: " + e.getMessage(),e);
+ }
+ }
+
+ @Override
+ public Boolean support(MessageVo messageVo) {
+ return SubcribeMsgMode.WEAPPMINIPROGRAM.name().equals(messageVo.getSubscribeMsgMode());
+ }
+
+ private String getTemplateId(String msgType) {
+ switch (msgType) {
+ case "BILL": return "9QlNxNONJBICzw3Vcetqbf9yv4lI9q9cR_px8ujlOu8";
+ }
+ return null;
+ }
+
+ private Map getPushData(MessageVo messageVo) {
+ switch (messageVo.getMessageType()) {
+ case "BILL": return buildBillData(messageVo);
+ }
+ return null;
+ }
+
+ public Map buildBillData(MessageVo messageVo) {
+ Map data = new HashMap<>();
+ //设置账单金额
+ Map amount2 = new HashMap<>();
+ amount2.put("value",messageVo.getTemplateValue().get("billAmount"));
+ data.put("amount2",amount2);
+ //设置账单日期
+ Map time3 = new HashMap<>();
+ time3.put("value",messageVo.getTemplateValue().get("billDate"));
+ data.put("time3",time3);
+ //设置备注
+ Map thing4 = new HashMap<>();
+ thing4.put("value",messageVo.getTemplateValue().get("remark"));
+ data.put("thing4",thing4);
+ //设置资产店名
+
+ Map thing8 = new HashMap<>();
+ thing8.put("value",messageVo.getTemplateValue().get("assetsName") + "");
+ data.put("thing8",thing8);
+
+ //设置房间号
+
+ Map thing1 = new HashMap<>();
+ thing1.put("value",messageVo.getTemplateValue().get("roomNo") + "");
+ data.put("thing1",thing1);
+
+ return data;
+ }
+
+ private String getForwardPage(String msgType) {
+ switch (msgType) {
+ case "BILL": return "unpaid";
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/org/chenyon/notice/NoticeVo.java b/src/main/java/org/chenyon/notice/NoticeVo.java
index 5ff72de..1a9f24a 100644
--- a/src/main/java/org/chenyon/notice/NoticeVo.java
+++ b/src/main/java/org/chenyon/notice/NoticeVo.java
@@ -1,5 +1,7 @@
package org.chenyon.notice;
+import org.chenyon.file.AttachmentVo;
+
import java.util.List;
public class NoticeVo {
@@ -14,7 +16,7 @@ public class NoticeVo {
private String updateBy;
private String updateTime;
private String remark;
- private List attachments;
+ private List attachments;
private List imgs;
public String getNoticeId() {
@@ -97,11 +99,11 @@ public class NoticeVo {
this.remark = remark;
}
- public List getAttachments() {
+ public List getAttachments() {
return attachments;
}
- public void setAttachments(List attachments) {
+ public void setAttachments(List attachments) {
this.attachments = attachments;
}
diff --git a/src/main/java/org/chenyon/oa/OaAssetService.java b/src/main/java/org/chenyon/oa/OaAssetService.java
index a5474ac..556e9d7 100644
--- a/src/main/java/org/chenyon/oa/OaAssetService.java
+++ b/src/main/java/org/chenyon/oa/OaAssetService.java
@@ -9,6 +9,7 @@ import org.rcy.framework.utils.json.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
+import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -42,6 +43,11 @@ public class OaAssetService {
return pageResult;
}
+ public List getBizZones() throws Exception {
+ OaResp oaResp = seeyonHttpClient.sendGet("获取商圈信息",OaApiUrl.QUERY_ALL_BIZZONE);
+ return JsonUtils.parseObject(oaResp.getDataStr(), List.class);
+ }
+
public OaAssetsVo queryAssetsDetail(String assetsNo) throws Exception {
Map params = new HashMap<>();
params.put("assetsNo",assetsNo);
@@ -49,4 +55,8 @@ public class OaAssetService {
return JsonUtils.parseObject(oaResp.getDataStr(),OaAssetsVo.class);
}
+ public List getFeatures() throws Exception {
+ OaResp oaResp = seeyonHttpClient.sendGet("获取特点信息",OaApiUrl.QUERY_ALL_FEATURE);
+ return JsonUtils.parseObject(oaResp.getDataStr(), List.class);
+ }
}
diff --git a/src/main/java/org/chenyon/oa/OaBillService.java b/src/main/java/org/chenyon/oa/OaBillService.java
index ec0e541..e139ed5 100644
--- a/src/main/java/org/chenyon/oa/OaBillService.java
+++ b/src/main/java/org/chenyon/oa/OaBillService.java
@@ -91,4 +91,9 @@ public class OaBillService {
return (Integer) oaResp.getData();
}
+ public String getBillPayReceiver(Map params) throws Exception {
+ OaResp oaResp = seeyonHttpClient.sendPost("获取账单收款方", OaApiUrl.BILL_PAY_RECEIVER, JsonUtils.convertJson(params));
+ return (String) oaResp.getData();
+ }
+
}
diff --git a/src/main/java/org/chenyon/oa/OaNoticeService.java b/src/main/java/org/chenyon/oa/OaNoticeService.java
index 15652e7..0dfa8cc 100644
--- a/src/main/java/org/chenyon/oa/OaNoticeService.java
+++ b/src/main/java/org/chenyon/oa/OaNoticeService.java
@@ -1,10 +1,13 @@
package org.chenyon.oa;
import org.chenyon.constants.OaApiUrl;
+import org.chenyon.file.OaFileHandlerService;
import org.chenyon.notice.NoticeQueryCondition;
import org.chenyon.notice.NoticeVo;
+import org.chenyon.oa.notice.OaNoticeVo;
import org.rcy.framework.api.entity.PageResult;
import org.rcy.framework.utils.json.JsonUtils;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -17,6 +20,8 @@ public class OaNoticeService {
@Autowired
private SeeyonHttpClient seeyonHttpClient;
+ @Autowired
+ private OaFileHandlerService oaFileHandlerService;
public PageResult pageQuery(NoticeQueryCondition condition) throws Exception {
OaResp oaResp = seeyonHttpClient.sendPost("分页查询招商公告信息", OaApiUrl.PAGE_QUERY_NOTICE, JsonUtils.convertJson(condition));
@@ -42,6 +47,15 @@ public class OaNoticeService {
Map params = new HashMap<>();
params.put("id",id);
OaResp oaResp = seeyonHttpClient.sendPost("查询公告详情",OaApiUrl.QUERY_NOTICE_DETAIL, params);
- return JsonUtils.parseObject(oaResp.getDataStr(),NoticeVo.class);
+ OaNoticeVo oaNoticeVo = JsonUtils.parseObject(oaResp.getDataStr(), OaNoticeVo.class);
+ NoticeVo vo = new NoticeVo();
+ BeanUtils.copyProperties(oaNoticeVo,vo);
+ if(oaNoticeVo.getAttachments() != null) {
+ vo.setAttachments(oaFileHandlerService.getAttachmentUrls(true,null,oaNoticeVo.getNoticeId(),oaNoticeVo.getNoticeId(),"noticeAttachment",oaNoticeVo.getAttachments()));
+ }
+ if(oaNoticeVo.getImgs() != null) {
+ vo.setImgs(oaFileHandlerService.getUrls(true,oaNoticeVo.getNoticeId(),oaNoticeVo.getNoticeId(),"noticeImg",oaNoticeVo.getImgs()));
+ }
+ return vo;
}
}
diff --git a/src/main/java/org/chenyon/oa/SeeyonHttpClient.java b/src/main/java/org/chenyon/oa/SeeyonHttpClient.java
index 279b9ff..2e7102a 100644
--- a/src/main/java/org/chenyon/oa/SeeyonHttpClient.java
+++ b/src/main/java/org/chenyon/oa/SeeyonHttpClient.java
@@ -62,7 +62,7 @@ public class SeeyonHttpClient {
return resovleResp(respStr);
}
- public String downloadFile(String bizType,String url,String refId,Boolean isPulic,String owner) throws Exception {
+ public Map downloadFile(String bizType,String url,String refId,Boolean isPulic,String owner) throws Exception {
Map headers = new HashMap<>();
headers.put("token",getToken());
log.info("下载OA文件请求参数为:" + refId + "," + isPulic + "," + owner);
@@ -81,10 +81,15 @@ public class SeeyonHttpClient {
}
savePath += File.separator + refId;
String fileGetUrl = oaHost + "/seeyon/rest" + url + "?refId=" + refId;
- File file = HttpRequestUtils.downloadFile(fileGetUrl, headers, savePath);
+ Map downloadResult = HttpRequestUtils.downloadFile(fileGetUrl, headers, savePath);
+ File file = (File) downloadResult.get("targetFile");
+ String bizFileName = (String) downloadResult.get("oriFileName");
log.info("文件绝对路径为:" + file.getAbsolutePath());
returnUrl += "/" + file.getName();
- return returnUrl;
+ Map resMap = new HashMap<>();
+ resMap.put("url",returnUrl);
+ resMap.put("fileName",bizFileName);
+ return resMap;
}
diff --git a/src/main/java/org/chenyon/oa/asset/OaAssetsVo.java b/src/main/java/org/chenyon/oa/asset/OaAssetsVo.java
index decc1d7..c26d350 100644
--- a/src/main/java/org/chenyon/oa/asset/OaAssetsVo.java
+++ b/src/main/java/org/chenyon/oa/asset/OaAssetsVo.java
@@ -4,6 +4,7 @@ package org.chenyon.oa.asset;
import org.chenyon.file.OaFileVo;
import java.io.Serializable;
+import java.util.List;
public class OaAssetsVo implements Serializable {
private String assetsNo; // 资产编号
@@ -15,6 +16,7 @@ public class OaAssetsVo implements Serializable {
private String formId; //表单记录ID
private OaFileVo detailImg; //详情图片
private OaFileVo vrImg; //vr图
+ private OaFileVo coverImg; //封面图
private String assetsDesc; //资产描述
private String assetsAddress; //资产地址
private String latitude; //纬度
@@ -22,7 +24,7 @@ public class OaAssetsVo implements Serializable {
private String unitNo; //单元号
private String floorNo; //楼层号
private String roomNo; //房间号
- private Boolean hasLift;//有无电梯
+ private String hasLift;//有无电梯
private String managerName; //管理员
private String managerPhone; //管理员电话
private String layout; //户型
@@ -32,6 +34,9 @@ public class OaAssetsVo implements Serializable {
private String waterFeeUnit; //水费单位
private String powerFee; //电费
private String powerFeeUnit; //电费单位
+ private String bizZone;
+ private List features;
+ private String renovationStatus; //装修状态
public String getAssetsNo() {
return assetsNo;
@@ -161,11 +166,11 @@ public class OaAssetsVo implements Serializable {
this.roomNo = roomNo;
}
- public Boolean getHasLift() {
+ public String getHasLift() {
return hasLift;
}
- public void setHasLift(Boolean hasLift) {
+ public void setHasLift(String hasLift) {
this.hasLift = hasLift;
}
@@ -240,4 +245,36 @@ public class OaAssetsVo implements Serializable {
public void setManagerName(String managerName) {
this.managerName = managerName;
}
+
+ public String getBizZone() {
+ return bizZone;
+ }
+
+ public void setBizZone(String bizZone) {
+ this.bizZone = bizZone;
+ }
+
+ public List getFeatures() {
+ return features;
+ }
+
+ public void setFeatures(List features) {
+ this.features = features;
+ }
+
+ public String getRenovationStatus() {
+ return renovationStatus;
+ }
+
+ public void setRenovationStatus(String renovationStatus) {
+ this.renovationStatus = renovationStatus;
+ }
+
+ public OaFileVo getCoverImg() {
+ return coverImg;
+ }
+
+ public void setCoverImg(OaFileVo coverImg) {
+ this.coverImg = coverImg;
+ }
}
diff --git a/src/main/java/org/chenyon/oa/notice/OaNoticeVo.java b/src/main/java/org/chenyon/oa/notice/OaNoticeVo.java
index 9190449..3af10f5 100644
--- a/src/main/java/org/chenyon/oa/notice/OaNoticeVo.java
+++ b/src/main/java/org/chenyon/oa/notice/OaNoticeVo.java
@@ -1,4 +1,115 @@
package org.chenyon.oa.notice;
+import org.chenyon.file.OaFileVo;
+
public class OaNoticeVo {
+
+ private String noticeId;
+ private String noticeTitle;
+ private String noticeType;
+ private String noticeContent;
+ private String status;
+ private String createBy;
+ private String createTime;
+ private String updateBy;
+ private String updateTime;
+ private String remark;
+ private OaFileVo attachments; //详情图片
+ private OaFileVo imgs; //vr图
+
+ public String getNoticeId() {
+ return noticeId;
+ }
+
+ public void setNoticeId(String noticeId) {
+ this.noticeId = noticeId;
+ }
+
+ public String getNoticeTitle() {
+ return noticeTitle;
+ }
+
+ public void setNoticeTitle(String noticeTitle) {
+ this.noticeTitle = noticeTitle;
+ }
+
+ public String getNoticeType() {
+ return noticeType;
+ }
+
+ public void setNoticeType(String noticeType) {
+ this.noticeType = noticeType;
+ }
+
+ public String getNoticeContent() {
+ return noticeContent;
+ }
+
+ public void setNoticeContent(String noticeContent) {
+ this.noticeContent = noticeContent;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getCreateBy() {
+ return createBy;
+ }
+
+ public void setCreateBy(String createBy) {
+ this.createBy = createBy;
+ }
+
+ public String getCreateTime() {
+ return createTime;
+ }
+
+ public void setCreateTime(String createTime) {
+ this.createTime = createTime;
+ }
+
+ public String getUpdateBy() {
+ return updateBy;
+ }
+
+ public void setUpdateBy(String updateBy) {
+ this.updateBy = updateBy;
+ }
+
+ public String getUpdateTime() {
+ return updateTime;
+ }
+
+ public void setUpdateTime(String updateTime) {
+ this.updateTime = updateTime;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public OaFileVo getAttachments() {
+ return attachments;
+ }
+
+ public void setAttachments(OaFileVo attachments) {
+ this.attachments = attachments;
+ }
+
+ public OaFileVo getImgs() {
+ return imgs;
+ }
+
+ public void setImgs(OaFileVo imgs) {
+ this.imgs = imgs;
+ }
}
diff --git a/src/main/java/org/chenyon/pay/CreateOrderResp.java b/src/main/java/org/chenyon/pay/CreateOrderResp.java
new file mode 100644
index 0000000..e664b1b
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/CreateOrderResp.java
@@ -0,0 +1,28 @@
+package org.chenyon.pay;
+
+public class CreateOrderResp {
+ private String errCode;
+ private String errMsg;
+ private String responseTimestamp;
+ private String mid;
+ private String tid;
+ private String msgId;
+ private String srcReserve;
+ private String merName;
+ private String merOrderId;
+ private String seqId;
+
+// "settleRefId":"35316566855N",
+// "status":"NEW_ORDER",
+// "totalAmount":"100",
+// "targetOrderId":"734605162687061091810",
+// "targetSys":"UAC",
+// "targetStatus":"SUCCESS",
+// "miniPayRequest":
+// {
+//
+// },
+// "targetMid":"",
+// "yxlmAmount":"100"
+
+}
diff --git a/src/main/java/org/chenyon/pay/Goods.java b/src/main/java/org/chenyon/pay/Goods.java
index 7ce9b0e..136c049 100644
--- a/src/main/java/org/chenyon/pay/Goods.java
+++ b/src/main/java/org/chenyon/pay/Goods.java
@@ -2,22 +2,46 @@ package org.chenyon.pay;
public class Goods {
+ /**
+ * 商户自定义商品编码
+ */
private String goodsId;
+ /**
+ * 商品名称
+ */
private String goodsName;
+ /**
+ * 商品数量
+ */
private String quantity;
+ /**
+ * 商品单价,单位为分
+ */
private String price;
private String unit;
+ /**
+ * 商品分类
+ */
private String goodsCategory;
+ /**
+ * 商品说明
+ */
private String body;
private String discount;
- /** 子商户号 */
+ /**
+ * 子商户号
+ * */
private String subMerchantId;
- /** 子订单号 */
+ /**
+ * 子订单号
+ * */
private String merOrderId;
- /** 子订单金额(分) */
+ /**
+ * 子订单金额(分)
+ * */
private String subOrderAmount;
public String getGoodsId() {
diff --git a/src/main/java/org/chenyon/pay/LocalKvRedis.java b/src/main/java/org/chenyon/pay/LocalKvRedis.java
new file mode 100644
index 0000000..632ccf5
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/LocalKvRedis.java
@@ -0,0 +1,76 @@
+package org.chenyon.pay;
+
+import org.springframework.stereotype.Component;
+
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+
+@Component
+public class LocalKvRedis {
+
+ // 存储 key -> value
+ private final ConcurrentHashMap store = new ConcurrentHashMap<>();
+
+ // 存储 key -> 过期时间(毫秒)
+ private final ConcurrentHashMap expireMap = new ConcurrentHashMap<>();
+
+ // 定时清理器
+ private final ScheduledExecutorService cleaner = Executors.newSingleThreadScheduledExecutor();
+
+ public LocalKvRedis() {
+ // 每秒清理一次过期 key
+ cleaner.scheduleAtFixedRate(() -> {
+ long now = System.currentTimeMillis();
+ for (String key : expireMap.keySet()) {
+ Long expireTime = expireMap.get(key);
+ if (expireTime != null && expireTime <= now) {
+ store.remove(key);
+ expireMap.remove(key);
+ }
+ }
+ }, 1, 1, TimeUnit.SECONDS);
+ }
+
+ // ========== 操作 ==========
+
+ // 设置永久 key
+ public void set(String key, String value) {
+ store.put(key, value);
+ expireMap.remove(key);
+ }
+
+ // 设置带 TTL 的 key(秒)
+ public void set(String key, String value, long ttlSeconds) {
+ store.put(key, value);
+ expireMap.put(key, System.currentTimeMillis() + ttlSeconds * 1000);
+ }
+
+ // 获取 key
+ public String get(String key) {
+ if (isExpired(key)) return null;
+ return store.get(key);
+ }
+
+ // 删除 key
+ public void del(String key) {
+ store.remove(key);
+ expireMap.remove(key);
+ }
+
+ // 判断 key 是否过期
+ private boolean isExpired(String key) {
+ Long expireTime = expireMap.get(key);
+ if (expireTime == null) return false;
+ if (System.currentTimeMillis() > expireTime) {
+ store.remove(key);
+ expireMap.remove(key);
+ return true;
+ }
+ return false;
+ }
+
+ // ========== 测试 ==========
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/Order.java b/src/main/java/org/chenyon/pay/Order.java
deleted file mode 100644
index b54b488..0000000
--- a/src/main/java/org/chenyon/pay/Order.java
+++ /dev/null
@@ -1,52 +0,0 @@
-package org.chenyon.pay;
-
-import org.rcy.framework.api.entity.BaseEntity;
-
-public class Order extends BaseEntity {
-
- private String bizId;
- private String payerId;
- private String payDate;
- private String amount;
- private String status;
-
- public String getBizId() {
- return bizId;
- }
-
- public void setBizId(String bizId) {
- this.bizId = bizId;
- }
-
- public String getPayerId() {
- return payerId;
- }
-
- public void setPayerId(String payerId) {
- this.payerId = payerId;
- }
-
- public String getPayDate() {
- return payDate;
- }
-
- public void setPayDate(String payDate) {
- this.payDate = payDate;
- }
-
- public String getAmount() {
- return amount;
- }
-
- public void setAmount(String amount) {
- this.amount = amount;
- }
-
- public String getStatus() {
- return status;
- }
-
- public void setStatus(String status) {
- this.status = status;
- }
-}
diff --git a/src/main/java/org/chenyon/pay/OrderService.java b/src/main/java/org/chenyon/pay/OrderService.java
new file mode 100644
index 0000000..30a7c0b
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/OrderService.java
@@ -0,0 +1,240 @@
+package org.chenyon.pay;
+
+import org.apache.commons.lang3.StringUtils;
+import org.chenyon.bill.UnpaidBillVo;
+import org.chenyon.oa.OaBillService;
+import org.chenyon.pay.shopcar.SatInfo;
+import org.chenyon.pay.shopcar.ShopCarOrderCreateRequest;
+import org.chenyon.pay.shopcar.TmPayOrderRespVo;
+import org.chenyon.pay.shopcar.VaFld;
+import org.chenyon.user.UserService;
+import org.rcy.framework.data.id.LongIdGenerator;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+@Service
+public class OrderService {
+
+ @Autowired
+ private WeAppOrderDao weAppOrderDao;
+ @Autowired
+ private WeAppSubOrderDao weAppSubOrderDao;
+
+ @Value("${chinaums.mid}")
+ private String mid;
+ @Value("${chinaums.tid}")
+ private String tid;
+ @Value("${chinaums.sourceNo}")
+ private String sourceNo;
+ @Value("${wx.appId}")
+ private String miniProgramAppId;
+
+ @Autowired
+ private TmPayService tmPayService;
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private OaBillService oaBillService;
+
+ @Value("${chinaums.subMid.gy}")
+ private String gyMid;
+ @Value("${chinaums.submid.wjfw}")
+ private String fwglMid;
+ @Value("${wx.appId}")
+ private String wxAppId;
+ @Value("${chinaums.pay.notifyUrl}")
+ private String notifyUrl;
+
+ /**
+ * 批量创建支付订单
+ * 【核心】批量前 校验所有 billNo 是否已经存在子订单
+ * 子订单唯一键:billNo
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public TmPayOrderRespVo createOrder(OrderVo orderVo) throws Exception {
+ // 1. 基础入参校验
+ if (orderVo == null || orderVo.getBillVoList() == null || orderVo.getBillVoList().isEmpty()) {
+ throw new Exception("批量支付账单不能为空");
+ }
+ if (StringUtils.isEmpty(orderVo.getPayerOpenId())) {
+ throw new Exception("支付人OPENID不能为空");
+ }
+
+ List billVoList = orderVo.getBillVoList();
+
+ // ======================================================================
+ // 【批量支付 最强幂等校验】
+ // 遍历所有子账单,根据 billNo 查询是否已存在支付记录
+ // 只要有一个已存在 → 整批拒绝支付
+ // ======================================================================
+ for (UnpaidBillVo billVo : billVoList) {
+ String billNo = billVo.getBillNo();
+ // 子订单唯一键:billNo
+ WeAppSubOrder existSubOrder = weAppSubOrderDao.selectByBillNo(billNo);
+ if (existSubOrder != null) {
+ throw new Exception("批量支付失败:账单号【" + billNo + "】已存在支付记录,禁止重复支付");
+ }
+ }
+
+ // 2. 生成主订单ID
+ Long mainOrderId = LongIdGenerator.generate();
+ String bizId = mainOrderId.toString();
+ orderVo.setBizId(bizId);
+
+ // 3. 主订单幂等校验
+ WeAppOrder existMainOrder = weAppOrderDao.findByBizId(bizId);
+ if (existMainOrder != null) {
+ TmPayOrderRespVo resp = new TmPayOrderRespVo();
+// resp.setOrderNo(existMainOrder.getTmOrderId());
+// resp.setAmount(existMainOrder.getAmount());
+ return resp;
+ }
+
+ // 4. 生成第三方支付订单号
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
+ int random = 1000000 + new Random().nextInt(9000000);
+ String tmOrderNo = sourceNo + sdf.format(new Date()) + random;
+
+ // 第三方单号唯一兜底
+ WeAppOrder orderByTmNo = weAppOrderDao.selectByTmOrderId(tmOrderNo);
+ if (orderByTmNo != null) {
+ throw new Exception("支付单号重复,请重新提交");
+ }
+
+ // 5. 调用支付创建分账订单
+ ShopCarOrderCreateRequest request = buildShopCarOrderCreateRequest(orderVo, tmOrderNo);
+ TmPayOrderRespVo payResp = tmPayService.weChatPayCreateSplitOrder(request);
+
+ // 6. 批量插入子订单 + 修复 BigDecimal 金额BUG
+ BigDecimal totalAmount = BigDecimal.ZERO;
+ for (UnpaidBillVo billVo : billVoList) {
+ WeAppSubOrder subOrder = new WeAppSubOrder();
+ subOrder.setMainOrderId(mainOrderId);
+ subOrder.setBillNo(billVo.getBillNo()); // 唯一键
+ subOrder.setAmount(billVo.getAmount());
+ subOrder.setPayStatus("0");
+ weAppSubOrderDao.insert(subOrder);
+
+ // 正确累加金额(修复原BUG)
+ totalAmount = totalAmount.add(new BigDecimal(billVo.getAmount()));
+ }
+
+ // 7. 插入主订单
+ WeAppOrder weAppOrder = new WeAppOrder();
+ weAppOrder.setId(mainOrderId);
+ weAppOrder.setBizId(bizId);
+ weAppOrder.setPayerId(orderVo.getPayer());
+ weAppOrder.setPayerName(orderVo.getPayerName());
+ weAppOrder.setTmOrderId(tmOrderNo);
+ weAppOrder.setAmount(totalAmount.toString());
+ weAppOrder.setPayStatus("0");
+ weAppOrderDao.insert(weAppOrder);
+
+ return payResp;
+ }
+
+ /**
+ * 构建分账请求(完全按你的业务逻辑)
+ */
+ private ShopCarOrderCreateRequest buildShopCarOrderCreateRequest(OrderVo orderVo, String orderNo) throws Exception {
+ ShopCarOrderCreateRequest request = new ShopCarOrderCreateRequest();
+ request.setVaMchntNo(mid);
+ request.setVaTermNo(tid);
+ request.setSubAppId(wxAppId);
+ request.setMchntOrderId(orderNo);
+ request.setMsgType("wx.unifiedOrder");
+ request.setNotifyUrl(notifyUrl);
+ request.setTradeType("MINI");
+ request.setSubOpenId(orderVo.getPayerOpenId());
+ request.setSysSource("OPT");
+
+ VaFld vaFld = new VaFld();
+ vaFld.setNewShopFlag("GWCXS");
+ vaFld.setSatType("01");
+ List satInfoList = new ArrayList<>();
+ vaFld.setSatInfo(satInfoList);
+
+ BigDecimal gyAmount = BigDecimal.ZERO;
+ BigDecimal fwglAmount = BigDecimal.ZERO;
+
+ for (UnpaidBillVo billVo : orderVo.getBillVoList()) {
+ Map param = new HashMap<>();
+ param.put("billNo", billVo.getBillNo());
+ param.put("bizType", billVo.getBizType());
+ String receiver = oaBillService.getBillPayReceiver(param);
+ billVo.setPayee(receiver);
+
+ int amountCent = (int) (Double.parseDouble(billVo.getAmount()) * 100);
+ BigDecimal cent = new BigDecimal(amountCent);
+
+ if (StringUtils.isNotBlank(receiver) && receiver.contains("广源")) {
+ gyAmount = gyAmount.add(cent);
+ } else {
+ fwglAmount = fwglAmount.add(cent);
+ }
+ }
+
+ if (gyAmount.compareTo(BigDecimal.ZERO) > 0) {
+ SatInfo info = new SatInfo();
+ info.setMerId(gyMid);
+ info.setFeeBear("Y");
+ info.setSatAmt(gyAmount.toString());
+ satInfoList.add(info);
+ }
+ if (fwglAmount.compareTo(BigDecimal.ZERO) > 0) {
+ SatInfo info = new SatInfo();
+ info.setMerId(fwglMid);
+ info.setFeeBear("Y");
+ info.setSatAmt(fwglAmount.toString());
+ satInfoList.add(info);
+ }
+
+ request.setTotalAmount(gyAmount.add(fwglAmount).toString());
+ request.setVaFld(vaFld);
+ return request;
+ }
+
+ /**
+ * 支付回调(幂等 + 批量更新子订单)
+ */
+ @Transactional(rollbackFor = Exception.class)
+ public void tmPayCallback(String tmOrderNo, String payResult) {
+ WeAppOrder order = weAppOrderDao.selectByTmOrderId(tmOrderNo);
+ if (order == null || "1".equals(order.getPayStatus())) {
+ return;
+ }
+
+ if ("SUCCESS".equalsIgnoreCase(payResult)) {
+ order.setPayStatus("1");
+ weAppOrderDao.updateByPrimaryKeySelective(order);
+
+ // 批量更新该主订单下 所有子订单(billNo)状态
+ List subList = weAppSubOrderDao.selectByMainOrderId(order.getId());
+ for (WeAppSubOrder sub : subList) {
+ sub.setPayStatus("1");
+ weAppSubOrderDao.updateById(sub);
+ }
+ } else {
+ order.setPayStatus("2");
+ weAppOrderDao.updateByPrimaryKeySelective(order);
+ }
+ }
+
+ public void callBack(String bizId) {
+ WeAppOrder order = weAppOrderDao.findByBizId(bizId);
+ if (order != null) {
+ tmPayCallback(order.getTmOrderId(), "SUCCESS");
+ }
+ }
+
+ private UnifiedOrderRequest buildUnifiedOrderRequest(OrderVo orderVo) {
+ return null;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/OrderVo.java b/src/main/java/org/chenyon/pay/OrderVo.java
new file mode 100644
index 0000000..1505a65
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/OrderVo.java
@@ -0,0 +1,80 @@
+package org.chenyon.pay;
+
+import org.chenyon.bill.UnpaidBillVo;
+
+import java.util.List;
+
+public class OrderVo {
+ private String bizId; //业务id
+ private String amount; //金额
+ private String payer; //付款方
+ private String payerName; //付款方名称
+ private String payStatus; //支付状态
+ private String payerOpenId; //
+ private List billVoList;
+ private String clientIp;
+
+ public String getBizId() {
+ return bizId;
+ }
+
+ public void setBizId(String bizId) {
+ this.bizId = bizId;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public String getPayer() {
+ return payer;
+ }
+
+ public void setPayer(String payer) {
+ this.payer = payer;
+ }
+
+ public List getBillVoList() {
+ return billVoList;
+ }
+
+ public void setBillVoList(List billVoList) {
+ this.billVoList = billVoList;
+ }
+
+ public String getPayStatus() {
+ return payStatus;
+ }
+
+ public void setPayStatus(String payStatus) {
+ this.payStatus = payStatus;
+ }
+
+ public String getPayerName() {
+ return payerName;
+ }
+
+ public void setPayerName(String payerName) {
+ this.payerName = payerName;
+ }
+
+ public String getPayerOpenId() {
+ return payerOpenId;
+ }
+
+ public void setPayerOpenId(String payerOpenId) {
+ this.payerOpenId = payerOpenId;
+ }
+
+ public String getClientIp() {
+ return clientIp;
+ }
+
+ public void setClientIp(String clientIp) {
+ this.clientIp = clientIp;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/SubOrder.java b/src/main/java/org/chenyon/pay/SubOrder.java
index d6999e7..9d470a1 100644
--- a/src/main/java/org/chenyon/pay/SubOrder.java
+++ b/src/main/java/org/chenyon/pay/SubOrder.java
@@ -10,6 +10,10 @@ public class SubOrder {
/** 金额(分) */
private String totalAmount;
+ /** 微信子商户appId*/
+ private String subAppId;
+ /** 用户子标识*/
+ private String subOpenId;
public String getMid() {
return mid;
@@ -34,4 +38,20 @@ public class SubOrder {
public void setTotalAmount(String totalAmount) {
this.totalAmount = totalAmount;
}
+
+ public String getSubAppId() {
+ return subAppId;
+ }
+
+ public void setSubAppId(String subAppId) {
+ this.subAppId = subAppId;
+ }
+
+ public String getSubOpenId() {
+ return subOpenId;
+ }
+
+ public void setSubOpenId(String subOpenId) {
+ this.subOpenId = subOpenId;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/TmHttpUtil.java b/src/main/java/org/chenyon/pay/TmHttpUtil.java
new file mode 100644
index 0000000..b18a859
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/TmHttpUtil.java
@@ -0,0 +1,190 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.utils.net.HttpRequestUtils;
+import org.rcy.framework.utils.net.HttpResponse;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+@Component
+public class TmHttpUtil {
+
+ @Value("${chinaums.appId}")
+ private String APP_ID;
+ @Value("${chinaums.appSecret}")
+ private String APP_KEY;
+ @Value("${chinaums.api.host}")
+ private String host;
+ @Autowired
+ private TmTokenService tmTokenService;
+
+ public enum AuthMode {
+ TOKEN, SIGNATURE
+ }
+
+ // =============================
+ // POST 请求
+ // =============================
+ public String post(String urlStr, String body, AuthMode mode) {
+ Map headers = new HashMap<>();
+ try {
+ String timestamp = now();
+ String nonce = uuid();
+
+ if (mode == AuthMode.TOKEN) {
+ String token = tmTokenService.getToken();
+ String authString = "OPEN-ACCESS-TOKEN accessToken=\"" + token + "\"" + "," + "AppId=\"" + APP_ID + "\"";
+ headers.put("Authorization", authString);
+ } else {
+ // 🔥 SIGN模式
+ String signature = buildBodySignature(body, timestamp, nonce);
+ String authString =
+ "OPEN-BODY-SIG " +
+ "AppId=\"" + APP_ID + "\"," +
+ "Timestamp=\"" + timestamp + "\"," +
+ "Nonce=\"" + nonce + "\"," +
+ "Signature=\"" + signature + "\"";
+ headers.put("Authorization", authString);
+ }
+ HttpResponse response = HttpRequestUtils.sendPost(host + urlStr, body, headers);
+ return response.getRespStr();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // =============================
+ // GET 请求
+ // =============================
+ public String get(String url, String content, AuthMode mode) {
+ Map headers = new HashMap<>();
+ String respStr = null;
+ try {
+ if (mode == AuthMode.TOKEN) {
+ String token = tmTokenService.getToken();
+ String authString = "OPEN-ACCESS-TOKEN accessToken=\"" + token + "\"" + "," + "AppId=\"" + APP_ID + "\"";
+ headers.put("Authorization", authString);
+ HttpResponse response = HttpRequestUtils.sendGet(host + url, headers);
+ respStr = response.getRespStr();
+ } else {
+ // 🔥 GET签名模式
+ String timestamp = now();
+ String nonce = uuid();
+
+ String signature = buildGetSignature(content, timestamp, nonce);
+
+ String finalUrl = host + url
+ + "?authorization=OPEN-FORM-PARAM"
+ + "&appId=" + APP_ID
+ + "×tamp=" + timestamp
+ + "&nonce=" + nonce
+ + "&content=" + URLEncoder.encode(content, "UTF-8")
+ + "&signature=" + signature;
+
+ HttpResponse response = HttpRequestUtils.sendGet(finalUrl, null);
+ respStr = response.getRespStr();
+ }
+ return respStr;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // =============================
+ // 🔐 POST签名
+ // =============================
+ private String buildBodySignature(String body, String timestamp, String nonce) {
+
+ String bodySha = sha256(body);
+ String signStr = APP_ID + timestamp + nonce + bodySha;
+
+ return base64(hmac(signStr, APP_KEY));
+ }
+
+ // =============================
+ // 🔐 GET签名
+ // =============================
+ private String buildGetSignature(String content, String timestamp, String nonce) throws Exception {
+
+ String contentSha = sha256(content);
+ String signStr = APP_ID + timestamp + nonce + contentSha;
+
+ String base64 = base64(hmac(signStr, APP_KEY));
+
+ return URLEncoder.encode(base64, "UTF-8");
+ }
+
+ // =============================
+ // 工具方法
+ // =============================
+ private String sha256(String str) {
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ byte[] hash = md.digest(str.getBytes(StandardCharsets.UTF_8));
+
+ StringBuilder hex = new StringBuilder();
+ for (byte b : hash) {
+ String s = Integer.toHexString(0xff & b);
+ if (s.length() == 1) hex.append('0');
+ hex.append(s);
+ }
+ return hex.toString();
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private byte[] hmac(String data, String key) {
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ mac.init(new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
+ return mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private String base64(byte[] data) {
+ return Base64.getEncoder().encodeToString(data);
+ }
+
+ private String now() {
+ return LocalDateTime.now()
+ .format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+ }
+
+ private String uuid() {
+ return UUID.randomUUID().toString().replace("-", "");
+ }
+
+ private String read(HttpURLConnection conn) throws Exception {
+ BufferedReader br = new BufferedReader(
+ new InputStreamReader(conn.getInputStream(), "UTF-8"));
+
+ StringBuilder sb = new StringBuilder();
+ String line;
+
+ while ((line = br.readLine()) != null) {
+ sb.append(line);
+ }
+
+ return sb.toString();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/TmPayService.java b/src/main/java/org/chenyon/pay/TmPayService.java
index e952955..9bda417 100644
--- a/src/main/java/org/chenyon/pay/TmPayService.java
+++ b/src/main/java/org/chenyon/pay/TmPayService.java
@@ -1,28 +1,24 @@
package org.chenyon.pay;
-import com.chinaums.open.api.OpenApiContext;
-import com.chinaums.open.api.internal.util.http.HttpTransport;
+import org.chenyon.pay.shopcar.MiniPayRequest;
+import org.chenyon.pay.shopcar.ShopCarOrderCreateRequest;
+import org.chenyon.pay.shopcar.TmPayOrderRespVo;
import org.rcy.framework.utils.json.JsonUtils;
-import org.springframework.beans.factory.annotation.Value;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.Map;
+
@Service
public class TmPayService {
- @Value("${chinaums.api.dev.host}")
- private String devHost;
- @Value("chinaums.api.prod.host")
- private String prodHost;
+ @Autowired
+ private TmHttpUtil tmHttpUtil;
public void weChatPayCreateOrder(UnifiedOrderRequest request) {
- String url = "/v1/netpay/wx/unified-order";
- String appId = "123456";
- String appKey = "123456";
- OpenApiContext context = TmPayApiContextBuilder.build(appId, appKey, url);
+ String url = "/v1/inip/upsp/shop/mini/pay";
Long totalAmount = null;
// if(Boolean.TRUE.equals(divisionFlag)){
// request.setDivisionFlag(divisionFlag);
@@ -35,10 +31,37 @@ public class TmPayService {
request.setMid("");// 设置商户号
request.setTid("");
try {
- HttpTransport.getInstance().doPost(context, JsonUtils.convertJson(request));
+
} catch (Exception e) {
throw new RuntimeException(e);
}
}
+ public TmPayOrderRespVo weChatPayCreateSplitOrder(ShopCarOrderCreateRequest request) {
+ String url = "/v1/inip/upsp/shop/mini/pay";
+ try {
+ String respStr = tmHttpUtil.post(url, JsonUtils.convertJson(request), TmHttpUtil.AuthMode.SIGNATURE);
+ Map map = JsonUtils.parseObject(respStr, Map.class);
+ String code = (String)map.get("respCode");
+ if(!"0000".equals(code)){
+ throw new RuntimeException("创建订单失败");
+ }
+ String forwardUrl = (String)map.get("url");
+ Map miniRequestMap = (Map) map.get("miniPayRequest");
+ MiniPayRequest miniPayRequest = new MiniPayRequest();
+ miniPayRequest.setAppId(miniRequestMap.get("appId"));
+ miniPayRequest.setNonceStr(miniRequestMap.get("nonceStr"));
+ miniPayRequest.setPackageStr(miniRequestMap.get("package"));
+ miniPayRequest.setPaySign(miniRequestMap.get("paySign"));
+ miniPayRequest.setSignType(miniRequestMap.get("signType"));
+ miniPayRequest.setTimeStamp(miniRequestMap.get("timeStamp"));
+ TmPayOrderRespVo tmPayOrderRespVo = new TmPayOrderRespVo();
+ tmPayOrderRespVo.setUrl(forwardUrl);
+ tmPayOrderRespVo.setMiniPayRequest(miniPayRequest);
+ return tmPayOrderRespVo;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
}
diff --git a/src/main/java/org/chenyon/pay/TmPaySignatureUtils.java b/src/main/java/org/chenyon/pay/TmPaySignatureUtils.java
new file mode 100644
index 0000000..3f2a2ae
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/TmPaySignatureUtils.java
@@ -0,0 +1,69 @@
+package org.chenyon.pay;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
+import java.security.MessageDigest;
+import java.util.Base64;
+
+public class TmPaySignatureUtils {
+
+ // SHA256(返回16进制小写)
+ public static String sha256Hex(String data) {
+ try {
+ MessageDigest digest = MessageDigest.getInstance("SHA-256");
+ byte[] hash = digest.digest(data.getBytes(StandardCharsets.UTF_8));
+ StringBuilder hex = new StringBuilder();
+ for (byte b : hash) {
+ String s = Integer.toHexString(0xff & b);
+ if (s.length() == 1) hex.append('0');
+ hex.append(s);
+ }
+ return hex.toString();
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // HmacSHA256 + Base64
+ public static String hmacSha256Base64(String data, String key) {
+ try {
+ Mac mac = Mac.getInstance("HmacSHA256");
+ SecretKeySpec secretKey =
+ new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), "HmacSHA256");
+ mac.init(secretKey);
+ byte[] raw = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
+ return Base64.getEncoder().encodeToString(raw);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ // =============================
+ // 🔥 POST Body签名
+ // =============================
+ public static String buildBodySignature(String appId, String timestamp, String nonce, String body, String appKey) {
+
+ String bodySha = sha256Hex(body);
+ String signStr = appId + timestamp + nonce + bodySha;
+
+ return hmacSha256Base64(signStr, appKey);
+ }
+
+ // =============================
+ // 🔥 GET签名
+ // =============================
+ public static String buildGetSignature(String appId, String timestamp, String nonce, String content, String appKey) {
+ try {
+ String contentSha = sha256Hex(content);
+ String signStr = appId + timestamp + nonce + contentSha;
+
+ String base64 = hmacSha256Base64(signStr, appKey);
+
+ return URLEncoder.encode(base64, "UTF-8");
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/TmTokenService.java b/src/main/java/org/chenyon/pay/TmTokenService.java
new file mode 100644
index 0000000..cf8d110
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/TmTokenService.java
@@ -0,0 +1,133 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.utils.json.JsonUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.Map;
+import java.util.UUID;
+
+@Service
+public class TmTokenService {
+
+ @Value("${chinaums.appId}")
+ private String APP_ID;
+ @Value("${chinaums.appSecret}")
+ private String APP_KEY;
+ @Value("${chinaums.api.host}")
+ private String host;
+ private final String TOKEN_URL = "/v2/token/access";
+ @Autowired
+ private LocalKvRedis localKvRedis;
+
+ // 获取Token(自动缓存)
+ public synchronized String getToken() throws IOException {
+ String token = localKvRedis.get("TM-Token");
+ if (token != null) {
+ return token;
+ }
+
+ String timestamp = now();
+ String nonce = UUID.randomUUID().toString().replace("-", "");
+ String signature = TmPaySignatureUtils.sha256Hex(APP_ID + timestamp + nonce + APP_KEY);
+ String json = "{"
+ + "\"appId\":\"" + APP_ID + "\","
+ + "\"timestamp\":\"" + timestamp + "\","
+ + "\"nonce\":\"" + nonce + "\","
+ + "\"signMethod\":\"SHA256\","
+ + "\"signature\":\"" + signature + "\""
+ + "}";
+
+ String resp = postJson(host + TOKEN_URL, json, null);
+ Map map = JsonUtils.parseObject(resp, Map.class);
+ String accessToken = (String)map.get("accessToken");
+ Integer expiresIn = Integer.parseInt(map.get("expiresIn") + "");
+ token = accessToken;
+ localKvRedis.set("TM-Token", token, expiresIn);
+ return token;
+ }
+
+ private String now() {
+ return LocalDateTime.now()
+ .format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
+ }
+
+ private String postJson(String urlStr, String json, Map headers) {
+
+ HttpURLConnection conn = null;
+ BufferedReader reader = null;
+
+ try {
+ URL url = new URL(urlStr);
+ conn = (HttpURLConnection) url.openConnection();
+
+ // =============================
+ // 基础配置
+ // =============================
+ conn.setRequestMethod("POST");
+ conn.setDoOutput(true);
+ conn.setDoInput(true);
+
+ conn.setConnectTimeout(15000);
+ conn.setReadTimeout(15000);
+
+ conn.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
+
+ // =============================
+ // 🔥 可选Header(比如token接口这里传null)
+ // =============================
+ if (headers != null) {
+ for (Map.Entry entry : headers.entrySet()) {
+ conn.setRequestProperty(entry.getKey(), entry.getValue());
+ }
+ }
+
+ // =============================
+ // 写入请求体
+ // =============================
+ try (OutputStream os = conn.getOutputStream()) {
+ os.write(json.getBytes("UTF-8"));
+ os.flush();
+ }
+
+ // =============================
+ // 读取响应(成功 or 失败都能读)
+ // =============================
+ int statusCode = conn.getResponseCode();
+
+ InputStream is;
+ if (statusCode >= 200 && statusCode < 300) {
+ is = conn.getInputStream();
+ } else {
+ is = conn.getErrorStream(); // 🔥关键:错误流
+ }
+
+ reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
+
+ StringBuilder response = new StringBuilder();
+ String line;
+
+ while ((line = reader.readLine()) != null) {
+ response.append(line);
+ }
+
+ return response.toString();
+
+ } catch (Exception e) {
+ throw new RuntimeException("POST请求异常: " + e.getMessage(), e);
+ } finally {
+ try {
+ if (reader != null) reader.close();
+ } catch (IOException ignored) {}
+
+ if (conn != null) conn.disconnect();
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/UnifiedOrderRequest.java b/src/main/java/org/chenyon/pay/UnifiedOrderRequest.java
index 8692535..71f4b24 100644
--- a/src/main/java/org/chenyon/pay/UnifiedOrderRequest.java
+++ b/src/main/java/org/chenyon/pay/UnifiedOrderRequest.java
@@ -17,11 +17,8 @@ public class UnifiedOrderRequest {
private String tid;
/** 订单总金额(分) */
- private Long totalAmount;
- /** 微信子商户appId*/
- private String subAppId;
- /** 用户子标识*/
- private String subOpenId;
+ private String totalAmount;
+
/** 微信:MINI / JSAPI */
private String tradeType;
@@ -36,7 +33,7 @@ public class UnifiedOrderRequest {
/** 同步分账标识*/
private Boolean divisionFlag;
/** 分账金额*/
- private Long platformAmount;
+ private String platformAmount;
/** 通知地址 */
private String notifyUrl;
@@ -156,30 +153,6 @@ public class UnifiedOrderRequest {
this.retCommParams = retCommParams;
}
- public Long getTotalAmount() {
- return totalAmount;
- }
-
- public void setTotalAmount(Long totalAmount) {
- this.totalAmount = totalAmount;
- }
-
- public String getSubAppId() {
- return subAppId;
- }
-
- public void setSubAppId(String subAppId) {
- this.subAppId = subAppId;
- }
-
- public String getSubOpenId() {
- return subOpenId;
- }
-
- public void setSubOpenId(String subOpenId) {
- this.subOpenId = subOpenId;
- }
-
public Boolean getDivisionFlag() {
return divisionFlag;
}
@@ -188,11 +161,19 @@ public class UnifiedOrderRequest {
this.divisionFlag = divisionFlag;
}
- public Long getPlatformAmount() {
+ public String getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(String totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public String getPlatformAmount() {
return platformAmount;
}
- public void setPlatformAmount(Long platformAmount) {
+ public void setPlatformAmount(String platformAmount) {
this.platformAmount = platformAmount;
}
}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/WeAppOrder.java b/src/main/java/org/chenyon/pay/WeAppOrder.java
new file mode 100644
index 0000000..f8efd77
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppOrder.java
@@ -0,0 +1,86 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.api.entity.BaseEntity;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+import java.util.Date;
+
+@Entity
+@Table(name = "ORDER")
+public class WeAppOrder extends BaseEntity {
+
+ private String bizId;
+ private String payerId;
+ private Date payDate;
+ private String amount;
+ private String payerName; //付款方名称
+ private String payStatus; //支付状态
+ private String payerOpenId; //
+ private String tmOrderId; //银联支付订单号
+
+
+ public String getBizId() {
+ return bizId;
+ }
+
+ public void setBizId(String bizId) {
+ this.bizId = bizId;
+ }
+
+ public String getPayerId() {
+ return payerId;
+ }
+
+ public void setPayerId(String payerId) {
+ this.payerId = payerId;
+ }
+
+ public Date getPayDate() {
+ return payDate;
+ }
+
+ public void setPayDate(Date payDate) {
+ this.payDate = payDate;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public String getPayerName() {
+ return payerName;
+ }
+
+ public void setPayerName(String payerName) {
+ this.payerName = payerName;
+ }
+
+ public String getPayStatus() {
+ return payStatus;
+ }
+
+ public void setPayStatus(String payStatus) {
+ this.payStatus = payStatus;
+ }
+
+ public String getPayerOpenId() {
+ return payerOpenId;
+ }
+
+ public void setPayerOpenId(String payerOpenId) {
+ this.payerOpenId = payerOpenId;
+ }
+
+ public String getTmOrderId() {
+ return tmOrderId;
+ }
+
+ public void setTmOrderId(String tmOrderId) {
+ this.tmOrderId = tmOrderId;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/WeAppOrderDao.java b/src/main/java/org/chenyon/pay/WeAppOrderDao.java
new file mode 100644
index 0000000..ca41ebe
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppOrderDao.java
@@ -0,0 +1,8 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.data.dao.BaseDao;
+
+public interface WeAppOrderDao extends BaseDao {
+ WeAppOrder findByBizId(String bizId);
+ WeAppOrder selectByTmOrderId(String tmOrderNo);
+}
diff --git a/src/main/java/org/chenyon/pay/WeAppOrderDao.xml b/src/main/java/org/chenyon/pay/WeAppOrderDao.xml
new file mode 100644
index 0000000..ebac760
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppOrderDao.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/WeAppSubOrder.java b/src/main/java/org/chenyon/pay/WeAppSubOrder.java
new file mode 100644
index 0000000..3c1aaf5
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppSubOrder.java
@@ -0,0 +1,56 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.api.entity.BaseEntity;
+
+import javax.persistence.Entity;
+import javax.persistence.Table;
+
+@Entity
+@Table(name = "SUB_ORDER")
+public class WeAppSubOrder extends BaseEntity {
+ private String billNo;
+ private String bizSubType;
+ private String amount;
+ private Long mainOrderId;
+ private String payStatus;
+
+ public String getBillNo() {
+ return billNo;
+ }
+
+ public void setBillNo(String billNo) {
+ this.billNo = billNo;
+ }
+
+ public String getBizSubType() {
+ return bizSubType;
+ }
+
+ public void setBizSubType(String bizSubType) {
+ this.bizSubType = bizSubType;
+ }
+
+ public String getAmount() {
+ return amount;
+ }
+
+ public void setAmount(String amount) {
+ this.amount = amount;
+ }
+
+ public Long getMainOrderId() {
+ return mainOrderId;
+ }
+
+ public void setMainOrderId(Long mainOrderId) {
+ this.mainOrderId = mainOrderId;
+ }
+
+ public String getPayStatus() {
+ return payStatus;
+ }
+
+ public void setPayStatus(String payStatus) {
+ this.payStatus = payStatus;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/WeAppSubOrderDao.java b/src/main/java/org/chenyon/pay/WeAppSubOrderDao.java
new file mode 100644
index 0000000..cd94c58
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppSubOrderDao.java
@@ -0,0 +1,15 @@
+package org.chenyon.pay;
+
+import org.rcy.framework.data.dao.BaseDao;
+
+import java.util.List;
+
+public interface WeAppSubOrderDao extends BaseDao {
+
+ WeAppSubOrder selectByBillNo(String billNo);
+
+ List selectByMainOrderId(Long mainOrderId);
+
+ Integer updateById(WeAppSubOrder subOrder);
+
+}
diff --git a/src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml b/src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml
new file mode 100644
index 0000000..4893a5f
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java b/src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java
new file mode 100644
index 0000000..b274c96
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java
@@ -0,0 +1,32 @@
+package org.chenyon.pay.shopcar;
+
+public class GoodsInfo {
+
+ private String goodsName;
+ private Integer goodsNum;
+ private Integer goodsPrice;
+
+ public String getGoodsName() {
+ return goodsName;
+ }
+
+ public void setGoodsName(String goodsName) {
+ this.goodsName = goodsName;
+ }
+
+ public Integer getGoodsNum() {
+ return goodsNum;
+ }
+
+ public void setGoodsNum(Integer goodsNum) {
+ this.goodsNum = goodsNum;
+ }
+
+ public Integer getGoodsPrice() {
+ return goodsPrice;
+ }
+
+ public void setGoodsPrice(Integer goodsPrice) {
+ this.goodsPrice = goodsPrice;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java b/src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java
new file mode 100644
index 0000000..73d35a9
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java
@@ -0,0 +1,58 @@
+package org.chenyon.pay.shopcar;
+
+public class MiniPayRequest {
+ private String timeStamp;
+ private String packageStr;
+ private String paySign;
+ private String appId;
+ private String signType;
+ private String nonceStr;
+
+ public String getTimeStamp() {
+ return timeStamp;
+ }
+
+ public void setTimeStamp(String timeStamp) {
+ this.timeStamp = timeStamp;
+ }
+
+ public String getPackageStr() {
+ return packageStr;
+ }
+
+ public void setPackageStr(String packageStr) {
+ this.packageStr = packageStr;
+ }
+
+ public String getPaySign() {
+ return paySign;
+ }
+
+ public void setPaySign(String paySign) {
+ this.paySign = paySign;
+ }
+
+ public String getAppId() {
+ return appId;
+ }
+
+ public void setAppId(String appId) {
+ this.appId = appId;
+ }
+
+ public String getSignType() {
+ return signType;
+ }
+
+ public void setSignType(String signType) {
+ this.signType = signType;
+ }
+
+ public String getNonceStr() {
+ return nonceStr;
+ }
+
+ public void setNonceStr(String nonceStr) {
+ this.nonceStr = nonceStr;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/shopcar/RetCommParams.java b/src/main/java/org/chenyon/pay/shopcar/RetCommParams.java
new file mode 100644
index 0000000..4b44ed3
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/RetCommParams.java
@@ -0,0 +1,16 @@
+package org.chenyon.pay.shopcar;
+
+import java.util.Map;
+
+public class RetCommParams {
+
+ private Map map;
+
+ public Map getMap() {
+ return map;
+ }
+
+ public void setMap(Map map) {
+ this.map = map;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/shopcar/SatInfo.java b/src/main/java/org/chenyon/pay/shopcar/SatInfo.java
new file mode 100644
index 0000000..d830c52
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/SatInfo.java
@@ -0,0 +1,105 @@
+package org.chenyon.pay.shopcar;
+
+/**
+ * 分账信息
+ */
+public class SatInfo {
+
+ /**
+ * 子商户号
+ */
+ private String merId;
+ /**
+ * 手续费承担方
+ */
+ private String feeBear;
+ /**
+ * 子商户上送交易
+ */
+ private String payBear;
+ /**
+ * 商户子订单号
+ */
+ private String merOrderId;
+ /**
+ * 分账所得额
+ */
+ private String satAmt;
+ private String orderDesc;
+ private String remark;
+ private Integer subsidyAmt;
+
+ private GoodsInfo goodsInfo;
+
+ public String getMerId() {
+ return merId;
+ }
+
+ public void setMerId(String merId) {
+ this.merId = merId;
+ }
+
+ public String getFeeBear() {
+ return feeBear;
+ }
+
+ public void setFeeBear(String feeBear) {
+ this.feeBear = feeBear;
+ }
+
+ public String getPayBear() {
+ return payBear;
+ }
+
+ public void setPayBear(String payBear) {
+ this.payBear = payBear;
+ }
+
+ public String getMerOrderId() {
+ return merOrderId;
+ }
+
+ public void setMerOrderId(String merOrderId) {
+ this.merOrderId = merOrderId;
+ }
+
+ public String getSatAmt() {
+ return satAmt;
+ }
+
+ public void setSatAmt(String satAmt) {
+ this.satAmt = satAmt;
+ }
+
+ public String getOrderDesc() {
+ return orderDesc;
+ }
+
+ public void setOrderDesc(String orderDesc) {
+ this.orderDesc = orderDesc;
+ }
+
+ public String getRemark() {
+ return remark;
+ }
+
+ public void setRemark(String remark) {
+ this.remark = remark;
+ }
+
+ public Integer getSubsidyAmt() {
+ return subsidyAmt;
+ }
+
+ public void setSubsidyAmt(Integer subsidyAmt) {
+ this.subsidyAmt = subsidyAmt;
+ }
+
+ public GoodsInfo getGoodsInfo() {
+ return goodsInfo;
+ }
+
+ public void setGoodsInfo(GoodsInfo goodsInfo) {
+ this.goodsInfo = goodsInfo;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderCreateRequest.java b/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderCreateRequest.java
new file mode 100644
index 0000000..1329f9c
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderCreateRequest.java
@@ -0,0 +1,493 @@
+package org.chenyon.pay.shopcar;
+
+import org.chenyon.pay.Goods;
+
+public class ShopCarOrderCreateRequest {
+ /**
+ * 商户订单号
+ */
+ private String mchntOrderId;
+ /**
+ * 商户号
+ */
+ private String vaMchntNo;
+ /**
+ * 终端号
+ */
+ private String vaTermNo;
+ /**
+ * 请求预留字段
+ */
+ private String srcReserve;
+ /**
+ * 业务模板,用来替代mid
+ * 作为大商户统一接入第三
+ * 方,用于POS通等转商户
+ * 交易场景
+ * MINIDEFAULT
+ */
+ private String instMid;
+ /**
+ * 消息类型
+ * 微信: wx.unifiedOrder
+ * 支付宝: trade.create
+ * 云闪付: uac.miniOrder
+ */
+ private String msgType;
+ /**
+ * 商品信息
+ */
+ private Goods goods;
+ /**
+ * 商户附加数据
+ */
+ private String attachedData;
+ /**
+ * 订单过期时间
+ */
+ private String expireTime;
+ /**
+ * 商品标记
+ */
+ private String goodsTag;
+ /**
+ * 商品交易单号
+ * 跟goods字段二选一,商品信息通过goods.add接口
+ * 提前上送
+ */
+ private String goodsTradeNo;
+ /**
+ * 订单描述
+ */
+ private String orderDesc;
+ /**
+ * 商品ID
+ */
+ private String productId;
+ /**
+ * 订单原始金额,单位分,
+ * 用于记录前端系统打折前
+ * 的金额
+ */
+ private String originalAmount;
+ /**
+ * 支付总金额,若divisionFlag为true,则:
+ * totalAmount=subOrders字段中的所有totalAmount
+ * 值之和 加上 platformAmount值=goods中的所有
+ * subOrderAmount值之和
+ */
+ private String totalAmount;
+ /**
+ * 支付结果通知地址
+ */
+ private String notifyUrl;
+ /**
+ * 网页跳转地址
+ */
+ private String returnUrl;
+ /**
+ * 下单场景
+ */
+ private String placeOrderScene;
+ /**
+ * 订单展示页面
+ */
+ private String showUrl;
+ /**
+ * subAppId
+ */
+ private String subAppId;
+ /**
+ * 用户子标识,商户自己公众号appid下的用户openid,可以通过微
+ * 信oauth接口获取。
+ */
+ private String subOpenId;
+ /**
+ * 支付宝买家ID,支付宝必传
+ * 需要商户自行调用支付宝接口获取,具体获取方式 请
+ * 根据支付宝接口文档。
+ */
+ private String userId;
+ /**
+ * 交易类型,值为MINI,如果使用云闪付云微小程序支付时需要上
+ * 送UP_WX_MINI
+ */
+ private String tradeType;
+ /**
+ * 是否需要限制信用卡支付
+ */
+ private String limitCreditCard;
+ /**
+ * 花呗分期数
+ */
+ private String installmentNumber;
+ /**
+ * 实名认证姓名,Base64编码
+ * 跨境交易时,该字段必须传
+ */
+ private String name;
+ /**
+ * 实名认证手机号,Base64编码
+ * 跨境交易时,该字段可选
+ */
+ private String mobile;
+ /**
+ * 实名认证证件类型,证件类型,微信,银联支持身份证、支付宝支持身份
+ * 证:IDENTITY_CARD、护照:PASSPORT、军官证:
+ * OFFICER_CARD、士兵证:SOLDIER_CARD、户口
+ * 本:HOKOU
+ * 跨境交易时,该字段必须传
+ */
+ private String certType;
+ /**
+ * 实名认证证件号,Base64编码
+ * 跨境交易时,该字段必须传
+ */
+ private String certNo;
+ /**
+ * 是否需要实名认证,需要实名认证时置为 T
+ * 跨境交易时,该字段必须传
+ */
+ private String fixBuyer;
+
+ private RetCommParams retCommParams;
+
+ private Boolean thirdPartyInstalSubsFlag;
+ private String bankCardNo;
+ private String invokeScene;
+ private String discountCode;
+
+ private String ylyxId;
+ private String ylyxName;
+ private String ylyxMerAbbr;
+ /**
+ * 系统来源,商终密:SZM
+ * 开放平台: OPT
+ * 当需要接收交易结果通知时,需上送从UP系统申请的
+ * 消息来源,同网付msgSrc,并且联系业务人员在新购
+ * 物车录入对应的密钥
+ */
+ private String sysSource;
+
+ private VaFld vaFld;
+
+ public String getMchntOrderId() {
+ return mchntOrderId;
+ }
+
+ public void setMchntOrderId(String mchntOrderId) {
+ this.mchntOrderId = mchntOrderId;
+ }
+
+ public String getVaMchntNo() {
+ return vaMchntNo;
+ }
+
+ public void setVaMchntNo(String vaMchntNo) {
+ this.vaMchntNo = vaMchntNo;
+ }
+
+ public String getVaTermNo() {
+ return vaTermNo;
+ }
+
+ public void setVaTermNo(String vaTermNo) {
+ this.vaTermNo = vaTermNo;
+ }
+
+ public String getSrcReserve() {
+ return srcReserve;
+ }
+
+ public void setSrcReserve(String srcReserve) {
+ this.srcReserve = srcReserve;
+ }
+
+ public String getInstMid() {
+ return instMid;
+ }
+
+ public void setInstMid(String instMid) {
+ this.instMid = instMid;
+ }
+
+ public String getMsgType() {
+ return msgType;
+ }
+
+ public void setMsgType(String msgType) {
+ this.msgType = msgType;
+ }
+
+ public Goods getGoods() {
+ return goods;
+ }
+
+ public void setGoods(Goods goods) {
+ this.goods = goods;
+ }
+
+ public String getAttachedData() {
+ return attachedData;
+ }
+
+ public void setAttachedData(String attachedData) {
+ this.attachedData = attachedData;
+ }
+
+ public String getExpireTime() {
+ return expireTime;
+ }
+
+ public void setExpireTime(String expireTime) {
+ this.expireTime = expireTime;
+ }
+
+ public String getGoodsTag() {
+ return goodsTag;
+ }
+
+ public void setGoodsTag(String goodsTag) {
+ this.goodsTag = goodsTag;
+ }
+
+ public String getGoodsTradeNo() {
+ return goodsTradeNo;
+ }
+
+ public void setGoodsTradeNo(String goodsTradeNo) {
+ this.goodsTradeNo = goodsTradeNo;
+ }
+
+ public String getOrderDesc() {
+ return orderDesc;
+ }
+
+ public void setOrderDesc(String orderDesc) {
+ this.orderDesc = orderDesc;
+ }
+
+ public String getProductId() {
+ return productId;
+ }
+
+ public void setProductId(String productId) {
+ this.productId = productId;
+ }
+
+ public String getOriginalAmount() {
+ return originalAmount;
+ }
+
+ public void setOriginalAmount(String originalAmount) {
+ this.originalAmount = originalAmount;
+ }
+
+ public String getTotalAmount() {
+ return totalAmount;
+ }
+
+ public void setTotalAmount(String totalAmount) {
+ this.totalAmount = totalAmount;
+ }
+
+ public String getNotifyUrl() {
+ return notifyUrl;
+ }
+
+ public void setNotifyUrl(String notifyUrl) {
+ this.notifyUrl = notifyUrl;
+ }
+
+ public String getReturnUrl() {
+ return returnUrl;
+ }
+
+ public void setReturnUrl(String returnUrl) {
+ this.returnUrl = returnUrl;
+ }
+
+ public String getPlaceOrderScene() {
+ return placeOrderScene;
+ }
+
+ public void setPlaceOrderScene(String placeOrderScene) {
+ this.placeOrderScene = placeOrderScene;
+ }
+
+ public String getShowUrl() {
+ return showUrl;
+ }
+
+ public void setShowUrl(String showUrl) {
+ this.showUrl = showUrl;
+ }
+
+ public String getSubAppId() {
+ return subAppId;
+ }
+
+ public void setSubAppId(String subAppId) {
+ this.subAppId = subAppId;
+ }
+
+ public String getSubOpenId() {
+ return subOpenId;
+ }
+
+ public void setSubOpenId(String subOpenId) {
+ this.subOpenId = subOpenId;
+ }
+
+ public String getUserId() {
+ return userId;
+ }
+
+ public void setUserId(String userId) {
+ this.userId = userId;
+ }
+
+ public String getTradeType() {
+ return tradeType;
+ }
+
+ public void setTradeType(String tradeType) {
+ this.tradeType = tradeType;
+ }
+
+ public String getLimitCreditCard() {
+ return limitCreditCard;
+ }
+
+ public void setLimitCreditCard(String limitCreditCard) {
+ this.limitCreditCard = limitCreditCard;
+ }
+
+ public String getInstallmentNumber() {
+ return installmentNumber;
+ }
+
+ public void setInstallmentNumber(String installmentNumber) {
+ this.installmentNumber = installmentNumber;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getMobile() {
+ return mobile;
+ }
+
+ public void setMobile(String mobile) {
+ this.mobile = mobile;
+ }
+
+ public String getCertType() {
+ return certType;
+ }
+
+ public void setCertType(String certType) {
+ this.certType = certType;
+ }
+
+ public String getCertNo() {
+ return certNo;
+ }
+
+ public void setCertNo(String certNo) {
+ this.certNo = certNo;
+ }
+
+ public String getFixBuyer() {
+ return fixBuyer;
+ }
+
+ public void setFixBuyer(String fixBuyer) {
+ this.fixBuyer = fixBuyer;
+ }
+
+ public RetCommParams getRetCommParams() {
+ return retCommParams;
+ }
+
+ public void setRetCommParams(RetCommParams retCommParams) {
+ this.retCommParams = retCommParams;
+ }
+
+ public Boolean getThirdPartyInstalSubsFlag() {
+ return thirdPartyInstalSubsFlag;
+ }
+
+ public void setThirdPartyInstalSubsFlag(Boolean thirdPartyInstalSubsFlag) {
+ this.thirdPartyInstalSubsFlag = thirdPartyInstalSubsFlag;
+ }
+
+ public String getBankCardNo() {
+ return bankCardNo;
+ }
+
+ public void setBankCardNo(String bankCardNo) {
+ this.bankCardNo = bankCardNo;
+ }
+
+ public String getInvokeScene() {
+ return invokeScene;
+ }
+
+ public void setInvokeScene(String invokeScene) {
+ this.invokeScene = invokeScene;
+ }
+
+ public String getDiscountCode() {
+ return discountCode;
+ }
+
+ public void setDiscountCode(String discountCode) {
+ this.discountCode = discountCode;
+ }
+
+ public String getYlyxId() {
+ return ylyxId;
+ }
+
+ public void setYlyxId(String ylyxId) {
+ this.ylyxId = ylyxId;
+ }
+
+ public String getYlyxName() {
+ return ylyxName;
+ }
+
+ public void setYlyxName(String ylyxName) {
+ this.ylyxName = ylyxName;
+ }
+
+ public String getYlyxMerAbbr() {
+ return ylyxMerAbbr;
+ }
+
+ public void setYlyxMerAbbr(String ylyxMerAbbr) {
+ this.ylyxMerAbbr = ylyxMerAbbr;
+ }
+
+ public String getSysSource() {
+ return sysSource;
+ }
+
+ public void setSysSource(String sysSource) {
+ this.sysSource = sysSource;
+ }
+
+ public VaFld getVaFld() {
+ return vaFld;
+ }
+
+ public void setVaFld(VaFld vaFld) {
+ this.vaFld = vaFld;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderQueryRequest.java b/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderQueryRequest.java
new file mode 100644
index 0000000..f8200ee
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/ShopCarOrderQueryRequest.java
@@ -0,0 +1,79 @@
+package org.chenyon.pay.shopcar;
+
+public class ShopCarOrderQueryRequest {
+ /**
+ * 商户订单号,必传
+ */
+ private String mchntOrderId;
+ /**
+ * 商户号,必传
+ */
+ private String vaMchntNo;
+ /**
+ * 终端号,必传
+ */
+ private String vaTermNo;
+ private String srcReserve;
+ private String instMid;
+ private String sysSource;
+ /**
+ * 增值域,必传
+ */
+ private VaFld vaFld;
+
+ public String getMchntOrderId() {
+ return mchntOrderId;
+ }
+
+ public void setMchntOrderId(String mchntOrderId) {
+ this.mchntOrderId = mchntOrderId;
+ }
+
+ public String getVaMchntNo() {
+ return vaMchntNo;
+ }
+
+ public void setVaMchntNo(String vaMchntNo) {
+ this.vaMchntNo = vaMchntNo;
+ }
+
+ public String getVaTermNo() {
+ return vaTermNo;
+ }
+
+ public void setVaTermNo(String vaTermNo) {
+ this.vaTermNo = vaTermNo;
+ }
+
+ public String getSrcReserve() {
+ return srcReserve;
+ }
+
+ public void setSrcReserve(String srcReserve) {
+ this.srcReserve = srcReserve;
+ }
+
+ public String getInstMid() {
+ return instMid;
+ }
+
+ public void setInstMid(String instMid) {
+ this.instMid = instMid;
+ }
+
+ public String getSysSource() {
+ return sysSource;
+ }
+
+ public void setSysSource(String sysSource) {
+ this.sysSource = sysSource;
+ }
+
+ public VaFld getVaFld() {
+ return vaFld;
+ }
+
+ public void setVaFld(VaFld vaFld) {
+ this.vaFld = vaFld;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java b/src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java
new file mode 100644
index 0000000..90df7e3
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java
@@ -0,0 +1,23 @@
+package org.chenyon.pay.shopcar;
+
+public class TmPayOrderRespVo {
+
+ private String url;
+ private MiniPayRequest miniPayRequest;
+
+ public String getUrl() {
+ return url;
+ }
+
+ public void setUrl(String url) {
+ this.url = url;
+ }
+
+ public MiniPayRequest getMiniPayRequest() {
+ return miniPayRequest;
+ }
+
+ public void setMiniPayRequest(MiniPayRequest miniPayRequest) {
+ this.miniPayRequest = miniPayRequest;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java b/src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java
new file mode 100644
index 0000000..1dd1d2a
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java
@@ -0,0 +1,22 @@
+package org.chenyon.pay.shopcar;
+
+public class TmPayResponse {
+ private String respCode;
+ private String respDesc;
+
+ public String getRespCode() {
+ return respCode;
+ }
+
+ public void setRespCode(String respCode) {
+ this.respCode = respCode;
+ }
+
+ public String getRespDesc() {
+ return respDesc;
+ }
+
+ public void setRespDesc(String respDesc) {
+ this.respDesc = respDesc;
+ }
+}
diff --git a/src/main/java/org/chenyon/pay/shopcar/VaFld.java b/src/main/java/org/chenyon/pay/shopcar/VaFld.java
new file mode 100644
index 0000000..34db062
--- /dev/null
+++ b/src/main/java/org/chenyon/pay/shopcar/VaFld.java
@@ -0,0 +1,81 @@
+package org.chenyon.pay.shopcar;
+
+import java.util.List;
+
+public class VaFld {
+
+ /**
+ * 新购物车标识,
+ * 新购物车交易需上送 如果不上送则为标准支付交易
+ * 线上-GWCXS
+ * 线下-BC-GWCBC
+ * 线下银行卡-GWCYH
+ */
+ private String newShopFlag;
+ /**
+ * 交易上送方式,01:主商户上送
+ * 02:子商户上送(目前仅支持公众号、小程序、H5、
+ * App、聚分期)
+ */
+ private String isSubMchntPay;
+ /**
+ * 平台分账金额
+ */
+ private String platAmt;
+ /**
+ * 分账类型,01-同步分账
+ * 02-异步分账
+ */
+ private String satType;
+
+ private GoodsInfo goodsInfo;
+ private List satInfo;
+
+ public String getNewShopFlag() {
+ return newShopFlag;
+ }
+
+ public void setNewShopFlag(String newShopFlag) {
+ this.newShopFlag = newShopFlag;
+ }
+
+ public String getIsSubMchntPay() {
+ return isSubMchntPay;
+ }
+
+ public void setIsSubMchntPay(String isSubMchntPay) {
+ this.isSubMchntPay = isSubMchntPay;
+ }
+
+ public String getPlatAmt() {
+ return platAmt;
+ }
+
+ public void setPlatAmt(String platAmt) {
+ this.platAmt = platAmt;
+ }
+
+ public String getSatType() {
+ return satType;
+ }
+
+ public void setSatType(String satType) {
+ this.satType = satType;
+ }
+
+ public GoodsInfo getGoodsInfo() {
+ return goodsInfo;
+ }
+
+ public void setGoodsInfo(GoodsInfo goodsInfo) {
+ this.goodsInfo = goodsInfo;
+ }
+
+ public List getSatInfo() {
+ return satInfo;
+ }
+
+ public void setSatInfo(List satInfo) {
+ this.satInfo = satInfo;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/potential/PotentialController.java b/src/main/java/org/chenyon/potential/PotentialController.java
index c69ad69..946ded3 100644
--- a/src/main/java/org/chenyon/potential/PotentialController.java
+++ b/src/main/java/org/chenyon/potential/PotentialController.java
@@ -1,7 +1,7 @@
package org.chenyon.potential;
-import org.chenyon.user.LoginCheck;
-import org.chenyon.user.UserContext;
+
+import org.apache.commons.lang3.StringUtils;
import org.chenyon.user.UserService;
import org.chenyon.user.UserVo;
import org.chenyon.wx.WxUserSession;
@@ -33,14 +33,23 @@ public class PotentialController {
public ResultMessage addViewRecord(HttpServletRequest request, @RequestParam("assetId") String assetId) {
try {
String token = request.getHeader("WT");
- String userType = request.getHeader("USERTYPE");
+ String userType = request.getParameter("userType");
+ if(StringUtils.isAnyBlank(token,userType)){
+ return ResultMessage.success();
+ }
+ String assetsNo = request.getParameter("assetId");
+ String assetsName = request.getParameter("assetsName");
WxUserSession session = wxUserSessionService.getSessionInfoByThirdSession(token);
UserVo userVo = userService.findByOpenIdAndUserType(session.getOpenId(), userType);
ViewRecordVo viewRecordVo = new ViewRecordVo();
- viewRecordVo.setAssetsNo(assetId);
+ viewRecordVo.setAssetsNo(assetsNo);
+ viewRecordVo.setAssetsName(assetsName);
viewRecordVo.setCusNo(userVo.getCusNo());
viewRecordVo.setPhone(userVo.getPhone());
viewRecordVo.setCusName(userVo.getUserName());
+ if(StringUtils.isBlank(userVo.getPhone())) {
+ return ResultMessage.success();
+ }
potentialService.add(viewRecordVo);
}catch (Exception e) {
log.warn("记录租户浏览记录失败: " + e.getMessage(),e);
diff --git a/src/main/java/org/chenyon/potential/ViewRecordVo.java b/src/main/java/org/chenyon/potential/ViewRecordVo.java
index 1695117..57673c4 100644
--- a/src/main/java/org/chenyon/potential/ViewRecordVo.java
+++ b/src/main/java/org/chenyon/potential/ViewRecordVo.java
@@ -6,6 +6,7 @@ public class ViewRecordVo {
private String cusName;
private String phone;
private String assetsNo;
+ private String assetsName;
public String getCusNo() {
return cusNo;
@@ -38,4 +39,12 @@ public class ViewRecordVo {
public void setAssetsNo(String assetsNo) {
this.assetsNo = assetsNo;
}
+
+ public String getAssetsName() {
+ return assetsName;
+ }
+
+ public void setAssetsName(String assetsName) {
+ this.assetsName = assetsName;
+ }
}
diff --git a/src/main/java/org/chenyon/reservation/ReservateController.java b/src/main/java/org/chenyon/reservation/ReservateController.java
index 3d3300b..0c628ba 100644
--- a/src/main/java/org/chenyon/reservation/ReservateController.java
+++ b/src/main/java/org/chenyon/reservation/ReservateController.java
@@ -61,7 +61,7 @@ public class ReservateController {
public ResultMessage countHandling() {
try {
UserContext userContext = UserContext.get();
- if(userContext == null || userContext.getCusNo() == null) {
+ if(userContext == null || userContext.getOpenId() == null) {
return ResultMessage.success(0);
}
return ResultMessage.success(reservateService.countHandling(userContext.getOpenId()));
diff --git a/src/main/java/org/chenyon/user/LoginController.java b/src/main/java/org/chenyon/user/LoginController.java
index e4d10fc..29c587b 100644
--- a/src/main/java/org/chenyon/user/LoginController.java
+++ b/src/main/java/org/chenyon/user/LoginController.java
@@ -8,6 +8,7 @@ import org.rcy.framework.utils.net.HttpRequestUtils;
import org.rcy.framework.utils.net.HttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@@ -81,6 +82,22 @@ public class LoginController {
return ResultMessage.success(userVo);
}
+ @GetMapping("/subscribeMsg")
+ @LoginCheck
+ public ResultMessage subscribeMsg(@RequestParam("subscribe") Boolean subscribe) throws Exception {
+ UserContext userContext = UserContext.get();
+ if(userContext == null) {
+ return ResultMessage.success();
+ }
+ WxUserSession wxUserSession = wxUserSessionService.getSessionInfoByThirdSession(userContext.getToken());
+ UserVo userVo = userService.findByOpenIdAndUserType(wxUserSession.getOpenId(), userContext.getUserType());
+ User user = new User();
+ BeanUtils.copyProperties(userVo,user);
+ user.setSubscribeMsg(subscribe);
+ userService.upsert(user);
+ return ResultMessage.success();
+ }
+
@PostMapping("/updateVerifyCode")
@LoginCheck
public ResultMessage updateVerifyCode(HttpServletRequest request,@RequestBody AuthInfoVo authInfoVo) throws Exception {
diff --git a/src/main/java/org/chenyon/user/UserDao.java b/src/main/java/org/chenyon/user/UserDao.java
index 03a92e6..56e2d48 100644
--- a/src/main/java/org/chenyon/user/UserDao.java
+++ b/src/main/java/org/chenyon/user/UserDao.java
@@ -4,5 +4,6 @@ import org.rcy.framework.data.dao.BaseDao;
import org.springframework.web.bind.annotation.RequestParam;
public interface UserDao extends BaseDao {
- User findByOpenIdAndUserType(@RequestParam("openId") String openId,@RequestParam("loginType") String loginType);
+ User findByOpenIdAndUserType(@RequestParam("openId") String openId,@RequestParam("userType") String userType);
+ User findByCusNo(@RequestParam("cusNo") String cusNo);
}
diff --git a/src/main/java/org/chenyon/user/UserDao.xml b/src/main/java/org/chenyon/user/UserDao.xml
index d3000e3..1bdd67c 100644
--- a/src/main/java/org/chenyon/user/UserDao.xml
+++ b/src/main/java/org/chenyon/user/UserDao.xml
@@ -4,6 +4,9 @@
+
\ No newline at end of file
diff --git a/src/main/java/org/chenyon/user/UserService.java b/src/main/java/org/chenyon/user/UserService.java
index 1b97f0c..4c98b39 100644
--- a/src/main/java/org/chenyon/user/UserService.java
+++ b/src/main/java/org/chenyon/user/UserService.java
@@ -25,6 +25,11 @@ public class UserService {
if(oldDbData != null) {
if(!oldDbData.getPhone().equals(user.getPhone())){
user.setId(oldDbData.getId());
+ }
+ if(user.getSubscribeMsg() != null && !user.getSubscribeMsg().equals(oldDbData.getSubscribeMsg())){
+ user.setId(oldDbData.getId());
+ }
+ if(user.getId() != null) {
userDao.updateByPrimaryKeySelective(user);
}
}else {
@@ -36,7 +41,7 @@ public class UserService {
User user = userDao.findByOpenIdAndUserType(openId, userType);
OaCusVo cusInfo = null;
try {
- if(user.getCusNo() != null) {
+ if(user != null && user.getCusNo() != null) {
cusInfo = oaCusService.getCusInfo(user.getCusNo());
}
}catch (Exception e) {
@@ -53,6 +58,16 @@ public class UserService {
return userVo;
}
+ public UserVo getByCusNo(String cusNo) {
+ User user = userDao.findByCusNo(cusNo);
+ if(user == null) {
+ return null;
+ }
+ UserVo userVo = new UserVo();
+ BeanUtils.copyProperties(user,userVo);
+ return userVo;
+ }
+
public void updateAuthInfo(String openId,String userType,String verifyCode) throws Exception {
//调用oa接口客商信息
User user = userDao.findByOpenIdAndUserType(openId, userType);
diff --git a/src/main/java/org/chenyon/user/UserVo.java b/src/main/java/org/chenyon/user/UserVo.java
index 27ad496..bce7805 100644
--- a/src/main/java/org/chenyon/user/UserVo.java
+++ b/src/main/java/org/chenyon/user/UserVo.java
@@ -10,6 +10,7 @@ public class UserVo implements Serializable {
private Boolean oaAuth;
private String userType = "0";
private String userName;
+ private Boolean subscribeMsg;
public String getOpenId() {
return openId;
@@ -58,4 +59,12 @@ public class UserVo implements Serializable {
public void setUserName(String userName) {
this.userName = userName;
}
+
+ public Boolean getSubscribeMsg() {
+ return subscribeMsg;
+ }
+
+ public void setSubscribeMsg(Boolean subscribeMsg) {
+ this.subscribeMsg = subscribeMsg;
+ }
}
diff --git a/src/main/java/org/chenyon/vr/VrDataController.java b/src/main/java/org/chenyon/vr/VrDataController.java
new file mode 100644
index 0000000..fd56d83
--- /dev/null
+++ b/src/main/java/org/chenyon/vr/VrDataController.java
@@ -0,0 +1,29 @@
+package org.chenyon.vr;
+
+import org.rcy.framework.api.entity.ResultMessage;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/vr")
+public class VrDataController {
+
+ private static final Logger log = LoggerFactory.getLogger(VrDataController.class);
+
+ @Autowired
+ private VrDataService vrDataService;
+
+ @GetMapping("/data")
+ public ResultMessage getVrData(String id) {
+ try {
+ return ResultMessage.success(vrDataService.getVrData(id));
+ }catch (Exception e) {
+ log.error(e.getMessage(),e);
+ }
+ return ResultMessage.success(new VrDataVo());
+ }
+}
diff --git a/src/main/java/org/chenyon/vr/VrDataService.java b/src/main/java/org/chenyon/vr/VrDataService.java
new file mode 100644
index 0000000..8ae57e8
--- /dev/null
+++ b/src/main/java/org/chenyon/vr/VrDataService.java
@@ -0,0 +1,45 @@
+package org.chenyon.vr;
+
+import org.chenyon.assets.AssetsQueryService;
+import org.chenyon.assets.vo.AssetsVo;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@Service
+public class VrDataService {
+
+ @Value("${cdn.domain}")
+ private String cdnDomain;
+ @Autowired
+ private AssetsQueryService assetsQueryService;
+
+ public VrDataVo getVrData(String id) throws Exception {
+ AssetsVo assets = assetsQueryService.getAssetsById(id);
+ if(assets == null || assets.getVrImgs() == null) {
+ return null;
+ }
+ List vrImgs = assets.getVrImgs();
+ VrDataVo dataVo = new VrDataVo();
+ dataVo.setName(assets.getAssetsName());
+ dataVo.setStartInde(0);
+ dataVo.setSpaces(buildVrSpace(vrImgs));
+ return dataVo;
+ }
+
+ private List buildVrSpace(List vrImgs) {
+ List vrSpaces = new ArrayList<>();
+ for (int i = 0; i < vrImgs.size(); i++) {
+ VrSpace vrSpace = new VrSpace();
+ vrSpace.setId(String.valueOf(i));
+ vrSpace.setName("资产全景"+i);
+ vrSpace.setType("image");
+ vrSpace.setSrc(cdnDomain + vrImgs.get(i));
+ vrSpaces.add(vrSpace);
+ }
+ return vrSpaces;
+ }
+}
diff --git a/src/main/java/org/chenyon/vr/VrDataVo.java b/src/main/java/org/chenyon/vr/VrDataVo.java
new file mode 100644
index 0000000..7bb7bf8
--- /dev/null
+++ b/src/main/java/org/chenyon/vr/VrDataVo.java
@@ -0,0 +1,33 @@
+package org.chenyon.vr;
+
+import java.util.List;
+
+public class VrDataVo {
+ private String name;
+ private Integer startInde; // 初始显示空间索引
+ private List spaces;
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Integer getStartInde() {
+ return startInde;
+ }
+
+ public void setStartInde(Integer startInde) {
+ this.startInde = startInde;
+ }
+
+ public List getSpaces() {
+ return spaces;
+ }
+
+ public void setSpaces(List spaces) {
+ this.spaces = spaces;
+ }
+}
diff --git a/src/main/java/org/chenyon/vr/VrSpace.java b/src/main/java/org/chenyon/vr/VrSpace.java
new file mode 100644
index 0000000..c036f1f
--- /dev/null
+++ b/src/main/java/org/chenyon/vr/VrSpace.java
@@ -0,0 +1,61 @@
+package org.chenyon.vr;
+
+import java.util.List;
+
+public class VrSpace {
+
+ private String id;
+ private String name;
+ private String type; // 类型:image | video | model | cubemap
+ private String src;
+ private Integer modelScale; //模型缩放
+ private List hotspots;
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getSrc() {
+ return src;
+ }
+
+ public void setSrc(String src) {
+ this.src = src;
+ }
+
+ public Integer getModelScale() {
+ return modelScale;
+ }
+
+ public void setModelScale(Integer modelScale) {
+ this.modelScale = modelScale;
+ }
+
+ public List getHotspots() {
+ return hotspots;
+ }
+
+ public void setHotspots(List hotspots) {
+ this.hotspots = hotspots;
+ }
+}
diff --git a/src/main/java/org/chenyon/vr/Vrhotspot.java b/src/main/java/org/chenyon/vr/Vrhotspot.java
new file mode 100644
index 0000000..e70fd2e
--- /dev/null
+++ b/src/main/java/org/chenyon/vr/Vrhotspot.java
@@ -0,0 +1,40 @@
+package org.chenyon.vr;
+
+public class Vrhotspot {
+ private String lon; // 经度
+ private String lat; // 纬度
+ private String targetId; // 点击后跳转到的空间 id
+ private String label;
+
+ public String getLon() {
+ return lon;
+ }
+
+ public void setLon(String lon) {
+ this.lon = lon;
+ }
+
+ public String getLat() {
+ return lat;
+ }
+
+ public void setLat(String lat) {
+ this.lat = lat;
+ }
+
+ public String getTargetId() {
+ return targetId;
+ }
+
+ public void setTargetId(String targetId) {
+ this.targetId = targetId;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+}
diff --git a/src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java b/src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java
new file mode 100644
index 0000000..090d6ee
--- /dev/null
+++ b/src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java
@@ -0,0 +1,27 @@
+package org.chenyon.pay;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.io.IOException;
+
+@RunWith(SpringJUnit4ClassRunner.class)
+@SpringBootTest
+public class TmPayTokenServiceTest {
+
+ @Autowired
+ private TmTokenService tmTokenService;
+
+ @Test
+ public void testGetToken() throws IOException {
+ String token = tmTokenService.getToken();
+ System.out.println(token);
+ }
+
+ public void testCreateOrder() {
+
+ }
+}