diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxPaidCallBackController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxPaidCallBackController.java new file mode 100644 index 0000000..2970625 --- /dev/null +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxPaidCallBackController.java @@ -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 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); + } + } +} diff --git a/mallinkCApi/src/main/java/com/iformall/controller/WxPayController.java b/mallinkCApi/src/main/java/com/iformall/controller/WxPayController.java new file mode 100644 index 0000000..f009157 --- /dev/null +++ b/mallinkCApi/src/main/java/com/iformall/controller/WxPayController.java @@ -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 redisTemplate; + + /** + * 停车费创建支付订单,只有supportPay=true时才调用此方法 + * + * @param paramMap + * @return + */ + @ApiOperation(value = "创建支付订单", notes = "{}") + @PostMapping("/createPayOrder") + public ResultData createPayOrder(@RequestBody Map 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())); + } + +} diff --git a/mallinkService/src/main/java/com/iformall/common/SysConfigConstant.java b/mallinkService/src/main/java/com/iformall/common/SysConfigConstant.java deleted file mode 100644 index 5326e19..0000000 --- a/mallinkService/src/main/java/com/iformall/common/SysConfigConstant.java +++ /dev/null @@ -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"; - -} diff --git a/mallinkService/src/main/java/com/iformall/domain/entity/PayAdapterResult.java b/mallinkService/src/main/java/com/iformall/domain/entity/PayAdapterResult.java new file mode 100644 index 0000000..aa90da0 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/entity/PayAdapterResult.java @@ -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; + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/entity/PayExtraParam.java b/mallinkService/src/main/java/com/iformall/domain/entity/PayExtraParam.java new file mode 100644 index 0000000..7731781 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/entity/PayExtraParam.java @@ -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; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/entity/WxPay.java b/mallinkService/src/main/java/com/iformall/domain/entity/WxPay.java new file mode 100644 index 0000000..d22ef13 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/entity/WxPay.java @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 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 packageParams = new HashMap(); + 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 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 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 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 params) { + return doPost(SANDBOX_GETSIGNKEY_URL, params); + } + + + + public static String doPost(String url, Map params) { + return HttpUtil.payPost(url, WxPayment.toXml(params)); + } + + public static String doPostSSL(String url, Map params, String certPath, String certPass) { + return HttpUtil.payPostSSL(url, WxPayment.toXml(params), certPath, certPass); + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/entity/WxPayOrderP.java b/mallinkService/src/main/java/com/iformall/domain/entity/WxPayOrderP.java new file mode 100644 index 0000000..d2a3235 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/entity/WxPayOrderP.java @@ -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(); + } +} diff --git a/mallinkService/src/main/java/com/iformall/domain/entity/WxPayment.java b/mallinkService/src/main/java/com/iformall/domain/entity/WxPayment.java new file mode 100644 index 0000000..cbcfd23 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/entity/WxPayment.java @@ -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 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 queryParas = new HashMap(); + 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 buildQueryParasMap(String appid, String sub_appid, String mch_id, String sub_mch_id, + String transaction_id, String out_trade_no, String paternerKey) { + Map params = new HashMap(); + + 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 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 params = new HashMap(); + 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 buildShortUrlParasMap(String appid, String sub_appid, String mch_id, + String sub_mch_id, String long_url, String paternerKey) { + Map params = new HashMap(); + 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 buildWeappSecondSignMap(String appId, String timestamp, String prepay_id, String paternerKey) { + Map params = new HashMap(); + Map 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 buildCloseMap(String appid, String sub_appid, String mch_id, String sub_mch_id, + String out_trade_no, String paternerKey) { + Map params = new HashMap(); + + 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 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 params = new HashMap(); + + 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 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 params = new HashMap(); + + 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 buildWeappRefundQueryMap(String appid, String mch_id, + String transaction_id, String out_trade_no, String out_refund_no, String refund_id, + String paternerKey) { + Map params = new HashMap(); + + 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 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 params = new HashMap(); + + 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 params, boolean urlEncoder) { + // 先将参数以其参数名的字典序升序进行排序 + TreeMap sortedParams = new TreeMap(params); + // 遍历排序后的字典,将所有参数按"key=value"格式拼接在一起 + StringBuilder sb = new StringBuilder(); + boolean first = true; + for (Entry 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 buildSignAfterParasMap(Map 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 buildSignAfterParasMapForHMAC(Map 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 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 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 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 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 params,boolean containChinese) { + StringBuilder xml = new StringBuilder(); + xml.append(""); + for (Entry 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(""); + } + xml.append(""); + return xml.toString(); + } + + public static String toXml(Map params) { + return toXmlContent(params,false); + } + + public static String toXmlWhitChinese(Map params) { + return toXmlContent(params,true); + } + + /** + * 针对支付的xml,没有嵌套节点的简单处理 + * + * @param xmlStr + * xml字符串 + * @return map集合 + */ + @SuppressWarnings("unchecked") + public static Map 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); + + /* + + + + + + */ + } + + + 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); + } + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/SysConfig.java b/mallinkService/src/main/java/com/iformall/domain/po/SysConfig.java new file mode 100644 index 0000000..2dd27cd --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/SysConfig.java @@ -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; +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/SysConfigValue.java b/mallinkService/src/main/java/com/iformall/domain/po/SysConfigValue.java new file mode 100644 index 0000000..afb3b8d --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/SysConfigValue.java @@ -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; + +} diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java new file mode 100644 index 0000000..288273c --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java @@ -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 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; + +} diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumPayType.java b/mallinkService/src/main/java/com/iformall/enums/EnumPayType.java new file mode 100644 index 0000000..28d0a32 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/enums/EnumPayType.java @@ -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; + } +} diff --git a/mallinkService/src/main/java/com/iformall/enums/EnumYesOrNo.java b/mallinkService/src/main/java/com/iformall/enums/EnumYesOrNo.java new file mode 100644 index 0000000..d8d27df --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/enums/EnumYesOrNo.java @@ -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; + } +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/SysConfigMapper.java b/mallinkService/src/main/java/com/iformall/mapper/SysConfigMapper.java new file mode 100644 index 0000000..3a08365 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/mapper/SysConfigMapper.java @@ -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 { + + List findList(SysConfig sysMonitor); + + SysConfig findByKey(SysConfig sysMonitor); + + +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/SysConfigValueMapper.java b/mallinkService/src/main/java/com/iformall/mapper/SysConfigValueMapper.java new file mode 100644 index 0000000..fcf456c --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/mapper/SysConfigValueMapper.java @@ -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 findByItemId(SysConfigValue record); + +} diff --git a/mallinkService/src/main/java/com/iformall/mapper/WxPayOrderMapper.java b/mallinkService/src/main/java/com/iformall/mapper/WxPayOrderMapper.java new file mode 100644 index 0000000..46f9e1b --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/mapper/WxPayOrderMapper.java @@ -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 selectById(@Param("id")Long id,@Param("tenantId")String tenantId); + + List findList(WxPayOrder wxCarPayOrder); + + WxPayOrder findOneByParkOderNo(@Param("parkOrderNo")String parkOrderNo,@Param("tenantId")String tenantId); + + Integer sum(WxPayOrder wxCarPayOrder); + +} diff --git a/mallinkService/src/main/java/com/iformall/service/SysConfigService.java b/mallinkService/src/main/java/com/iformall/service/SysConfigService.java new file mode 100644 index 0000000..5776fcd --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/SysConfigService.java @@ -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 listAsPage(SysConfig record, Integer pageIndex, Integer pageSize,TenantEntity tenantEntity); + + /** + * 根据实体查询列表 + * + * @param record + * @return + */ + List 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); +} diff --git a/mallinkService/src/main/java/com/iformall/service/impl/SysConfigServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/SysConfigServiceImpl.java new file mode 100644 index 0000000..ccb7c42 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/impl/SysConfigServiceImpl.java @@ -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 baseRedisTemplate; + + + @Override + public PageInfo listAsPage(SysConfig record, Integer pageIndex, Integer pageSize,TenantEntity tenantEntity) { + PageInfo 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 getList(SysConfig record,TenantEntity tenantEntity) { + List 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); + } + } + +} diff --git a/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayAdapterService.java b/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayAdapterService.java new file mode 100644 index 0000000..d4b1b61 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayAdapterService.java @@ -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 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 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()); + } + } + } +} diff --git a/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayV2AdapterService.java b/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayV2AdapterService.java new file mode 100644 index 0000000..ef21412 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/wx/BaseWxPayV2AdapterService.java @@ -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 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) 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 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()); + } + } + } + + + +} diff --git a/mallinkService/src/main/java/com/iformall/service/wx/WxMiniAppPayAdapterService.java b/mallinkService/src/main/java/com/iformall/service/wx/WxMiniAppPayAdapterService.java new file mode 100644 index 0000000..3aef100 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/wx/WxMiniAppPayAdapterService.java @@ -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 payOrderMap = BeanUtils.toStringMap(wxPayOrderP); + wxPayOrderP.setSign(WxPayment.createSign(payOrderMap, apiKey)); + return wxPayOrderP; + } + + private PayAdapterResult getOrderPResult(Map 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 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 returnMap = WxPayment.xmlToMap(response); + return getOrderPResult(returnMap,wxPayOrderP.getNonce_str(),apiKey); + } + + +} diff --git a/mallinkService/src/main/java/com/iformall/service/wx/WxPayService.java b/mallinkService/src/main/java/com/iformall/service/wx/WxPayService.java new file mode 100644 index 0000000..cdb1084 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/wx/WxPayService.java @@ -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 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 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); + +} diff --git a/mallinkService/src/main/java/com/iformall/service/wx/WxPayServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/wx/WxPayServiceImpl.java new file mode 100644 index 0000000..648d142 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/wx/WxPayServiceImpl.java @@ -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 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 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); + } + +} diff --git a/mallinkService/src/main/java/com/iformall/utils/BeanUtils.java b/mallinkService/src/main/java/com/iformall/utils/BeanUtils.java new file mode 100644 index 0000000..9efcc0e --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/BeanUtils.java @@ -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 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 toMap(Object bean) + throws Exception { + Map returnMap = new LinkedTreeMap(); + if (bean instanceof Map) { + returnMap.putAll((Map)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 toStringMap(Object bean) + throws Exception { + Map returnMap = new LinkedTreeMap(); + if (bean instanceof Map) { + returnMap.putAll((Map)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; + } + +} diff --git a/mallinkService/src/main/java/com/iformall/utils/Constant.java b/mallinkService/src/main/java/com/iformall/utils/Constant.java index b739742..69cf56c 100644 --- a/mallinkService/src/main/java/com/iformall/utils/Constant.java +++ b/mallinkService/src/main/java/com/iformall/utils/Constant.java @@ -9,5 +9,6 @@ public class Constant { public static final String currentUser = "currentUser"; public static final String TENANT_ID = "tenantId"; public static final String PARENT_TENANT_ID = "parentTenantId"; - + public static final String paymentReceiverParamIsv = "isvModel"; + public static final String paymentReceicerParamApiKey = "apiKey"; } diff --git a/mallinkService/src/main/java/com/iformall/utils/DataUtil.java b/mallinkService/src/main/java/com/iformall/utils/DataUtil.java new file mode 100644 index 0000000..8127f28 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/DataUtil.java @@ -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)
+ * 实用于对如下对象做判断: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)
+ * 实用于对如下对象做判断: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", "
  "); + 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 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(); + } +} \ No newline at end of file diff --git a/mallinkService/src/main/java/com/iformall/utils/DateUtils.java b/mallinkService/src/main/java/com/iformall/utils/DateUtils.java new file mode 100644 index 0000000..a76cbe5 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/DateUtils.java @@ -0,0 +1,1536 @@ +package com.iformall.utils; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; + +import javax.xml.datatype.XMLGregorianCalendar; +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.time.*; +import java.time.temporal.ChronoUnit; +import java.util.*; + +/** + * 日期处理 + * + * @author stormeye.wu + * @email wugq@mippoint.com + * @date 2016年12月21日 下午12:53:33 + */ +public class DateUtils { + /** 时间格式(yyyy-MM-dd) */ + public final static String DATE_PATTERN = "yyyy-MM-dd"; + /** 时间格式(yyyy-MM-dd HH:mm:ss) */ + public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; + + public final static String DATE_PATTERN_MONTH = "yyyy-MM"; + + public final static String[] weekObj=new String[]{"日","一","二","三","四","五","六"}; + + public final static String DATE_PATTERN_NOSPACE = "yyyyMMdd"; + + public final static String DATE_PATTERN_ALL_NOSPACE = "yyyyMMddHHmmss"; + + public static String format(Date date) { + return format(date, DATE_PATTERN); + } + + public static String formatDateTime(Date date) { + return format(date, DATE_TIME_PATTERN); + } + + + public static String format(Date date, String pattern) { + if(date != null){ + SimpleDateFormat df = new SimpleDateFormat(pattern); + return df.format(date); + } + return null; + } + + public static final int MONTH_JAN = 1; + public static final int MONTH_FEB = 2; + public static final int MONTH_MAR = 3; + public static final int MONTH_APR = 4; + public static final int MONTH_MAY = 5; + public static final int MONTH_JUN = 6; + public static final int MONTH_JUL = 7; + public static final int MONTH_AUG = 8; + public static final int MONTH_SEP = 9; + public static final int MONTH_OCT = 10; + public static final int MONTH_NOV = 11; + public static final int MONTH_DEC = 12; + + public static int TIME_ROOT = 2011; + + /** + * 获得系统时间 TODO: format:yyyy-MM-dd HH:mm:ss + * + * @return time + */ + public static String getSystemTime(String format) { + // 系统时间 + String time = ""; + SimpleDateFormat timeformat = new SimpleDateFormat(format); + time = timeformat.format(Calendar.getInstance().getTime());// 求得本地机的系统时间; + return time; + } + + public static Calendar getDateFromString(String timeStr, String format) { + SimpleDateFormat formatter = new SimpleDateFormat(format); + Calendar calendar = Calendar.getInstance(); + try { + Date date = formatter.parse(timeStr); + calendar.setTime(date); + } catch (ParseException e) { + e.printStackTrace(); + } + return calendar; + } + + /** + * 获得系统时间 TODO: format:yyyy-MM-dd HH:mm:ss + * + * @return Calendar + */ + public static Calendar getSystemTime() { + // 系统时间 + Calendar time = Calendar.getInstance(); + time.setTime(new Date());// 求得本地机的系统时间; + return time; + } + + /** + * 时间比较 + * + * @param time1 + * @param time2 + * @return + */ + public static boolean isDateBefore(Calendar time1, Calendar time2) { + if (time1 != null && time2 != null) { + return time1.getTime().before(time2.getTime()); + } + return false; + } + + /** + * 时间比较 + * + * @param time1 + * @param time2 + * @return + */ + public static boolean isDateAfter(Calendar time1, Calendar time2) { + if (time1 != null && time2 != null) { + return time1.getTime().before(time2.getTime()); + } + return false; + } + + /** + * 时间比较 系统时间早于输入时间 + * + * @param date2 + * @return + */ + public static boolean isDateBefore(String date2) { + try { + // 获得系统时间 + Date date1 = new Date(); + DateFormat df = DateFormat.getDateTimeInstance(); + return date1.before(df.parse(date2)); + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 时间比较 系统时间早于输入时间 + * + * @param date2 + * @return + */ + public static boolean isDateBefore(Date date2) { + if(Objects.isNull(date2)) return false ; + // 获得系统时间 + Date date1 = new Date(); + DateFormat df = DateFormat.getDateTimeInstance(); + return date1.before(date2); + } + + /** + * 系统时间晚于输入时间 + * + * @param date2 + * @return + */ + public static boolean isDateAfter(String date2) { + try { + // 获得系统时间 + Date date1 = new Date(); + DateFormat df = DateFormat.getDateTimeInstance(); + return date1.after(df.parse(date2)); + } catch (ParseException e) { + e.printStackTrace(); + return false; + } + } + + /** + * 时间比较(不含日期) 系统时间早于输入时间 + * + * @param time + * @return + */ + public static boolean isTimeBefore(String time) { + String date = ""; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date dd = Calendar.getInstance().getTime(); + date = sdf.format(dd); + return isDateBefore(date + " " + time); + } + + /** + * 时间比较(不含日期) 系统时间晚于输入时间 + * + * @param time + * @return + */ + public static boolean isTimeAfter(String time) { + String date = ""; + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date dd = Calendar.getInstance().getTime(); + date = sdf.format(dd); + return isDateAfter(date + " " + time); + } + + /** + * 时间转换 TODO:将框架时间控件获得的时间转化成自己想要的时间 + * + * @return + */ + public static String timeFormat(String format, String oldTime) { + String formatTime = ""; + + if (!"".equals(oldTime)) { + try { + SimpleDateFormat time = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + Date date = time.parse(oldTime); + SimpleDateFormat timeformat = new SimpleDateFormat(format); + formatTime = timeformat.format(date); + } catch (ParseException e) { + e.printStackTrace(); + } + } + + return formatTime; + } + + + public static String date2String(Calendar calendar) { + Date date = calendar.getTime(); + SimpleDateFormat dateFormatter = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + String timeStr = dateFormatter.format(date); + return timeStr; + } + + + public static String date2StringYMD(Calendar calendar) { + Date date = calendar.getTime(); + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); + String timeStr = dateFormatter.format(date); + return timeStr; + } + + public static String date2String(Date date) { + SimpleDateFormat dateFormatter = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + String timeStr = dateFormatter.format(date); + return timeStr; + } + + + public static String date2String(Date date, String fomartStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat(fomartStr); + String timeStr = dateFormatter.format(date); + return timeStr; + } + + public static String date2String(Calendar date, String fomartStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat(fomartStr); + String timeStr = dateFormatter.format(date.getTime()); + return timeStr; + } + + + public static Calendar string2Date(String timeStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat( + "yyyy-MM-dd HH:mm:ss"); + Calendar calendar = Calendar.getInstance(); + + try { + Date date = dateFormatter.parse(timeStr); + calendar.setTime(date); + } catch (Exception e) { + e.printStackTrace(); + } + + return calendar; + } + + /*** + * String转换为Calendar + * + * @param timeStr + * 时间字符串 + * @param formaStr + * 匹配格式 + * @return + */ + public static Calendar strToDate(String timeStr, String formaStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat(formaStr); + Calendar calendar = Calendar.getInstance(); + + try { + Date date = dateFormatter.parse(timeStr); + calendar.setTime(date); + } catch (Exception e) { + e.printStackTrace(); + } + + return calendar; + } + + + public static Date stringToDate(String timeStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); + + Date date = null; + try { + date = dateFormatter.parse(timeStr); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return date; + } + + public static Date stringToDate(String timeStr,String formaStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat(formaStr); + + Date date = null; + try { + date = dateFormatter.parse(timeStr); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return date; + } + + /** + * 获得当前时间的前3天 + * + */ + + public static String getTimeBefore3() { + Date myDate = new Date(); + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * 3; + myDate.setTime(myTime * 1000); + String mDate = formatter.format(myDate); + return mDate; + } + + /** + * 获得当前时间前几天 + * + * @param days + * 前几天 + * @return + */ + public static String getTimeBefore(int days, Date myDate) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * days; + Date date = new Date(myTime * 1000); + return formatter.format(date); + } + + /** + * 获得当前时间前几天 + * + * @param days + * 前几天 + * @return + */ + public static String getTimeBefore(int days, Date myDate,String format) { + SimpleDateFormat formatter = new SimpleDateFormat(format); + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * days; + Date date = new Date(myTime * 1000); + return formatter.format(date); + } + + /** + * 获得当前时间前几小时的时间 + * + * @param hour + * 前几小时 + * @return + */ + public static String getHourTimeBefore(int hour, Date myDate) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long myTime = (myDate.getTime() / 1000) - 60 * 60 * hour; + Date date = new Date(myTime * 1000); + return formatter.format(date); + } + + /** + * 获得当前时间前几秒的时间 + * + * @param + * + * @return + */ + public static String getSecondsTimeBefore(int seconds, Date myDate) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + long myTime = (myDate.getTime() / 1000) - seconds; + Date date = new Date(myTime * 1000); + return formatter.format(date); + } + + /** + * 获得当前时间后几秒的时间 + * + * @param + * @return + */ + public static Date getSecondsTimeAfter(int seconds, Date myDate) { + long myTime = (myDate.getTime() / 1000) + seconds; + Date testDate = new Date(myTime * 1000); + return testDate; + } + + /** + * 获得当前时间后几分钟的时间 + * + * @param + * @return + */ + public static Date getMinuteTimeAfter(int minute, Date myDate) { + long myTime = (myDate.getTime() / 1000) + 60 * minute; + Date testDate = new Date(myTime * 1000); + return testDate; + } + + /** + * 获得当前时间后几小时的时间 + * + * @param hour + * 后几小时 + * @return + */ + public static Date getHourTimeAfter(int hour, Date myDate) { + long myTime = (myDate.getTime() / 1000) + 60 * 60 * hour; + Date testDate = new Date(myTime * 1000); + return testDate; + } + + /** + * 获得当前时间后几天的时间 + * + * @param days 后几天 + * + * @return + */ + public static Date getTimeAfterDays(int days, Date myDate) { + Calendar now = Calendar.getInstance(); + now.setTime(myDate); + now.set(Calendar.DATE, now.get(Calendar.DATE) + days); + return now.getTime(); + } + + /** + * 获得当前时间后几个月的时间 + * + * @param days 后几天 + * + * @return + */ + public static Date getTimeAfterMonths(int months, Date myDate) { + Calendar now = Calendar.getInstance(); + now.setTime(myDate); + now.set(Calendar.MONTH, now.get(Calendar.MONTH) + months); + return now.getTime(); + } + + /** + * 获得指定时间前几天,格式yyyy-MM-dd + * + * @param days + * 前几天 + * @return + */ + public static String getTimeBefore(int days, String date) { + Date myDate = null; + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + try { + myDate = formatter.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (myDate != null) { + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * days; + myDate.setTime(myTime * 1000); + String mDate = formatter.format(myDate); + return mDate; + } + + return null; + } + + public static String getTimeBeforeByFormat(int days, String date, + String format) { + Date myDate = null; + SimpleDateFormat formatter = new SimpleDateFormat(format); + try { + myDate = formatter.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (myDate != null) { + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * days; + myDate.setTime(myTime * 1000); + String mDate = formatter.format(myDate); + return mDate; + } + + return null; + } + + + + /** + * XMLGregorianCalendar转String + * + * @param cal + * @return + */ + public static String xMLGregorianCalendar2String(XMLGregorianCalendar cal) { + if (null != cal) { + Calendar calendar = cal.toGregorianCalendar(); + String result = date2String(calendar); + return result; + } else { + return null; + } + } + + /** + * 字符串转为Calendar + * + * @param timeStr + * 时间字符串格式为yyyy-MM-dd + * @return + */ + public static Calendar str2Date(String timeStr) { + SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd"); + Calendar calendar = Calendar.getInstance(); + try { + Date date = dateFormatter.parse(timeStr); + calendar.setTime(date); + } catch (Exception e) { + e.printStackTrace(); + } + + return calendar; + } + + /** + * java.util.Date转java.sql.date + */ + public static Timestamp utilDate2SqlDate(Date utildate) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss"); + formatter.format(utildate); + java.sql.Date sqldate = new java.sql.Date(utildate.getTime()); + Timestamp result = new Timestamp(sqldate.getTime()); + return result; + } + + + public static List getTjTimeList(String str_startTime, + String str_endTime, String type) { + List listTjTime = new ArrayList(); + // 按日统计 + if ("0".equals(type)) { + int startYear = Integer.parseInt(str_startTime.substring(0, 4)); + int endYear = Integer.parseInt(str_endTime.substring(0, 4)); + int startMonth = Integer.parseInt(str_startTime.substring(5, 7)); + int endMonth = Integer.parseInt(str_endTime.substring(5, 7)); + int startDay = Integer.parseInt(str_startTime.substring(8)); + int endDay = Integer.parseInt(str_endTime.substring(8)); + // 开始时间 + Calendar start = Calendar.getInstance(); + start.set(startYear, startMonth - 1, startDay); + // 结束时间 + Calendar end = Calendar.getInstance(); + end.set(endYear, endMonth - 1, endDay); + // 日间隔数 + long rjg = (end.getTimeInMillis() - start.getTimeInMillis()) + / (1000 * 24 * 60 * 60); + for (int i = 0; i <= rjg; i++) { + if (i != 0) { + startDay++; + } + switch (startMonth) { + case 2: + // 如果是闰年 + if (startYear % 4 == 0 && startYear % 100 != 0 + || startYear % 400 == 0) { + if (startDay > 29) { + startMonth++; + startDay -= 29; + } + } else { + if (startDay > 28) { + startMonth++; + startDay -= 28; + } + } + // listTjTime.add(startYear+"-0"+startMonth+"-"+(startDay>9?startDay:"0"+startDay)); + break; + case 4: + if (startDay > 30) { + startMonth++; + startDay -= 30; + } + // listTjTime.add(startYear+"-0"+startMonth+"-"+(startDay>9?startDay:"0"+startDay)); + break; + case 6: + if (startDay > 30) { + startMonth++; + startDay -= 30; + } + // listTjTime.add(startYear+"-0"+startMonth+"-"+(startDay>9?startDay:"0"+startDay)); + break; + case 9: + if (startDay > 30) { + startMonth++; + startDay -= 30; + //listTjTime.add(startYear + "-" + startMonth + "-0" + // + startDay); + } else { + // listTjTime.add(startYear+"-0"+startMonth+"-"+(startDay>9?startDay:"0"+startDay)); + } + break; + case 11: + if (startDay > 30) { + startMonth++; + startDay -= 30; + } else { + // listTjTime.add(startYear+"-"+startMonth+"-"+(startDay>9?startDay:"0"+startDay)); + } + break; + case 12: + if (startDay > 31) { + startYear++; + startMonth = 1; + startDay -= 31; + } + // listTjTime.add(startYear+"-"+(startMonth>9?startMonth:"0"+startMonth)+"-"+(startDay>9?startDay:"0"+startDay)); + break; + default: + if (startDay > 31) { + startMonth++; + startDay -= 31; + } + // listTjTime.add(startYear+"-"+(startMonth>9?startMonth:"0"+startMonth)+"-"+(startDay>9?startDay:"0"+startDay)); + break; + } + listTjTime.add(startYear + "-" + + (startMonth > 9 ? startMonth : "0" + startMonth) + + "-" + (startDay > 9 ? startDay : "0" + startDay)); + + } + + } + // 按月统计 + if ("1".equals(type)) { + // 开始年 + int startYear = Integer.parseInt(str_startTime.substring(0, 4)); + // 结束年 + int endYear = Integer.parseInt(str_endTime.substring(0, 4)); + // 开始月 + int startMonth = Integer.parseInt(str_startTime.substring(5)); + // 结束月 + int endMonth = Integer.parseInt(str_endTime.substring(5)); + // 如果是同一年的 + if (startYear == endYear) { + // 循环将从开始到结束的所有日期放到list中 + for (int i = 0; i <= endMonth - startMonth; i++) { + if ((startMonth + i) >= 10) { + listTjTime.add(startYear + "-" + (startMonth + i)); + } else { + listTjTime.add(startYear + "-0" + (startMonth + i)); + } + + } + return listTjTime; + } else { + // 年跨度差值 + int ncz = endYear - startYear; + // 通过循环先将开始那一年的日期加到list中 + for (int i = 0; i <= 12 - startMonth; i++) { + if ((startMonth + i) >= 10) { + listTjTime.add(startYear + "-" + (startMonth + i)); + } else { + listTjTime.add(startYear + "-0" + (startMonth + i)); + } + } + // 如果年跨度大于1 + if (ncz > 1) { + // 循环开始和结束中间的年数 + for (int i = 1; i < ncz; i++) { + // 循环12次,将一年的时间加到list + for (int j = 1; j <= 12; j++) { + if (j >= 10) { + listTjTime.add((startYear + i) + "-" + j); + } else { + listTjTime.add((startYear + i) + "-0" + j); + } + } + } + } + // 通过循环将结束那一年的日期加到list中 + for (int i = 1; i <= endMonth; i++) { + if (i >= 10) { + listTjTime.add(endYear + "-" + i); + } else { + listTjTime.add(endYear + "-0" + i); + } + + } + return listTjTime; + } + + } + // 按年统计 + if ("2".equals(type)) { + int startYear = Integer.parseInt(str_startTime.substring(0, 4)); + int endYear = Integer.parseInt(str_endTime.substring(0, 4)); + for (int i = 0; i <= endYear - startYear; i++) { + listTjTime.add(startYear + i + ""); + } + return listTjTime; + } + return listTjTime; + } + + /** + * 获取当前天数是当年的第几天 + * + * @return + */ + public static String getCurrentDaysofYear() { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String currentDay = format.format(new Date()); + return getDayIndexofYear(currentDay); + } + + /** + * 判断是否为闰年 + * + * @param year + * @return + */ + public static boolean isLeapYear(int year) { + // 判断是不是闰年 + if (year % 400 == 0 || (year % 4 == 0 && year % 100 != 0)) { + return true; + } + return false; + } + + /** + * 获得当月的天数 + * + * @param month + * 月份 + * @param isLeapYear + * 是否为闰年 + * @return + */ + public static int getDayofMonth(int month, boolean isLeapYear) { + // 非闰年 + final int[] normal = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + // 闰年 + final int[] leapYear = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; + + if (month != 0 && !isLeapYear) { + return normal[month - 1]; + } + if (month != 0 && isLeapYear) { + return leapYear[month - 1]; + } + return 0; + } + + public static int getDayofYear(int year) { + if (isLeapYear(year)) + return 366; + return 365; + } + + /** + * 根据日期获取日期在当年中的天数 + * + * @param date + * @return + */ + public static String getDayIndexofYear(String date) { + int year = 0; + int month = 0; + int day = 0; + String strIndex = ""; + boolean isLeapYear = false; + int index = 0; + if (date != null) { + String[] timeArray = date.split("-"); + if (timeArray != null && timeArray.length > 0) { + year = Integer.valueOf(timeArray[0]); + month = Integer.valueOf(timeArray[1]); + day = Integer.valueOf(timeArray[2]); + + isLeapYear = isLeapYear(year); + for (int i = 1; i < month; i++) { + index += getDayofMonth(i, isLeapYear); + } + + index += day; + + if (index < 10) { + strIndex = "00" + String.valueOf(index); + } else if (index < 100 && index >= 10) { + strIndex = "0" + String.valueOf(index); + } else { + strIndex = index + ""; + } + return strIndex; + } + } + + return strIndex; + } + + /** + * 获取当前时间,以分钟计算 + * + * @return + */ + private int index = 0; + + public static Date getMondayOfThisWeek() { + Calendar c = Calendar.getInstance(); + int day_of_week = c.get(Calendar.DAY_OF_WEEK) - 1; + if (day_of_week == 0) + day_of_week = 7; + c.add(Calendar.DATE, -day_of_week + 1); + return c.getTime(); + } + + public int getIndex() { + return index; + } + + public void setIndex(int index) { + this.index = index; + } + + public static String getMintuesFromRoot() { + + Calendar cal = Calendar.getInstance(); + cal.setTime(new Date()); + int year = cal.get(Calendar.YEAR); + int day = 0; + int hours = cal.get(Calendar.HOUR_OF_DAY); + int minutes = cal.get(Calendar.MINUTE); + int seconds = cal.get(Calendar.SECOND); + + if (year > 2020) + TIME_ROOT = 2020; + + for (int i = TIME_ROOT; i < year; i++) { + day += getDayofYear(i); + } + day += Integer.valueOf(getCurrentDaysofYear()); + + minutes = day * hours * minutes; + + String mins = String.valueOf(minutes); + String sec = String.valueOf(seconds); + switch (mins.length()) { + case 4: + mins = "0".concat(mins); + case 5: + mins = "0".concat(mins); + case 6: + mins = mins.concat(sec.substring(sec.length() - 1, sec.length())); + } + return mins; + } + + /** + * 获得一个时间的前段时间 + * + * @param days + * 跨度 + * @param date + * 当前时间 yyyy-MM-dd/yyyy-MM/yyyy + * @param type + * 类型(0日,1月,2年) + * @return + */ + public static String getTimeBefore(int days, String date, String type) { + if ("0".equals(type)) { + Date myDate = null; + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + try { + myDate = formatter.parse(date); + } catch (ParseException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + if (myDate != null) { + long myTime = (myDate.getTime() / 1000) - 60 * 60 * 24 * days; + myDate.setTime(myTime * 1000); + String mDate = formatter.format(myDate); + return mDate; + } + } + if ("1".equals(type)) { + try { + int month = Integer.valueOf(date.substring(5, 7)); + int year = Integer.valueOf(date.substring(0, 4)); + if (days - month > 0) { + // 年跨度 + int step = (days - month) / 12 + 1; + // 除去整年后的余月 + int m = (days - month) % 12; + year = year - step; + month = 12 - m; + } else { + month = month - days; + } + String newDate = year + "-" + (month > 9 ? month : "0" + month); + return newDate; + } catch (NumberFormatException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + if ("2".equals(type)) { + int year = Integer.valueOf(date.substring(0, 4)); + String newDate = (year - days) + ""; + return newDate; + } + + return ""; + } + + public static Calendar string2Date(String timeStr, String format) { + SimpleDateFormat dateFormatter = new SimpleDateFormat(format); + Calendar calendar = Calendar.getInstance(); + + try { + Date date = dateFormatter.parse(timeStr); + calendar.setTime(date); + } catch (Exception e) { + e.printStackTrace(); + } + return calendar; + } + + public static boolean isValidDate(String str) { + boolean convertSuccess = true; + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + try { + format.setLenient(false); + format.parse(str); + } catch (ParseException e) { + // e.printStackTrace(); + // 如果throw java.text.ParseException或者NullPointerException,就说明格式不对 + convertSuccess = false; + } + return convertSuccess; + } + + public static String getTimeAfter(int days, Date myDate) { + SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + Calendar now = Calendar.getInstance(); + now.setTime(myDate); + now.set(Calendar.DATE, now.get(Calendar.DATE) + days); + String mDate = formatter.format(now.getTime()); + return mDate; + } + + public static String getMonthStr(int month) { + if (month < 10) { + return "0" + String.valueOf(month); + } else { + return String.valueOf(month); + } + } + + /** + * 判断时间是否在时间段内 + * @param date + * @param timeStart + * @param timeEnd + * @return + */ + public static boolean isInDate(Date date, String timeStart, String timeEnd) { + SimpleDateFormat sdf = new SimpleDateFormat("HH:mm"); + String strDate = sdf.format(date); + + // 截取当前时间时分 + String[] dateArr = strDate.split(":"); + int strDateH = Integer.parseInt(dateArr[0]); + int strDateM = Integer.parseInt(dateArr[1]); + int strDateT = strDateH * 60 + strDateM; + + // 截取开始时间时分 + String[] startArr = timeStart.split(":"); + int strDateBeginH = Integer.parseInt(startArr[0]); + int strDateBeginM = Integer.parseInt(startArr[1]); + int strDateBeginT = strDateBeginH * 60 + strDateBeginM; + // 截取结束时间时分 + String[] endArr = timeEnd.split(":"); + int strDateEndH = Integer.parseInt(endArr[0]); + int strDateEndM = Integer.parseInt(endArr[1]); + int strDateEndT = strDateEndH * 60 + strDateEndM; + + + if (strDateT >= strDateBeginT && strDateT <= strDateEndT) { + return true; + } else { + return false; + } + } + + /** + * 判断时间是否在时间段内 + * @param date + * @param curDate + * @return + */ + public static boolean isInDate15Mins(Date date, Date curDate) { + long diff = 0; + if (curDate.before(date)) { + diff = date.getTime() - curDate.getTime(); + } else { + diff = curDate.getTime() - date.getTime(); + } + + if (diff <= (1000*60*15)) { + return true; + } else { + return false; + } + } + + public static Date getDayBegin(Date date) { + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + cale.set(Calendar.HOUR_OF_DAY, 0); //将小时至0 + cale.set(Calendar.MINUTE, 0); //将分钟至0 + cale.set(Calendar.SECOND,0); //将秒至0 + cale.set(Calendar.MILLISECOND, 0); //将毫秒至0 + return cale.getTime(); + } + + public static Date getDayEnd(Date date) { + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + return DateUtils.getDateFromString(DateUtils.date2String(cale.getTime(),"yyyy-MM-dd")+" 23:59:59","yyyy-MM-dd HH:mm:ss").getTime(); + } + + /** + * 获取当前月的第一天 + * @return + */ + public static Date getFirstDayForCurrMonth(){ + Calendar cale = Calendar.getInstance(); + cale.add(Calendar.MONTH, 0); + cale.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 + cale.set(Calendar.HOUR_OF_DAY, 0); //将小时至0 + cale.set(Calendar.MINUTE, 0); //将分钟至0 + cale.set(Calendar.SECOND,0); //将秒至0 + cale.set(Calendar.MILLISECOND, 0); //将毫秒至0 + return cale.getTime(); + } + /** + * 获取当前月的第一天 + * @return + */ + public static Date getFirstDayForCurrMonth(Date date){ + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + cale.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天 + return cale.getTime(); + } + + /** + * 获取指定月的最后一天 + * @return + */ + public static Date getLastDayForMonth(Date date){ + Calendar ca = Calendar.getInstance(); + ca.setTime(date); + ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); + return DateUtils.getDateFromString(DateUtils.date2String(ca.getTime(),"yyyy-MM-dd")+" 23:59:59","yyyy-MM-dd HH:mm:ss").getTime(); + } + + /** + * 获取指定月的最后一天 + * @return + */ + public static Date getLastDayForMonth(String date){ + try { + Calendar ca = Calendar.getInstance(); + ca.setTime(new SimpleDateFormat("yyyy-MM-dd").parse(date)); + ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); + return ca.getTime(); + } catch (ParseException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 获取指定日期n个月后的最后一天 + * @return + */ + public static Date getLastDayForMonth(Date date, int amount){ + Calendar ca = Calendar.getInstance(); + ca.setTime(date); + ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH)); + ca.add(Calendar.MONTH, amount); + return ca.getTime(); + } + + /** + * 取得指定月的天数 + * */ + public static int getMonthDayCount(Date date) { + Calendar a = Calendar.getInstance(); + a.setTime(date); + a.set(Calendar.DATE, 1);//把日期设置为当月第一天 + a.roll(Calendar.DATE, -1);//日期回滚一天,也就是最后一天 + int maxDate = a.get(Calendar.DATE); + return maxDate; + } + + /** + * 计算两个日期相隔多少天 + * @param smdate + * @param bdate + * @return + * @throws ParseException + */ + public static int daysBetween(Date smdate,Date bdate) { + try { + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); + smdate=sdf.parse(sdf.format(smdate)); + bdate=sdf.parse(sdf.format(bdate)); + Calendar cal = Calendar.getInstance(); + cal.setTime(smdate); + long time1 = cal.getTimeInMillis(); + cal.setTime(bdate); + long time2 = cal.getTimeInMillis(); + long between_days=(time2-time1)/(1000*3600*24); + return Integer.parseInt(String.valueOf(between_days)); + }catch (Exception e){ + e.printStackTrace(); + } + return 0; + } + + public static int monthsBetween(Date begin,Date end) { + Calendar _bc = Calendar.getInstance(); + _bc.setTime(begin); + + Calendar _ec = Calendar.getInstance(); + _ec.setTime(end); + + int i = _ec.get(Calendar.YEAR) - _bc.get(Calendar.YEAR); + int month = 0; + if (i < 0) { + month = -i * 12; + }else { + month = i * 12; + } + int result = _ec.get(Calendar.MONTH) - _bc.get(Calendar.MONTH) + month; + return Math.abs(result); + } + + /** + * 日期距离今天还有几天 + * @param date + * @return <0:已过n天;=0:当天 ;>0 n天前 + */ + public static int birthdaysBetween(Date date) { + Calendar todayCal = Calendar.getInstance(); + Calendar birthdayCal = Calendar.getInstance(); + birthdayCal.setTime(date); + return birthdayCal.get(Calendar.DAY_OF_YEAR) - todayCal.get(Calendar.DAY_OF_YEAR) ; + } + + /** + * 获取指定日期n个月后的第一天 + * @return + */ + public static Date getFirstDayOfNextMonth(Date date,int amount){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH,1); + calendar.add(Calendar.MONTH, amount); + return calendar.getTime(); + } + + /** + * 获取指定日期n个月后的最后一天 + * @return + */ + public static Date getLastDayOfNextMonth(Date date,int amount){ + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.set(Calendar.DAY_OF_MONTH,1); + calendar.add(Calendar.MONTH, amount); + Date d = calendar.getTime(); + return getFirstDayForCurrMonth(d); + } + + /** + * 判断时间是否在时间段内 + * @param nowTime + * @param beginTime + * @param endTime + * @return + */ + public static boolean belongCalendar(Date nowTime, Date beginTime, Date endTime) { + Calendar date = Calendar.getInstance(); + date.setTime(nowTime); + Calendar begin = Calendar.getInstance(); + begin.setTime(beginTime); + Calendar end = Calendar.getInstance(); + end.setTime(endTime); + if (date.after(begin) && date.before(end)) { + return true; + } else if (nowTime.compareTo(beginTime) == 0 || nowTime.compareTo(endTime) == 0) { + return true; + } else { + return false; + } + } + + /** + * 计算两个时间 相差n个月 零n天 + * @return + */ + public static int[] getDiff(Date startDate,Date endDate) { + SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd"); + if(sd.format(startDate).equals(sd.format(endDate))){ + return new int[] {0, 0}; + } + + ZoneId zone = ZoneId.systemDefault(); + LocalDateTime localDateTime = LocalDateTime.ofInstant(startDate.toInstant(), zone); + LocalDate start = localDateTime.toLocalDate(); + + localDateTime = LocalDateTime.ofInstant(endDate.toInstant(), zone); + LocalDate end = localDateTime.toLocalDate(); + + if (!start.isBefore(end)) { + throw new IllegalArgumentException("日期不正确,请检查。"); + } + + Period period = Period.between(start, end); + int years = period.getYears(); + int months = period.getMonths(); + int days = period.getDays(); + + return new int[] {years * 12 + months, days}; + } + + /** + * 获取设置后的时间 + * @param date + * @param type Calendar.DATE Calendar.MONTH + * @param set + * @return + */ + public static Date getDaySet(Date date,int type,int set){ + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + cale.add(type,set); + return cale.getTime(); + } + + /** + * 判断两日期是否同一个月 + * @param date1 + * @param date2 + * @return + */ + public static boolean isSameMonth(Date date1, Date date2) { + + Calendar calendar1 = Calendar.getInstance(); + calendar1.setTime(date1); + Calendar calendar2 = Calendar.getInstance(); + calendar2.setTime(date2); + int year1 = calendar1.get(Calendar.YEAR); + int year2 = calendar2.get(Calendar.YEAR); + int month1 = calendar1.get(Calendar.MONTH); + int month2 = calendar2.get(Calendar.MONTH); + System.out.println(year1 + " " + month1); + System.out.println(year2 + " " + month2); + return calendar1.get(Calendar.YEAR) == calendar2.get(Calendar.YEAR) && calendar1.get(Calendar.MONTH) == calendar2.get(Calendar.MONTH); + + } + + /** + * 获取上个月的今天 + */ + public static Date getLastMonthToDay() { + Date date = new Date(); + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); // 设置为当前时间 + calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) - 1); // 设置为上一个月 + return calendar.getTime(); + } + + /** + * 计算两个日期之间的间隔天数 + * @param startDate + * @param endDate + * @return + */ + public static long startToEnd(Date startDate, Date endDate){ + String[] startStr = new SimpleDateFormat("yyyy-MM-dd").format(startDate).split("-"); + String[] endStr = new SimpleDateFormat("yyyy-MM-dd").format(endDate).split("-"); + Integer startYear = Integer.parseInt(startStr[0]); + Integer startMonth = Integer.parseInt(startStr[1]); + Integer startDay = Integer.parseInt(startStr[2]); + Integer endYear = Integer.parseInt(endStr[0]); + Integer endMonth = Integer.parseInt(endStr[1]); + Integer endDay = Integer.parseInt(endStr[2]); + LocalDate endLocalDate = LocalDate.of(endYear,endMonth,endDay); + LocalDate startLocalDate = LocalDate.of(startYear,startMonth,startDay); + return startLocalDate.until(endLocalDate, ChronoUnit.DAYS); + } + + /* + public static void main(String[] args) throws Exception { + SimpleDateFormat dd = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + Date ll; + ll = dd.parse("2019-07-27 11:00:00"); + Date next = DateUtils.getTimeAfterDays(30, ll); + System.out.println(next); + } + */ + + + /** + * 获取多少岁 + * @param birthDay + * @return + * @throws Exception + */ + public static int getAge(Date birthDay){ + Calendar cal = Calendar.getInstance(); + if (cal.before(birthDay)) { //出生日期晚于当前时间,无法计算 + throw new IllegalArgumentException( + "The birthDay is before Now.It's unbelievable!"); + } + int yearNow = cal.get(Calendar.YEAR); //当前年份 + int monthNow = cal.get(Calendar.MONTH); //当前月份 + int dayOfMonthNow = cal.get(Calendar.DAY_OF_MONTH); //当前日期 + cal.setTime(birthDay); + int yearBirth = cal.get(Calendar.YEAR); + int monthBirth = cal.get(Calendar.MONTH); + int dayOfMonthBirth = cal.get(Calendar.DAY_OF_MONTH); + int age = yearNow - yearBirth; //计算整岁数 + if (monthNow <= monthBirth) { + if (monthNow == monthBirth) { + if (dayOfMonthNow < dayOfMonthBirth) age--;//当前日期在生日之前,年龄减一 + }else{ + age--;//当前月份在生日之前,年龄减一 + } + } return age; + } + + /** + * 获取当前日期是星期几
+ * + * @param date + * @return 当前日期是星期几 + */ + public static int getWeekOfDate(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int w = cal.get(Calendar.DAY_OF_WEEK) ; + if (w == 1) + w = 7; + return w - 1; + } + + /** + * 获取当前日期是当前月的第几天
+ * + * @param date + * @return 获取当前日期是当前月的第几天 + */ + public static int getMonthOfDate(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int m = cal.get(Calendar.DAY_OF_MONTH); + return m; + } + + /** + * 获取当前日期是几月
+ * + * @param date + * @return 获取当前日期是几月 + */ + public static int getMonth(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int month = cal.get(Calendar.MONTH) + 1; + return month; + } + + /** + * 获取当前日期是哪年
+ * + * @param date + * @return 获取当前日期是哪年 + */ + public static int getYear(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + int year = cal.get(Calendar.YEAR); + return year; + } + + /** + * 判断生日 + * @param date + * @return + */ + public static boolean isBirthdays(Date date) { + Calendar todayCal = Calendar.getInstance(); + int todayMonth = todayCal.get(Calendar.MONTH) + 1; + int todayDay = todayCal.get(Calendar.DAY_OF_MONTH); + Calendar birthdayCal = Calendar.getInstance(); + birthdayCal.setTime(date); + int birthMonth = birthdayCal.get(Calendar.MONTH) + 1; + int birthDay = birthdayCal.get(Calendar.DAY_OF_MONTH); + if(todayMonth == birthMonth && todayDay == birthDay){ + return true; + } + return false; + } + + /** + * 获取当前日期零点
+ * + * @param date + * @return 获取当前日期零点 + */ + public static Date getDateZero(Date date) { + Calendar cal = Calendar.getInstance(); + cal.setTime(date); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + public static boolean isSameDate(Date date1, Date date2) { + Calendar cal1 = Calendar.getInstance(); + cal1.setTime(date1); + Calendar cal2 = Calendar.getInstance(); + cal2.setTime(date2); + boolean isSameYear = cal1.get(Calendar.YEAR) == cal2 + .get(Calendar.YEAR); + boolean isSameMonth = isSameYear + && cal1.get(Calendar.MONTH) == cal2.get(Calendar.MONTH); + boolean isSameDate = isSameMonth + && cal1.get(Calendar.DAY_OF_MONTH) == cal2 + .get(Calendar.DAY_OF_MONTH); + return isSameDate; + } + + /** + * 获取i年后的今天 + * @return + */ + public static String getAfterYear(Date date,int i){ + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Calendar cale = Calendar.getInstance(); + cale.setTime(date); + cale.add(Calendar.YEAR, i); + return format.format(cale.getTime()); + } + + /** + 2. * 获取精确到秒的时间戳 + 3. * @return + 4. */ + public static int getSecondTimestamp(Date date){ + if (null == date) { + return 0; + } + String timestamp = String.valueOf(date.getTime()); + int length = timestamp.length(); + if (length > 3) { + return Integer.valueOf(timestamp.substring(0,length-3)); + } else { + return 0; + } + } + + /** + * 遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE + * 转换 + * @param rfcDate + * @return + */ + public static Date rfc3339Formatter(String rfcDate) { + DateTime dateTime = new DateTime(rfcDate); + long timeInMillis = dateTime.toCalendar(Locale.getDefault()).getTimeInMillis(); + return new Date(timeInMillis); + } + + /** + * 遵循rfc3339标准格式,格式为yyyy-MM-DDTHH:mm:ss+TIMEZONE + * 转换 北京时间 + * @param date + * @return + */ + public static String toRfc3339Str(Date date) { + DateTime dateTime = new DateTime(date, DateTimeZone.forTimeZone(TimeZone.getTimeZone("Asia/Shanghai"))); + return dateTime.toString(); + } +} diff --git a/mallinkService/src/main/java/com/iformall/utils/HttpUtil.java b/mallinkService/src/main/java/com/iformall/utils/HttpUtil.java new file mode 100644 index 0000000..7d78d77 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/HttpUtil.java @@ -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 nvps = new ArrayList(); + 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 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 set = headMap.keySet(); +// for(String key: set){ +// request.addHeader(key,headMap.get(key)); +// } +// } +// +// //设置参数 +// List nvps = new ArrayList(); +// 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 nvps = new ArrayList(); + 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 nvps = new ArrayList(); + 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 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 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 sslContextMap = new ConcurrentHashMap(); + 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; +// } +// +// } + +} + diff --git a/mallinkService/src/main/java/com/iformall/utils/MapUtil.java b/mallinkService/src/main/java/com/iformall/utils/MapUtil.java new file mode 100644 index 0000000..33115fa --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/MapUtil.java @@ -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 getOrderMap() { + Map paramMap = new TreeMap( + new Comparator() { + public int compare(String obj1, String obj2) { + // 降序排序 + return obj1.compareTo(obj2); + } + }); + return paramMap; + } +} diff --git a/mallinkService/src/main/java/com/iformall/utils/SysConfigConstant.java b/mallinkService/src/main/java/com/iformall/utils/SysConfigConstant.java new file mode 100644 index 0000000..d773b11 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/SysConfigConstant.java @@ -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"; + +} diff --git a/mallinkService/src/main/java/com/iformall/utils/Utility.java b/mallinkService/src/main/java/com/iformall/utils/Utility.java new file mode 100644 index 0000000..879a093 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/Utility.java @@ -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 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(); + } + + +} diff --git a/mallinkService/src/main/java/com/iformall/utils/XmlUtil.java b/mallinkService/src/main/java/com/iformall/utils/XmlUtil.java new file mode 100644 index 0000000..1b31af0 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/utils/XmlUtil.java @@ -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处理器
+ * + * @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 = ""; + Document document = null; + try { + if (pStrXml.indexOf(" 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 = ""; + Document document = null; + try { + if (pStrXml.indexOf(""; + Document document = null; + try { + if (pStrXml.indexOf(" dom2Map(Document doc) { + Map maproot = new HashMap(); + if (doc == null) + return maproot; + Element root = doc.getRootElement(); + + List list1 = root.elements(); + for (Object obj : list1) { + Element element = (Element) obj; + Map map = new HashMap(); + element2Map(element, map); + maproot.put(element.getName(), map); + } + return maproot; + } + + /** + * Element to map + * + * @param e + * @return + */ + public static void element2Map(Element e, Map map) { + List 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 cMap = new HashMap(); + 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 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 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 集合转化成 xml格式 + */ + public static String getRequestXml(SortedMap parameters){ + StringBuilder sb = new StringBuilder(); + sb.append(""); + 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+">"+""); + }else { + sb.append("<"+k+">"+v+""); + } + } + sb.append(""); + return sb.toString(); + } + +} \ No newline at end of file diff --git a/mallinkService/src/main/resources/mapper/SysConfigMapper.xml b/mallinkService/src/main/resources/mapper/SysConfigMapper.xml new file mode 100644 index 0000000..abf5cef --- /dev/null +++ b/mallinkService/src/main/resources/mapper/SysConfigMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + `id`,`config_item_key`,`config_item_remark`,`create_date`,`update_date`,`is_hide`,`status` + + + + where 1 = 1 + + and `id` = #{id} + + + and `config_item_key` = #{configItemKey} + + + and `is_hide` = #{isHide} + + + and `status` = #{status} + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + + + + diff --git a/mallinkService/src/main/resources/mapper/SysConfigValueMapper.xml b/mallinkService/src/main/resources/mapper/SysConfigValueMapper.xml new file mode 100644 index 0000000..bd150ea --- /dev/null +++ b/mallinkService/src/main/resources/mapper/SysConfigValueMapper.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + `id`,`tenant_id`,`parent_tenant_id`,`config_item_id`,`config_item_value`,`update_date`,`create_date` + + + + where 1=1 + + + and `id` = #{id} + + + + and `tenant_id` = #{tenantId} + + + and `parent_tenant_id` = #{parentTenantId} + + + + and `config_item_id` = #{configItemId} + + + + and `config_item_value` = #{configItemValue} + + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + + diff --git a/mallinkService/src/main/resources/mapper/WxPayOrderMapper.xml b/mallinkService/src/main/resources/mapper/WxPayOrderMapper.xml new file mode 100644 index 0000000..c9e1a59 --- /dev/null +++ b/mallinkService/src/main/resources/mapper/WxPayOrderMapper.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + `id`,`tenant_id`,`parent_tenant_id`,`create_time`,`update_time`,`c_user_id`,`c_user_phone`,`pay_amount`, + `pay_time`,`transaction_id` + + + + where `tenant_id` = #{tenantId} + + + and `id` = #{id} + + + + and `parent_tenant_id` = #{parentTenantId} + + + + and `create_time` = #{createTime} + + + + and `update_time` = #{updateTime} + + + + and `c_user_id` = #{cUserId} + + + + and `pay_amount` = #{payAmount} + + + + and `pay_time` = #{payTime} + + + + and `transaction_id` like concat('%', #{transactionId},'%') + + + + and `c_user_phone` like concat('%', #{cUserPhone},'%') + + + + and `create_time` >= #{begin} + + + + and `create_time` <= #{end} + + + + and c_user_id in + + #{uidItem} + + + + + and id in + + #{idItem} + + + order by ${sortColumns} + + + + + + + + +