@@ -0,0 +1,64 @@ | |||||
package com.iformall.controller; | |||||
import com.iformall.annotation.AuthIgnore; | |||||
import com.iformall.domain.entity.WxPayment; | |||||
import com.iformall.service.wx.WxPayService; | |||||
import com.iformall.utils.XmlUtil; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.apache.commons.io.IOUtils; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.web.bind.annotation.PathVariable; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.web.bind.annotation.RestController; | |||||
import java.nio.charset.Charset; | |||||
import java.util.Map; | |||||
import java.util.SortedMap; | |||||
import java.util.TreeMap; | |||||
import javax.servlet.http.HttpServletRequest; | |||||
@Slf4j | |||||
@RestController | |||||
@RequestMapping("/paidCallback") | |||||
public class WxPaidCallBackController extends BaseController { | |||||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
@Autowired | |||||
private WxPayService wxPayService; | |||||
/** | |||||
* @description 停车费支付成功通知 | |||||
* {dataItems=[{"inTime":"2020-12-09 11:21:15","carNumber":"浙-AF81797","inCarPhoto":"p201127315/NISSP_IMG_PARK_IN/20201209/a9f1130651b9493f8eab64f14afbdd47","isReal":0,"itemId":"a9f1130651b9493f8eab64f14afbdd47","inOperator":"超级管理员","equipName":"东门入口","parkName":"杭州东站西子国际","vehicleInfo":"{\"plateNo\":\"浙-AF81797\",\"plateColor\":\"GREEN\",\"plateBackColor\":0,\"plateWordColor\":0,\"vehicleColor\":null,\"vehicleLogo\":null,\"vehicleModel\":null,\"mainModel\":0,\"subModel\":0,\"vehicleModelTrust\":0,\"mainModelTrust\":0,\"subModelTrust\":0,\"plateNoTrust\":1,\"vehicleLogoTrust\":0,\"vehicleColorTrust\":0}","equipCode":"208202496","parkCode":"p201127315"}], pno=dzxzgj, sn=6C958D99D2769AA16F3A3F06E962263F, tn=-2, ts=20201209112118886, ve=1.0} | |||||
* | |||||
* | |||||
* | |||||
* @Params [paramMap] | |||||
* @return com.iformall.common.Result | |||||
* @Author furunxin | |||||
* @Date 2020/7/8 上午8:27 | |||||
**/ | |||||
@AuthIgnore | |||||
@RequestMapping(value = "/paid/{tenantId}") | |||||
public String parkInCallback(@PathVariable String tenantId,HttpServletRequest request) { | |||||
Map<String, String> paramMap = null; | |||||
String response = ""; | |||||
String xml = ""; | |||||
try { | |||||
xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); | |||||
paramMap = WxPayment.xmlToMap(xml); | |||||
paramMap.put("tenantId", tenantId); | |||||
wxPayService.handlePaidCallBack(tenantId, paramMap); | |||||
logger.info("carPaid wxpay, notify success, req : " + xml + ", resp: " + response.toString()); | |||||
return response; | |||||
} catch (Exception e) { | |||||
logger.error("Paid wxpay, notify error, req: " + xml + ", e: " + e.getMessage()); | |||||
SortedMap resultMap = new TreeMap(); | |||||
resultMap.put("return_code", "FAIL"); | |||||
resultMap.put("return_msg", e.getMessage()); | |||||
return XmlUtil.getRequestXml(resultMap); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,143 @@ | |||||
package com.iformall.controller; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.iformall.common.ErrorCode; | |||||
import com.iformall.common.IdWorker; | |||||
import com.iformall.common.Result; | |||||
import com.iformall.common.ResultData; | |||||
import com.iformall.domain.entity.PayAdapterResult; | |||||
import com.iformall.domain.po.*; | |||||
import com.iformall.domain.po.base.BaseEntity; | |||||
import com.iformall.domain.po.base.BaseEntity.SortField; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import com.iformall.enums.*; | |||||
import com.iformall.exception.MallinkException; | |||||
import com.iformall.service.*; | |||||
import com.iformall.service.wx.WxPayService; | |||||
import com.iformall.utils.Constant; | |||||
import com.iformall.utils.SysConfigConstant; | |||||
import io.swagger.annotations.Api; | |||||
import io.swagger.annotations.ApiImplicitParam; | |||||
import io.swagger.annotations.ApiImplicitParams; | |||||
import io.swagger.annotations.ApiOperation; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.beans.factory.annotation.Qualifier; | |||||
import org.springframework.data.redis.core.RedisTemplate; | |||||
import org.springframework.web.bind.annotation.*; | |||||
import java.util.Date; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
@RestController | |||||
@RequestMapping("/api/pay") | |||||
public class WxPayController extends BaseController { | |||||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
@Autowired | |||||
WxPayService wxPayService; | |||||
@Autowired | |||||
WxAppinfoService wxAppinfoService; | |||||
@Autowired | |||||
WxPayAccountService wxPayAccountService; | |||||
@Autowired | |||||
SysConfigService sysConfigService; | |||||
@Autowired | |||||
@Qualifier("objectCommonRedisTemplate") | |||||
RedisTemplate<String, Object> redisTemplate; | |||||
/** | |||||
* 停车费创建支付订单,只有supportPay=true时才调用此方法 | |||||
* | |||||
* @param paramMap | |||||
* @return | |||||
*/ | |||||
@ApiOperation(value = "创建支付订单", notes = "{}") | |||||
@PostMapping("/createPayOrder") | |||||
public ResultData createPayOrder(@RequestBody Map<String, String> paramMap) { | |||||
WxCUser wxCUser = this.getCUser(); | |||||
//String carNumber = paramMap.get("carNumber"); | |||||
try { | |||||
WxAppinfo cAppInfo = wxAppinfoService.getCAppInfoFromRedis(wxCUser.getTenantId()); | |||||
if(cAppInfo == null){ | |||||
throw new MallinkException(ErrorCode.APPINFO_NOFUND.getCode(),"未查询到C端小程序"); | |||||
} | |||||
WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(cAppInfo.getPayId()); | |||||
if(payAccount == null){ | |||||
throw new MallinkException(ErrorCode.APPINFO_NOFUND.getCode(),"未查询到payAccount."); | |||||
} | |||||
String receiverAccount = payAccount.getSubMchId(); | |||||
String apiKey = payAccount.getMerchantApiKey(); | |||||
int rlength = receiverAccount.length(); | |||||
//最大128 cuserId,cuserPhone,carNumber,amountType,merchantAccount,parkOrderNo | |||||
StringBuffer attachSb = new StringBuffer() | |||||
.append(wxCUser.getId()).append(",") | |||||
.append(wxCUser.getPhone()); | |||||
//创建微信支付订单 | |||||
final IdWorker idWorker = IdWorker.get(); | |||||
String uniquePayOrderNo = String.valueOf(idWorker.nextId()); | |||||
String attach = attachSb.toString(); | |||||
String productPre = uniquePayOrderNo;//中文签名错误 | |||||
//String productPre = "ParkOrderId"; | |||||
SysConfig sysConfig = sysConfigService.getByKey(SysConfigConstant.sale_price, payAccount); | |||||
SysConfig payCallBack = sysConfigService.getByKey(SysConfigConstant.pay_call_back, payAccount); | |||||
PayAdapterResult wxResult = wxPayService.createWxPayOrder(payAccount,cAppInfo,false,false,wxCUser.getOpenId(), receiverAccount, productPre, attach, uniquePayOrderNo, Integer.parseInt(sysConfig.getConfigItemValue()), | |||||
"127.0.0.1", payCallBack.getConfigItemValue(), apiKey, new Date()); | |||||
if (wxResult.isSuccess()) { | |||||
return new ResultData(wxResult); | |||||
}else { | |||||
return new ResultData(Result.ERROR,wxResult.getMsg()); | |||||
} | |||||
} catch (Exception e) { | |||||
logger.error("createPayOrder error",e); | |||||
return new ResultData(Result.ERROR,e.getMessage()); | |||||
} | |||||
} | |||||
/** | |||||
* 停车费支付订单列表 | |||||
* | |||||
* @param paramMap | |||||
* @return | |||||
*/ | |||||
@GetMapping("/payOrderList") | |||||
@ApiImplicitParams({ | |||||
@ApiImplicitParam(name = "pageNum", value = "页数", dataType = "int", paramType = "query", required = true), | |||||
@ApiImplicitParam(name = "pageSize", value = "每页条数", dataType = "int", paramType = "query", required = true), | |||||
}) | |||||
public ResultData payOrderList(Integer pageNum, Integer pageSize) { | |||||
WxCUser wxCUser = this.getCUser(); | |||||
WxPayOrder carPayOrder = new WxPayOrder(); | |||||
carPayOrder.updateTenantInfo(getTenantInfo()); | |||||
carPayOrder.setcUserId(wxCUser.getId()); | |||||
carPayOrder.setSortColumns(BaseEntity.SortField.CreateTime_DESC); | |||||
return new ResultData(wxPayService.listPayOrderAsPage(carPayOrder, pageNum, pageSize)); | |||||
} | |||||
/** | |||||
* 停车费支付订单详情 | |||||
* | |||||
* @param paramMap | |||||
* @return | |||||
*/ | |||||
@GetMapping("/payOrderDetail") | |||||
@ApiImplicitParams({ | |||||
@ApiImplicitParam(name = "id", value = "id", dataType = "Long", paramType = "query", required = true) | |||||
}) | |||||
public ResultData payOrderDetail(Long id) { | |||||
return new ResultData(wxPayService.detailWxCarPayOrder(id, getTenantInfo().getTenantId())); | |||||
} | |||||
} |
@@ -1,13 +0,0 @@ | |||||
package com.iformall.common; | |||||
public class SysConfigConstant { | |||||
public static final String vierfy_seconds_key="vierfySeconds"; | |||||
public static final String card_vierfy_seconds_key="cardVierfySeconds"; | |||||
public static final String default_merchant_b_user = "defaultMerchantBUserId"; | |||||
public static final String coupon_detail_show_selled = "couponDetailShowSelled"; | |||||
public static final String coupon_list_show_selled = "couponListShowSelled"; | |||||
public static final String member_seconds_key="memberSeconds"; | |||||
public static final String merchant_credit_locked="merchantCreditLocked"; | |||||
} |
@@ -0,0 +1,50 @@ | |||||
package com.iformall.domain.entity; | |||||
import java.io.Serializable; | |||||
public class PayAdapterResult implements Serializable{ | |||||
private static final long serialVersionUID = -6647306162758854293L; | |||||
private boolean isSuccess; | |||||
private String msg; | |||||
private Object data; | |||||
private String transactionId; | |||||
public PayAdapterResult() { | |||||
} | |||||
public PayAdapterResult(boolean isSuccess,String msg,Object data,String transactionId) { | |||||
this.isSuccess = isSuccess; | |||||
this.msg = msg; | |||||
this.data = data; | |||||
this.transactionId = transactionId; | |||||
} | |||||
public boolean isSuccess() { | |||||
return isSuccess; | |||||
} | |||||
public void setSuccess(boolean isSuccess) { | |||||
this.isSuccess = isSuccess; | |||||
} | |||||
public String getMsg() { | |||||
return msg; | |||||
} | |||||
public void setMsg(String msg) { | |||||
this.msg = msg; | |||||
} | |||||
public Object getData() { | |||||
return data; | |||||
} | |||||
public void setData(Object data) { | |||||
this.data = data; | |||||
} | |||||
public String getTransactionId() { | |||||
return transactionId; | |||||
} | |||||
public void setTransactionId(String transactionId) { | |||||
this.transactionId = transactionId; | |||||
} | |||||
} |
@@ -0,0 +1,29 @@ | |||||
package com.iformall.service.pay.entity; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
public class PayExtraParam { | |||||
private Map map = new HashMap(); | |||||
public PayExtraParam() { | |||||
} | |||||
public PayExtraParam(Object key,Object value) { | |||||
map.put(key, value); | |||||
} | |||||
public Object getValue(String key) { | |||||
if (map.containsKey(key)) { | |||||
return map.get(key); | |||||
} | |||||
return null; | |||||
} | |||||
public PayExtraParam set(Object key,Object value) { | |||||
this.map.put(key, value); | |||||
return this; | |||||
} | |||||
} |
@@ -0,0 +1,340 @@ | |||||
package com.iformall.domain.entity; | |||||
import java.security.cert.X509Certificate; | |||||
import java.util.HashMap; | |||||
import java.util.List; | |||||
import java.util.Map; | |||||
import javax.crypto.IllegalBlockSizeException; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; | |||||
import com.github.binarywang.wxpay.config.WxPayConfig; | |||||
import com.github.binarywang.wxpay.exception.WxPayException; | |||||
import com.github.binarywang.wxpay.service.WxPayService; | |||||
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; | |||||
import com.iformall.domain.po.WxPayAccount; | |||||
import com.iformall.utils.HttpUtil; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
public class WxPay { | |||||
protected static Logger log = LoggerFactory.getLogger(WxPay.class); | |||||
// 统一下单接口 | |||||
private static final String UNIFIEDORDER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; | |||||
// 订单查询 | |||||
private static final String ORDERQUERY_URL = "https://api.mch.weixin.qq.com/pay/orderquery"; | |||||
// 关闭订单 | |||||
private static final String CLOSEORDER_URL = "https://api.mch.weixin.qq.com/pay/closeorder"; | |||||
// 撤销订单 | |||||
private static final String REVERSE_URL = "https://api.mch.weixin.qq.com/secapi/pay/reverse"; | |||||
// 申请退款 | |||||
private static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; | |||||
// 查询退款 | |||||
private static final String REFUNDQUERY_URL = "https://api.mch.weixin.qq.com/pay/refundquery"; | |||||
// 下载对账单 | |||||
private static final String DOWNLOADBILLY_URL = "https://api.mch.weixin.qq.com/pay/downloadbill"; | |||||
// 交易保障 | |||||
private static final String REPORT_URL = "https://api.mch.weixin.qq.com/payitil/report"; | |||||
// 转换短链接 | |||||
private static final String SHORT_URL = "https://api.mch.weixin.qq.com/tools/shorturl"; | |||||
// 授权码查询openId接口 | |||||
private static final String AUTHCODETOOPENID_URL = "https://api.mch.weixin.qq.com/tools/authcodetoopenid"; | |||||
// 刷卡支付 | |||||
private static final String MICROPAY_URL = "https://api.mch.weixin.qq.com/pay/micropay"; | |||||
// 企业付款 | |||||
private static final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; | |||||
// 查询企业付款 | |||||
private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; | |||||
// 查询代金券批次 | |||||
private static final String GETCOUPONSTOCK_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock"; | |||||
// 查询代金券信息 | |||||
private static final String GETCOUPONINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/querycouponsinfo"; | |||||
// 沙箱 | |||||
private static final String SANDBOX_GETSIGNKEY_URL = "https://api.mch.weixin.qq.com/sandboxnew/pay/getsignkey"; | |||||
private WxPay() { | |||||
} | |||||
/** | |||||
* 交易类型枚举 | |||||
* | |||||
* @author Javen 2017年4月15日 | |||||
* JSAPI--公众号支付、NATIVE--原生扫码支付、APP--app支付,统一下单接口trade_type的传参可参考这里 | |||||
* MICROPAY--刷卡支付,刷卡支付有单独的支付接口,不调用统一下单接口 | |||||
*/ | |||||
public static enum TradeType { | |||||
JSAPI, NATIVE, APP, WAP, MICROPAY | |||||
} | |||||
/** | |||||
* 统一下单 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native_sl.php?chapter=9_1 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1 | |||||
* | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String pushOrder(Map<String, String> params) { | |||||
return doPost(UNIFIEDORDER_URL, params); | |||||
} | |||||
/** | |||||
* 订单查询 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_2 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_2 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String orderQuery(Map<String, String> params) { | |||||
return doPost(ORDERQUERY_URL, params); | |||||
} | |||||
/** | |||||
* 关闭订单 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi_sl.php?chapter=9_3 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_3 | |||||
* | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String closeOrder(Map<String, String> params) { | |||||
return doPost(CLOSEORDER_URL, params); | |||||
} | |||||
/** | |||||
* 撤销订单 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_11&index=3 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_11&index=3 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @param certPath | |||||
* 证书文件目录 | |||||
* @param certPass | |||||
* 证书密码 | |||||
* @return | |||||
*/ | |||||
public static String orderReverse(Map<String, String> params, String certPath, String certPass) { | |||||
return doPostSSL(REVERSE_URL, params, certPath, certPass); | |||||
} | |||||
/** | |||||
* 申请退款 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_4 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_4 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @param certPath | |||||
* 证书文件目录 | |||||
* @param certPass | |||||
* 证书密码 | |||||
* @return | |||||
*/ | |||||
public static String orderRefund(Map<String, String> params, String certPath, String certPass) { | |||||
return doPostSSL(REFUND_URL, params, certPath, certPass); | |||||
} | |||||
/** | |||||
* 查询退款 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_5 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_5 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String orderRefundQuery(Map<String, String> params) { | |||||
return doPost(REFUNDQUERY_URL, params); | |||||
} | |||||
/** | |||||
* 下载对账单 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_6 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_6 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String downloadBill(Map<String, String> params) { | |||||
return doPost(DOWNLOADBILLY_URL, params); | |||||
} | |||||
/** | |||||
* 交易保障 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_14&index=7 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_14&index=7 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String orderReport(Map<String, String> params) { | |||||
return doPost(REPORT_URL, params); | |||||
} | |||||
/** | |||||
* 转换短链接 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_9&index=8 | |||||
* 商户模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_9&index=8 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String toShortUrl(Map<String, String> params) { | |||||
return doPost(SHORT_URL, params); | |||||
} | |||||
/** | |||||
* 授权码查询openId | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_12&index=9 | |||||
* 商户模式接入文档: | |||||
* https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_13&index=9 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String authCodeToOpenid(Map<String, String> params) { | |||||
return doPost(AUTHCODETOOPENID_URL, params); | |||||
} | |||||
/** | |||||
* 刷卡支付 | |||||
* 服务商模式接入文档:https://pay.weixin.qq.com/wiki/doc/api/micropay_sl.php?chapter=9_10&index=1 | |||||
* 商户模式接入文档: | |||||
* https://pay.weixin.qq.com/wiki/doc/api/micropay.php?chapter=9_10&index=1 | |||||
* | |||||
* @param params | |||||
* 请求参数 | |||||
* @return | |||||
*/ | |||||
public static String micropay(Map<String, String> params) { | |||||
return WxPay.doPost(MICROPAY_URL, params); | |||||
} | |||||
/** | |||||
*企业付款到零钱:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2, | |||||
*微信后来改为 商家转账到零钱 产品 | |||||
* @param params | |||||
* 请求参数 | |||||
* @param certPath | |||||
* 证书文件目录 | |||||
* @param certPassword | |||||
* 证书密码 | |||||
* @return {String} | |||||
*/ | |||||
public static String transfers(Map<String, String> params, String certPath, String certPassword) { | |||||
return WxPay.doPostSSL(TRANSFERS_URL, params, certPath, certPassword); | |||||
} | |||||
/** | |||||
* 查询企业付款 | |||||
* https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 | |||||
* @param params | |||||
* 请求参数 | |||||
* @param certPath | |||||
* 证书文件目录 | |||||
* @param certPassword | |||||
* 证书密码 | |||||
* @return {String} | |||||
*/ | |||||
public static String getTransferInfo(Map<String, String> params, String certPath, String certPassword) { | |||||
return WxPay.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword); | |||||
} | |||||
/** | |||||
* 商户模式下 扫码模式一之生成二维码 | |||||
* | |||||
* @param appid | |||||
* @param mch_id | |||||
* @param product_id | |||||
* @param partnerKey | |||||
* @param isToShortUrl | |||||
* 是否转化为短连接 | |||||
* @return | |||||
*/ | |||||
public static String getCodeUrl(String appid, String mch_id, String product_id, String partnerKey, | |||||
boolean isToShortUrl) { | |||||
String url = "weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXX&mch_id=XXXXX&product_id=XXXXX&time_stamp=XXXXX&nonce_str=XXXXX"; | |||||
String timeStamp = Long.toString(System.currentTimeMillis() / 1000); | |||||
String nonceStr = Long.toString(System.currentTimeMillis()); | |||||
Map<String, String> packageParams = new HashMap<String, String>(); | |||||
packageParams.put("appid", appid); | |||||
packageParams.put("mch_id", mch_id); | |||||
packageParams.put("product_id", product_id); | |||||
packageParams.put("time_stamp", timeStamp); | |||||
packageParams.put("nonce_str", nonceStr); | |||||
String packageSign = WxPayment.createSign(packageParams, partnerKey); | |||||
String qrCodeUrl = WxPayment.replace(url, "XXXXX", packageSign, appid, mch_id, product_id, timeStamp, | |||||
nonceStr); | |||||
if (isToShortUrl) { | |||||
String shortResult = WxPay | |||||
.toShortUrl(WxPayment.buildShortUrlParasMap(appid, null, mch_id, null, qrCodeUrl, partnerKey)); | |||||
if (log.isDebugEnabled()) { | |||||
log.info(shortResult); | |||||
} | |||||
Map<String, String> shortMap = WxPayment.xmlToMap(shortResult); | |||||
String return_code = shortMap.get("return_code"); | |||||
if (WxPayment.codeIsOK(return_code)) { | |||||
String result_code = shortMap.get("result_code"); | |||||
if (WxPayment.codeIsOK(result_code)) { | |||||
qrCodeUrl = shortMap.get("short_url"); | |||||
} | |||||
} | |||||
} | |||||
return qrCodeUrl; | |||||
} | |||||
/** | |||||
* 查询代金券批次 | |||||
* https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_4&index=5 | |||||
* | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String getCouponStock(Map<String, String> params) { | |||||
return doPost(GETCOUPONSTOCK_URL, params); | |||||
} | |||||
/** | |||||
* 查询代金券信息 | |||||
* https://pay.weixin.qq.com/wiki/doc/api/tools/sp_coupon.php?chapter=12_5&index=6 | |||||
* | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String getCouponInfo(Map<String, String> params) { | |||||
return doPost(GETCOUPONINFO_URL, params); | |||||
} | |||||
/** | |||||
* 获取验签秘钥API | |||||
* https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_1 | |||||
* | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String sanboxSignGet(Map<String, String> params) { | |||||
return doPost(SANDBOX_GETSIGNKEY_URL, params); | |||||
} | |||||
public static String doPost(String url, Map<String, String> params) { | |||||
return HttpUtil.payPost(url, WxPayment.toXml(params)); | |||||
} | |||||
public static String doPostSSL(String url, Map<String, String> params, String certPath, String certPass) { | |||||
return HttpUtil.payPostSSL(url, WxPayment.toXml(params), certPath, certPass); | |||||
} | |||||
} |
@@ -0,0 +1,50 @@ | |||||
package com.iformall.domain.entity; | |||||
import lombok.Data; | |||||
/** | |||||
* Created by Stormeye on 2018/8/10. | |||||
* 普通商户模式 | |||||
*/ | |||||
@Data | |||||
public class WxPayOrderP { | |||||
private String appid; // 小程序ID | |||||
private String mch_id; // 商户号 | |||||
private String nonce_str; // 随机字符串 | |||||
private String sign; // 签名 | |||||
private String body; // 商品简单描述 128 | |||||
private String attach; // 附加数据 | |||||
private String out_trade_no; // 商户订单号 | |||||
private Integer total_fee; // 支付金额 | |||||
private String spbill_create_ip; // 支付IP | |||||
private String goods_tag; // 优惠标识 | |||||
private String notify_url; // 通知地址 | |||||
private String trade_type; // 支付类型 | |||||
private String product_id; // 商品ID - 扫码必传 | |||||
private String time_start; // 开始时间 | |||||
private String time_expire; // 失效时间 | |||||
private String openid; // openId | |||||
@Override | |||||
public String toString() { | |||||
final StringBuilder sb = new StringBuilder("WxPayOrderP{"); | |||||
sb.append("appid='").append(appid).append('\''); | |||||
sb.append(", mch_id='").append(mch_id).append('\''); | |||||
sb.append(", nonce_str='").append(nonce_str).append('\''); | |||||
sb.append(", sign='").append(sign).append('\''); | |||||
sb.append(", attach='").append(attach).append('\''); | |||||
sb.append(", body='").append(body).append('\''); | |||||
sb.append(", out_trade_no='").append(out_trade_no).append('\''); | |||||
sb.append(", total_fee=").append(total_fee); | |||||
sb.append(", spbill_create_ip='").append(spbill_create_ip).append('\''); | |||||
sb.append(", goods_tag='").append(goods_tag).append('\''); | |||||
sb.append(", notify_url='").append(notify_url).append('\''); | |||||
sb.append(", trade_type='").append(trade_type).append('\''); | |||||
sb.append(", product_id='").append(product_id).append('\''); | |||||
sb.append(", time_start='").append(time_start).append('\''); | |||||
sb.append(", time_expire='").append(time_expire).append('\''); | |||||
sb.append(", openid='").append(openid).append('\''); | |||||
sb.append('}'); | |||||
return sb.toString(); | |||||
} | |||||
} |
@@ -0,0 +1,646 @@ | |||||
package com.iformall.domain.entity; | |||||
import com.iformall.utils.*; | |||||
import org.apache.commons.codec.digest.HmacAlgorithms; | |||||
import org.apache.commons.codec.digest.HmacUtils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.UnsupportedEncodingException; | |||||
import java.net.URLEncoder; | |||||
import java.nio.charset.Charset; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import java.util.Map.Entry; | |||||
import java.util.TreeMap; | |||||
public class WxPayment { | |||||
/** | |||||
* 构建参数 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param device_info | |||||
* @param body | |||||
* @param detail | |||||
* @param attach | |||||
* @param out_trade_no | |||||
* @param total_fee | |||||
* @param spbill_create_ip | |||||
* @param auth_code | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String device_info, String body, String detail, String attach, String out_trade_no, String total_fee, | |||||
String spbill_create_ip, String auth_code, String paternerKey) { | |||||
Map<String, String> queryParas = new HashMap<String, String>(); | |||||
queryParas.put("appid", appid); | |||||
queryParas.put("sub_appid", sub_appid); | |||||
queryParas.put("mch_id", mch_id); | |||||
queryParas.put("sub_mch_id", sub_mch_id); | |||||
queryParas.put("device_info", device_info); | |||||
queryParas.put("nonce_str", String.valueOf(System.currentTimeMillis())); | |||||
queryParas.put("body", body); | |||||
queryParas.put("detail", detail); | |||||
queryParas.put("attach", attach); | |||||
queryParas.put("out_trade_no", out_trade_no); | |||||
queryParas.put("total_fee", total_fee); | |||||
queryParas.put("spbill_create_ip", spbill_create_ip); | |||||
queryParas.put("auth_code", auth_code); | |||||
String sign = WxPayment.createSign(queryParas, paternerKey); | |||||
queryParas.put("sign", sign); | |||||
return queryParas; | |||||
} | |||||
/** | |||||
* 封装查询请求参数 参考代码 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param transaction_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildQueryParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String transaction_id, String out_trade_no, String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
params.put("transaction_id", transaction_id); | |||||
params.put("out_trade_no", out_trade_no); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 构建统一下单参数 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* 否 | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* 服务商模式下必须 | |||||
* @param device_info | |||||
* 否 | |||||
* @param body | |||||
* @param detail | |||||
* 否 | |||||
* @param attach | |||||
* 否 | |||||
* @param out_trade_no | |||||
* @param total_fee | |||||
* @param spbill_create_ip | |||||
* @param paternerKey | |||||
* @param notify_url | |||||
* @param openId // JSAPI 必传 | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildUnifiedOrderParasMap(String appid, String sub_appid, String mch_id, | |||||
String sub_mch_id, String device_info, String body, String detail, String attach, String out_trade_no, | |||||
String total_fee, String spbill_create_ip, String notify_url, String paternerKey, | |||||
String openId) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
params.put("device_info", device_info); | |||||
params.put("body", body); | |||||
params.put("detail", detail); | |||||
params.put("attach", attach); | |||||
params.put("out_trade_no", out_trade_no); | |||||
params.put("total_fee", total_fee); | |||||
params.put("spbill_create_ip", spbill_create_ip); | |||||
params.put("notify_url", notify_url); | |||||
params.put("trade_type", "JSAPI"); | |||||
// params.put("product_id", product_id); // trade_type=NATIVE时(即扫码支付)必传 | |||||
params.put("openid", openId); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 构建短链接参数 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param long_url | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildShortUrlParasMap(String appid, String sub_appid, String mch_id, | |||||
String sub_mch_id, String long_url, String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
params.put("long_url", long_url); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 小程序统一下单后二次签名 | |||||
* | |||||
* @param appId | |||||
* @param timestamp | |||||
* @param prepay_id | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildWeappSecondSignMap(String appId, String timestamp, String prepay_id, String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
Map<String, String> sighMap = MapUtil.getOrderMap(); | |||||
sighMap.put("appId", appId); | |||||
sighMap.put("timeStamp", timestamp); | |||||
sighMap.put("package", "prepay_id="+prepay_id); | |||||
//sighMap.put("signType", "MD5"); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 关闭订单 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildCloseMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String out_trade_no, String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
params.put("out_trade_no", out_trade_no); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 申请退款 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildRefundMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String transaction_id, String out_trade_no, String out_refund_no, | |||||
String total_fee, String refund_fee, String refund_desc, String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
params.put("transaction_id", transaction_id); | |||||
params.put("out_trade_no", out_trade_no); | |||||
params.put("out_refund_no", out_refund_no); | |||||
params.put("total_fee", total_fee); | |||||
params.put("refund_fee", refund_fee); | |||||
params.put("refund_desc", refund_desc); | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 查询退款 | |||||
* | |||||
* @param appid | |||||
* @param sub_appid | |||||
* @param mch_id | |||||
* @param sub_mch_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildRefundQueryMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String transaction_id, String out_trade_no, String out_refund_no, String refund_id, | |||||
String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
if(!StringUtils.isBlank(refund_id)) { | |||||
params.put("refund_id", refund_id); | |||||
} else if (!StringUtils.isBlank(out_refund_no)) { | |||||
params.put("out_refund_no", out_refund_no); | |||||
} else if (!StringUtils.isBlank(transaction_id)) { | |||||
params.put("transaction_id", transaction_id); | |||||
} else if (!StringUtils.isBlank(out_trade_no)) { | |||||
params.put("out_trade_no", out_trade_no); | |||||
} | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 查询退款 | |||||
* | |||||
* @param appid | |||||
* @param mch_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildWeappRefundQueryMap(String appid, String mch_id, | |||||
String transaction_id, String out_trade_no, String out_refund_no, String refund_id, | |||||
String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("mch_id", mch_id); | |||||
if(!StringUtils.isBlank(refund_id)) { | |||||
params.put("refund_id", refund_id); | |||||
} else if (!StringUtils.isBlank(out_refund_no)) { | |||||
params.put("out_refund_no", out_refund_no); | |||||
} else if (!StringUtils.isBlank(transaction_id)) { | |||||
params.put("transaction_id", transaction_id); | |||||
} else if (!StringUtils.isBlank(out_trade_no)) { | |||||
params.put("out_trade_no", out_trade_no); | |||||
} | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 服务商查询退款 | |||||
* | |||||
* @param appid | |||||
* @param mch_id | |||||
* @param out_trade_no | |||||
* @param paternerKey | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> buildSWeappRefundQueryMap(String appid, String sub_appid, String mch_id, String sub_mch_id, | |||||
String transaction_id, String out_trade_no, String out_refund_no, String refund_id, | |||||
String paternerKey) { | |||||
Map<String, String> params = new HashMap<String, String>(); | |||||
params.put("appid", appid); | |||||
params.put("sub_appid", sub_appid); | |||||
params.put("mch_id", mch_id); | |||||
params.put("sub_mch_id", sub_mch_id); | |||||
if(!StringUtils.isBlank(refund_id)) { | |||||
params.put("refund_id", refund_id); | |||||
} else if (!StringUtils.isBlank(out_refund_no)) { | |||||
params.put("out_refund_no", out_refund_no); | |||||
} else if (!StringUtils.isBlank(transaction_id)) { | |||||
params.put("transaction_id", transaction_id); | |||||
} else if (!StringUtils.isBlank(out_trade_no)) { | |||||
params.put("out_trade_no", out_trade_no); | |||||
} | |||||
return buildSignAfterParasMap(params, paternerKey); | |||||
} | |||||
/** | |||||
* 组装签名的字段 | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @param urlEncoder | |||||
* 是否urlEncoder | |||||
* @return String | |||||
*/ | |||||
public static String packageSign(Map<String, String> params, boolean urlEncoder) { | |||||
// 先将参数以其参数名的字典序升序进行排序 | |||||
TreeMap<String, String> sortedParams = new TreeMap<String, String>(params); | |||||
// 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起 | |||||
StringBuilder sb = new StringBuilder(); | |||||
boolean first = true; | |||||
for (Entry<String, String> param : sortedParams.entrySet()) { | |||||
String value = param.getValue(); | |||||
if (StringUtils.isBlank(value)) { | |||||
continue; | |||||
} | |||||
if (first) { | |||||
first = false; | |||||
} else { | |||||
sb.append("&"); | |||||
} | |||||
sb.append(param.getKey()).append("="); | |||||
if (urlEncoder) { | |||||
try { | |||||
value = urlEncode(value); | |||||
} catch (UnsupportedEncodingException e) { | |||||
} | |||||
} | |||||
sb.append(value); | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
/** | |||||
* urlEncode | |||||
* | |||||
* @param src | |||||
* 微信参数 | |||||
* @return String | |||||
* @throws UnsupportedEncodingException | |||||
* 编码错误 | |||||
*/ | |||||
public static String urlEncode(String src) throws UnsupportedEncodingException { | |||||
return URLEncoder.encode(src, Charset.forName("UTF-8").name()).replace("+", "%20"); | |||||
} | |||||
/** | |||||
* 构建签名之后的参数 | |||||
* | |||||
* @param params | |||||
* @param paternerKey | |||||
* @return Map | |||||
*/ | |||||
public static Map<String, String> buildSignAfterParasMap(Map<String, String> params, String paternerKey) { | |||||
params.put("nonce_str", Utility.generateUUID().replace("-", "")); | |||||
String sign = WxPayment.createSign(params, paternerKey); | |||||
params.put("sign", sign); | |||||
return params; | |||||
} | |||||
/** | |||||
* 构建签名之后的参数 | |||||
* | |||||
* @param params | |||||
* @param paternerKey | |||||
* @return Map | |||||
*/ | |||||
public static Map<String, String> buildSignAfterParasMapForHMAC(Map<String, String> params, String paternerKey) { | |||||
params.put("nonce_str", Utility.generateUUID().replace("-", "")); | |||||
String sign = WxPayment.createSignHMAC(params, paternerKey); | |||||
params.put("sign", sign); | |||||
return params; | |||||
} | |||||
/** | |||||
* 生成签名 | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @param partnerKey | |||||
* 支付密钥 | |||||
* @return sign | |||||
*/ | |||||
public static String createSign(Map<String, String> params, String partnerKey) { | |||||
// 生成签名前先去除sign | |||||
params.remove("sign"); | |||||
String stringA = packageSign(params, false); | |||||
String stringSignTemp = stringA + "&key=" + partnerKey; | |||||
return HashUtil.md5(stringSignTemp).toUpperCase(); | |||||
} | |||||
/** | |||||
* 生成签名 | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @param partnerKey | |||||
* 支付密钥 | |||||
* @return sign | |||||
*/ | |||||
public static String createSignHMAC(Map<String, String> params, String partnerKey) { | |||||
// 生成签名前先去除sign | |||||
params.remove("sign"); | |||||
String stringA = packageSign(params, false); | |||||
String stringSignTemp = stringA + "&key=" + partnerKey; | |||||
return new HmacUtils(HmacAlgorithms.HMAC_SHA_256, partnerKey).hmacHex(stringSignTemp).toUpperCase(); | |||||
} | |||||
/** | |||||
* 支付异步通知时校验sign | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @param paternerKey | |||||
* 支付密钥 | |||||
* @return {boolean} | |||||
*/ | |||||
public static boolean verifyNotify(Map<String, String> params, String paternerKey) { | |||||
String sign = params.get("sign"); | |||||
if (sign == null) | |||||
return true; | |||||
String localSign = WxPayment.createSign(params, paternerKey); | |||||
return sign.equals(localSign); | |||||
} | |||||
/** | |||||
* 支付异步通知时校验sign | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @param paternerKey | |||||
* 支付密钥 | |||||
* @return {boolean} | |||||
*/ | |||||
public static boolean verifyNotifyHMAC(Map<String, String> params, String paternerKey) { | |||||
String sign = params.get("sign"); | |||||
if (sign == null) | |||||
return true; | |||||
String localSign = WxPayment.createSignHMAC(params, paternerKey); | |||||
return sign.equals(localSign); | |||||
} | |||||
/** | |||||
* 判断接口返回的code是否是SUCCESS | |||||
* | |||||
* @param return_code、result_code | |||||
* @return | |||||
*/ | |||||
public static boolean codeIsOK(String return_code) { | |||||
return StringUtils.isNotBlank(return_code) && "SUCCESS".equals(return_code); | |||||
} | |||||
/** | |||||
* 微信下单map to xml | |||||
* | |||||
* @param params | |||||
* 参数 | |||||
* @return String | |||||
*/ | |||||
private static String toXmlContent(Map<String, String> params,boolean containChinese) { | |||||
StringBuilder xml = new StringBuilder(); | |||||
xml.append("<xml>"); | |||||
for (Entry<String, String> entry : params.entrySet()) { | |||||
String key = entry.getKey(); | |||||
String value = entry.getValue(); | |||||
// 略过空值 | |||||
if (StringUtils.isBlank(value)) | |||||
continue; | |||||
xml.append("<").append(key).append(">"); | |||||
xml.append(entry.getValue()); | |||||
xml.append("</").append(key).append(">"); | |||||
} | |||||
xml.append("</xml>"); | |||||
return xml.toString(); | |||||
} | |||||
public static String toXml(Map<String, String> params) { | |||||
return toXmlContent(params,false); | |||||
} | |||||
public static String toXmlWhitChinese(Map<String, String> params) { | |||||
return toXmlContent(params,true); | |||||
} | |||||
/** | |||||
* 针对支付的xml,没有嵌套节点的简单处理 | |||||
* | |||||
* @param xmlStr | |||||
* xml字符串 | |||||
* @return map集合 | |||||
*/ | |||||
@SuppressWarnings("unchecked") | |||||
public static Map<String, String> xmlToMap(String xmlStr) { | |||||
return XmlUtil.parseXml2Map(xmlStr); | |||||
} | |||||
/** | |||||
* 替换url中的参数 | |||||
* | |||||
* @param str | |||||
* @param regex | |||||
* @param args | |||||
* @return | |||||
*/ | |||||
public static String replace(String str, String regex, String... args) { | |||||
int length = args.length; | |||||
for (int i = 0; i < length; i++) { | |||||
str = str.replaceFirst(regex, args[i]); | |||||
} | |||||
return str; | |||||
} | |||||
private static void getSanboxKeyTest() { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("mch_id", "1511925291"); | |||||
// map.put("sub_mch_id", "1513691501"); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
String sign = WxPayment.createSign(map, "XHZfpVA0NzoXgLEjsujctUTcyj8Zur2C"); | |||||
map.put("sign", sign); | |||||
String response = WxPay.sanboxSignGet(map); | |||||
System.out.println(response); | |||||
/* | |||||
<xml> | |||||
<return_code><![CDATA[SUCCESS]]></return_code> | |||||
<return_msg><![CDATA[ok]]></return_msg> | |||||
<sandbox_signkey><![CDATA[7e9d244da17632cdf608e04564a628da]]></sandbox_signkey> | |||||
</xml> | |||||
*/ | |||||
} | |||||
private static void getDownloadBillTest(String signKey) { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("appid", "wxed2f44705544b892"); | |||||
map.put("mch_id", "1511925291"); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
map.put("bill_date", "20190524"); | |||||
map.put("bill_type", "ALL"); | |||||
String sign = WxPayment.createSign(map, signKey); | |||||
map.put("sign", sign); | |||||
String response = WxPay.downloadBill(map); | |||||
System.out.println(response); | |||||
} | |||||
private static void microPaySanbox(String signKey, String outTradeNo) { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("appid", "wxed2f44705544b892"); | |||||
map.put("mch_id", "1511925291"); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
map.put("body", "image形象店-深圳腾大- QQ公仔"); | |||||
map.put("out_trade_no", outTradeNo); | |||||
map.put("total_fee", "502"); | |||||
map.put("spbill_create_ip", "172.16.115.182"); | |||||
map.put("auth_code", "134659695358765866"); | |||||
String sign = WxPayment.createSign(map, signKey); | |||||
map.put("sign", sign); | |||||
String response = WxPay.micropay(map); | |||||
System.out.println("micropay"); | |||||
System.out.println(response); | |||||
} | |||||
private static void queryPaySanbox(String signKey, String outTradeNo) { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("appid", "wxed2f44705544b892"); | |||||
map.put("mch_id", "1511925291"); | |||||
map.put("out_trade_no", outTradeNo); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
String sign = WxPayment.createSign(map, signKey); | |||||
map.put("sign", sign); | |||||
String response = WxPay.orderQuery(map); | |||||
System.out.println("micropayQuery"); | |||||
System.out.println(response); | |||||
} | |||||
private static void refundSanbox(String signKey, String outTradeNo, String outRefundNo) { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("appid", "wxed2f44705544b892"); | |||||
map.put("mch_id", "1511925291"); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
map.put("out_trade_no", outTradeNo); | |||||
map.put("out_refund_no", outRefundNo); | |||||
map.put("total_fee", "502"); | |||||
map.put("refund_fee", "501"); | |||||
String sign = WxPayment.createSign(map, signKey); | |||||
map.put("sign", sign); | |||||
String response = WxPay.orderRefund(map, "/opt/iformall/service/apiclient_cert.p12", "1511925291"); | |||||
System.out.println("refund"); | |||||
System.out.println(response); | |||||
} | |||||
private static void refundQuerySanbox(String signKey, String outTradeNo, String outRefundNo) { | |||||
Map map = MapUtil.getOrderMap(); | |||||
map.put("appid", "wxed2f44705544b892"); | |||||
map.put("mch_id", "1511925291"); | |||||
map.put("nonce_str", RandomUtils.getStr(32)); | |||||
map.put("out_trade_no", outTradeNo); | |||||
map.put("out_refund_no", outRefundNo); | |||||
String sign = WxPayment.createSign(map, signKey); | |||||
map.put("sign", sign); | |||||
String response = WxPay.orderRefundQuery(map); | |||||
System.out.println("refundQuery"); | |||||
System.out.println(response); | |||||
} | |||||
public static void main(String[] args) { | |||||
String signKey = "7e9d244da17632cdf608e04564a628da"; | |||||
String outTradeNo = "1459833232543346"; | |||||
String outRefundNo = "143446547"; | |||||
microPaySanbox(signKey, outTradeNo); | |||||
queryPaySanbox(signKey, outTradeNo); | |||||
refundSanbox(signKey, outTradeNo, outRefundNo); | |||||
refundQuerySanbox(signKey, outTradeNo, outRefundNo); | |||||
} | |||||
} |
@@ -0,0 +1,37 @@ | |||||
package com.iformall.domain.po; | |||||
import java.util.Date; | |||||
import com.baomidou.mybatisplus.annotation.TableField; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import com.iformall.domain.po.base.BaseEntity; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
@TableName(value = "sys_config") | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = true) | |||||
public class SysConfig extends BaseEntity { | |||||
private static final long serialVersionUID = 1L; | |||||
protected Long id; | |||||
@io.swagger.annotations.ApiModelProperty(value="配置项key",name="configItemKey") | |||||
private String configItemKey; | |||||
@io.swagger.annotations.ApiModelProperty(value="配置项说明",name="configItemRemark") | |||||
private String configItemRemark; | |||||
@io.swagger.annotations.ApiModelProperty(value="",name="createDate") | |||||
private Date createDate; | |||||
@io.swagger.annotations.ApiModelProperty(value="",name="updateDate") | |||||
private Date updateDate; | |||||
@io.swagger.annotations.ApiModelProperty(value="是否隐藏",name="isHide") | |||||
private Integer isHide; | |||||
@io.swagger.annotations.ApiModelProperty(value="0-有效 1-无效",name="status") | |||||
private Integer status; | |||||
@io.swagger.annotations.ApiModelProperty(value="配置项value,查询显示用",name="configItemValue") | |||||
@TableField(exist = false) | |||||
private String configItemValue; | |||||
} |
@@ -0,0 +1,38 @@ | |||||
package com.iformall.domain.po; | |||||
import com.baomidou.mybatisplus.annotation.IdType; | |||||
import com.baomidou.mybatisplus.annotation.TableId; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import com.iformall.domain.po.base.BaseEntity; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import java.util.Date; | |||||
/** | |||||
* 系统用户Token | |||||
* | |||||
* @author Stormeye | |||||
*/ | |||||
@Data | |||||
@TableName("sys_config_value") | |||||
@EqualsAndHashCode(callSuper = true) | |||||
public class SysConfigValue extends TenantEntity { | |||||
private static final long serialVersionUID = -5887774776970688169L; | |||||
private Long id; | |||||
@io.swagger.annotations.ApiModelProperty(value="配置项id",name="configItemId") | |||||
private Long configItemId; | |||||
@io.swagger.annotations.ApiModelProperty(value="配置项value",name="configItemValue") | |||||
private String configItemValue; | |||||
@io.swagger.annotations.ApiModelProperty(value="过期时间",name="expireTime") | |||||
private Date createDate; | |||||
@io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateTime") | |||||
private Date updateDate; | |||||
} |
@@ -0,0 +1,55 @@ | |||||
package com.iformall.domain.po; | |||||
import com.baomidou.mybatisplus.annotation.TableField; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import lombok.Data; | |||||
import lombok.EqualsAndHashCode; | |||||
import lombok.ToString; | |||||
import java.util.*; | |||||
@TableName(value = "wx_pay_order") | |||||
@Data | |||||
@EqualsAndHashCode(callSuper = true) | |||||
@ToString | |||||
public class WxPayOrder extends TenantEntity { | |||||
private static final long serialVersionUID = -5094915301794376964L; | |||||
protected Long id; | |||||
@io.swagger.annotations.ApiModelProperty(value="创建时间",name="createTime") | |||||
private Date createTime; | |||||
@io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateTime") | |||||
private Date updateTime; | |||||
@io.swagger.annotations.ApiModelProperty(value="用户ID",name="cUserId") | |||||
private Long cUserId; | |||||
@TableField(exist = false) | |||||
private List<Long> userIds; | |||||
@io.swagger.annotations.ApiModelProperty(value="用户手机号",name="cUserPhone") | |||||
private String cUserPhone; | |||||
public Long getcUserId() { | |||||
return cUserId; | |||||
} | |||||
public void setcUserId(Long cUserId) { | |||||
this.cUserId = cUserId; | |||||
} | |||||
public String getcUserPhone() { | |||||
return cUserPhone; | |||||
} | |||||
public void setcUserPhone(String cUserPhone) { | |||||
this.cUserPhone = cUserPhone; | |||||
} | |||||
@io.swagger.annotations.ApiModelProperty(value="支付金额(分)",name="payAmount") | |||||
private Integer payAmount; | |||||
@io.swagger.annotations.ApiModelProperty(value="支付时间",name="payTime") | |||||
private Date payTime; | |||||
@io.swagger.annotations.ApiModelProperty(value="微信生成的订单号",name="transactionId") | |||||
private String transactionId; | |||||
@TableField(exist = false) | |||||
private Date begin; | |||||
@TableField(exist = false) | |||||
private Date end; | |||||
} |
@@ -0,0 +1,34 @@ | |||||
package com.iformall.enums; | |||||
public enum EnumPayType { | |||||
CAR_ISV_MERCHANT(1, "特约停车商户"), | |||||
CAR_OWN_MERCHANT(2, "自有停车商户"), | |||||
PAY_ACCOUNT(3,"小程序收款账户") | |||||
; | |||||
public static EnumPayType getEnum(Integer code) { | |||||
for (EnumPayType value : values()) { | |||||
if (value.getCode().equals(code)) { | |||||
return value; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
private Integer code; | |||||
private String message; | |||||
EnumPayType(Integer code, String message) { | |||||
this.code = code; | |||||
this.message = message; | |||||
} | |||||
public Integer getCode() { | |||||
return code; | |||||
} | |||||
public String getMessage() { | |||||
return message; | |||||
} | |||||
} |
@@ -0,0 +1,33 @@ | |||||
package com.iformall.enums; | |||||
public enum EnumYesOrNo { | |||||
YES(1, "是"), | |||||
NO(0, "否"), | |||||
; | |||||
public static EnumYesOrNo getEnum(Integer code) { | |||||
for (EnumYesOrNo value : values()) { | |||||
if (value.getCode().equals(code)) { | |||||
return value; | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
private Integer code; | |||||
private String message; | |||||
EnumYesOrNo(Integer code, String message) { | |||||
this.code = code; | |||||
this.message = message; | |||||
} | |||||
public Integer getCode() { | |||||
return code; | |||||
} | |||||
public String getMessage() { | |||||
return message; | |||||
} | |||||
} |
@@ -0,0 +1,14 @@ | |||||
package com.iformall.mapper; | |||||
import java.util.*; | |||||
import com.iformall.common.CommonMapper; | |||||
import com.iformall.domain.po.SysConfig; | |||||
public interface SysConfigMapper extends CommonMapper<SysConfig, Long> { | |||||
List<SysConfig> findList(SysConfig sysMonitor); | |||||
SysConfig findByKey(SysConfig sysMonitor); | |||||
} |
@@ -0,0 +1,10 @@ | |||||
package com.iformall.mapper; | |||||
import com.iformall.common.CommonMapper; | |||||
import com.iformall.domain.po.SysConfigValue; | |||||
public interface SysConfigValueMapper extends CommonMapper<SysConfigValue, Long> { | |||||
SysConfigValue findByItemId(SysConfigValue record); | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.iformall.mapper; | |||||
import java.util.*; | |||||
import org.apache.ibatis.annotations.Param; | |||||
import com.iformall.common.CommonMapper; | |||||
import com.iformall.domain.po.WxPayOrder; | |||||
public interface WxPayOrderMapper extends CommonMapper<WxPayOrder, Long> { | |||||
WxPayOrder selectById(@Param("id")Long id,@Param("tenantId")String tenantId); | |||||
List<WxPayOrder> findList(WxPayOrder wxCarPayOrder); | |||||
WxPayOrder findOneByParkOderNo(@Param("parkOrderNo")String parkOrderNo,@Param("tenantId")String tenantId); | |||||
Integer sum(WxPayOrder wxCarPayOrder); | |||||
} |
@@ -0,0 +1,40 @@ | |||||
package com.iformall.service; | |||||
import com.github.pagehelper.PageInfo; | |||||
import com.iformall.domain.po.SysConfig; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import java.util.List; | |||||
public interface SysConfigService { | |||||
PageInfo<SysConfig> listAsPage(SysConfig record, Integer pageIndex, Integer pageSize,TenantEntity tenantEntity); | |||||
/** | |||||
* 根据实体查询列表 | |||||
* | |||||
* @param record | |||||
* @return | |||||
*/ | |||||
List<SysConfig> getList(SysConfig record,TenantEntity tenantEntity); | |||||
/** | |||||
* 根据Id获得实体 | |||||
* | |||||
* @param id | |||||
* @return | |||||
*/ | |||||
SysConfig getById(Long id,TenantEntity tenantEntity); | |||||
SysConfig getByKey(String key,TenantEntity tenantEntity); | |||||
/** | |||||
* 保存或更新实体 | |||||
* | |||||
* @param | |||||
*/ | |||||
void saveConfigValue(Long id,TenantEntity tenantEntity,String value); | |||||
void saveOrUpdate(SysConfig record); | |||||
} |
@@ -0,0 +1,147 @@ | |||||
package com.iformall.service.impl; | |||||
import java.util.*; | |||||
import com.iformall.domain.po.SysConfig; | |||||
import com.iformall.domain.po.SysConfigValue; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import com.iformall.mapper.SysConfigMapper; | |||||
import com.iformall.mapper.SysConfigValueMapper; | |||||
import com.iformall.service.SysConfigService; | |||||
import com.iformall.utils.RedisCacheUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.beans.factory.annotation.Qualifier; | |||||
import org.springframework.data.redis.core.RedisTemplate; | |||||
import org.springframework.stereotype.Service; | |||||
import com.github.pagehelper.PageHelper; | |||||
import com.github.pagehelper.PageInfo; | |||||
import com.iformall.common.IdWorker; | |||||
@Service | |||||
public class SysConfigServiceImpl implements SysConfigService { | |||||
private static final String cache_prex = "sysconfig:%s:%s"; | |||||
@Autowired | |||||
SysConfigMapper sysConfigMapper; | |||||
@Autowired | |||||
SysConfigValueMapper sysConfigValueMapper; | |||||
@Autowired | |||||
@Qualifier("objectCommonRedisTemplate") | |||||
RedisTemplate<String, Object> baseRedisTemplate; | |||||
@Override | |||||
public PageInfo<SysConfig> listAsPage(SysConfig record, Integer pageIndex, Integer pageSize,TenantEntity tenantEntity) { | |||||
PageInfo<SysConfig> page = PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> sysConfigMapper.findList(record)); | |||||
if (null != page && null != page.getList()) { | |||||
for (SysConfig config : page.getList()) { | |||||
SysConfigValue cvq = new SysConfigValue(); | |||||
cvq.setConfigItemId(config.getId()); | |||||
cvq.updateTenantInfo(tenantEntity); | |||||
SysConfigValue configValue = sysConfigValueMapper.findByItemId(cvq); | |||||
if (null != configValue) { | |||||
config.setConfigItemValue(configValue.getConfigItemValue()); | |||||
} | |||||
} | |||||
} | |||||
return page; | |||||
} | |||||
@Override | |||||
public List<SysConfig> getList(SysConfig record,TenantEntity tenantEntity) { | |||||
List<SysConfig> list = sysConfigMapper.findList(record); | |||||
if (null != list) { | |||||
for (SysConfig config : list) { | |||||
SysConfigValue cvq = new SysConfigValue(); | |||||
cvq.setConfigItemId(config.getId()); | |||||
cvq.updateTenantInfo(tenantEntity); | |||||
SysConfigValue configValue = sysConfigValueMapper.findByItemId(cvq); | |||||
if (null != configValue) { | |||||
config.setConfigItemValue(configValue.getConfigItemValue()); | |||||
} | |||||
} | |||||
} | |||||
return list; | |||||
} | |||||
@Override | |||||
public SysConfig getById(Long id,TenantEntity tenantEntity) { | |||||
SysConfig config = sysConfigMapper.selectById(id); | |||||
if (null != config ) { | |||||
SysConfigValue cvq = new SysConfigValue(); | |||||
cvq.setConfigItemId(config.getId()); | |||||
cvq.updateTenantInfo(tenantEntity); | |||||
SysConfigValue configValue = sysConfigValueMapper.findByItemId(cvq); | |||||
if (null != configValue) { | |||||
config.setConfigItemValue(configValue.getConfigItemValue()); | |||||
} | |||||
} | |||||
return config; | |||||
} | |||||
@Override | |||||
public SysConfig getByKey(String key,TenantEntity tenantEntity) { | |||||
SysConfig config = RedisCacheUtils.getCacheObject(baseRedisTemplate, String.format(cache_prex, tenantEntity.getTenantId(),key), SysConfig.class); | |||||
if (null == config) { | |||||
SysConfig cq = new SysConfig(); | |||||
cq.setConfigItemKey(key); | |||||
config = sysConfigMapper.findByKey(cq); | |||||
if (null != config ) { | |||||
SysConfigValue cvq = new SysConfigValue(); | |||||
cvq.setConfigItemId(config.getId()); | |||||
cvq.updateTenantInfo(tenantEntity); | |||||
SysConfigValue configValue = sysConfigValueMapper.findByItemId(cvq); | |||||
if (null != configValue) { | |||||
config.setConfigItemValue(configValue.getConfigItemValue()); | |||||
RedisCacheUtils.cache(baseRedisTemplate, String.format(cache_prex, tenantEntity.getTenantId(),key), config, 3600*24*3); | |||||
} | |||||
} | |||||
} | |||||
return config; | |||||
} | |||||
@Override | |||||
public void saveConfigValue(Long id,TenantEntity tenantEntity,String value) { | |||||
SysConfig config = sysConfigMapper.selectById(id); | |||||
SysConfigValue cvq = new SysConfigValue(); | |||||
cvq.setConfigItemId(config.getId()); | |||||
cvq.updateTenantInfo(tenantEntity); | |||||
SysConfigValue configValue = sysConfigValueMapper.findByItemId(cvq); | |||||
if (null != configValue) { | |||||
configValue.setConfigItemValue(value); | |||||
configValue.setUpdateDate(new Date()); | |||||
sysConfigValueMapper.updateById(configValue); | |||||
}else { | |||||
final IdWorker idWorker = IdWorker.get(); | |||||
configValue = new SysConfigValue(); | |||||
configValue.setConfigItemId(config.getId()); | |||||
configValue.setId(idWorker.nextId()); | |||||
configValue.updateTenantInfo(tenantEntity); | |||||
configValue.setConfigItemValue(value); | |||||
configValue.setCreateDate(new Date()); | |||||
sysConfigValueMapper.insert(configValue); | |||||
} | |||||
RedisCacheUtils.removeCache(baseRedisTemplate, String.format(cache_prex, tenantEntity.getTenantId(),config.getConfigItemKey())); | |||||
} | |||||
@Override | |||||
public void saveOrUpdate(SysConfig record) { | |||||
Date curr = new Date(); | |||||
if (record.getId() == null) { | |||||
final IdWorker idWorker = IdWorker.get(); | |||||
record.setId(idWorker.nextId()); | |||||
record.setCreateDate(curr); | |||||
record.setUpdateDate(curr); | |||||
sysConfigMapper.insert(record); | |||||
} else { | |||||
record.setUpdateDate(curr); | |||||
sysConfigMapper.updateById(record); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,198 @@ | |||||
package com.iformall.service.wx; | |||||
import java.io.File; | |||||
import java.util.Date; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; | |||||
import com.iformall.common.ErrorCode; | |||||
import com.iformall.common.Result; | |||||
import com.iformall.common.ResultData; | |||||
import com.iformall.domain.po.PosCouponOrderVerify; | |||||
import com.iformall.domain.po.WxAppinfo; | |||||
import com.iformall.domain.po.WxBatchOrder; | |||||
import com.iformall.domain.po.WxCouponOrder; | |||||
import com.iformall.domain.po.WxOrder; | |||||
import com.iformall.domain.po.WxPayAccount; | |||||
import com.iformall.domain.po.WxPayOrder; | |||||
import com.iformall.enums.EnumCouponOrderStatus; | |||||
import com.iformall.enums.EnumOrderFrom; | |||||
import com.iformall.enums.EnumOrderStatus; | |||||
import com.iformall.enums.EnumOrderType; | |||||
import com.iformall.enums.EnumPayMode; | |||||
import com.iformall.enums.EnumPayStatus; | |||||
import com.iformall.exception.MallinkException; | |||||
import com.iformall.pay.WxPay; | |||||
import com.iformall.pay.WxPayOrderQ; | |||||
import com.iformall.pay.WxPayOrderSQ; | |||||
import com.iformall.pay.WxPayment; | |||||
import com.iformall.service.QrCodeService; | |||||
import com.iformall.service.helper.WxPayOrderServiceHelper; | |||||
import com.iformall.service.order.entity.WxComposeChildOrderShare; | |||||
import com.iformall.service.pay.service.pay.PayAdapterService; | |||||
import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | |||||
import com.iformall.utils.BeanUtils; | |||||
import com.iformall.utils.MaUtil; | |||||
import com.iformall.utils.MapUtil; | |||||
import com.iformall.utils.QRCodeUtils; | |||||
import com.iformall.utils.Utility; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.open.api.WxOpenService; | |||||
@Slf4j | |||||
public class BaseWxPayAdapterService { | |||||
@Autowired | |||||
WxOpenService openService; | |||||
@Autowired | |||||
MaUtil maUtil; | |||||
/** | |||||
* 做为支付的扩展数据 | |||||
* @param payOrder | |||||
* @return | |||||
*/ | |||||
protected String getAttach(WxPayOrder payOrder) { | |||||
Map<String,String> map = new HashMap<>(); | |||||
map.put("tenantId",payOrder.getTenantId()); | |||||
return JSON.toJSONString(map); | |||||
} | |||||
protected String getMerchantUid(WxPayOrder payOrder,WxOrder order) { | |||||
WxComposeChildOrderShare share = payOrder.getChildOrderShare(order.getId()); | |||||
return share.getMerchantUid(); | |||||
} | |||||
protected File getQrCode(WxAppinfo appinfo,String pageUrl,int type,String sceneParam) throws WxErrorException { | |||||
boolean isFmOpen = false; | |||||
WxMaService wxMaService; | |||||
if(isFmOpen) { | |||||
wxMaService = openService.getWxOpenComponentService().getWxMaServiceByAppid(appinfo.getAppId()); | |||||
} else { | |||||
wxMaService = maUtil.getWeappService(appinfo); | |||||
} | |||||
boolean autoColor = false; | |||||
boolean isHyaline = true; | |||||
WxMaCodeLineColor color = new WxMaCodeLineColor("0", "0", "0"); | |||||
String pathStr = ""; | |||||
if (StringUtils.isNotBlank(sceneParam)) { | |||||
pathStr = pageUrl + "?scene="+sceneParam; | |||||
} else { | |||||
pathStr = pageUrl; | |||||
} | |||||
if(type == 0) { | |||||
final File codeFile = wxMaService.getQrcodeService().createQrcode(pathStr, QRCodeUtils.QR_WIDTH); | |||||
return codeFile; | |||||
}else { | |||||
final File codeFile = wxMaService.getQrcodeService().createWxaCodeUnlimit(sceneParam, pageUrl, QRCodeUtils.QR_WIDTH, autoColor, color, isHyaline); | |||||
return codeFile; | |||||
} | |||||
} | |||||
JSONObject errorMapClose = JSON.parseObject("{" + | |||||
"\"ORDERPAID\":{\"detail\":\"订单已支付\",\"reason\":\"订单已支付,不能发起关单\",\"resolution\":\"订单已支付,不能发起关单,请当作已支付的正常交易\"}," + | |||||
"\"SYSTEMERROR\":{\"detail\":\"系统错误\",\"reason\":\"系统错误\",\"resolution\":\"系统异常,请重新调用该API\"}," + | |||||
"\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"订单已关闭,无法重复关闭\",\"resolution\":\"订单已关闭,无需继续调用\"}," + | |||||
"\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||||
"\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||||
"\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"reason\":\"请检查XML参数格式是否正确\"}}"); | |||||
/** | |||||
* 收款码支付回撤,都是2.0版本 | |||||
* @param appInfo | |||||
* @param record | |||||
* @param payAccount | |||||
* @return | |||||
* @throws Exception | |||||
*/ | |||||
protected PayAdapterResult payOrderReverse(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount,String subMchId) throws Exception { | |||||
String response = payOrderReverseWx(appInfo, record,payAccount,subMchId); | |||||
log.info("pay order reverse, " + record.toString() + ", response: " + response); | |||||
Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
String return_code = returnMap.get("return_code"); | |||||
String result_code = returnMap.get("result_code"); | |||||
if ("SUCCESS".equalsIgnoreCase(return_code)) { | |||||
if ("SUCCESS".equals(result_code)) { | |||||
return new PayAdapterResult(true, "订单撤销成功", returnMap, null); | |||||
} else { | |||||
String errMsg = ""; | |||||
JSONObject errObj = errorMapClose.getJSONObject(result_code); | |||||
if (errObj != null) { | |||||
errMsg = errObj.toJSONString(); | |||||
} else { | |||||
errMsg = returnMap.get("return_msg"); | |||||
} | |||||
return new PayAdapterResult(false, errMsg, returnMap, null); | |||||
} | |||||
} else { | |||||
String errMsg = returnMap.get("return_msg"); | |||||
return new PayAdapterResult(false, errMsg, returnMap, null); | |||||
} | |||||
} | |||||
private String payOrderReverseWx(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount,String subMchId) { | |||||
// get payAccount | |||||
if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
// 普通商户号模式 | |||||
WxPayOrderQ payOrderC = new WxPayOrderQ(); | |||||
String noncestr = Utility.generate32UUID(); | |||||
payOrderC.setAppid(appInfo.getAppId()); | |||||
payOrderC.setMch_id(payAccount.getMchId()); | |||||
payOrderC.setNonce_str(noncestr); | |||||
payOrderC.setOut_trade_no(record.getPayOrderNo()); | |||||
try { | |||||
Map map = BeanUtils.toStringMap(payOrderC); | |||||
payOrderC.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||||
map = BeanUtils.toStringMap(payOrderC); | |||||
String response = WxPay.orderReverse(map, payAccount.getCertPath(), payAccount.getMchId()); | |||||
log.info("request:" + map.toString() + "\nresponse:" + response); | |||||
return response; | |||||
} catch (RuntimeException e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} | |||||
} else { | |||||
// 服务商模式 | |||||
WxPayOrderSQ payOrderSC = new WxPayOrderSQ(); | |||||
String noncestr = Utility.generate32UUID(); | |||||
payOrderSC.setAppid(appInfo.getParentAppId()); | |||||
payOrderSC.setSub_appid(appInfo.getAppId()); | |||||
payOrderSC.setMch_id(payAccount.getMchId()); | |||||
payOrderSC.setSub_mch_id(subMchId); | |||||
payOrderSC.setNonce_str(noncestr); | |||||
payOrderSC.setOut_trade_no(record.getPayOrderNo()); | |||||
payOrderSC.setSign_type("HMAC-SHA256"); | |||||
try { | |||||
Map map = BeanUtils.toStringMap(payOrderSC); | |||||
payOrderSC.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||||
map = BeanUtils.toStringMap(payOrderSC); | |||||
String response = WxPay.orderReverse(map, payAccount.getCertPath(), payAccount.getMchId()); | |||||
log.info("request:" + map.toString() + "\nresponse:" + response); | |||||
return response; | |||||
} catch (RuntimeException e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,159 @@ | |||||
package com.iformall.service.wx; | |||||
import java.io.File; | |||||
import java.util.Date; | |||||
import java.util.Map; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | |||||
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; | |||||
import com.iformall.common.ErrorCode; | |||||
import com.iformall.common.Result; | |||||
import com.iformall.common.ResultData; | |||||
import com.iformall.domain.po.PosCouponOrderVerify; | |||||
import com.iformall.domain.po.WxAppinfo; | |||||
import com.iformall.domain.po.WxBatchOrder; | |||||
import com.iformall.domain.po.WxCouponOrder; | |||||
import com.iformall.domain.po.WxOrder; | |||||
import com.iformall.domain.po.WxPayAccount; | |||||
import com.iformall.domain.po.WxPayOrder; | |||||
import com.iformall.enums.EnumCouponOrderStatus; | |||||
import com.iformall.enums.EnumOrderFrom; | |||||
import com.iformall.enums.EnumOrderStatus; | |||||
import com.iformall.enums.EnumOrderType; | |||||
import com.iformall.enums.EnumPayMode; | |||||
import com.iformall.enums.EnumPayStatus; | |||||
import com.iformall.exception.MallinkException; | |||||
import com.iformall.pay.WxPay; | |||||
import com.iformall.pay.WxPayOrderQ; | |||||
import com.iformall.pay.WxPayOrderSQ; | |||||
import com.iformall.pay.WxPayment; | |||||
import com.iformall.service.QrCodeService; | |||||
import com.iformall.service.helper.WxPayOrderServiceHelper; | |||||
import com.iformall.service.pay.service.pay.PayAdapterService; | |||||
import com.iformall.service.pay.service.pay.entity.PayAdapterResult; | |||||
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; | |||||
import com.iformall.service.pay.service.pay.wx.BaseWxPayAdapterService; | |||||
import com.iformall.utils.BeanUtils; | |||||
import com.iformall.utils.MaUtil; | |||||
import com.iformall.utils.QRCodeUtils; | |||||
import com.iformall.utils.Utility; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import me.chanjar.weixin.common.error.WxErrorException; | |||||
import me.chanjar.weixin.open.api.WxOpenService; | |||||
@Slf4j | |||||
public class BaseWxPayV2AdapterService extends BaseWxPayAdapterService{ | |||||
protected PayQueryAdapterResult queryPayStatus(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) | |||||
throws Exception { | |||||
Map<String, String> retMap = WxPayOrderServiceHelper.wxOrderPayStatusMap(oldRecord, appInfo, payAccount); | |||||
int code = WxPayOrderServiceHelper.getPayStatusFromMap(retMap,oldRecord.getPayOrderNo()); | |||||
String msg = WxPayOrderServiceHelper.getPayStatusMsg(retMap, oldRecord.getPayOrderNo()); | |||||
PayQueryAdapterResult result = new PayQueryAdapterResult(code, msg,null, retMap,retMap.get("transaction_id"),retMap.get("time_end")); | |||||
return result; | |||||
} | |||||
protected int queryPayStatus(PayQueryAdapterResult statusObject, String orderOutNo) throws Exception { | |||||
return WxPayOrderServiceHelper.getPayStatusFromMap((Map<String, String>) statusObject.getData(),orderOutNo); | |||||
} | |||||
protected int queryPayStatusCode(WxPayOrder oldRecord, WxAppinfo appInfo, WxPayAccount payAccount) | |||||
throws Exception { | |||||
return WxPayOrderServiceHelper.wxOrderPayStatus(oldRecord, appInfo, payAccount); | |||||
} | |||||
JSONObject errorMapClose = JSON.parseObject("{" + | |||||
"\"ORDERPAID\":{\"detail\":\"订单已支付\",\"reason\":\"订单已支付,不能发起关单\",\"resolution\":\"订单已支付,不能发起关单,请当作已支付的正常交易\"}," + | |||||
"\"SYSTEMERROR\":{\"detail\":\"系统错误\",\"reason\":\"系统错误\",\"resolution\":\"系统异常,请重新调用该API\"}," + | |||||
"\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"订单已关闭,无法重复关闭\",\"resolution\":\"订单已关闭,无需继续调用\"}," + | |||||
"\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||||
"\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||||
"\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"reason\":\"请检查XML参数格式是否正确\"}}"); | |||||
protected PayAdapterResult closeOrder(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) { | |||||
String response = closeOrderWx(appInfo, record,payAccount); | |||||
log.info("pay order close, " + record.toString() + ", response: " + response); | |||||
Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
String return_code = returnMap.get("return_code"); | |||||
String result_code = returnMap.get("result_code"); | |||||
if ("SUCCESS".equalsIgnoreCase(return_code)) { | |||||
if ("SUCCESS".equals(result_code)) { | |||||
return new PayAdapterResult(true, "success", returnMap, null); | |||||
} else { | |||||
String errMsg = ""; | |||||
JSONObject errObj = errorMapClose.getJSONObject(result_code); | |||||
if (errObj != null) { | |||||
errMsg = errObj.toJSONString(); | |||||
} else { | |||||
errMsg = returnMap.get("return_msg"); | |||||
} | |||||
return new PayAdapterResult(false, errMsg, returnMap, null); | |||||
} | |||||
} else { | |||||
String errMsg = returnMap.get("return_msg"); | |||||
return new PayAdapterResult(false, errMsg, returnMap, null); | |||||
} | |||||
} | |||||
private String closeOrderWx(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) { | |||||
// get payAccount | |||||
if (payAccount.getType() == EnumPayMode.MCH.getCode()) { | |||||
// 普通商户号模式 | |||||
WxPayOrderQ payOrderC = new WxPayOrderQ(); | |||||
String noncestr = Utility.generate32UUID(); | |||||
payOrderC.setAppid(appInfo.getAppId()); | |||||
payOrderC.setMch_id(payAccount.getMchId()); | |||||
payOrderC.setNonce_str(noncestr); | |||||
payOrderC.setOut_trade_no(record.getPayOrderNo()); | |||||
try { | |||||
Map map = BeanUtils.toStringMap(payOrderC); | |||||
payOrderC.setSign(WxPayment.createSign(map, payAccount.getApiKey())); | |||||
map = BeanUtils.toStringMap(payOrderC); | |||||
String response = WxPay.closeOrder(map); | |||||
log.info("request:" + map.toString() + "\nresponse:" + response); | |||||
return response; | |||||
} catch (RuntimeException e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} | |||||
} else { | |||||
// 服务商模式 | |||||
WxPayOrderSQ payOrderSC = new WxPayOrderSQ(); | |||||
String noncestr = Utility.generate32UUID(); | |||||
payOrderSC.setAppid(appInfo.getParentAppId()); | |||||
payOrderSC.setSub_appid(appInfo.getAppId()); | |||||
payOrderSC.setMch_id(payAccount.getMchId()); | |||||
payOrderSC.setSub_mch_id(payAccount.getSubMchId()); | |||||
payOrderSC.setNonce_str(noncestr); | |||||
payOrderSC.setOut_trade_no(record.getPayOrderNo()); | |||||
payOrderSC.setSign_type("HMAC-SHA256"); | |||||
try { | |||||
Map map = BeanUtils.toStringMap(payOrderSC); | |||||
payOrderSC.setSign(WxPayment.createSignHMAC(map, payAccount.getApiKey())); | |||||
map = BeanUtils.toStringMap(payOrderSC); | |||||
String response = WxPay.closeOrder(map); | |||||
log.info("request:" + map.toString() + "\nresponse:" + response); | |||||
return response; | |||||
} catch (RuntimeException e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} catch (Exception e) { | |||||
throw new MallinkException(ErrorCode.PAY_ORDER_ERROR.getCode(), e.getMessage()); | |||||
} | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,114 @@ | |||||
package com.iformall.service.wx; | |||||
import java.util.Date; | |||||
import java.util.Map; | |||||
import com.iformall.domain.entity.PayAdapterResult; | |||||
import com.iformall.domain.entity.WxPay; | |||||
import com.iformall.domain.entity.WxPayOrderP; | |||||
import com.iformall.domain.entity.WxPayment; | |||||
import org.springframework.stereotype.Service; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.iformall.utils.BeanUtils; | |||||
import com.iformall.utils.MapUtil; | |||||
import com.iformall.utils.Utility; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
@Slf4j | |||||
@Service | |||||
public class WxMiniAppPayAdapterService extends BaseWxPayV2AdapterService{ | |||||
JSONObject errorMap = JSON.parseObject("{" + | |||||
"\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," + | |||||
"\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," + | |||||
"\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," + | |||||
"\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"当前订单已关闭,无法支付\",\"resolution\":\"当前订单已关闭,请重新下单\"}," + | |||||
"\"SYSTEMERROR\":{\"detail\":\"系统错误\t\",\"reason\":\"系统超时\",\"resolution\":\"系统异常,请用相同参数重新调用\"}," + | |||||
"\"APPID_NOT_EXIST\":{\"detail\":\"APPID不存在\",\"reason\":\"参数中缺少APPID\",\"resolution\":\"请检查APPID是否正确\"}," + | |||||
"\"MCHID_NOT_EXIST\":{\"detail\":\"MCHID不存在\",\"reason\":\"参数中缺少MCHID\",\"resolution\":\"请检查MCHID是否正确\"}," + | |||||
"\"APPID_MCHID_NOT_MATCH\":{\"detail\":\"appid和mch_id不匹配\",\"reason\":\"appid和mch_id不匹配\",\"resolution\":\"请确认appid和mch_id是否匹配\"}," + | |||||
"\"LACK_PARAMS\":{\"detail\":\"缺少参数\t\",\"reason\":\"缺少必要的请求参数\",\"resolution\":\"请检查参数是否齐全\"}," + | |||||
"\"OUT_TRADE_NO_USED\":{\"detail\":\"商户订单号重复\",\"reason\":\"同一笔交易不能多次提交\",\"resolution\":\"请核实商户订单号是否重复提交\"}," + | |||||
"\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," + | |||||
"\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"resolution\":\"请检查XML参数格式是否正确\"}," + | |||||
"\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," + | |||||
"\"POST_DATA_EMPTY\":{\"detail\":\"post数据为空\",\"reason\":\"post数据不能为空\",\"resolution\":\"请检查post数据是否为空\"}," + | |||||
"\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}"); | |||||
private WxPayOrderP generateWxPayOrderP(String openId,String appId,String mchId,String productName,String attach,String payOrderNo,Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate,String productId)throws Exception { | |||||
// 统一下单 普通商户模式 | |||||
String noncestr = Utility.generate32UUID(); | |||||
WxPayOrderP wxPayOrderP = new WxPayOrderP(); | |||||
wxPayOrderP.setOpenid(openId); | |||||
wxPayOrderP.setAppid(appId); | |||||
wxPayOrderP.setMch_id(mchId); | |||||
wxPayOrderP.setNonce_str(noncestr); | |||||
wxPayOrderP.setBody(productName); | |||||
wxPayOrderP.setAttach(attach); | |||||
wxPayOrderP.setOut_trade_no(payOrderNo); | |||||
wxPayOrderP.setTotal_fee(fee); | |||||
wxPayOrderP.setSpbill_create_ip(ip); // 终端IP | |||||
wxPayOrderP.setGoods_tag(productName); | |||||
wxPayOrderP.setNotify_url(notifyUrl); | |||||
wxPayOrderP.setTrade_type(WxPay.TradeType.JSAPI.name()); // 终端类型 | |||||
if (null != productId) { | |||||
wxPayOrderP.setProduct_id(productId); | |||||
} | |||||
wxPayOrderP.setTime_start(Utility.getDataFormatStringYYYYMMDDHHmmss(currentDate)); | |||||
Date futureDate = new Date(); | |||||
futureDate.setTime(currentDate.getTime() + 15 * 60 * 1000); | |||||
wxPayOrderP.setTime_expire(Utility.getDataFormatStringYYYYMMDDHHmmss(futureDate)); // 15分钟后结束 | |||||
Map<String, String> payOrderMap = BeanUtils.toStringMap(wxPayOrderP); | |||||
wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, apiKey)); | |||||
return wxPayOrderP; | |||||
} | |||||
private PayAdapterResult getOrderPResult(Map<String, String> returnMap,String noncestr,String apiKey) { | |||||
PayAdapterResult par = new PayAdapterResult(); | |||||
String result_code = returnMap.get("result_code"); | |||||
if ("SUCCESS".equals(result_code)) { | |||||
par.setSuccess(true); | |||||
par.setMsg("success."); | |||||
par.setData(returnMap); | |||||
String prepay_id = returnMap.get("prepay_id"); | |||||
String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); | |||||
Map<String, String> sighMap = MapUtil.getOrderMap(); | |||||
sighMap.put("appId", returnMap.get("appid")); | |||||
sighMap.put("timeStamp", timestamp); | |||||
sighMap.put("nonceStr", noncestr); | |||||
sighMap.put("package", "prepay_id=" + prepay_id); | |||||
sighMap.put("signType", "MD5"); | |||||
String signAgent = WxPayment.createSign(sighMap, apiKey); | |||||
returnMap.put("timeStamp", timestamp); | |||||
returnMap.put("nonceStr", noncestr); | |||||
returnMap.put("package", "prepay_id=" + prepay_id); | |||||
returnMap.put("paySign", signAgent); | |||||
log.info("back to UI: " + returnMap.toString()); | |||||
} else { | |||||
String errMsg = ""; | |||||
JSONObject errObj = errorMap.getJSONObject(result_code); | |||||
if (errObj != null) { | |||||
errMsg = errObj.toJSONString(); | |||||
} else { | |||||
errMsg = returnMap.get("return_msg"); | |||||
} | |||||
par.setSuccess(false); | |||||
par.setMsg(errMsg); | |||||
par.setData(returnMap); | |||||
} | |||||
return par; | |||||
} | |||||
public PayAdapterResult pay(String openId,String appId,String mchId,String productName,String attach,String payOrderNo,Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception { | |||||
WxPayOrderP wxPayOrderP = generateWxPayOrderP(openId, appId, mchId, productName, attach, payOrderNo, fee, ip, notifyUrl, apiKey, currentDate,null); | |||||
String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); | |||||
log.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); | |||||
Map<String, String> returnMap = WxPayment.xmlToMap(response); | |||||
return getOrderPResult(returnMap,wxPayOrderP.getNonce_str(),apiKey); | |||||
} | |||||
} |
@@ -0,0 +1,28 @@ | |||||
package com.iformall.service.wx; | |||||
import java.util.Date; | |||||
import java.util.Map; | |||||
import com.github.pagehelper.PageInfo; | |||||
import com.iformall.domain.entity.PayAdapterResult; | |||||
import com.iformall.domain.po.WxAppinfo; | |||||
import com.iformall.domain.po.WxPayOrder; | |||||
import com.iformall.domain.po.WxPayAccount; | |||||
public interface WxPayService { | |||||
public PageInfo<WxPayOrder> listPayOrderAsPage(WxPayOrder record, Integer pageIndex, Integer pageSize); | |||||
//share:是否分账,服务商模式下生效 | |||||
public PayAdapterResult createWxPayOrder(WxPayAccount payAccount,WxAppinfo cAppInfo,boolean isIsvModel,boolean share,String appId,String mchId,String productName,String attach,String payOrderNo, | |||||
Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception; | |||||
public String handlePaidCallBack(String tenantId,Map<String, String> paramMap); | |||||
public void handlePaidSuccess(String tenantId,Long orderId,Long cUserId,Integer fee,Date paidTime,String transcationId, | |||||
String userPhone) throws Exception; | |||||
public WxPayOrder detailPayOrder(Long id,String tenantId); | |||||
public Integer sumPayOrder(WxPayOrder record); | |||||
} |
@@ -0,0 +1,182 @@ | |||||
package com.iformall.service.wx; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.github.pagehelper.PageHelper; | |||||
import com.github.pagehelper.PageInfo; | |||||
import com.iformall.common.ErrorCode; | |||||
import com.iformall.common.IdWorker; | |||||
import com.iformall.domain.entity.PayAdapterResult; | |||||
import com.iformall.domain.po.WxAppinfo; | |||||
import com.iformall.domain.po.WxPayOrder; | |||||
import com.iformall.domain.po.WxPayAccount; | |||||
import com.iformall.domain.po.base.TenantEntity; | |||||
import com.iformall.exception.MallinkException; | |||||
import com.iformall.mapper.WxAppinfoMapper; | |||||
import com.iformall.mapper.WxPayOrderMapper; | |||||
import com.iformall.mapper.WxPayAccountMapper; | |||||
import com.iformall.service.WxAppinfoService; | |||||
import com.iformall.service.WxPayAccountService; | |||||
import com.iformall.utils.DateUtils; | |||||
import com.iformall.utils.RedisLock; | |||||
import com.iformall.utils.XmlUtil; | |||||
import java.util.Date; | |||||
import java.util.Map; | |||||
import java.util.SortedMap; | |||||
import java.util.TreeMap; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import org.springframework.beans.factory.annotation.Autowired; | |||||
import org.springframework.context.annotation.Lazy; | |||||
import org.springframework.stereotype.Service; | |||||
@Service | |||||
public class WxPayServiceImpl implements WxPayService { | |||||
private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
@Autowired | |||||
WxPayOrderMapper wxPayOrderMapper; | |||||
@Autowired | |||||
WxMiniAppPayAdapterService wxMiniAppPayAdapterService; | |||||
@Autowired | |||||
WxAppinfoMapper wxAppinfoMapper; | |||||
@Autowired | |||||
WxPayAccountMapper wxPayAccountMapper; | |||||
@Autowired | |||||
RedisLock redisLock; | |||||
@Lazy | |||||
@Autowired | |||||
WxAppinfoService wxAppinfoService; | |||||
@Lazy | |||||
@Autowired | |||||
WxPayAccountService wxPayAccountService; | |||||
@Override | |||||
public PageInfo<WxPayOrder> listPayOrderAsPage(WxPayOrder record, Integer pageIndex, Integer pageSize) { | |||||
return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> wxPayOrderMapper.findList(record)); | |||||
} | |||||
@Override | |||||
public PayAdapterResult createWxPayOrder(WxPayAccount payAccount,WxAppinfo cAppInfo,boolean isIsvModel,boolean share,String openId,String mchId,String productName,String attach,String payOrderNo, | |||||
Integer fee,String ip,String notifyUrl,String apiKey,Date currentDate) throws Exception { | |||||
return wxMiniAppPayAdapterService.pay(openId, cAppInfo.getAppId(),mchId, productName, attach, payOrderNo, fee, ip, notifyUrl, apiKey, currentDate); | |||||
} | |||||
private String notifyErrorResult(String msg) { | |||||
SortedMap resultMap = new TreeMap(); | |||||
resultMap.put("return_code", "FAIL"); | |||||
resultMap.put("return_msg", msg); | |||||
return XmlUtil.getRequestXml(resultMap); | |||||
} | |||||
private String notifySuccessResult() { | |||||
SortedMap resultMap = new TreeMap(); | |||||
resultMap.put("return_code", "SUCCESS"); | |||||
resultMap.put("return_msg", "OK"); | |||||
return XmlUtil.getRequestXml(resultMap); | |||||
} | |||||
@Override | |||||
public String handlePaidCallBack(String tenantId,Map<String, String> paramMap) { | |||||
logger.info("handleCarPaidCallBack."+JSON.toJSONString(paramMap)); | |||||
//支付返回消息 | |||||
String returnCode = paramMap.get("return_code"); | |||||
if ("SUCCESS".equals(returnCode)) { | |||||
String resultCode = paramMap.get("result_code"); | |||||
if ("SUCCESS".equals(resultCode)) { | |||||
//判断支付金额是否大于0 | |||||
String cashFeeStr = paramMap.get("cash_fee"); | |||||
Integer cashFee = Integer.parseInt(cashFeeStr); | |||||
if (cashFee > 0 ) { | |||||
try { | |||||
//String payOrderNo = paramMap.get("out_trade_no"); | |||||
String time_end = paramMap.get("time_end"); | |||||
String transcationId = paramMap.get("transaction_id"); | |||||
TenantEntity teq = new TenantEntity(); | |||||
teq.setTenantId(tenantId); | |||||
String attach = paramMap.get("attach"); | |||||
Long cUserId = null; | |||||
String userPhone = null; | |||||
if (!StringUtils.isBlank(attach)) { | |||||
String[] attrs = attach.split(","); | |||||
if (attrs.length == 2) { | |||||
cUserId = Long.parseLong(attrs[0]); | |||||
userPhone = attrs[1]; | |||||
} | |||||
} | |||||
String payOrderNo = paramMap.get("out_trade_no"); | |||||
handlePaidSuccess(tenantId,Long.parseLong(payOrderNo),cUserId,Integer.parseInt(cashFeeStr), | |||||
DateUtils.string2Date(time_end, DateUtils.DATE_PATTERN_ALL_NOSPACE).getTime(),transcationId, | |||||
userPhone); | |||||
} catch (Exception e) { | |||||
logger.error("handlePaidCallBackError.",e); | |||||
return notifyErrorResult(e.getMessage()); | |||||
} | |||||
} | |||||
return notifySuccessResult(); | |||||
}else { | |||||
String errorMsg = paramMap.get("err_code_des"); | |||||
return notifyErrorResult(errorMsg); | |||||
} | |||||
}else { | |||||
String errorMsg = paramMap.get("return_msg"); | |||||
return notifyErrorResult(errorMsg); | |||||
} | |||||
} | |||||
@Override | |||||
public void handlePaidSuccess(String tenantId,Long orderId,Long cUserId,Integer fee,Date paidTime,String transcationId, | |||||
String userPhone) throws Exception{ | |||||
//查询该笔订单是否已经存在 | |||||
WxPayOrder payOrder = wxPayOrderMapper.selectById(orderId, tenantId); | |||||
//String parkOrderNo = ParkCreatePayOrder.getRealParkOrderNumber(payOrderNo,EnumCarVendor.getEnum(carVendor)); | |||||
if (null == payOrder) { | |||||
//此处需要加锁,防止并发设置 | |||||
long time = System.currentTimeMillis() + RedisLock.TIMEOUT; | |||||
String timeStr = String.valueOf(time); | |||||
boolean stocksetlock = redisLock.lock("carPayOrderLock_"+orderId, timeStr); | |||||
if (stocksetlock) { | |||||
try { | |||||
//创建停车支付订单记录 | |||||
final IdWorker idworker = IdWorker.get(); | |||||
payOrder = new WxPayOrder(); | |||||
Long id = idworker.nextId(); | |||||
payOrder.setId(id); | |||||
payOrder.setTenantId(tenantId); | |||||
payOrder.setCreateTime(new Date()); | |||||
payOrder.setUpdateTime(new Date()); | |||||
payOrder.setcUserId(cUserId); | |||||
payOrder.setPayAmount(fee); | |||||
payOrder.setPayTime(paidTime); | |||||
payOrder.setTransactionId(transcationId); | |||||
payOrder.setcUserPhone(userPhone); | |||||
wxPayOrderMapper.insert(payOrder); | |||||
}catch(Exception e) { | |||||
logger.error("handlePaidSuccess fail.",e); | |||||
throw new MallinkException(ErrorCode.SERVER_ERROR.getCode(),"支付失败"+orderId); | |||||
}finally { | |||||
redisLock.unlock("carPayOrderLock_"+orderId, timeStr); | |||||
} | |||||
} | |||||
} | |||||
} | |||||
@Override | |||||
public WxPayOrder detailPayOrder(Long id,String tenantId) { | |||||
return wxPayOrderMapper.selectById(id, tenantId); | |||||
} | |||||
@Override | |||||
public Integer sumPayOrder(WxPayOrder record) { | |||||
return wxPayOrderMapper.sum(record); | |||||
} | |||||
} |
@@ -0,0 +1,165 @@ | |||||
package com.iformall.utils; | |||||
import com.google.gson.internal.LinkedTreeMap; | |||||
import java.beans.BeanInfo; | |||||
import java.beans.IntrospectionException; | |||||
import java.beans.Introspector; | |||||
import java.beans.PropertyDescriptor; | |||||
import java.lang.reflect.InvocationTargetException; | |||||
import java.lang.reflect.Method; | |||||
import java.util.Map; | |||||
import java.util.Objects; | |||||
/** | |||||
* Created by Stormeye on 2018/8/10. | |||||
*/ | |||||
public class BeanUtils { | |||||
/** | |||||
* 如果是null,将返回字符串0 | |||||
* | |||||
* @param param | |||||
* @return | |||||
*/ | |||||
public static String ifNullTo0(String param) { | |||||
if (param == null || param.equals("null")) { | |||||
return "0"; | |||||
} | |||||
return param; | |||||
} | |||||
public static Object getValue(Object obj, String pro) throws NoSuchMethodException { | |||||
return getValue(obj, pro, null); | |||||
} | |||||
/** | |||||
* 根据属性名称获取JavaBean中对应的属性值 | |||||
* | |||||
* @param obj 对象 | |||||
* @param pro 对应属性名称 | |||||
* @param num 整型参数 | |||||
* @return 对象对应属性值 | |||||
*/ | |||||
public static Object getValue(Object obj, String pro, Integer num) throws NoSuchMethodException { | |||||
Class<?> clazz = obj.getClass(); | |||||
do { | |||||
try { | |||||
String methodName = "getSimpleRegionModel" + pro.substring(0, 1).toUpperCase() + pro.substring(1); | |||||
Method method; | |||||
if (!Objects.isNull(num)) { | |||||
method = clazz.getDeclaredMethod(methodName, Integer.class); | |||||
return method.invoke(obj, num); | |||||
} else { | |||||
method = clazz.getDeclaredMethod(methodName); | |||||
return method.invoke(obj); | |||||
} | |||||
} catch (NoSuchMethodException e) { | |||||
clazz = clazz.getSuperclass(); | |||||
} catch (InvocationTargetException | IllegalAccessException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} while (clazz != Object.class); | |||||
throw new NoSuchMethodException("no such method name : " + "getSimpleRegionModel" + pro.substring(0, 1).toUpperCase() + pro.substring(1)); | |||||
} | |||||
public static void transMap2Bean2(Map<String, Object> map, Object obj) { | |||||
if (map == null || obj == null) { | |||||
return; | |||||
} | |||||
try { | |||||
org.apache.commons.beanutils.BeanUtils.populate(obj, map); | |||||
} catch (Exception e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
/** | |||||
* 根据key数组和value数组拼接json | |||||
* | |||||
* @param keys key数组 | |||||
* @param values value数据 | |||||
* @return json | |||||
* @throws Exception | |||||
*/ | |||||
public static String wrapToJsonByKeyValue(String[] keys, String[] values) throws Exception { | |||||
StringBuilder stringBuilder = new StringBuilder(); | |||||
if (keys.length != values.length) { | |||||
throw new Exception("长度不匹配,不能进行JSON格式的转换"); | |||||
} | |||||
for (int i = 0; i < keys.length; i++) { | |||||
stringBuilder.append("\"").append(keys[i]).append("\":\"").append(values[i]).append("\","); | |||||
} | |||||
return "{" + stringBuilder.substring(0, stringBuilder.length() - 1) + "}"; | |||||
} | |||||
/** | |||||
* Converts a JavaBean to a map | |||||
* | |||||
* @param bean JavaBean to convert | |||||
* @return map converted | |||||
* @throws IntrospectionException failed to get class fields | |||||
* @throws IllegalAccessException failed to instant JavaBean | |||||
* @throws InvocationTargetException failed to call setters | |||||
*/ | |||||
public static final Map<String, Object> toMap(Object bean) | |||||
throws Exception { | |||||
Map<String, Object> returnMap = new LinkedTreeMap(); | |||||
if (bean instanceof Map) { | |||||
returnMap.putAll((Map<String, Object>)bean); | |||||
return returnMap; | |||||
} | |||||
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); | |||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); | |||||
for (int i = 0; i< propertyDescriptors.length; i++) { | |||||
PropertyDescriptor descriptor = propertyDescriptors[i]; | |||||
String propertyName = descriptor.getName(); | |||||
if (!propertyName.equals("class")) { | |||||
Method readMethod = descriptor.getReadMethod(); | |||||
Object result = readMethod.invoke(bean, new Object[0]); | |||||
if (result != null) { | |||||
returnMap.put(propertyName, result); | |||||
} else { | |||||
returnMap.put(propertyName, ""); | |||||
} | |||||
} | |||||
} | |||||
return returnMap; | |||||
} | |||||
/** | |||||
* Converts a JavaBean to a map | |||||
* | |||||
* @param bean JavaBean to convert | |||||
* @return map converted | |||||
* @throws IntrospectionException failed to get class fields | |||||
* @throws IllegalAccessException failed to instant JavaBean | |||||
* @throws InvocationTargetException failed to call setters | |||||
*/ | |||||
public static final Map<String, String> toStringMap(Object bean) | |||||
throws Exception { | |||||
Map<String, String> returnMap = new LinkedTreeMap(); | |||||
if (bean instanceof Map) { | |||||
returnMap.putAll((Map<String, String>)bean); | |||||
return returnMap; | |||||
} | |||||
BeanInfo beanInfo = Introspector.getBeanInfo(bean.getClass()); | |||||
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); | |||||
for (int i = 0; i< propertyDescriptors.length; i++) { | |||||
PropertyDescriptor descriptor = propertyDescriptors[i]; | |||||
String propertyName = descriptor.getName(); | |||||
if (!propertyName.equals("class")) { | |||||
Method readMethod = descriptor.getReadMethod(); | |||||
Object result = readMethod.invoke(bean, new Object[0]); | |||||
if (result != null) { | |||||
returnMap.put(propertyName, String.valueOf(result)); | |||||
} else { | |||||
returnMap.put(propertyName, ""); | |||||
} | |||||
} | |||||
} | |||||
return returnMap; | |||||
} | |||||
} |
@@ -9,5 +9,6 @@ public class Constant { | |||||
public static final String currentUser = "currentUser"; | public static final String currentUser = "currentUser"; | ||||
public static final String TENANT_ID = "tenantId"; | public static final String TENANT_ID = "tenantId"; | ||||
public static final String PARENT_TENANT_ID = "parentTenantId"; | public static final String PARENT_TENANT_ID = "parentTenantId"; | ||||
public static final String paymentReceiverParamIsv = "isvModel"; | |||||
public static final String paymentReceicerParamApiKey = "apiKey"; | |||||
} | } |
@@ -0,0 +1,323 @@ | |||||
package com.iformall.utils; | |||||
import org.apache.commons.lang3.ArrayUtils; | |||||
import org.apache.commons.lang3.StringUtils; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.net.MalformedURLException; | |||||
import java.net.URL; | |||||
import java.security.CodeSource; | |||||
import java.security.ProtectionDomain; | |||||
import java.util.Collection; | |||||
import java.util.Map; | |||||
/** | |||||
* 常见的辅助类 | |||||
* | |||||
* @author Stormeye | |||||
* @since 2011-11-08 | |||||
*/ | |||||
public final class DataUtil { | |||||
private DataUtil() { | |||||
} | |||||
/** | |||||
* 十进制字节数组转十六进制字符串 | |||||
* | |||||
* @param b | |||||
* @return | |||||
*/ | |||||
public static final String byte2hex(byte[] b) { // 一个字节数,转成16进制字符串 | |||||
StringBuilder hs = new StringBuilder(b.length * 2); | |||||
String stmp = ""; | |||||
for (int n = 0; n < b.length; n++) { | |||||
// 整数转成十六进制表示 | |||||
stmp = Integer.toHexString(b[n] & 0XFF); | |||||
if (stmp.length() == 1) | |||||
hs.append("0").append(stmp); | |||||
else | |||||
hs.append(stmp); | |||||
} | |||||
return hs.toString(); // 转成大写 | |||||
} | |||||
/** | |||||
* 十六进制字符串转十进制字节数组 | |||||
* | |||||
* @param hs | |||||
* @return | |||||
*/ | |||||
public static final byte[] hex2byte(String hs) { | |||||
byte[] b = hs.getBytes(); | |||||
if ((b.length % 2) != 0) | |||||
throw new IllegalArgumentException("长度不是偶数"); | |||||
byte[] b2 = new byte[b.length / 2]; | |||||
for (int n = 0; n < b.length; n += 2) { | |||||
String item = new String(b, n, 2); | |||||
// 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个十进制字节 | |||||
b2[n / 2] = (byte) Integer.parseInt(item, 16); | |||||
} | |||||
return b2; | |||||
} | |||||
/** | |||||
* 这个方法可以通过与某个类的class文件的相对路径来获取文件或目录的绝对路径。 通常在程序中很难定位某个相对路径,特别是在B/S应用中。 | |||||
* 通过这个方法,我们可以根据我们程序自身的类文件的位置来定位某个相对路径。 | |||||
* 比如:某个txt文件相对于程序的Test类文件的路径是../../resource/test.txt, | |||||
* 那么使用本方法Path.getFullPathRelateClass("../../resource/test.txt",Test.class) | |||||
* 得到的结果是txt文件的在系统中的绝对路径。 | |||||
* | |||||
* @param relatedPath 相对路径 | |||||
* @param cls 用来定位的类 | |||||
* @return 相对路径所对应的绝对路径 | |||||
* @throws IOException 因为本方法将查询文件系统,所以可能抛出IO异常 | |||||
*/ | |||||
public static final String getFullPathRelateClass(String relatedPath, Class<?> cls) { | |||||
String path = null; | |||||
if (relatedPath == null) { | |||||
throw new NullPointerException(); | |||||
} | |||||
String clsPath = getPathFromClass(cls); | |||||
File clsFile = new File(clsPath); | |||||
String tempPath = clsFile.getParent() + File.separator + relatedPath; | |||||
File file = new File(tempPath); | |||||
try { | |||||
path = file.getCanonicalPath(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return path; | |||||
} | |||||
/** | |||||
* 获取class文件所在绝对路径 | |||||
* | |||||
* @param cls | |||||
* @return | |||||
* @throws IOException | |||||
*/ | |||||
public static final String getPathFromClass(Class<?> cls) { | |||||
String path = null; | |||||
if (cls == null) { | |||||
throw new NullPointerException(); | |||||
} | |||||
URL url = getClassLocationURL(cls); | |||||
if (url != null) { | |||||
path = url.getPath(); | |||||
if ("jar".equalsIgnoreCase(url.getProtocol())) { | |||||
try { | |||||
path = new URL(path).getPath(); | |||||
} catch (MalformedURLException e) { | |||||
} | |||||
int location = path.indexOf("!/"); | |||||
if (location != -1) { | |||||
path = path.substring(0, location); | |||||
} | |||||
} | |||||
File file = new File(path); | |||||
try { | |||||
path = file.getCanonicalPath(); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
} | |||||
return path; | |||||
} | |||||
/** | |||||
* 判断对象是否Empty(null或元素为0)<br> | |||||
* 实用于对如下对象做判断:String Collection及其子类 Map及其子类 | |||||
* | |||||
* @param pObj 待检查对象 | |||||
* @return boolean 返回的布尔值 | |||||
*/ | |||||
public static final boolean isEmpty(Object pObj) { | |||||
if (pObj == null) | |||||
return true; | |||||
if (pObj == "") | |||||
return true; | |||||
if (pObj instanceof String) { | |||||
if (((String) pObj).trim().length() == 0) { | |||||
return true; | |||||
} | |||||
} else if (pObj instanceof Collection<?>) { | |||||
if (((Collection<?>) pObj).size() == 0) { | |||||
return true; | |||||
} | |||||
} else if (pObj instanceof Map<?, ?>) { | |||||
if (((Map<?, ?>) pObj).size() == 0) { | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* 判断对象是否为NotEmpty(!null或元素>0)<br> | |||||
* 实用于对如下对象做判断:String Collection及其子类 Map及其子类 | |||||
* | |||||
* @param pObj 待检查对象 | |||||
* @return boolean 返回的布尔值 | |||||
*/ | |||||
public static final boolean isNotEmpty(Object pObj) { | |||||
if (pObj == null) | |||||
return false; | |||||
if (pObj == "") | |||||
return false; | |||||
if (pObj instanceof String) { | |||||
if (((String) pObj).trim().length() == 0) { | |||||
return false; | |||||
} | |||||
} else if (pObj instanceof Collection<?>) { | |||||
if (((Collection<?>) pObj).size() == 0) { | |||||
return false; | |||||
} | |||||
} else if (pObj instanceof Map<?, ?>) { | |||||
if (((Map<?, ?>) pObj).size() == 0) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* JS输出含有\n的特殊处理 | |||||
* | |||||
* @param pStr | |||||
* @return | |||||
*/ | |||||
public static final String replace4JsOutput(String pStr) { | |||||
pStr = pStr.replace("\r\n", "<br/> "); | |||||
pStr = pStr.replace("\t", " "); | |||||
pStr = pStr.replace(" ", " "); | |||||
return pStr; | |||||
} | |||||
/** | |||||
* 分别去空格 | |||||
* | |||||
* @param paramArray | |||||
* @return | |||||
*/ | |||||
public static final String[] trim(String[] paramArray) { | |||||
if (ArrayUtils.isEmpty(paramArray)) { | |||||
return paramArray; | |||||
} | |||||
String[] resultArray = new String[paramArray.length]; | |||||
for (int i = 0; i < paramArray.length; i++) { | |||||
String param = paramArray[i]; | |||||
resultArray[i] = StringUtils.trim(param); | |||||
} | |||||
return resultArray; | |||||
} | |||||
/** | |||||
* 获取类的class文件位置的URL | |||||
* | |||||
* @param cls | |||||
* @return | |||||
*/ | |||||
private static URL getClassLocationURL(final Class<?> cls) { | |||||
if (cls == null) | |||||
throw new IllegalArgumentException("null input: cls"); | |||||
URL result = null; | |||||
final String clsAsResource = cls.getName().replace('.', '/').concat(".class"); | |||||
final ProtectionDomain pd = cls.getProtectionDomain(); | |||||
if (pd != null) { | |||||
final CodeSource cs = pd.getCodeSource(); | |||||
if (cs != null) | |||||
result = cs.getLocation(); | |||||
if (result != null) { | |||||
if ("file".equals(result.getProtocol())) { | |||||
try { | |||||
if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) | |||||
result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clsAsResource)); | |||||
else if (new File(result.getFile()).isDirectory()) | |||||
result = new URL(result, clsAsResource); | |||||
} catch (MalformedURLException ignore) { | |||||
} | |||||
} | |||||
} | |||||
} | |||||
if (result == null) { | |||||
final ClassLoader clsLoader = cls.getClassLoader(); | |||||
result = clsLoader != null ? clsLoader.getResource(clsAsResource) | |||||
: ClassLoader.getSystemResource(clsAsResource); | |||||
} | |||||
return result; | |||||
} | |||||
/** 初始化设置默认值 */ | |||||
public static final <K> K ifNull(K k, K defaultValue) { | |||||
if (k == null) { | |||||
return defaultValue; | |||||
} | |||||
return k; | |||||
} | |||||
public static String unicodeToUtf8(String theString) { | |||||
char aChar; | |||||
int len = theString.length(); | |||||
StringBuffer outBuffer = new StringBuffer(len); | |||||
for (int x = 0; x < len;) { | |||||
aChar = theString.charAt(x++); | |||||
if (aChar == '\\') { | |||||
aChar = theString.charAt(x++); | |||||
if (aChar == 'u') { | |||||
// Read the xxxx | |||||
int value = 0; | |||||
for (int i = 0; i < 4; i++) { | |||||
aChar = theString.charAt(x++); | |||||
switch (aChar) { | |||||
case '0': | |||||
case '1': | |||||
case '2': | |||||
case '3': | |||||
case '4': | |||||
case '5': | |||||
case '6': | |||||
case '7': | |||||
case '8': | |||||
case '9': | |||||
value = (value << 4) + aChar - '0'; | |||||
break; | |||||
case 'a': | |||||
case 'b': | |||||
case 'c': | |||||
case 'd': | |||||
case 'e': | |||||
case 'f': | |||||
value = (value << 4) + 10 + aChar - 'a'; | |||||
break; | |||||
case 'A': | |||||
case 'B': | |||||
case 'C': | |||||
case 'D': | |||||
case 'E': | |||||
case 'F': | |||||
value = (value << 4) + 10 + aChar - 'A'; | |||||
break; | |||||
default: | |||||
throw new IllegalArgumentException( | |||||
"Malformed \\uxxxx encoding."); | |||||
} | |||||
} | |||||
outBuffer.append((char) value); | |||||
} else { | |||||
if (aChar == 't') | |||||
aChar = '\t'; | |||||
else if (aChar == 'r') | |||||
aChar = '\r'; | |||||
else if (aChar == 'n') | |||||
aChar = '\n'; | |||||
else if (aChar == 'f') | |||||
aChar = '\f'; | |||||
outBuffer.append(aChar); | |||||
} | |||||
} else | |||||
outBuffer.append(aChar); | |||||
} | |||||
return outBuffer.toString(); | |||||
} | |||||
} |
@@ -0,0 +1,644 @@ | |||||
package com.iformall.utils; | |||||
import okhttp3.MediaType; | |||||
import okhttp3.OkHttpClient; | |||||
import okhttp3.Request; | |||||
import okhttp3.RequestBody; | |||||
import org.apache.commons.io.IOUtils; | |||||
import org.apache.http.*; | |||||
import org.apache.http.client.CookieStore; | |||||
import org.apache.http.client.entity.UrlEncodedFormEntity; | |||||
import org.apache.http.client.methods.CloseableHttpResponse; | |||||
import org.apache.http.client.methods.HttpGet; | |||||
import org.apache.http.client.methods.HttpPost; | |||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||||
import org.apache.http.entity.StringEntity; | |||||
import org.apache.http.impl.client.BasicCookieStore; | |||||
import org.apache.http.impl.client.CloseableHttpClient; | |||||
import org.apache.http.impl.client.HttpClients; | |||||
import org.apache.http.message.BasicNameValuePair; | |||||
import org.apache.http.protocol.HTTP; | |||||
import org.apache.http.ssl.SSLContexts; | |||||
import org.apache.http.util.EntityUtils; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import com.github.binarywang.wxpay.service.WxPayService; | |||||
import cn.binarywang.wx.miniapp.api.WxMaService; | |||||
import javax.net.ssl.HttpsURLConnection; | |||||
import javax.net.ssl.KeyManager; | |||||
import javax.net.ssl.KeyManagerFactory; | |||||
import javax.net.ssl.SSLContext; | |||||
import java.io.*; | |||||
import java.net.URI; | |||||
import java.net.URL; | |||||
import java.nio.charset.Charset; | |||||
import java.security.KeyManagementException; | |||||
import java.security.KeyStore; | |||||
import java.security.KeyStoreException; | |||||
import java.security.NoSuchAlgorithmException; | |||||
import java.security.SecureRandom; | |||||
import java.security.UnrecoverableKeyException; | |||||
import java.security.cert.CertificateException; | |||||
import java.util.*; | |||||
import java.util.concurrent.ConcurrentHashMap; | |||||
/** | |||||
* @author | |||||
* @date | |||||
* HttpClient工具类 | |||||
*/ | |||||
public class HttpUtil { | |||||
private static final Logger logger = LoggerFactory.getLogger(HttpUtil.class); | |||||
private static final MediaType CONTENT_TYPE_FORM = MediaType.parse("application/x-www-form-urlencoded"); | |||||
private static final String DEFAULT_USER_AGENT = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36"; | |||||
// /** | |||||
// * get请求 | |||||
// * @return | |||||
// */ | |||||
// public static String doGet(String url) { | |||||
// try { | |||||
// CloseableHttpClient client = HttpClients.createDefault(); | |||||
// //发送get请求 | |||||
// HttpGet request = new HttpGet(url); | |||||
// HttpResponse response = client.execute(request); | |||||
// | |||||
// /**请求发送成功,并得到响应**/ | |||||
// if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { | |||||
// /**读取服务器返回过来的json字符串数据**/ | |||||
// String strResult = EntityUtils.toString(response.getEntity()); | |||||
// | |||||
// return strResult; | |||||
// } | |||||
// } | |||||
// catch (IOException e) { | |||||
// logger.error(e.getMessage()); | |||||
// throw new RuntimeException(e); | |||||
// } | |||||
// | |||||
// return null; | |||||
// } | |||||
/** | |||||
* get请求 | |||||
* @return | |||||
*/ | |||||
public static byte[] doWiwidePicGet(String url, String signature) { | |||||
try { | |||||
CloseableHttpClient client = HttpClients.createDefault(); | |||||
//发送get请求 | |||||
HttpGet request = new HttpGet(url); | |||||
request.setHeader("Cookie", "Signature="+signature); | |||||
HttpResponse response = client.execute(request); | |||||
/**请求发送成功,并得到响应**/ | |||||
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { | |||||
/**读取服务器返回过来的json字符串数据**/ | |||||
byte[] bytes = EntityUtils.toByteArray(response.getEntity()); | |||||
return bytes; | |||||
} | |||||
} | |||||
catch (IOException e) { | |||||
logger.error(e.getMessage()); | |||||
throw new RuntimeException(e); | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* post请求(用于key-value格式的参数) | |||||
* @param url | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String doPost(String url, Map params){ | |||||
// 定义HttpClient | |||||
CloseableHttpClient client = HttpClients.createDefault(); | |||||
BufferedReader in = null; | |||||
try { | |||||
// 实例化HTTP方法 | |||||
HttpPost request = new HttpPost(); | |||||
request.setURI(new URI(url)); | |||||
//设置参数 | |||||
List<NameValuePair> nvps = new ArrayList<NameValuePair>(); | |||||
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) { | |||||
String name = (String) iter.next(); | |||||
String value = String.valueOf(params.get(name)); | |||||
nvps.add(new BasicNameValuePair(name, value)); | |||||
//System.out.println(name +"-"+value); | |||||
} | |||||
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8)); | |||||
HttpResponse response = client.execute(request); | |||||
int code = response.getStatusLine().getStatusCode(); | |||||
if(code == 200){ //请求成功 | |||||
in = new BufferedReader(new InputStreamReader(response.getEntity() | |||||
.getContent(),"utf-8")); | |||||
StringBuilder sb = new StringBuilder(""); | |||||
String line = ""; | |||||
String NL = System.getProperty("line.separator"); | |||||
while ((line = in.readLine()) != null) { | |||||
sb.append(line + NL); | |||||
} | |||||
in.close(); | |||||
client.close(); | |||||
return sb.toString(); | |||||
} | |||||
else{ // | |||||
logger.info("状态码:" + code); | |||||
client.close(); | |||||
} | |||||
} | |||||
catch(Exception e){ | |||||
logger.error(e.getMessage()); | |||||
return null; | |||||
} | |||||
return null; | |||||
} | |||||
// /** | |||||
// * post请求(用于key-value格式的参数) | |||||
// * @param url | |||||
// * @param params | |||||
// * @return | |||||
// */ | |||||
// public static String doPost(String url,Map<String,String> headMap, Map params){ | |||||
// | |||||
// // 定义HttpClient | |||||
// CloseableHttpClient client = HttpClients.createDefault(); | |||||
// | |||||
// BufferedReader in = null; | |||||
// try { | |||||
// | |||||
// // 实例化HTTP方法 | |||||
// HttpPost request = new HttpPost(); | |||||
// request.setURI(new URI(url)); | |||||
// if(headMap != null){ | |||||
// Set<String> set = headMap.keySet(); | |||||
// for(String key: set){ | |||||
// request.addHeader(key,headMap.get(key)); | |||||
// } | |||||
// } | |||||
// | |||||
// //设置参数 | |||||
// List<NameValuePair> nvps = new ArrayList<NameValuePair>(); | |||||
// for (Iterator iter = params.keySet().iterator(); iter.hasNext();) { | |||||
// String name = (String) iter.next(); | |||||
// String value = String.valueOf(params.get(name)); | |||||
// nvps.add(new BasicNameValuePair(name, value)); | |||||
// | |||||
// //System.out.println(name +"-"+value); | |||||
// } | |||||
// request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8)); | |||||
// | |||||
// HttpResponse response = client.execute(request); | |||||
// int code = response.getStatusLine().getStatusCode(); | |||||
// if(code == 200){ //请求成功 | |||||
// in = new BufferedReader(new InputStreamReader(response.getEntity() | |||||
// .getContent(),"utf-8")); | |||||
// StringBuilder sb = new StringBuilder(""); | |||||
// String line = ""; | |||||
// String NL = System.getProperty("line.separator"); | |||||
// while ((line = in.readLine()) != null) { | |||||
// sb.append(line + NL); | |||||
// } | |||||
// | |||||
// in.close(); | |||||
// | |||||
// client.close(); | |||||
// | |||||
// return sb.toString(); | |||||
// } | |||||
// else{ // | |||||
// logger.info("状态码:" + code); | |||||
// client.close(); | |||||
// } | |||||
// } | |||||
// catch(Exception e){ | |||||
// logger.error(e.getMessage()); | |||||
// return null; | |||||
// } | |||||
// | |||||
// return null; | |||||
// } | |||||
/** | |||||
* post请求(用于key-value格式的参数,wiwide) | |||||
* @param url | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String doPostWiwide(String url, String token, Map params){ | |||||
//CookieStore store= new BasicCookieStore(); | |||||
//HttpClients.custom().setDefaultCookieStore(store).build(); | |||||
// 定义HttpClient | |||||
CloseableHttpClient client = HttpClients.createDefault(); | |||||
BufferedReader in = null; | |||||
try { | |||||
// 实例化HTTP方法 | |||||
HttpPost request = new HttpPost(); | |||||
request.setURI(new URI(url)); | |||||
request.setHeader("Content-Type", "application/x-www-form-urlencoded"); | |||||
request.setHeader("Accept-Charset", "utf-8"); | |||||
request.setHeader("wiwidefumaotoken", token); | |||||
//设置参数 | |||||
List<NameValuePair> nvps = new ArrayList<NameValuePair>(); | |||||
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) { | |||||
String name = (String) iter.next(); | |||||
String value = String.valueOf(params.get(name)); | |||||
nvps.add(new BasicNameValuePair(name, value)); | |||||
//System.out.println(name +"-"+value); | |||||
} | |||||
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8)); | |||||
HttpResponse response = client.execute(request); | |||||
int code = response.getStatusLine().getStatusCode(); | |||||
if(code == 200){ //请求成功 | |||||
in = new BufferedReader(new InputStreamReader(response.getEntity() | |||||
.getContent(),"utf-8")); | |||||
StringBuilder sb = new StringBuilder(""); | |||||
String line = ""; | |||||
String NL = System.getProperty("line.separator"); | |||||
while ((line = in.readLine()) != null) { | |||||
sb.append(line + NL); | |||||
} | |||||
in.close(); | |||||
client.close(); | |||||
return sb.toString(); | |||||
} | |||||
else{ // | |||||
logger.info("状态码:" + code); | |||||
client.close(); | |||||
} | |||||
} | |||||
catch(Exception e){ | |||||
logger.error(e.getMessage()); | |||||
return null; | |||||
} | |||||
return null; | |||||
} | |||||
/** | |||||
* post请求(用于key-value格式的参数,wiwide) | |||||
* @param url | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String doPostWiwideNew(String url, String signature, Map params){ | |||||
//CookieStore store= new BasicCookieStore(); | |||||
//HttpClients.custom().setDefaultCookieStore(store).build(); | |||||
// 定义HttpClient | |||||
CloseableHttpClient client = HttpClients.createDefault(); | |||||
BufferedReader in = null; | |||||
try { | |||||
// 实例化HTTP方法 | |||||
HttpPost request = new HttpPost(); | |||||
request.setURI(new URI(url)); | |||||
request.setHeader("Content-Type", "application/x-www-form-urlencoded"); | |||||
request.setHeader("Accept-Charset", "utf-8"); | |||||
request.setHeader("Cookie", "Signature="+signature); | |||||
//设置参数 | |||||
List<NameValuePair> nvps = new ArrayList<NameValuePair>(); | |||||
for (Iterator iter = params.keySet().iterator(); iter.hasNext();) { | |||||
String name = (String) iter.next(); | |||||
String value = String.valueOf(params.get(name)); | |||||
nvps.add(new BasicNameValuePair(name, value)); | |||||
//System.out.println(name +"-"+value); | |||||
} | |||||
request.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8)); | |||||
HttpResponse response = client.execute(request); | |||||
int code = response.getStatusLine().getStatusCode(); | |||||
if(code == 200){ //请求成功 | |||||
in = new BufferedReader(new InputStreamReader(response.getEntity() | |||||
.getContent(),"utf-8")); | |||||
StringBuilder sb = new StringBuilder(""); | |||||
String line = ""; | |||||
String NL = System.getProperty("line.separator"); | |||||
while ((line = in.readLine()) != null) { | |||||
sb.append(line + NL); | |||||
} | |||||
in.close(); | |||||
client.close(); | |||||
return sb.toString(); | |||||
} | |||||
else{ // | |||||
logger.info("状态码:" + code); | |||||
client.close(); | |||||
} | |||||
} | |||||
catch(Exception e){ | |||||
logger.error(e.getMessage()); | |||||
return null; | |||||
} | |||||
return null; | |||||
} | |||||
// /** | |||||
// * post请求(用于请求json格式的参数) | |||||
// * @param url | |||||
// * @param params | |||||
// * @return | |||||
// */ | |||||
// public static String doPost(String url, String params) throws Exception { | |||||
// | |||||
// CloseableHttpClient httpclient = HttpClients.createDefault(); | |||||
// HttpPost httpPost = new HttpPost(url);// 创建httpPost | |||||
// httpPost.setHeader("Accept", "application/json"); | |||||
// httpPost.setHeader("Content-Type", "application/json"); | |||||
// String charSet = "UTF-8"; | |||||
// StringEntity entity = new StringEntity(params, charSet); | |||||
// httpPost.setEntity(entity); | |||||
// CloseableHttpResponse response = null; | |||||
// | |||||
// try { | |||||
// response = httpclient.execute(httpPost); | |||||
// StatusLine status = response.getStatusLine(); | |||||
// int state = status.getStatusCode(); | |||||
// if (state == HttpStatus.SC_OK) { | |||||
// HttpEntity responseEntity = response.getEntity(); | |||||
// String jsonString = EntityUtils.toString(responseEntity); | |||||
// return jsonString; | |||||
// } | |||||
// else{ | |||||
// logger.info("请求返回:"+state+"("+url+")"); | |||||
// } | |||||
// } | |||||
// finally { | |||||
// if (response != null) { | |||||
// try { | |||||
// response.close(); | |||||
// } catch (IOException e) { | |||||
// logger.error(e.getMessage()); | |||||
// } | |||||
// } | |||||
// try { | |||||
// httpclient.close(); | |||||
// } catch (IOException e) { | |||||
// logger.error(e.getMessage()); | |||||
// } | |||||
// } | |||||
// return null; | |||||
// } | |||||
/** | |||||
* post请求(用于请求json格式的参数) | |||||
* @param url | |||||
* @param params | |||||
* @return | |||||
*/ | |||||
public static String doPost(String url, Map<String,String> headMap, String params){ | |||||
CloseableHttpClient httpclient = HttpClients.createDefault(); | |||||
HttpPost httpPost = new HttpPost(url);// 创建httpPost | |||||
httpPost.setHeader("Accept", "application/json"); | |||||
httpPost.setHeader("Content-Type", "application/json"); | |||||
if(headMap != null){ | |||||
Set<String> set = headMap.keySet(); | |||||
for(String key: set){ | |||||
httpPost.addHeader(key,headMap.get(key)); | |||||
} | |||||
} | |||||
String charSet = "UTF-8"; | |||||
StringEntity entity = new StringEntity(params, charSet); | |||||
httpPost.setEntity(entity); | |||||
CloseableHttpResponse response = null; | |||||
try { | |||||
response = httpclient.execute(httpPost); | |||||
StatusLine status = response.getStatusLine(); | |||||
int state = status.getStatusCode(); | |||||
if (state == HttpStatus.SC_OK) { | |||||
HttpEntity responseEntity = response.getEntity(); | |||||
String jsonString = EntityUtils.toString(responseEntity); | |||||
return jsonString; | |||||
} | |||||
else{ | |||||
logger.info("请求返回:"+state+"("+url+")"); | |||||
} | |||||
} | |||||
catch(Exception e){ | |||||
logger.error(e.getMessage()); | |||||
return null; | |||||
} | |||||
finally { | |||||
if (response != null) { | |||||
try { | |||||
response.close(); | |||||
} catch (IOException e) { | |||||
logger.error(e.getMessage()); | |||||
} | |||||
} | |||||
try { | |||||
httpclient.close(); | |||||
} catch (IOException e) { | |||||
logger.error(e.getMessage()); | |||||
} | |||||
} | |||||
return null; | |||||
} | |||||
public static String payPost(String url, String params) { | |||||
RequestBody body = RequestBody.create(CONTENT_TYPE_FORM, params); | |||||
Request request = null; | |||||
try { | |||||
request = new Request.Builder().addHeader("Accept-Charset", "utf-8") | |||||
.addHeader("Content-Type", "application/x-www-form-urlencoded") | |||||
.addHeader("Content-Length", String.valueOf(body.contentLength())) | |||||
.url(url).post(body).build(); | |||||
return exec(request); | |||||
} catch (IOException e) { | |||||
logger.error(e.getMessage()); | |||||
return null; | |||||
} | |||||
} | |||||
private static OkHttpClient OkHttpClient = new OkHttpClient(); | |||||
private static String exec(okhttp3.Request request) { | |||||
try { | |||||
okhttp3.Response response = OkHttpClient.newCall(request).execute(); | |||||
// String header = response.header("X-Tt-Logid"); | |||||
// logger.info("X-Tt-Logid="+header); | |||||
if (!response.isSuccessful()) | |||||
throw new RuntimeException("Unexpected code " + response); | |||||
return response.body().string(); | |||||
} catch (IOException e) { | |||||
logger.error(e.getMessage()); | |||||
throw new RuntimeException(e); | |||||
} | |||||
} | |||||
private static Map<String,SSLContext> sslContextMap = new ConcurrentHashMap<String,SSLContext>(); | |||||
private static SSLContext getSSLContext(String certPath, String certPass) throws KeyStoreException, NoSuchAlgorithmException, | |||||
CertificateException, FileNotFoundException, IOException, UnrecoverableKeyException, KeyManagementException { | |||||
String key = certPath+certPass; | |||||
SSLContext sslContext = sslContextMap.get(key); | |||||
if ( null == sslContext ) { | |||||
synchronized("sslContextLock"+key) { | |||||
sslContext = sslContextMap.get(key); | |||||
if (null == sslContext) { | |||||
KeyStore clientStore = KeyStore.getInstance("PKCS12"); | |||||
clientStore.load(new FileInputStream(certPath), certPass.toCharArray()); | |||||
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); | |||||
kmf.init(clientStore, certPass.toCharArray()); | |||||
KeyManager[] kms = kmf.getKeyManagers(); | |||||
sslContext = SSLContext.getInstance("TLS"); | |||||
sslContext.init(kms, null, new SecureRandom()); | |||||
sslContextMap.put(key, sslContext); | |||||
} | |||||
} | |||||
} | |||||
return sslContext; | |||||
} | |||||
public static String payPostSSL(String url, String data, String certPath, String certPass) { | |||||
HttpsURLConnection conn = null; | |||||
OutputStream out = null; | |||||
InputStream inputStream = null; | |||||
BufferedReader reader = null; | |||||
try { | |||||
SSLContext sslContext = getSSLContext(certPath, certPass); | |||||
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory()); | |||||
URL _url = new URL(url); | |||||
conn = (HttpsURLConnection) _url.openConnection(); | |||||
conn.setConnectTimeout(25000); | |||||
conn.setReadTimeout(25000); | |||||
conn.setRequestMethod("POST"); | |||||
conn.setDoOutput(true); | |||||
conn.setDoInput(true); | |||||
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); | |||||
conn.setRequestProperty("User-Agent", DEFAULT_USER_AGENT); | |||||
conn.connect(); | |||||
out = conn.getOutputStream(); | |||||
out.write(data.getBytes(Charset.forName("UTF-8"))); | |||||
out.flush(); | |||||
inputStream = conn.getInputStream(); | |||||
reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName("UTF-8"))); | |||||
StringBuilder sb = new StringBuilder(); | |||||
String line = null; | |||||
while ((line = reader.readLine()) != null) { | |||||
sb.append(line).append("\n"); | |||||
} | |||||
return sb.toString(); | |||||
} catch (Exception e) { | |||||
logger.error(e.getMessage()); | |||||
throw new RuntimeException(e); | |||||
} finally { | |||||
IOUtils.closeQuietly(out); | |||||
IOUtils.closeQuietly(reader); | |||||
IOUtils.closeQuietly(inputStream); | |||||
if (conn != null) { | |||||
conn.disconnect(); | |||||
} | |||||
} | |||||
} | |||||
// private static String ClientCustomSSL(String url, String p12file, String mch_id, String xmlStr) throws Exception{ | |||||
// KeyStore keyStore = KeyStore.getInstance("PKCS12"); | |||||
// FileInputStream instream = new FileInputStream(new File(p12file)); | |||||
// try { | |||||
// keyStore.load(instream, mch_id.toCharArray()); | |||||
// } finally { | |||||
// instream.close(); | |||||
// } | |||||
// | |||||
// // Trust own CA and all self-signed certs | |||||
// SSLContext sslcontext = SSLContexts.custom() | |||||
// .loadKeyMaterial(keyStore, mch_id.toCharArray()) | |||||
// .build(); | |||||
// // Allow TLSv1 protocol only | |||||
// SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( | |||||
// sslcontext, | |||||
// new String[] { "TLSv1" }, | |||||
// null, | |||||
// SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); | |||||
// CloseableHttpClient httpclient = HttpClients.custom() | |||||
// .setSSLSocketFactory(sslsf) | |||||
// .build(); | |||||
// try { | |||||
// HttpPost httpPost = new HttpPost(url); | |||||
// StringEntity entityStr = new StringEntity(xmlStr); | |||||
// entityStr.setContentType("text/xml"); | |||||
// //logger.info("entityStr--------------"+entityStr); | |||||
// httpPost.setEntity(entityStr); | |||||
// | |||||
// CloseableHttpResponse response = httpclient.execute(httpPost); | |||||
// try { | |||||
// HttpEntity entity = response.getEntity(); | |||||
// | |||||
// //System.out.println("----------------------------------------"); | |||||
// //System.out.println(response.getStatusLine()); | |||||
// if (entity != null) { | |||||
// //System.out.println("Response content length: " + entity.getContentLength()); | |||||
// BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent())); | |||||
// StringBuilder sb = new StringBuilder(); | |||||
// String line = null; | |||||
// while ((line = bufferedReader.readLine()) != null) { | |||||
// sb.append(line).append("\n"); | |||||
// } | |||||
// return sb.toString(); | |||||
// } | |||||
// EntityUtils.consume(entity); | |||||
// } finally { | |||||
// response.close(); | |||||
// } | |||||
// } finally { | |||||
// httpclient.close(); | |||||
// return null; | |||||
// } | |||||
// | |||||
// } | |||||
} | |||||
@@ -0,0 +1,22 @@ | |||||
package com.iformall.utils; | |||||
import java.util.Comparator; | |||||
import java.util.Map; | |||||
import java.util.TreeMap; | |||||
public class MapUtil { | |||||
/** | |||||
* 获取带排序的Map | |||||
* @return | |||||
*/ | |||||
public static Map<String, String> getOrderMap() { | |||||
Map<String, String> paramMap = new TreeMap<String, String>( | |||||
new Comparator<String>() { | |||||
public int compare(String obj1, String obj2) { | |||||
// 降序排序 | |||||
return obj1.compareTo(obj2); | |||||
} | |||||
}); | |||||
return paramMap; | |||||
} | |||||
} |
@@ -0,0 +1,8 @@ | |||||
package com.iformall.utils; | |||||
public class SysConfigConstant { | |||||
public static final String sale_price="salePrice"; | |||||
public static final String pay_call_back = "payCallBack"; | |||||
} |
@@ -0,0 +1,612 @@ | |||||
package com.iformall.utils; | |||||
import org.slf4j.Logger; | |||||
import org.slf4j.LoggerFactory; | |||||
import java.io.File; | |||||
import java.io.UnsupportedEncodingException; | |||||
import java.math.BigDecimal; | |||||
import java.net.URLDecoder; | |||||
import java.net.URLEncoder; | |||||
import java.text.NumberFormat; | |||||
import java.text.ParseException; | |||||
import java.text.SimpleDateFormat; | |||||
import java.util.*; | |||||
import java.util.regex.Matcher; | |||||
import java.util.regex.Pattern; | |||||
/** | |||||
* @author Stormeye | |||||
* @since 2018.08.09 | |||||
*/ | |||||
public final class Utility { | |||||
private final static Logger logger = LoggerFactory.getLogger(Utility.class); | |||||
// @Autowired | |||||
// private ReloadableResourceBundleMessageSource messageSource; | |||||
public static String generateUUID() { | |||||
return UUID.randomUUID().toString(); | |||||
} | |||||
public static String generate32UUID() { | |||||
return UUID.randomUUID().toString().replaceAll("-", ""); | |||||
} | |||||
public static boolean isEmpty(CharSequence str) { | |||||
if (str == null || str.length() == 0) | |||||
return true; | |||||
else | |||||
return false; | |||||
} | |||||
public static boolean isBlank(CharSequence str) { | |||||
int strLen; | |||||
if (str == null || (strLen = str.length()) == 0) { | |||||
return true; | |||||
} | |||||
for (int i = 0; i < strLen; i++) { | |||||
if ((Character.isWhitespace(str.charAt(i)) == false)) { | |||||
return false; | |||||
} | |||||
} | |||||
return true; | |||||
} | |||||
/** | |||||
* format time to "yyyy-MM-dd" | |||||
* @param time | |||||
* @return | |||||
*/ | |||||
public static String formatTime(int time){ | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
/** | |||||
* format timestamp to "yyyy-MM-dd HH:mm:ss" | |||||
* @param time | |||||
* @return | |||||
*/ | |||||
public static String formatTimestamp(int time){ | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
/** | |||||
* getSimpleRegionModel the day end time by given the time point | |||||
* e.g. given timePoint is "2015.5.13 13:45:32", the returned day end time is "2015.5.13 23:59:59" | |||||
* @param timePoint | |||||
* @return | |||||
*/ | |||||
public static int getDayEndTime(int timePoint){ | |||||
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")); | |||||
long theTime = ((long)timePoint)*1000; | |||||
calendar.setTimeInMillis(theTime); | |||||
int year = calendar.get(Calendar.YEAR); | |||||
int month = calendar.get(Calendar.MONTH); | |||||
int day = calendar.get(Calendar.DAY_OF_MONTH); | |||||
int hour = calendar.get(Calendar.HOUR_OF_DAY); | |||||
int minute = calendar.get(Calendar.MINUTE); | |||||
int second = calendar.get(Calendar.SECOND); | |||||
calendar.clear(); | |||||
calendar.set(year, month, day, 23, 59, 59); | |||||
int ret = (int)(calendar.getTimeInMillis()/1000); | |||||
return ret; | |||||
} | |||||
public static int getDayStartTime(int timePoint) { | |||||
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT+8")); | |||||
long theTime = ((long)timePoint)*1000; | |||||
calendar.setTimeInMillis(theTime); | |||||
int year = calendar.get(Calendar.YEAR); | |||||
int month = calendar.get(Calendar.MONTH); | |||||
int day = calendar.get(Calendar.DAY_OF_MONTH); | |||||
int hour = calendar.get(Calendar.HOUR_OF_DAY); | |||||
int minute = calendar.get(Calendar.MINUTE); | |||||
int second = calendar.get(Calendar.SECOND); | |||||
calendar.clear(); | |||||
calendar.set(year, month, day, 0, 0, 0); | |||||
int ret = (int)(calendar.getTimeInMillis()/1000); | |||||
return ret; | |||||
} | |||||
public static int getLastHourEndTime(int timePoint) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd-HH"); | |||||
String curHour = sf.format(System.currentTimeMillis()); | |||||
int ret = timePoint; | |||||
try { | |||||
ret = (int)((sf.parse(curHour).getTime())/1000); | |||||
} catch(ParseException ex) { | |||||
ex.printStackTrace(); | |||||
} | |||||
return ret - 1; | |||||
} | |||||
/** | |||||
* Encrypt plain text | |||||
* @param plainText | |||||
* @return encrypted string for cvn2 | |||||
*/ | |||||
public static String encryptText(String plainText) { | |||||
return plainText; | |||||
} | |||||
/** | |||||
* Decrypt to plain text | |||||
* @param decryptedText | |||||
* @return encrypted string for cvn2 | |||||
*/ | |||||
public static String decryptedText(String decryptedText) { | |||||
return decryptedText; | |||||
} | |||||
/** | |||||
* Mask the bankcard Number, e.g. 18911113927 to 189******3927 | |||||
* @param idCardNo | |||||
* @return masked phone number | |||||
*/ | |||||
public static String maskIdCard(String idCardNo) { | |||||
if(isEmpty(idCardNo) || idCardNo.length() < 18) { | |||||
return idCardNo; | |||||
} | |||||
return idCardNo.substring(0,4) + "**" + idCardNo.substring(6, 12) + "***" + idCardNo.substring(15, 18); | |||||
} | |||||
/** | |||||
* Mask the bankcard Number, e.g. 18911113927 to 189******3927 | |||||
* @param bankCardNo | |||||
* @return masked phone number | |||||
*/ | |||||
public static String maskBankCard(String bankCardNo) { | |||||
if(bankCardNo.length() <= 8) { | |||||
return bankCardNo; | |||||
} | |||||
return bankCardNo.substring(0,4) + "******" + bankCardNo.substring(bankCardNo.length() - 4, bankCardNo.length()); | |||||
} | |||||
/** | |||||
* Mask the user name, e.g. | |||||
* @param userName | |||||
* @return masked phone number | |||||
*/ | |||||
public static String maskUserName(String userName) { | |||||
switch (userName.length()) { | |||||
case 0: | |||||
case 1: | |||||
return "*"; | |||||
default: | |||||
return userName.replaceAll(".", "*").replaceFirst(".$",userName.substring(userName.length() - 1)); | |||||
} | |||||
} | |||||
public static String maskPhoneNum(String phoneNum) { | |||||
if(phoneNum==null || phoneNum.length() < 4) { | |||||
return phoneNum; | |||||
} | |||||
return phoneNum.substring(0,3) + "****" + phoneNum.substring(phoneNum.length() - 4, phoneNum.length()); | |||||
} | |||||
/** | |||||
* Convert current time into int type. used for create_time/update time | |||||
* @param | |||||
* @return timestamp | |||||
*/ | |||||
public static int getCurrentTimeStamp() { | |||||
if(debugCurrentTimeStamp == 0) { | |||||
return (int) (System.currentTimeMillis() / 1000); | |||||
}else { | |||||
return debugCurrentTimeStamp; | |||||
} | |||||
} | |||||
public static int convertDate2TimeStamp(Date date) { | |||||
return (int) (date.getTime() / 1000); | |||||
} | |||||
private static int debugCurrentTimeStamp = 0; | |||||
/** | |||||
* For test purpose, getCurrentTimeStamp will return the timestamp if non-zero. | |||||
* @param | |||||
* @return timestamp | |||||
*/ | |||||
public static void setDebugCurrentTimeStamp(int timeStamp) { | |||||
debugCurrentTimeStamp = timeStamp; | |||||
} | |||||
public static String generateInvitationCode(Set<String> existingCode){ | |||||
int invitationCode = (int)((Math.random()*9+1)*100000); | |||||
if(existingCode != null){ | |||||
while(existingCode.contains(String.valueOf(invitationCode))){ | |||||
invitationCode++; | |||||
if(invitationCode>=999999){ | |||||
invitationCode = (int)((Math.random()*9+1)*100000); | |||||
} | |||||
} | |||||
} | |||||
return String.valueOf(invitationCode); | |||||
} | |||||
public static String generateOrderId(String gid) { | |||||
if (null == gid) { | |||||
return ""; | |||||
} | |||||
return "SDLC" + gid.replaceAll("-", ""); | |||||
} | |||||
public static String getDataFormatString(int currentSec) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
return sf.format(((long) currentSec) * 1000); | |||||
} | |||||
public static String getDataFormatString2(int currentSec) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日"); | |||||
return sf.format(((long) currentSec) * 1000); | |||||
} | |||||
public static String getDataFormatString3(Date date) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyy年MM月dd日"); | |||||
return sf.format(date); | |||||
} | |||||
public static String convertDecimal2PercentRate(BigDecimal rate) { | |||||
NumberFormat percent = NumberFormat.getPercentInstance(); | |||||
percent.setMaximumFractionDigits(1); | |||||
return percent.format(rate.setScale(3, BigDecimal.ROUND_DOWN)); | |||||
} | |||||
public static String convertLineFeedCharacter(String msg){ | |||||
if(msg == null || msg.isEmpty()){ | |||||
return ""; | |||||
} | |||||
msg = msg.replace("\\\\n", "\\n"); | |||||
return msg; | |||||
} | |||||
public static int getSimpleDayEndTime(int timePoint){ | |||||
Calendar ca = new GregorianCalendar(); | |||||
ca.setTime(new Date(((long) timePoint) * 1000)); | |||||
ca.set(Calendar.HOUR_OF_DAY, 23); | |||||
ca.set(Calendar.MINUTE, 59); | |||||
ca.set(Calendar.SECOND, 59); | |||||
long ret = ca.getTime().getTime()/1000; | |||||
return (int) ret; | |||||
} | |||||
public static String urlEncodeUTF8(String s) { | |||||
try { | |||||
return URLEncoder.encode(s, "UTF-8"); | |||||
} catch (UnsupportedEncodingException e) { | |||||
throw new UnsupportedOperationException(e); | |||||
} | |||||
} | |||||
public static String urlDecodeUTF8(String s) { | |||||
try { | |||||
return URLDecoder.decode(s, "UTF-8"); | |||||
} catch (UnsupportedEncodingException e) { | |||||
throw new UnsupportedOperationException(e); | |||||
} | |||||
} | |||||
public static int dateStringToTimeStamp(String dateStr){ | |||||
int timeStamp = 0; | |||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
try { | |||||
Date date = sdf.parse(dateStr); | |||||
timeStamp= (int) (date.getTime()/1000); | |||||
} catch (ParseException e) { | |||||
logger.error("dateStringToTimeStamp exception = {}", e); | |||||
} | |||||
return timeStamp; | |||||
} | |||||
public static int dateStringToTimeStamp(String dateStr,String format){ | |||||
int timeStamp = 0; | |||||
SimpleDateFormat sdf = new SimpleDateFormat(format); | |||||
try { | |||||
Date date = sdf.parse(dateStr); | |||||
timeStamp= (int) (date.getTime()/1000); | |||||
} catch (ParseException e) { | |||||
logger.error("dateStringToTimeStamp exception = {}", e); | |||||
} | |||||
return timeStamp; | |||||
} | |||||
public static Object convert(Object object, Class<?> type) { | |||||
if (object instanceof Number) { | |||||
Number number = (Number) object; | |||||
if (type.equals(byte.class) || type.equals(Byte.class)) { | |||||
return number.byteValue(); | |||||
} | |||||
if (type.equals(short.class) || type.equals(Short.class)) { | |||||
return number.shortValue(); | |||||
} | |||||
if (type.equals(int.class) || type.equals(Integer.class)) { | |||||
return number.intValue(); | |||||
} | |||||
if (type.equals(long.class) || type.equals(Long.class)) { | |||||
return number.longValue(); | |||||
} | |||||
if (type.equals(float.class) || type.equals(Float.class)) { | |||||
return number.floatValue(); | |||||
} | |||||
if (type.equals(double.class) || type.equals(Double.class)) { | |||||
return number.doubleValue(); | |||||
} | |||||
} | |||||
return object; | |||||
} | |||||
public static int getFirstDayByDate(final Date date) { | |||||
Calendar instance = Calendar.getInstance(); | |||||
instance.setTime(date); | |||||
instance.set(instance.get(Calendar.YEAR), instance.get(Calendar.MONTH), 1, 0, 0, 0); | |||||
int ret = (int) (instance.getTimeInMillis()/1000); | |||||
return ret; | |||||
} | |||||
public static boolean decimalEqualsScale2(BigDecimal one , BigDecimal two) { | |||||
if (one == null || two == null) { | |||||
return false; | |||||
} | |||||
final BigDecimal o1 = one.setScale(2 , BigDecimal.ROUND_DOWN); | |||||
final BigDecimal o2 = two.setScale(2 , BigDecimal.ROUND_DOWN); | |||||
return o1.compareTo(o2) == 0; | |||||
} | |||||
public static int decimalCompareScale2(BigDecimal one , BigDecimal two) { | |||||
if (one == null || two == null) { | |||||
return -1; | |||||
} | |||||
final BigDecimal o1 = one.setScale(2 , BigDecimal.ROUND_DOWN); | |||||
final BigDecimal o2 = two.setScale(2 , BigDecimal.ROUND_DOWN); | |||||
return o1.compareTo(o2); | |||||
} | |||||
public static BigDecimal setScale2RoundDown(BigDecimal one) { | |||||
if (one == null) { | |||||
return null; | |||||
} | |||||
return one.setScale(2, BigDecimal.ROUND_DOWN); | |||||
} | |||||
public static boolean isNumeric(String str){ | |||||
Pattern pattern = Pattern.compile("[0-9]*"); | |||||
Matcher isNum = pattern.matcher(str); | |||||
if( !isNum.matches() ){ | |||||
return false; | |||||
} | |||||
return true; | |||||
} | |||||
public static String dateFormat(Date date, String pattern) { | |||||
SimpleDateFormat sdf = new SimpleDateFormat(pattern); | |||||
return sdf.format(date); | |||||
} | |||||
public static int getCurrentWeekStartTime(int dayTime) { | |||||
Calendar currentDate = Calendar.getInstance(); | |||||
currentDate.setTime(new Date(dayTime * 1000L)); | |||||
currentDate.setFirstDayOfWeek(Calendar.MONDAY); | |||||
currentDate.set(Calendar.HOUR_OF_DAY, 0); | |||||
currentDate.set(Calendar.MINUTE, 0); | |||||
currentDate.set(Calendar.SECOND, 0); | |||||
currentDate.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); | |||||
return (int)(currentDate.getTimeInMillis() / 1000L); | |||||
} | |||||
public static int getCurrentWeekEndTime(int dayTime) { | |||||
Calendar currentDate = Calendar.getInstance(); | |||||
currentDate.setTime(new Date(dayTime * 1000L)); | |||||
currentDate.setFirstDayOfWeek(Calendar.MONDAY); | |||||
currentDate.set(Calendar.HOUR_OF_DAY, 23); | |||||
currentDate.set(Calendar.MINUTE, 59); | |||||
currentDate.set(Calendar.SECOND, 59); | |||||
currentDate.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); | |||||
return (int)(currentDate.getTimeInMillis() / 1000L); | |||||
} | |||||
public static int getCurrentMonthStartTime(int dayTime) { | |||||
Calendar currentDate = Calendar.getInstance(); | |||||
currentDate.setTime(new Date(dayTime * 1000L)); | |||||
currentDate.set(Calendar.HOUR_OF_DAY, 0); | |||||
currentDate.set(Calendar.MINUTE, 0); | |||||
currentDate.set(Calendar.SECOND, 0); | |||||
currentDate.set(Calendar.DAY_OF_MONTH, currentDate | |||||
.getActualMinimum(Calendar.DAY_OF_MONTH)); | |||||
return (int)(currentDate.getTimeInMillis() / 1000L); | |||||
} | |||||
public static int getCurrentMonthEndTime(int dayTime) { | |||||
Calendar currentDate = Calendar.getInstance(); | |||||
currentDate.setTime(new Date(dayTime * 1000L)); | |||||
currentDate.set(Calendar.HOUR_OF_DAY, 23); | |||||
currentDate.set(Calendar.MINUTE, 59); | |||||
currentDate.set(Calendar.SECOND, 59); | |||||
currentDate.set(Calendar.DAY_OF_MONTH, currentDate | |||||
.getActualMaximum(Calendar.DAY_OF_MONTH)); | |||||
return (int)(currentDate.getTimeInMillis() / 1000L); | |||||
} | |||||
/** | |||||
* format time to "yyyy-MM-dd" | |||||
* @param time | |||||
* @return | |||||
*/ | |||||
public static String formatTimeYYMMDDHH(int time){ | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHH"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
public static String formatTimeMMDD(int time){ | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("MMdd"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
public static String formatTimeMMDotDD(int time) { | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("MM.dd"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
public static String formatTimeYmdHm(int time) { | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
public static int getDayByType(int time, int type) { | |||||
long t = time * 1000L; | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.setTime(new Date(t)); | |||||
return calendar.get(type); | |||||
} | |||||
public static int addTime(int time , int type , int nums) { | |||||
long t = time * 1000L; | |||||
Calendar calendar = Calendar.getInstance(); | |||||
calendar.setTime(new Date(t)); | |||||
calendar.add(type, nums); | |||||
return (int)(calendar.getTimeInMillis() / 1000L); | |||||
} | |||||
public static BigDecimal convertCoord2Decimal(Integer coordLat) { | |||||
return new BigDecimal(coordLat).divide(new BigDecimal(100000), 5, BigDecimal.ROUND_HALF_DOWN); | |||||
} | |||||
public static BigDecimal convertScale(Double amount) { | |||||
return amount != null ? new BigDecimal(amount).setScale(1,BigDecimal.ROUND_HALF_DOWN) : BigDecimal.ZERO; | |||||
} | |||||
public static String convertLevel(String level) { | |||||
if (level != null && level.matches("\\d+(.\\d+)?")) { | |||||
return new BigDecimal(level) | |||||
.multiply(new BigDecimal(2.0)) | |||||
.setScale(1, BigDecimal.ROUND_HALF_UP).toString(); | |||||
} | |||||
return level; | |||||
} | |||||
public static String getUTFString(String content) { | |||||
try { | |||||
return new String(content.getBytes("ISO-8859-1"), "utf-8"); | |||||
} catch (UnsupportedEncodingException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return ""; | |||||
} | |||||
/** | |||||
* 金额 分转换元(精确到2位小数) | |||||
* @param money (单位分) | |||||
* @return | |||||
*/ | |||||
public static BigDecimal getAmount(Integer money) { | |||||
return new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN); | |||||
} | |||||
public static String getDataFormatStringYYYYMMDDHHmmss(int currentSec) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); | |||||
return sf.format(((long) currentSec) * 1000); | |||||
} | |||||
public static String getDataFormatStringYYYYMMDDHHmmss(Date currentDate) { | |||||
SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss"); | |||||
return sf.format(currentDate); | |||||
} | |||||
public static Date getDateFromString(String timeEnd) throws ParseException { | |||||
timeEnd = timeEnd.replaceAll("[[\\s-:punct:]]",""); | |||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); | |||||
return sdf.parse(timeEnd); | |||||
} | |||||
public static Date getDateTtFromString(String timeEnd) throws ParseException { | |||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
return sdf.parse(timeEnd); | |||||
} | |||||
public static String getOrderNo() { | |||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | |||||
String dateStr = sdf.format(new Date()); | |||||
return dateStr.substring(0,4)+dateStr.substring(5,7)+dateStr.substring(8,10)+dateStr.substring(11,13)+dateStr.substring(14,16)+dateStr.substring(17,19)+RandomUtils.getNum(5); | |||||
} | |||||
/** | |||||
* 金额 分转换元(精确到1位小数) | |||||
* @param money (单位角) | |||||
* @return | |||||
*/ | |||||
public static String getAmountStr(Integer money) { | |||||
return new BigDecimal(money).divide(new BigDecimal(100), 2, BigDecimal.ROUND_DOWN).toString(); | |||||
} | |||||
/** | |||||
* format time to "yyyyMMdd" | |||||
* @param time | |||||
* @return | |||||
*/ | |||||
public static String formatTimeYmd(int time){ | |||||
long t = time * 1000l; | |||||
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd"); | |||||
String ret = formatter.format(new Date(t)); | |||||
return ret; | |||||
} | |||||
public static boolean isFileExist(String filePath) { | |||||
File path=new File(filePath); | |||||
if(path.exists()){ | |||||
return true; | |||||
} | |||||
return false; | |||||
} | |||||
/** | |||||
* @param text | |||||
* 目标字符串 | |||||
* @param length | |||||
* 截取长度 | |||||
* @param encode | |||||
* 采用的编码方式 | |||||
* @return | |||||
* @throws UnsupportedEncodingException | |||||
*/ | |||||
public static String substring(String text, int length, String encode) | |||||
throws UnsupportedEncodingException { | |||||
if (text == null) { | |||||
return null; | |||||
} | |||||
StringBuilder sb = new StringBuilder(); | |||||
int currentLength = 0; | |||||
for (char c : text.toCharArray()) { | |||||
currentLength += String.valueOf(c).getBytes(encode).length; | |||||
if (currentLength <= length) { | |||||
sb.append(c); | |||||
} else { | |||||
break; | |||||
} | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
} |
@@ -0,0 +1,459 @@ | |||||
package com.iformall.utils; | |||||
import org.apache.commons.logging.Log; | |||||
import org.apache.commons.logging.LogFactory; | |||||
import org.dom4j.*; | |||||
import org.dom4j.tree.DefaultElement; | |||||
import javax.xml.parsers.DocumentBuilder; | |||||
import javax.xml.parsers.DocumentBuilderFactory; | |||||
import javax.xml.transform.OutputKeys; | |||||
import javax.xml.transform.Transformer; | |||||
import javax.xml.transform.TransformerFactory; | |||||
import javax.xml.transform.dom.DOMSource; | |||||
import javax.xml.transform.stream.StreamResult; | |||||
import java.io.StringWriter; | |||||
import java.util.*; | |||||
/** | |||||
* XML处理器<br> | |||||
* | |||||
* @author XiongChun | |||||
* @since 2009-07-07 | |||||
*/ | |||||
@SuppressWarnings({ "rawtypes", "unchecked" }) | |||||
public final class XmlUtil { | |||||
private static Log log = LogFactory.getLog(XmlUtil.class); | |||||
private XmlUtil() { | |||||
} | |||||
/** | |||||
* 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式) | |||||
* | |||||
* @param pStrXml 待解析的XML字符串 | |||||
* @return outDto 返回Dto | |||||
*/ | |||||
public static final Map parseXml2Map(String pStrXml) { | |||||
Map map = new HashMap(); | |||||
String strTitle = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||||
Document document = null; | |||||
try { | |||||
if (pStrXml.indexOf("<?xml") < 0) | |||||
pStrXml = strTitle + pStrXml; | |||||
document = DocumentHelper.parseText(pStrXml); | |||||
} catch (DocumentException e) { | |||||
log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||||
} | |||||
// 获取根节点 | |||||
Element elNode = document.getRootElement(); | |||||
// 遍历节点属性值将其压入Dto | |||||
for (Iterator it = elNode.elementIterator(); it.hasNext();) { | |||||
Element leaf = (Element) it.next(); | |||||
map.put(leaf.getName().toLowerCase(), leaf.getData()); | |||||
} | |||||
return map; | |||||
} | |||||
/** | |||||
* 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式) 应用于复杂对象 | |||||
* | |||||
* @param doc 待解析的XML字符串 | |||||
* @return outDto 返回Dto | |||||
*/ | |||||
public static Map Dom2Map(Document doc) { | |||||
Map map = new HashMap(); | |||||
if (doc == null) | |||||
return map; | |||||
Element root = doc.getRootElement(); | |||||
for (Iterator iterator = root.elementIterator(); iterator.hasNext();) { | |||||
Element e = (Element) iterator.next(); | |||||
// System.out.println(e.getName()); | |||||
List list = e.elements(); | |||||
if (list.size() > 0) { | |||||
map.put(e.getName(), Dom2Map(e)); | |||||
} else | |||||
map.put(e.getName(), e.getText()); | |||||
} | |||||
return map; | |||||
} | |||||
public static Map Dom2Map(Element e) { | |||||
Map map = new HashMap(); | |||||
List list = e.elements(); | |||||
if (list.size() > 0) { | |||||
for (int i = 0; i < list.size(); i++) { | |||||
Element iter = (Element) list.get(i); | |||||
List mapList = new ArrayList(); | |||||
if (iter.elements().size() > 0) { | |||||
Map m = Dom2Map(iter); | |||||
if (map.get(iter.getName()) != null) { | |||||
Object obj = map.get(iter.getName()); | |||||
if (!obj.getClass().getName().equals("java.util.ArrayList")) { | |||||
mapList = new ArrayList(); | |||||
mapList.add(obj); | |||||
mapList.add(m); | |||||
} | |||||
if (obj.getClass().getName().equals("java.util.ArrayList")) { | |||||
mapList = (List) obj; | |||||
mapList.add(m); | |||||
} | |||||
map.put(iter.getName(), mapList); | |||||
} else | |||||
map.put(iter.getName(), m); | |||||
} else { | |||||
if (map.get(iter.getName()) != null) { | |||||
Object obj = map.get(iter.getName()); | |||||
if (!obj.getClass().getName().equals("java.util.ArrayList")) { | |||||
mapList = new ArrayList(); | |||||
mapList.add(obj); | |||||
mapList.add(iter.getText()); | |||||
} | |||||
if (obj.getClass().getName().equals("java.util.ArrayList")) { | |||||
mapList = (List) obj; | |||||
mapList.add(iter.getText()); | |||||
} | |||||
map.put(iter.getName(), mapList); | |||||
} else | |||||
map.put(iter.getName(), iter.getText()); | |||||
} | |||||
} | |||||
} else | |||||
map.put(e.getName(), e.getText()); | |||||
return map; | |||||
} | |||||
/** | |||||
* 解析XML并将其节点元素压入Dto返回(基于节点值形式的XML格式) | |||||
* | |||||
* @param pStrXml 待解析的XML字符串 | |||||
* @param pXPath 节点路径(例如:"//paralist/row" 则表示根节点paralist下的row节点的xPath路径) | |||||
* @return outDto 返回Dto | |||||
*/ | |||||
public static final Map parseXml2Map(String pStrXml, String pXPath) { | |||||
Map map = new HashMap(); | |||||
String strTitle = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||||
Document document = null; | |||||
try { | |||||
if (pStrXml.indexOf("<?xml") < 0) | |||||
pStrXml = strTitle + pStrXml; | |||||
document = DocumentHelper.parseText(pStrXml); | |||||
} catch (DocumentException e) { | |||||
log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||||
} | |||||
// 获取根节点 | |||||
Element elNode = document.getRootElement(); | |||||
// 遍历节点属性值将其压入Dto | |||||
for (Iterator it = elNode.elementIterator(); it.hasNext();) { | |||||
Element leaf = (Element) it.next(); | |||||
map.put(leaf.getName().toLowerCase(), leaf.getData()); | |||||
} | |||||
return map; | |||||
} | |||||
/** | |||||
* 将Dto转换为符合XML标准规范格式的字符串(基于节点值形式) | |||||
* | |||||
* @param map 传入的Dto对象 | |||||
* @param pRootNodeName 根结点名 | |||||
* @return string 返回XML格式字符串 | |||||
*/ | |||||
public static final String parseDto2Xml(Map map, String pRootNodeName) { | |||||
Document document = DocumentHelper.createDocument(); | |||||
// 增加一个根元素节点 | |||||
document.addElement(pRootNodeName); | |||||
Element root = document.getRootElement(); | |||||
Iterator keyIterator = map.keySet().iterator(); | |||||
while (keyIterator.hasNext()) { | |||||
String key = (String) keyIterator.next(); | |||||
String value = (String) map.get(key); | |||||
Element leaf = root.addElement(key); | |||||
leaf.setText(value); | |||||
} | |||||
// 将XML的头声明信息截去 | |||||
String outXml = document.asXML().substring(39); | |||||
return outXml; | |||||
} | |||||
/** | |||||
* 将Dto转换为符合XML标准规范格式的字符串(基于节点值形式) | |||||
* | |||||
* @param map 传入的Dto对象 | |||||
* @param pRootNodeName 根结点名 | |||||
* @return string 返回XML格式字符串 | |||||
*/ | |||||
public static final String parseDto2XmlHasHead(Map map, String pRootNodeName) { | |||||
Document document = DocumentHelper.createDocument(); | |||||
// 增加一个根元素节点 | |||||
document.addElement(pRootNodeName); | |||||
Element root = document.getRootElement(); | |||||
Iterator keyIterator = map.keySet().iterator(); | |||||
while (keyIterator.hasNext()) { | |||||
String key = (String) keyIterator.next(); | |||||
String value = (String) map.get(key); | |||||
Element leaf = root.addElement(key); | |||||
leaf.setText(value); | |||||
} | |||||
// 将XML的头声明信息截去 | |||||
// String outXml = document.asXML().substring(39); | |||||
String outXml = document.asXML(); | |||||
return outXml; | |||||
} | |||||
/** | |||||
* 将Dto转换为符合XML标准规范格式的字符串(基于属性值形式) | |||||
* | |||||
* @param map 传入的Dto对象 | |||||
* @param pRootNodeName 根节点名 | |||||
* @param pFirstNodeName 一级节点名 | |||||
* @return string 返回XML格式字符串 | |||||
*/ | |||||
public static final String parseMap2Xml(Map map, String pRootNodeName, String pFirstNodeName) { | |||||
Document document = DocumentHelper.createDocument(); | |||||
// 增加一个根元素节点 | |||||
document.addElement(pRootNodeName); | |||||
Element root = document.getRootElement(); | |||||
root.addElement(pFirstNodeName); | |||||
Element firstEl = (Element) document.selectSingleNode("/" + pRootNodeName + "/" + pFirstNodeName); | |||||
Iterator keyIterator = map.keySet().iterator(); | |||||
while (keyIterator.hasNext()) { | |||||
String key = (String) keyIterator.next(); | |||||
String value = (String) map.get(key); | |||||
firstEl.addAttribute(key, value); | |||||
} | |||||
// 将XML的头声明信息丢去 | |||||
String outXml = document.asXML().substring(39); | |||||
return outXml; | |||||
} | |||||
/** | |||||
* 将List数据类型转换为符合XML格式规范的字符串(基于节点属性值的方式) | |||||
* | |||||
* @param pList 传入的List数据(List对象可以是Dto、VO、Domain的属性集) | |||||
* @param pRootNodeName 根节点名称 | |||||
* @param pFirstNodeName 行节点名称 | |||||
* @return string 返回XML格式字符串 | |||||
*/ | |||||
public static final String parseList2Xml(List pList, String pRootNodeName, String pFirstNodeName) { | |||||
Document document = DocumentHelper.createDocument(); | |||||
Element elRoot = document.addElement(pRootNodeName); | |||||
for (int i = 0; i < pList.size(); i++) { | |||||
Map map = (Map) pList.get(i); | |||||
Element elRow = elRoot.addElement(pFirstNodeName); | |||||
Iterator it = map.entrySet().iterator(); | |||||
while (it.hasNext()) { | |||||
Map.Entry entry = (Map.Entry) it.next(); | |||||
elRow.addAttribute((String) entry.getKey(), String.valueOf(entry.getValue())); | |||||
} | |||||
} | |||||
String outXml = document.asXML().substring(39); | |||||
return outXml; | |||||
} | |||||
/** | |||||
* 将List数据类型转换为符合XML格式规范的字符串(基于节点值的方式) | |||||
* | |||||
* @param pList 传入的List数据(List对象可以是Dto、VO、Domain的属性集) | |||||
* @param pRootNodeName 根节点名称 | |||||
* @param pFirstNodeName 行节点名称 | |||||
* @return string 返回XML格式字符串 | |||||
*/ | |||||
public static final String parseList2XmlBasedNode(List pList, String pRootNodeName, String pFirstNodeName) { | |||||
Document document = DocumentHelper.createDocument(); | |||||
Element output = document.addElement(pRootNodeName); | |||||
for (int i = 0; i < pList.size(); i++) { | |||||
Map map = (Map) pList.get(i); | |||||
Element elRow = output.addElement(pFirstNodeName); | |||||
Iterator it = map.entrySet().iterator(); | |||||
while (it.hasNext()) { | |||||
Map.Entry entry = (Map.Entry) it.next(); | |||||
Element leaf = elRow.addElement((String) entry.getKey()); | |||||
leaf.setText(String.valueOf(entry.getValue())); | |||||
} | |||||
} | |||||
String outXml = document.asXML().substring(39); | |||||
return outXml; | |||||
} | |||||
/** | |||||
* 将XML规范的字符串转为List对象(XML基于节点属性值的方式) | |||||
* | |||||
* @param pStrXml 传入的符合XML格式规范的字符串 | |||||
* @return list 返回List对象 | |||||
*/ | |||||
public static final List parseXml2List(String pStrXml) { | |||||
List lst = new ArrayList(); | |||||
String strTitle = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; | |||||
Document document = null; | |||||
try { | |||||
if (pStrXml.indexOf("<?xml") < 0) | |||||
pStrXml = strTitle + pStrXml; | |||||
document = DocumentHelper.parseText(pStrXml); | |||||
} catch (DocumentException e) { | |||||
log.error("==开发人员请注意:==\n将XML格式的字符串转换为XML DOM对象时发生错误啦!" + "\n详细错误信息如下:", e); | |||||
} | |||||
// 获取到根节点 | |||||
Element elRoot = document.getRootElement(); | |||||
// 获取根节点的所有子节点元素 | |||||
Iterator elIt = elRoot.elementIterator(); | |||||
while (elIt.hasNext()) { | |||||
Element el = (Element) elIt.next(); | |||||
Iterator attrIt = el.attributeIterator(); | |||||
Map map = new HashMap(); | |||||
while (attrIt.hasNext()) { | |||||
Attribute attribute = (Attribute) attrIt.next(); | |||||
map.put(attribute.getName().toLowerCase(), attribute.getData()); | |||||
} | |||||
lst.add(map); | |||||
} | |||||
return lst; | |||||
} | |||||
/** | |||||
* Document to map | |||||
* | |||||
* @param doc | |||||
* @return | |||||
*/ | |||||
public static Map<String, Object> dom2Map(Document doc) { | |||||
Map<String, Object> maproot = new HashMap<String, Object>(); | |||||
if (doc == null) | |||||
return maproot; | |||||
Element root = doc.getRootElement(); | |||||
List list1 = root.elements(); | |||||
for (Object obj : list1) { | |||||
Element element = (Element) obj; | |||||
Map<String, Object> map = new HashMap<String, Object>(); | |||||
element2Map(element, map); | |||||
maproot.put(element.getName(), map); | |||||
} | |||||
return maproot; | |||||
} | |||||
/** | |||||
* Element to map | |||||
* | |||||
* @param e | |||||
* @return | |||||
*/ | |||||
public static void element2Map(Element e, Map<String, Object> map) { | |||||
List<Element> list = e.elements(); | |||||
if (e.attributeCount() > 0) { | |||||
for (Object attri : e.attributes()) { | |||||
Attribute at = (Attribute) attri; | |||||
map.put(at.getName(), at.getValue()); | |||||
} | |||||
} | |||||
if (list.size() < 1 && DataUtil.isEmpty(e.getText())) { | |||||
return; | |||||
} else if (list.size() < 1 && !DataUtil.isEmpty(e.getText())) { | |||||
map.put("text", e.getText()); | |||||
} | |||||
for (Object aList : list) { | |||||
Element iter = (Element) aList; | |||||
Map<String, Object> cMap = new HashMap<String, Object>(); | |||||
element2Map(iter, cMap); | |||||
map.put(iter.getName(), cMap); | |||||
} | |||||
} | |||||
/** | |||||
* 将mq查询结果包装成list--dto的形式,dto内容为item中的内容 | |||||
* | |||||
* @param recv | |||||
* @return | |||||
*/ | |||||
public static Map MqResToDto(String recv) { | |||||
// System.out.println("####recv"+recv); | |||||
List res = new ArrayList(); | |||||
Map map = new HashMap(); | |||||
try { | |||||
Document doc = DocumentHelper.parseText(recv); | |||||
List list = doc.selectNodes("//item"); | |||||
Iterator<DefaultElement> it = list.iterator(); | |||||
while (it.hasNext()) { | |||||
Map elementdto = XmlUtil.Dom2Map(it.next()); | |||||
res.add(elementdto); | |||||
} | |||||
map.put("resultList", res);// 放入结果集 | |||||
/* | |||||
* 如果存在REC_MNT,说明是分页查询类,需要将总记录数返回 | |||||
*/ | |||||
Node de = doc.selectSingleNode("//REC_MNT"); | |||||
if (DataUtil.isNotEmpty(de)) { | |||||
map.put("countInteger", de.getText()); | |||||
} | |||||
} catch (Exception e) { | |||||
log.error(XmlUtil.class, e); | |||||
} | |||||
return map; | |||||
} | |||||
/** | |||||
* 将Map转换为XML格式的字符串 | |||||
* | |||||
* @param data Map类型数据 | |||||
* @return XML格式的字符串 | |||||
* @throws Exception | |||||
*/ | |||||
public static String mapToXml(Map<String, String> data) throws Exception { | |||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); | |||||
DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder(); | |||||
org.w3c.dom.Document document = documentBuilder.newDocument(); | |||||
org.w3c.dom.Element root = document.createElement("xml"); | |||||
document.appendChild(root); | |||||
for (String key: data.keySet()) { | |||||
String value = data.get(key); | |||||
if (value == null) { | |||||
value = ""; | |||||
} | |||||
value = value.trim(); | |||||
org.w3c.dom.Element filed = document.createElement(key); | |||||
filed.appendChild(document.createTextNode(value)); | |||||
root.appendChild(filed); | |||||
} | |||||
TransformerFactory tf = TransformerFactory.newInstance(); | |||||
Transformer transformer = tf.newTransformer(); | |||||
DOMSource source = new DOMSource(document); | |||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); | |||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); | |||||
StringWriter writer = new StringWriter(); | |||||
StreamResult result = new StreamResult(writer); | |||||
transformer.transform(source, result); | |||||
String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", ""); | |||||
try { | |||||
writer.close(); | |||||
} | |||||
catch (Exception ex) { | |||||
} | |||||
return output; | |||||
} | |||||
/* | |||||
* 将SortedMap<Object,Object> 集合转化成 xml格式 | |||||
*/ | |||||
public static String getRequestXml(SortedMap<Object,Object> parameters){ | |||||
StringBuilder sb = new StringBuilder(); | |||||
sb.append("<xml>"); | |||||
Set es = parameters.entrySet(); | |||||
Iterator it = es.iterator(); | |||||
while(it.hasNext()) { | |||||
Map.Entry entry = (Map.Entry)it.next(); | |||||
String k = (String)entry.getKey(); | |||||
String v = (String)entry.getValue(); | |||||
if ("attach".equalsIgnoreCase(k)||"body".equalsIgnoreCase(k)||"sign".equalsIgnoreCase(k)|| | |||||
"return_code".equalsIgnoreCase(k)||"return_msg".equalsIgnoreCase(k)) { | |||||
sb.append("<"+k+">"+"<![CDATA["+v+"]]></"+k+">"); | |||||
}else { | |||||
sb.append("<"+k+">"+v+"</"+k+">"); | |||||
} | |||||
} | |||||
sb.append("</xml>"); | |||||
return sb.toString(); | |||||
} | |||||
} |
@@ -0,0 +1,50 @@ | |||||
<?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="com.iformall.mapper.SysConfigMapper"> | |||||
<resultMap id="BaseResultMap" type="com.iformall.domain.po.SysConfig"> | |||||
<id column="id" jdbcType="BIGINT" property="id" /> | |||||
<result column="config_item_key" jdbcType="VARCHAR" property="configItemKey" /> | |||||
<result column="config_item_remark" jdbcType="VARCHAR" property="configItemRemark" /> | |||||
<result column="create_date" jdbcType="TIMESTAMP" property="createDate" /> | |||||
<result column="update_date" jdbcType="TIMESTAMP" property="updateDate" /> | |||||
<result column="is_hide" jdbcType="INTEGER" property="isHide" /> | |||||
<result column="status" jdbcType="INTEGER" property="status" /> | |||||
</resultMap> | |||||
<sql id="allColumns"> | |||||
`id`,`config_item_key`,`config_item_remark`,`create_date`,`update_date`,`is_hide`,`status` | |||||
</sql> | |||||
<sql id="dynamicWhereConditions"> | |||||
where 1 = 1 | |||||
<if test=" null != id "> | |||||
and `id` = #{id} | |||||
</if> | |||||
<if test=" null != configItemKey "> | |||||
and `config_item_key` = #{configItemKey} | |||||
</if> | |||||
<if test=" null != isHide "> | |||||
and `is_hide` = #{isHide} | |||||
</if> | |||||
<if test=" null != status "> | |||||
and `status` = #{status} | |||||
</if> | |||||
<if test=" null != ids "> | |||||
and id in | |||||
<foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
#{idItem} | |||||
</foreach> | |||||
</if> | |||||
<if test=" null != sortColumns"> order by ${sortColumns} </if> | |||||
</sql> | |||||
<select id="findList" parameterType="com.iformall.domain.po.SysConfig" resultMap="BaseResultMap"> | |||||
select <include refid="allColumns" /> from sys_config | |||||
<include refid="dynamicWhereConditions" /> | |||||
</select> | |||||
<select id="findByKey" parameterType="com.iformall.domain.po.SysConfig" resultMap="BaseResultMap"> | |||||
select <include refid="allColumns" /> from sys_config where `config_item_key` = #{configItemKey} | |||||
</select> | |||||
</mapper> |
@@ -0,0 +1,54 @@ | |||||
<?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="com.iformall.mapper.SysConfigValueMapper"> | |||||
<resultMap id="BaseResultMap" type="com.iformall.domain.po.SysConfigValue"> | |||||
<id column="id" jdbcType="BIGINT" property="id"/> | |||||
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/> | |||||
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId"/> | |||||
<result column="config_item_id" jdbcType="BIGINT" property="configItemId"/> | |||||
<result column="config_item_value" jdbcType="VARCHAR" property="configItemValue"/> | |||||
<result column="update_date" jdbcType="TIMESTAMP" property="updateDate"/> | |||||
<result column="create_date" jdbcType="TIMESTAMP" property="createDate"/> | |||||
</resultMap> | |||||
<sql id="allColumns"> | |||||
`id`,`tenant_id`,`parent_tenant_id`,`config_item_id`,`config_item_value`,`update_date`,`create_date` | |||||
</sql> | |||||
<sql id="dynamicWhereConditions"> | |||||
where 1=1 | |||||
<if test=" null != id "> | |||||
and `id` = #{id} | |||||
</if> | |||||
<if test=" null != tenantId and '' != tenantId"> | |||||
and `tenant_id` = #{tenantId} | |||||
</if> | |||||
<if test=" null != parentTenantId and '' != parentTenantId"> | |||||
and `parent_tenant_id` = #{parentTenantId} | |||||
</if> | |||||
<if test=" null != configItemId "> | |||||
and `config_item_id` = #{configItemId} | |||||
</if> | |||||
<if test=" null != configItemValue "> | |||||
and `config_item_value` = #{configItemValue} | |||||
</if> | |||||
<if test=" null != ids "> | |||||
and id in | |||||
<foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
#{idItem} | |||||
</foreach> | |||||
</if> | |||||
<if test=" null != sortColumns">order by ${sortColumns}</if> | |||||
</sql> | |||||
<select id="findByItemId" parameterType="com.iformall.domain.po.SysConfigValue" resultMap="BaseResultMap"> | |||||
select <include refid="allColumns"/> from sys_config_value | |||||
where `config_item_id` = #{configItemId} and `tenant_id` = #{tenantId} | |||||
</select> | |||||
</mapper> |
@@ -0,0 +1,102 @@ | |||||
<?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="com.iformall.mapper.WxPayOrderMapper"> | |||||
<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxPayOrder"> | |||||
<id column="id" jdbcType="BIGINT" property="id"/> | |||||
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/> | |||||
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" /> | |||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/> | |||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/> | |||||
<result column="c_user_id" jdbcType="BIGINT" property="cUserId"/> | |||||
<result column="c_user_phone" jdbcType="VARCHAR" property="cUserPhone"/> | |||||
<result column="pay_amount" jdbcType="INTEGER" property="payAmount"/> | |||||
<result column="pay_time" jdbcType="TIMESTAMP" property="payTime"/> | |||||
<result column="transaction_id" jdbcType="VARCHAR" property="transactionId"/> | |||||
</resultMap> | |||||
<sql id="allColumns"> | |||||
`id`,`tenant_id`,`parent_tenant_id`,`create_time`,`update_time`,`c_user_id`,`c_user_phone`,`pay_amount`, | |||||
`pay_time`,`transaction_id` | |||||
</sql> | |||||
<sql id="dynamicWhereConditions"> | |||||
where `tenant_id` = #{tenantId} | |||||
<if test=" null != id "> | |||||
and `id` = #{id} | |||||
</if> | |||||
<if test=" null != parentTenantId and '' != parentTenantId"> | |||||
and `parent_tenant_id` = #{parentTenantId} | |||||
</if> | |||||
<if test=" null != createTime "> | |||||
and `create_time` = #{createTime} | |||||
</if> | |||||
<if test=" null != updateTime "> | |||||
and `update_time` = #{updateTime} | |||||
</if> | |||||
<if test=" null != cUserId "> | |||||
and `c_user_id` = #{cUserId} | |||||
</if> | |||||
<if test=" null != payAmount "> | |||||
and `pay_amount` = #{payAmount} | |||||
</if> | |||||
<if test=" null != payTime "> | |||||
and `pay_time` = #{payTime} | |||||
</if> | |||||
<if test=" null != transactionId "> | |||||
and `transaction_id` like concat('%', #{transactionId},'%') | |||||
</if> | |||||
<if test=" null != cUserPhone "> | |||||
and `c_user_phone` like concat('%', #{cUserPhone},'%') | |||||
</if> | |||||
<if test=" null != begin "> | |||||
and `create_time` >= #{begin} | |||||
</if> | |||||
<if test=" null != end "> | |||||
and `create_time` <= #{end} | |||||
</if> | |||||
<if test=" null != userIds "> | |||||
and c_user_id in | |||||
<foreach collection="userIds" index="index" item="uidItem" open="(" separator="," close=")"> | |||||
#{uidItem} | |||||
</foreach> | |||||
</if> | |||||
<if test=" null != ids "> | |||||
and id in | |||||
<foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")"> | |||||
#{idItem} | |||||
</foreach> | |||||
</if> | |||||
<if test=" null != sortColumns">order by ${sortColumns}</if> | |||||
</sql> | |||||
<select id="selectById" parameterType="java.util.HashMap" resultMap="BaseResultMap"> | |||||
select <include refid="allColumns"/> from wx_pay_order where id = #{id} and tenant_id = #{tenantId} | |||||
</select> | |||||
<select id="findList" parameterType="com.iformall.domain.po.WxPayOrder" resultMap="BaseResultMap"> | |||||
select | |||||
<include refid="allColumns"/> | |||||
from wx_pay_order | |||||
<include refid="dynamicWhereConditions"/> | |||||
</select> | |||||
<select id="sum" parameterType="com.iformall.domain.po.WxPayOrder" resultType="Integer"> | |||||
select sum(pay_amount) | |||||
from wx_pay_order | |||||
<include refid="dynamicWhereConditions"/> | |||||
</select> | |||||
</mapper> |