更新代码
This commit is contained in:
2
pom.xml
2
pom.xml
@@ -55,7 +55,7 @@
|
||||
<dependency>
|
||||
<groupId>com.maxmind.geoip2</groupId>
|
||||
<artifactId>geoip2</artifactId>
|
||||
<version>2.12.0</version> <!-- 请检查最新版本 -->
|
||||
<version>2.15.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.lionsoul</groupId>
|
||||
|
||||
@@ -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<>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<String> 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<String> getBizZones() throws Exception {
|
||||
return oaAssetService.getBizZones();
|
||||
}
|
||||
|
||||
public List<String> 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<String> 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<String> assetsCoverImg = oaFileHandlerService.getUrls(true, oaAssetsVo.getAssetsNo(), oaAssetsVo.getFormId(), "AssetsCoverImg", oaAssetsVo.getCoverImg());
|
||||
if(assetsCoverImg != null && assetsCoverImg.size() >= 1) {
|
||||
assetsVo.setCoverImgUrl(assetsCoverImg.get(0));
|
||||
}
|
||||
return assetsVo;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String> 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<String> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
public void setFeatures(List<String> features) {
|
||||
this.features = features;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<OaBillVo> 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<String,Object> params = new HashMap<>();
|
||||
params.put("billNo",billNo);
|
||||
params.put("bizType",bizType);
|
||||
return oaBillService.getBillPayReceiver(params);
|
||||
}
|
||||
}
|
||||
|
||||
15
src/main/java/org/chenyon/bill/BillStatusUpdateVo.java
Normal file
15
src/main/java/org/chenyon/bill/BillStatusUpdateVo.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.chenyon.bill;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class BillStatusUpdateVo {
|
||||
private List<String> billIds;
|
||||
|
||||
public List<String> getBillIds() {
|
||||
return billIds;
|
||||
}
|
||||
|
||||
public void setBillIds(List<String> billIds) {
|
||||
this.billIds = billIds;
|
||||
}
|
||||
}
|
||||
41
src/main/java/org/chenyon/bill/UnpaidBillVo.java
Normal file
41
src/main/java/org/chenyon/bill/UnpaidBillVo.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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";
|
||||
/**
|
||||
* 统计未缴水电费账单数
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,9 +61,9 @@ public class ContractService {
|
||||
if(oaContractVo.getAssetsVos() != null) {
|
||||
List<OaAssetsVo> assetsVos = oaContractVo.getAssetsVos();
|
||||
OaAssetsVo assetsVo = assetsVos.get(0);
|
||||
List<String> assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
|
||||
if(assetsDetailImgs != null) {
|
||||
contractVo.setCoverImgUrl(assetsDetailImgs.get(0));
|
||||
List<String> 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<ContractAssetsVo> 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<String> assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
|
||||
List<String> 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<OaAssetsVo> assetsVos = oaContractVo.getAssetsVos();
|
||||
OaAssetsVo assetsVo = assetsVos.get(0);
|
||||
List<String> assetsDetailImgs = oaFileHandlerService.getUrls(true,assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsDetailImg", assetsVo.getDetailImg());
|
||||
List<String> assetsCoverImgs = oaFileHandlerService.getUrls(true, assetsVo.getAssetsNo(), assetsVo.getFormId(), "AssetsCoverImg", assetsVo.getCoverImg());
|
||||
List<String> 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));
|
||||
|
||||
@@ -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") ? "个人" : "单位");
|
||||
|
||||
22
src/main/java/org/chenyon/file/AttachmentVo.java
Normal file
22
src/main/java/org/chenyon/file/AttachmentVo.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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<String, String> map = refLocalUrl(oaFileLocalRefVo);
|
||||
return new ArrayList<>(map.keySet());
|
||||
}
|
||||
|
||||
public List<AttachmentVo> 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<String, String> map = refLocalUrl(oaFileLocalRefVo);
|
||||
List<AttachmentVo> 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<String> getUrls(Boolean viewPublic,String bizId, String formId, String oaFieldFlag, OaFileVo oaFileVo){
|
||||
return getUrls(viewPublic,null,bizId,formId,oaFieldFlag,oaFileVo);
|
||||
}
|
||||
|
||||
public List<String> refLocalUrl(OaFileLocalRefVo oaFileLocalRefVo) {
|
||||
public Map<String,String> refLocalUrl(OaFileLocalRefVo oaFileLocalRefVo) {
|
||||
OaFileFindCondition condition1 = new OaFileFindCondition();
|
||||
condition1.setBizId(oaFileLocalRefVo.getBizId());
|
||||
condition1.setOaFormId(oaFileLocalRefVo.getOaFormId());
|
||||
@@ -64,7 +86,7 @@ public class OaFileHandlerService {
|
||||
List<OaFileLocalSubRef> subRefInfos = oaFileLocalSubRefDao.findFileInfoByMainRefId(localRefDb.getRefId());
|
||||
//先删除旧的
|
||||
Set<String> subRefSet = oaFileLocalRefVo.getSubRefIds().stream().collect(Collectors.toSet());
|
||||
List<String> nSubUrls = new ArrayList<>();
|
||||
Map<String,String> 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<String> dbSubRefSet = subRefInfos.stream().map(s -> s.getRefId()).collect(Collectors.toSet());
|
||||
@@ -89,7 +111,7 @@ public class OaFileHandlerService {
|
||||
return nSubUrls;
|
||||
}
|
||||
//附件信息完全删除
|
||||
List<String> ncSubUrls = new ArrayList<>();
|
||||
Map<String,String> ncSubUrls = new HashMap<>();
|
||||
List<String> 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<String> nSubUrls) {
|
||||
private void reBuildSubRef(String bizType,String subRefId, String mainRefId, Boolean isPublic, String owner, Map<String,String> 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<String, String> 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) {
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String,String> 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<String, String> getTemplateValue() {
|
||||
return templateValue;
|
||||
}
|
||||
|
||||
public void setTemplateValue(Map<String, String> templateValue) {
|
||||
this.templateValue = templateValue;
|
||||
}
|
||||
|
||||
public String getMessageText() {
|
||||
return messageText;
|
||||
}
|
||||
|
||||
public void setMessageText(String messageText) {
|
||||
this.messageText = messageText;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
<if test="messageReceiver != null">
|
||||
AND messageReceiver = #{messageReceiver}
|
||||
</if>
|
||||
|
||||
<if test="hasRead != null">
|
||||
AND hasRead = #{hasRead}
|
||||
</if>
|
||||
</where>
|
||||
</sql>
|
||||
</mapper>
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<SubscribeMsgSender> 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 = " 中文<xml><ToUserName><![CDATA[oia2TjjewbmiOUlr6X-1crbLOvLw]]></ToUserName><FromUserName><![CDATA[gh_7f083739789a]]></FromUserName><CreateTime>1407743423</CreateTime><MsgType><![CDATA[video]]></MsgType><Video><MediaId><![CDATA[eYJ1MbwPRJtOvIEabaxHs7TX2D-HV71s79GUxqdUkjm6Gs2Ed1KF3ulAOA9H1xG0]]></MediaId><Title><![CDATA[testCallBackReplyVideo]]></Title><Description><![CDATA[testCallBackReplyVideo]]></Description></Video></xml>";
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String,String> 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<String, String> getTemplateValue() {
|
||||
return templateValue;
|
||||
}
|
||||
|
||||
public void setTemplateValue(Map<String, String> templateValue) {
|
||||
this.templateValue = templateValue;
|
||||
}
|
||||
}
|
||||
7
src/main/java/org/chenyon/message/SubcribeMsgMode.java
Normal file
7
src/main/java/org/chenyon/message/SubcribeMsgMode.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.chenyon.message;
|
||||
|
||||
public enum SubcribeMsgMode {
|
||||
WEAPPMINIPROGRAM,
|
||||
SMS,
|
||||
EMAIL,;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.chenyon.message;
|
||||
|
||||
public interface SubscribeMsgSender {
|
||||
void sendSubscribeMsg(MessageVo messageVo);
|
||||
Boolean support(MessageVo messageVo);
|
||||
}
|
||||
111
src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java
Normal file
111
src/main/java/org/chenyon/message/WeAppMiniProgramMsgSender.java
Normal file
@@ -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<String,Object> 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<String,Object> getPushData(MessageVo messageVo) {
|
||||
switch (messageVo.getMessageType()) {
|
||||
case "BILL": return buildBillData(messageVo);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Map<String,Object> buildBillData(MessageVo messageVo) {
|
||||
Map<String,Object> data = new HashMap<>();
|
||||
//设置账单金额
|
||||
Map<String,Object> amount2 = new HashMap<>();
|
||||
amount2.put("value",messageVo.getTemplateValue().get("billAmount"));
|
||||
data.put("amount2",amount2);
|
||||
//设置账单日期
|
||||
Map<String,Object> time3 = new HashMap<>();
|
||||
time3.put("value",messageVo.getTemplateValue().get("billDate"));
|
||||
data.put("time3",time3);
|
||||
//设置备注
|
||||
Map<String,Object> thing4 = new HashMap<>();
|
||||
thing4.put("value",messageVo.getTemplateValue().get("remark"));
|
||||
data.put("thing4",thing4);
|
||||
//设置资产店名
|
||||
|
||||
Map<String,Object> thing8 = new HashMap<>();
|
||||
thing8.put("value",messageVo.getTemplateValue().get("assetsName") + "");
|
||||
data.put("thing8",thing8);
|
||||
|
||||
//设置房间号
|
||||
|
||||
Map<String,Object> 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String> attachments;
|
||||
private List<AttachmentVo> attachments;
|
||||
private List<String> imgs;
|
||||
|
||||
public String getNoticeId() {
|
||||
@@ -97,11 +99,11 @@ public class NoticeVo {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public List<String> getAttachments() {
|
||||
public List<AttachmentVo> getAttachments() {
|
||||
return attachments;
|
||||
}
|
||||
|
||||
public void setAttachments(List<String> attachments) {
|
||||
public void setAttachments(List<AttachmentVo> attachments) {
|
||||
this.attachments = attachments;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<String> 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<String,Object> params = new HashMap<>();
|
||||
params.put("assetsNo",assetsNo);
|
||||
@@ -49,4 +55,8 @@ public class OaAssetService {
|
||||
return JsonUtils.parseObject(oaResp.getDataStr(),OaAssetsVo.class);
|
||||
}
|
||||
|
||||
public List<String> getFeatures() throws Exception {
|
||||
OaResp oaResp = seeyonHttpClient.sendGet("获取特点信息",OaApiUrl.QUERY_ALL_FEATURE);
|
||||
return JsonUtils.parseObject(oaResp.getDataStr(), List.class);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,4 +91,9 @@ public class OaBillService {
|
||||
return (Integer) oaResp.getData();
|
||||
}
|
||||
|
||||
public String getBillPayReceiver(Map<String,Object> params) throws Exception {
|
||||
OaResp oaResp = seeyonHttpClient.sendPost("获取账单收款方", OaApiUrl.BILL_PAY_RECEIVER, JsonUtils.convertJson(params));
|
||||
return (String) oaResp.getData();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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<NoticeVo> pageQuery(NoticeQueryCondition condition) throws Exception {
|
||||
OaResp oaResp = seeyonHttpClient.sendPost("分页查询招商公告信息", OaApiUrl.PAGE_QUERY_NOTICE, JsonUtils.convertJson(condition));
|
||||
@@ -42,6 +47,15 @@ public class OaNoticeService {
|
||||
Map<String,Object> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<String,String> downloadFile(String bizType,String url,String refId,Boolean isPulic,String owner) throws Exception {
|
||||
Map<String,String> 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<String, Object> 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<String,String> resMap = new HashMap<>();
|
||||
resMap.put("url",returnUrl);
|
||||
resMap.put("fileName",bizFileName);
|
||||
return resMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<String> 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<String> getFeatures() {
|
||||
return features;
|
||||
}
|
||||
|
||||
public void setFeatures(List<String> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
28
src/main/java/org/chenyon/pay/CreateOrderResp.java
Normal file
28
src/main/java/org/chenyon/pay/CreateOrderResp.java
Normal file
@@ -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"
|
||||
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
76
src/main/java/org/chenyon/pay/LocalKvRedis.java
Normal file
76
src/main/java/org/chenyon/pay/LocalKvRedis.java
Normal file
@@ -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<String, String> store = new ConcurrentHashMap<>();
|
||||
|
||||
// 存储 key -> 过期时间(毫秒)
|
||||
private final ConcurrentHashMap<String, Long> 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;
|
||||
}
|
||||
|
||||
// ========== 测试 ==========
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
240
src/main/java/org/chenyon/pay/OrderService.java
Normal file
240
src/main/java/org/chenyon/pay/OrderService.java
Normal file
@@ -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<UnpaidBillVo> 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<SatInfo> satInfoList = new ArrayList<>();
|
||||
vaFld.setSatInfo(satInfoList);
|
||||
|
||||
BigDecimal gyAmount = BigDecimal.ZERO;
|
||||
BigDecimal fwglAmount = BigDecimal.ZERO;
|
||||
|
||||
for (UnpaidBillVo billVo : orderVo.getBillVoList()) {
|
||||
Map<String, Object> 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<WeAppSubOrder> 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;
|
||||
}
|
||||
}
|
||||
80
src/main/java/org/chenyon/pay/OrderVo.java
Normal file
80
src/main/java/org/chenyon/pay/OrderVo.java
Normal file
@@ -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<UnpaidBillVo> 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<UnpaidBillVo> getBillVoList() {
|
||||
return billVoList;
|
||||
}
|
||||
|
||||
public void setBillVoList(List<UnpaidBillVo> 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
190
src/main/java/org/chenyon/pay/TmHttpUtil.java
Normal file
190
src/main/java/org/chenyon/pay/TmHttpUtil.java
Normal file
@@ -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<String,String> 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<String,String> 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();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,7 +31,34 @@ 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<String,String> miniRequestMap = (Map<String, String>) 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);
|
||||
}
|
||||
|
||||
69
src/main/java/org/chenyon/pay/TmPaySignatureUtils.java
Normal file
69
src/main/java/org/chenyon/pay/TmPaySignatureUtils.java
Normal file
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
133
src/main/java/org/chenyon/pay/TmTokenService.java
Normal file
133
src/main/java/org/chenyon/pay/TmTokenService.java
Normal file
@@ -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<String, String> 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<String, String> 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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
86
src/main/java/org/chenyon/pay/WeAppOrder.java
Normal file
86
src/main/java/org/chenyon/pay/WeAppOrder.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
8
src/main/java/org/chenyon/pay/WeAppOrderDao.java
Normal file
8
src/main/java/org/chenyon/pay/WeAppOrderDao.java
Normal file
@@ -0,0 +1,8 @@
|
||||
package org.chenyon.pay;
|
||||
|
||||
import org.rcy.framework.data.dao.BaseDao;
|
||||
|
||||
public interface WeAppOrderDao extends BaseDao<WeAppOrder> {
|
||||
WeAppOrder findByBizId(String bizId);
|
||||
WeAppOrder selectByTmOrderId(String tmOrderNo);
|
||||
}
|
||||
13
src/main/java/org/chenyon/pay/WeAppOrderDao.xml
Normal file
13
src/main/java/org/chenyon/pay/WeAppOrderDao.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="org.chenyon.pay.WeAppOrderDao">
|
||||
<select id="findByBizId" resultType="WeAppOrder">
|
||||
select * from order where bizId = #{bizId};
|
||||
</select>
|
||||
<select id="selectByTmOrderId" resultType="WeAppOrder">
|
||||
select * from order where bizId = #{bizId};
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
56
src/main/java/org/chenyon/pay/WeAppSubOrder.java
Normal file
56
src/main/java/org/chenyon/pay/WeAppSubOrder.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
15
src/main/java/org/chenyon/pay/WeAppSubOrderDao.java
Normal file
15
src/main/java/org/chenyon/pay/WeAppSubOrderDao.java
Normal file
@@ -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> {
|
||||
|
||||
WeAppSubOrder selectByBillNo(String billNo);
|
||||
|
||||
List<WeAppSubOrder> selectByMainOrderId(Long mainOrderId);
|
||||
|
||||
Integer updateById(WeAppSubOrder subOrder);
|
||||
|
||||
}
|
||||
7
src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml
Normal file
7
src/main/java/org/chenyon/pay/WeAppSubOrderDao.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
|
||||
<mapper namespace="org.chenyon.pay.WeAppSubOrderDao">
|
||||
|
||||
</mapper>
|
||||
32
src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java
Normal file
32
src/main/java/org/chenyon/pay/shopcar/GoodsInfo.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
58
src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java
Normal file
58
src/main/java/org/chenyon/pay/shopcar/MiniPayRequest.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
16
src/main/java/org/chenyon/pay/shopcar/RetCommParams.java
Normal file
16
src/main/java/org/chenyon/pay/shopcar/RetCommParams.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package org.chenyon.pay.shopcar;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class RetCommParams {
|
||||
|
||||
private Map<String, Object> map;
|
||||
|
||||
public Map<String, Object> getMap() {
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setMap(Map<String, Object> map) {
|
||||
this.map = map;
|
||||
}
|
||||
}
|
||||
105
src/main/java/org/chenyon/pay/shopcar/SatInfo.java
Normal file
105
src/main/java/org/chenyon/pay/shopcar/SatInfo.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
23
src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java
Normal file
23
src/main/java/org/chenyon/pay/shopcar/TmPayOrderRespVo.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
22
src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java
Normal file
22
src/main/java/org/chenyon/pay/shopcar/TmPayResponse.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
81
src/main/java/org/chenyon/pay/shopcar/VaFld.java
Normal file
81
src/main/java/org/chenyon/pay/shopcar/VaFld.java
Normal file
@@ -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> 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<SatInfo> getSatInfo() {
|
||||
return satInfo;
|
||||
}
|
||||
|
||||
public void setSatInfo(List<SatInfo> satInfo) {
|
||||
this.satInfo = satInfo;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -4,5 +4,6 @@ import org.rcy.framework.data.dao.BaseDao;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
public interface UserDao extends BaseDao<User> {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
|
||||
<mapper namespace="org.chenyon.user.UserDao">
|
||||
<select id="findByOpenIdAndUserType" resultType="User">
|
||||
select * from USER where openId = #{openId}
|
||||
select * from USER where openId = #{openId} and userType = #{userType}
|
||||
</select>
|
||||
<select id="findByCusNo" resultType="User">
|
||||
select * from USER where cusNo = #{cusNo}
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
29
src/main/java/org/chenyon/vr/VrDataController.java
Normal file
29
src/main/java/org/chenyon/vr/VrDataController.java
Normal file
@@ -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());
|
||||
}
|
||||
}
|
||||
45
src/main/java/org/chenyon/vr/VrDataService.java
Normal file
45
src/main/java/org/chenyon/vr/VrDataService.java
Normal file
@@ -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<String> vrImgs = assets.getVrImgs();
|
||||
VrDataVo dataVo = new VrDataVo();
|
||||
dataVo.setName(assets.getAssetsName());
|
||||
dataVo.setStartInde(0);
|
||||
dataVo.setSpaces(buildVrSpace(vrImgs));
|
||||
return dataVo;
|
||||
}
|
||||
|
||||
private List<VrSpace> buildVrSpace(List<String> vrImgs) {
|
||||
List<VrSpace> 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;
|
||||
}
|
||||
}
|
||||
33
src/main/java/org/chenyon/vr/VrDataVo.java
Normal file
33
src/main/java/org/chenyon/vr/VrDataVo.java
Normal file
@@ -0,0 +1,33 @@
|
||||
package org.chenyon.vr;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class VrDataVo {
|
||||
private String name;
|
||||
private Integer startInde; // 初始显示空间索引
|
||||
private List<VrSpace> 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<VrSpace> getSpaces() {
|
||||
return spaces;
|
||||
}
|
||||
|
||||
public void setSpaces(List<VrSpace> spaces) {
|
||||
this.spaces = spaces;
|
||||
}
|
||||
}
|
||||
61
src/main/java/org/chenyon/vr/VrSpace.java
Normal file
61
src/main/java/org/chenyon/vr/VrSpace.java
Normal file
@@ -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<Vrhotspot> 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<Vrhotspot> getHotspots() {
|
||||
return hotspots;
|
||||
}
|
||||
|
||||
public void setHotspots(List<Vrhotspot> hotspots) {
|
||||
this.hotspots = hotspots;
|
||||
}
|
||||
}
|
||||
40
src/main/java/org/chenyon/vr/Vrhotspot.java
Normal file
40
src/main/java/org/chenyon/vr/Vrhotspot.java
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
27
src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java
Normal file
27
src/test/java/org/chenyon/pay/TmPayTokenServiceTest.java
Normal file
@@ -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() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user