springcloud_k8s_panzhihuazhihuishequ/applets/src/main/java/com/panzhihua/applets/api/ShopFlowerApi.java
@@ -1,17 +1,21 @@ package com.panzhihua.applets.api; import com.panzhihua.common.controller.BaseController; import com.panzhihua.common.model.dtos.community.convenient.ConvenientMerchantDTO; import com.panzhihua.common.model.dtos.shop.*; import com.panzhihua.common.model.vos.LoginUserInfoVO; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.model.vos.community.convenient.ConvenientElevatingPointVO; import com.panzhihua.common.model.vos.community.convenient.ConvenientMerchantVO; import com.panzhihua.common.model.vos.shop.*; import com.panzhihua.common.service.community.CommunityService; import com.panzhihua.common.validated.PutGroup; import io.swagger.annotations.Api; import io.swagger.annotations.ApiImplicitParam; import io.swagger.annotations.ApiImplicitParams; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.annotation.Resource; @@ -31,14 +35,19 @@ private CommunityService communityService; /* @ApiOperation(value = "查询店铺详情", response = PageShopStoreVO.class) @PostMapping("shopstoredetail") public R shopStoreDetail(@RequestBody PageComShopStoreDTO comShopStoreDTO) { if (comShopStoreDTO == null || comShopStoreDTO.getStoreId() == null) { return R.fail("参数错误"); } return communityService.shopStoreDetail(comShopStoreDTO); }*/ @ApiOperation(value = "查询便民服务商家详情", response = ConvenientMerchantVO.class) @GetMapping("/merchant/getMerchantByUserId") public R getMerchant(@RequestParam("userId") Long userId) { return communityService.getMerchantByUserId(userId); } @ApiOperation(value = "编辑便民服务商家") @PutMapping("/merchant/put") public R putMerchant(@RequestBody @Validated(PutGroup.class) ConvenientMerchantDTO convenientMerchantDTO) { convenientMerchantDTO.setUpdatedBy(this.getUserId()); convenientMerchantDTO.setCreatedBy(this.getUserId()); return communityService.putMerchant(convenientMerchantDTO); } @ApiOperation(value = "分页查询商品列表", response = ComShopFlowerGoodsVO.class) @PostMapping("pageShopGoods") springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/constants/PayCpmstant.java
@@ -36,4 +36,19 @@ * 电动车商城活动订单支付回调地址 */ public static final String BATTERY_STORE_ACTIVITY_PAY_NOTIFY_URL = "/api/huacheng-applets/wx/batteryActivityPayNotify"; public static final String REFUND_URL = "https://api.mch.weixin.qq.com/secapi/pay/refund"; /** * 微信支付返回支付成功的参数名字 */ public static final String RETURN_CODE_CODE = "return_code"; /** * 微信退款接口返回成功的参数名称 */ public static final String RESULT_CODE_CODE = "result_code"; /** * 微信退款接口请求key */ public static final String REFUND_KEY= "GMWTEJ7NOVPQLL1FTMLT49H693LOUABJ"; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/dtos/shop/ComShopFlowerRefundOrderDTO.java
New file @@ -0,0 +1,86 @@ package com.panzhihua.common.model.dtos.shop; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; /** * @auther yh * @create 2022-11-08 17:25:45 * @describe 退款申请 */ @Data @ApiModel("退款申请") public class ComShopFlowerRefundOrderDTO { /** * 退款订单id */ @ApiModelProperty(value = "退款订单id") private Long id; /** * 店铺id */ @ApiModelProperty(value = "店铺id") private Long storeId; /** * 原始订单号 */ @ApiModelProperty(value = "原始订单号") private String orderNo; /** * 原始订单id */ @ApiModelProperty(value = "原始订单id") private String orderId; /** * 支付总金额 */ @ApiModelProperty(value = "支付总金额") private BigDecimal payAmount; /** * 申请退款金额 */ @ApiModelProperty(value = "申请退款金额") private BigDecimal refundAmount; /** * 退款原因 */ @ApiModelProperty(value = "退款原因") private String refundReason; /** * 退款照片 */ @ApiModelProperty(value = "退款照片") private String refundPic; /** * 处理结果 */ @ApiModelProperty(value = "处理结果(1.同意 2.拒绝)") private String handleResult; /** * 商家备注 */ @ApiModelProperty(value = "商家备注") private String remark; /** * 用户id */ @ApiModelProperty(value = "用户id", hidden = true) private Long userId; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/dtos/shop/PageComOrderRefundDTO.java
New file @@ -0,0 +1,29 @@ package com.panzhihua.common.model.dtos.shop; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; /** * @auther lyq * @create 2021-04-14 15:02:14 * @describe 分页查询订单列表 */ @Data @ApiModel("分页查询退款订单列表") public class PageComOrderRefundDTO { @ApiModelProperty(value = "分页-当前页数", example = "1") private Long pageNum = 1L; @ApiModelProperty(value = "分页-每页记录数", example = "10") private Long pageSize = 10L; @ApiModelProperty(value = "订单状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中)") private Integer status; @ApiModelProperty(value = "店铺id") private Long storeId; @ApiModelProperty(value = "用户id", hidden = true) private Long userId; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/model/vos/shop/ComShopFlowerRefundOrderVO.java
New file @@ -0,0 +1,125 @@ package com.panzhihua.common.model.vos.shop; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; import java.util.Date; /** * @ClassName: ComShopFlowerRefundOrderVO * @Author: yh * @Date: 2022/11/16 15:05 * @Description: TODO */ @Data public class ComShopFlowerRefundOrderVO { /** * 订单id */ @ApiModelProperty("退款订单id") private Long id; /** * 店铺id */ @ApiModelProperty("店铺id") private Long storeId; /** * 用户id */ @ApiModelProperty("用户id") private Long userId; /** * 原始订单号 */ @ApiModelProperty("原始订单号") private String orderNo; /** * 原始订单id */ @ApiModelProperty("原始订单id") private String orderId; /** * 退款订单号 */ @ApiModelProperty("退款订单号") private String refundOrderNo; /** * 订单状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中) */ @ApiModelProperty("订单状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中)") private Integer status; /** * 删除状态(1.未删除 2.已删除) */ @ApiModelProperty("删除状态(1.未删除 2.已删除)") private Integer deleteStatus; /** * 支付总金额 */ @ApiModelProperty("支付总金额") private BigDecimal payAmount; /** * 申请退款金额 */ @ApiModelProperty("申请退款金额") private BigDecimal refundAmount; /** * 退款原因 */ @ApiModelProperty("退款原因") private String refundReason; /** * 退款照片 */ @ApiModelProperty("退款照片") private String refundPic; /** * 申请时间 */ @ApiModelProperty("申请时间") private Date createAt; /** * 修改时间 */ @ApiModelProperty("修改时间") private Date updateAt; /** * 处理时间 */ @ApiModelProperty("处理时间") private Date handleTime; /** * 退款时间 */ @ApiModelProperty("退款时间") private Date refundTime; /** * 处理结果 */ @ApiModelProperty("处理结果(1.同意 2.拒绝)") private String handleResult; /** * 商家备注 */ @ApiModelProperty("商家备注") private String remark; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/service/community/CommunityService.java
@@ -6541,6 +6541,14 @@ R getMerchant(@RequestParam("merchantId") Long merchantId); /** * 获取便民服务商家详情 * @param userId * @return */ @GetMapping("/convenient/merchant/getMerchantByUserId") R getMerchantByUserId(@RequestParam("userId") Long userId); /** * 禁用/启用便民服务商家 * @param disableOrEnableConvenientMerchantDTO * @return @@ -10945,5 +10953,5 @@ * @return */ @PostMapping("/shopFlower/pageOrderByStoreId") R pageOrderByStoreId(@RequestBody PageComFlowerOrderListDTO pageComFlowerOrderListDTO) R pageOrderByStoreId(@RequestBody PageComFlowerOrderListDTO pageComFlowerOrderListDTO); } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/HttpClientUtil.java
@@ -4,27 +4,35 @@ import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.security.KeyStore; import java.util.Iterator; import java.util.List; import java.util.Map; import com.alibaba.fastjson.JSONObject; import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; 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.client.methods.HttpUriRequest; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicHeader; import org.apache.http.ssl.SSLContexts; import org.apache.http.util.EntityUtils; import org.springframework.util.ObjectUtils; import com.panzhihua.common.constants.HttpConstant; import lombok.extern.slf4j.Slf4j; import javax.net.ssl.SSLContext; /** * @program: springcloud_k8s_panzhihuazhihuishequ @@ -332,4 +340,67 @@ return in; } /** * 退款请求微信 * @param url 请求地址 * @param data 请求数据 * @param mchId 商户id * @param isTest 是否是测试 * @return 退款结果 * @throws Exception 抛出异常 */ public static String doRefund(String url, String data,String mchId,Boolean isTest) throws Exception{ KeyStore keyStore = KeyStore.getInstance("PKCS12"); //P12文件目录 证书路径,这里需要你自己修改,linux下还是windows下的根路径 String filepath = ""; if(isTest){ filepath = "D:\\wx\\WXCertUtil\\cert\\"; }else{ filepath = "/mnt/data/refund/huacheng/"; } System.out.println("filepath->"+filepath); FileInputStream instream = new FileInputStream(filepath+"apiclient_cert.p12"); try { keyStore.load(instream, mchId.toCharArray());//这里写密码..默认是你的MCHID } finally { instream.close(); } // Trust own CA and all self-signed certs SSLContext sslcontext = SSLContexts.custom() .loadKeyMaterial(keyStore, mchId.toCharArray())//这里也是写密码的 .build(); // Allow TLSv1 protocol only SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslcontext, SSLConnectionSocketFactory.getDefaultHostnameVerifier()); CloseableHttpClient httpclient = HttpClients.custom() .setSSLSocketFactory(sslsf) .build(); try { HttpPost httpost = new HttpPost(url); // 设置响应头信息 httpost.addHeader("Connection", "keep-alive"); httpost.addHeader("Accept", "*/*"); httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); httpost.addHeader("Host", "api.mch.weixin.qq.com"); httpost.addHeader("X-Requested-With", "XMLHttpRequest"); httpost.addHeader("Cache-Control", "max-age=0"); httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) "); httpost.setEntity(new StringEntity(data, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httpost); try { HttpEntity entity = response.getEntity(); String jsonStr = EntityUtils.toString(response.getEntity(), "UTF-8"); log.info("请求微信退款接口返回结果:" + JSONObject.toJSONString(jsonStr)); EntityUtils.consume(entity); return jsonStr; } finally { response.close(); } } finally { httpclient.close(); } } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/WxPayUtils.java
@@ -1,10 +1,12 @@ package com.panzhihua.common.utlis; import java.math.BigDecimal; import java.util.LinkedHashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; import com.panzhihua.common.utlis.wx.WXPayUtil; import org.json.XML; import com.alibaba.fastjson.JSON; @@ -138,4 +140,31 @@ return result.toJSONString(); } public static String refund(String appid,String mchId,String orderNo,BigDecimal totalFee,BigDecimal refundFee,String refundNo,Boolean isTest) throws Exception { //创建请求地址 String url = PayCpmstant.REFUND_URL; Map<String, String> paramMap = new LinkedHashMap<>(); paramMap.put("appid",appid); paramMap.put("mch_id",mchId); paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); paramMap.put("out_refund_no",refundNo); paramMap.put("out_trade_no",orderNo); paramMap.put("refund_fee",String.valueOf(refundFee.multiply(BigDecimal.valueOf(100)).longValue())); paramMap.put("total_fee",String.valueOf(totalFee.multiply(BigDecimal.valueOf(100)).longValue())); paramMap.put("sign",WXPayUtil.generateSignature(paramMap,PayCpmstant.REFUND_KEY)); log.info("微信退款请求参数:{},{},{},{}",url,WXPayUtil.mapToXml(paramMap),mchId,isTest); //接收请求返回值 String content = HttpClientUtil.doRefund(url,WXPayUtil.mapToXml(paramMap),mchId,isTest); log.info("微信退款返回字符串:{}",content); Map<String, String> resultMap = WXPayUtil.xmlToMap(content); if (PayCpmstant.RETURN_CODE.equals(resultMap.get(PayCpmstant.RETURN_CODE_CODE)) && PayCpmstant.RETURN_CODE.equals(resultMap.get(PayCpmstant.RESULT_CODE_CODE))) { log.info("调用微信退款申请接口成功"); return JSONObject.toJSONString(resultMap); }else{ log.error("调用微信退款申请接口失败"); return ""; } } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/wx/WXPayConstants.java
New file @@ -0,0 +1,59 @@ package com.panzhihua.common.utlis.wx; import org.apache.http.client.HttpClient; /** * 常量 */ public class WXPayConstants { public enum SignType { MD5, HMACSHA256 } public static final String DOMAIN_API = "api.mch.weixin.qq.com"; public static final String DOMAIN_API2 = "api2.mch.weixin.qq.com"; public static final String DOMAIN_APIHK = "apihk.mch.weixin.qq.com"; public static final String DOMAIN_APIUS = "apius.mch.weixin.qq.com"; public static final String FAIL = "FAIL"; public static final String SUCCESS = "SUCCESS"; public static final String HMACSHA256 = "HMAC-SHA256"; public static final String MD5 = "MD5"; public static final String FIELD_SIGN = "sign"; public static final String FIELD_SIGN_TYPE = "sign_type"; public static final String WXPAYSDK_VERSION = "WXPaySDK/3.0.9"; public static final String USER_AGENT = WXPAYSDK_VERSION + " (" + System.getProperty("os.arch") + " " + System.getProperty("os.name") + " " + System.getProperty("os.version") + ") Java/" + System.getProperty("java.version") + " HttpClient/" + HttpClient.class.getPackage().getImplementationVersion(); public static final String MICROPAY_URL_SUFFIX = "/pay/micropay"; public static final String UNIFIEDORDER_URL_SUFFIX = "/pay/unifiedorder"; public static final String ORDERQUERY_URL_SUFFIX = "/pay/orderquery"; public static final String REVERSE_URL_SUFFIX = "/secapi/pay/reverse"; public static final String CLOSEORDER_URL_SUFFIX = "/pay/closeorder"; public static final String REFUND_URL_SUFFIX = "/secapi/pay/refund"; public static final String REFUNDQUERY_URL_SUFFIX = "/pay/refundquery"; public static final String DOWNLOADBILL_URL_SUFFIX = "/pay/downloadbill"; public static final String REPORT_URL_SUFFIX = "/payitil/report"; public static final String SHORTURL_URL_SUFFIX = "/tools/shorturl"; public static final String AUTHCODETOOPENID_URL_SUFFIX = "/tools/authcodetoopenid"; // sandbox public static final String SANDBOX_MICROPAY_URL_SUFFIX = "/sandboxnew/pay/micropay"; public static final String SANDBOX_UNIFIEDORDER_URL_SUFFIX = "/sandboxnew/pay/unifiedorder"; public static final String SANDBOX_ORDERQUERY_URL_SUFFIX = "/sandboxnew/pay/orderquery"; public static final String SANDBOX_REVERSE_URL_SUFFIX = "/sandboxnew/secapi/pay/reverse"; public static final String SANDBOX_CLOSEORDER_URL_SUFFIX = "/sandboxnew/pay/closeorder"; public static final String SANDBOX_REFUND_URL_SUFFIX = "/sandboxnew/secapi/pay/refund"; public static final String SANDBOX_REFUNDQUERY_URL_SUFFIX = "/sandboxnew/pay/refundquery"; public static final String SANDBOX_DOWNLOADBILL_URL_SUFFIX = "/sandboxnew/pay/downloadbill"; public static final String SANDBOX_REPORT_URL_SUFFIX = "/sandboxnew/payitil/report"; public static final String SANDBOX_SHORTURL_URL_SUFFIX = "/sandboxnew/tools/shorturl"; public static final String SANDBOX_AUTHCODETOOPENID_URL_SUFFIX = "/sandboxnew/tools/authcodetoopenid"; } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/wx/WXPayUtil.java
New file @@ -0,0 +1,297 @@ package com.panzhihua.common.utlis.wx; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.io.StringWriter; import java.security.MessageDigest; import java.security.SecureRandom; import java.util.*; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.xml.parsers.DocumentBuilder; 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 org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.panzhihua.common.utlis.wx.WXPayConstants.SignType; public class WXPayUtil { private static final String SYMBOLS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; private static final Random RANDOM = new SecureRandom(); /** * XML格式字符串转换为Map * * @param strXML XML字符串 * @return XML数据转换后的Map * @throws Exception */ public static Map<String, String> xmlToMap(String strXML) throws Exception { try { Map<String, String> data = new HashMap<String, String>(); DocumentBuilder documentBuilder = WXPayXmlUtil.newDocumentBuilder(); InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8")); org.w3c.dom.Document doc = documentBuilder.parse(stream); doc.getDocumentElement().normalize(); NodeList nodeList = doc.getDocumentElement().getChildNodes(); for (int idx = 0; idx < nodeList.getLength(); ++idx) { Node node = nodeList.item(idx); if (node.getNodeType() == Node.ELEMENT_NODE) { org.w3c.dom.Element element = (org.w3c.dom.Element) node; data.put(element.getNodeName(), element.getTextContent()); } } try { stream.close(); } catch (Exception ex) { // do nothing } return data; } catch (Exception ex) { WXPayUtil.getLogger().warn("Invalid XML, can not convert to map. Error message: {}. XML content: {}", ex.getMessage(), strXML); throw ex; } } /** * 将Map转换为XML格式的字符串 * * @param data Map类型数据 * @return XML格式的字符串 * @throws Exception */ public static String mapToXml(Map<String, String> data) throws Exception { org.w3c.dom.Document document = WXPayXmlUtil.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; } /** * 生成带有 sign 的 XML 格式字符串 * * @param data Map类型数据 * @param key API密钥 * @return 含有sign字段的XML */ public static String generateSignedXml(final Map<String, String> data, String key) throws Exception { return generateSignedXml(data, key, SignType.MD5); } /** * 生成带有 sign 的 XML 格式字符串 * * @param data Map类型数据 * @param key API密钥 * @param signType 签名类型 * @return 含有sign字段的XML */ public static String generateSignedXml(final Map<String, String> data, String key, SignType signType) throws Exception { String sign = generateSignature(data, key, signType); data.put(WXPayConstants.FIELD_SIGN, sign); return mapToXml(data); } /** * 判断签名是否正确 * * @param xmlStr XML格式数据 * @param key API密钥 * @return 签名是否正确 * @throws Exception */ public static boolean isSignatureValid(String xmlStr, String key) throws Exception { Map<String, String> data = xmlToMap(xmlStr); if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) { return false; } String sign = data.get(WXPayConstants.FIELD_SIGN); return generateSignature(data, key).equals(sign); } /** * 判断签名是否正确,必须包含sign字段,否则返回false。使用MD5签名。 * * @param data Map类型数据 * @param key API密钥 * @return 签名是否正确 * @throws Exception */ public static boolean isSignatureValid(Map<String, String> data, String key) throws Exception { return isSignatureValid(data, key, SignType.MD5); } /** * 判断签名是否正确,必须包含sign字段,否则返回false。 * * @param data Map类型数据 * @param key API密钥 * @param signType 签名方式 * @return 签名是否正确 * @throws Exception */ public static boolean isSignatureValid(Map<String, String> data, String key, SignType signType) throws Exception { if (!data.containsKey(WXPayConstants.FIELD_SIGN) ) { return false; } String sign = data.get(WXPayConstants.FIELD_SIGN); return generateSignature(data, key, signType).equals(sign); } /** * 生成签名 * * @param data 待签名数据 * @param key API密钥 * @return 签名 */ public static String generateSignature(final Map<String, String> data, String key) throws Exception { return generateSignature(data, key, SignType.MD5); } /** * 生成签名. 注意,若含有sign_type字段,必须和signType参数保持一致。 * * @param data 待签名数据 * @param key API密钥 * @param signType 签名方式 * @return 签名 */ public static String generateSignature(final Map<String, String> data, String key, SignType signType) throws Exception { Set<String> keySet = data.keySet(); String[] keyArray = keySet.toArray(new String[keySet.size()]); Arrays.sort(keyArray); StringBuilder sb = new StringBuilder(); for (String k : keyArray) { if (k.equals(WXPayConstants.FIELD_SIGN)) { continue; } if (data.get(k).trim().length() > 0) // 参数值为空,则不参与签名 sb.append(k).append("=").append(data.get(k).trim()).append("&"); } sb.append("key=").append(key); if (SignType.MD5.equals(signType)) { return MD5(sb.toString()).toUpperCase(); } else if (SignType.HMACSHA256.equals(signType)) { return HMACSHA256(sb.toString(), key); } else { throw new Exception(String.format("Invalid sign_type: %s", signType)); } } /** * 获取随机字符串 Nonce Str * * @return String 随机字符串 */ public static String generateNonceStr() { char[] nonceChars = new char[32]; for (int index = 0; index < nonceChars.length; ++index) { nonceChars[index] = SYMBOLS.charAt(RANDOM.nextInt(SYMBOLS.length())); } return new String(nonceChars); } /** * 生成 MD5 * * @param data 待处理数据 * @return MD5结果 */ public static String MD5(String data) throws Exception { MessageDigest md = MessageDigest.getInstance("MD5"); byte[] array = md.digest(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } /** * 生成 HMACSHA256 * @param data 待处理数据 * @param key 密钥 * @return 加密结果 * @throws Exception */ public static String HMACSHA256(String data, String key) throws Exception { Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA256"); sha256_HMAC.init(secret_key); byte[] array = sha256_HMAC.doFinal(data.getBytes("UTF-8")); StringBuilder sb = new StringBuilder(); for (byte item : array) { sb.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3)); } return sb.toString().toUpperCase(); } /** * 日志 * @return */ public static Logger getLogger() { Logger logger = LoggerFactory.getLogger("wxpay java sdk"); return logger; } /** * 获取当前时间戳,单位秒 * @return */ public static long getCurrentTimestamp() { return System.currentTimeMillis()/1000; } /** * 获取当前时间戳,单位毫秒 * @return */ public static long getCurrentTimestampMs() { return System.currentTimeMillis(); } } springcloud_k8s_panzhihuazhihuishequ/common/src/main/java/com/panzhihua/common/utlis/wx/WXPayXmlUtil.java
New file @@ -0,0 +1,30 @@ package com.panzhihua.common.utlis.wx; import javax.xml.XMLConstants; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.w3c.dom.Document; /** * 2018/7/3 */ public final class WXPayXmlUtil { public static DocumentBuilder newDocumentBuilder() throws ParserConfigurationException { DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); documentBuilderFactory.setFeature("http://xml.org/sax/features/external-general-entities", false); documentBuilderFactory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); documentBuilderFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); documentBuilderFactory.setXIncludeAware(false); documentBuilderFactory.setExpandEntityReferences(false); return documentBuilderFactory.newDocumentBuilder(); } public static Document newDocument() throws ParserConfigurationException { return newDocumentBuilder().newDocument(); } } springcloud_k8s_panzhihuazhihuishequ/community_backstage/src/main/java/com/panzhihua/community_backstage/api/ShopFlowerApi.java
@@ -4,6 +4,7 @@ import com.panzhihua.common.model.dtos.community.convenient.ConvenientMerchantDTO; import com.panzhihua.common.model.dtos.shop.PageComShopFlowerGoodsDTO; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.model.vos.community.convenient.ConvenientMerchantVO; import com.panzhihua.common.model.vos.shop.AddShopFlowerGoodsVO; import com.panzhihua.common.model.vos.shop.PageShopGoodsVO; import com.panzhihua.common.service.community.CommunityService; @@ -49,6 +50,12 @@ private UserService userService; @ApiOperation(value = "查询便民服务商家详情", response = ConvenientMerchantVO.class) @GetMapping("/merchant/getMerchantByUserId") public R getMerchant(@RequestParam("userId") Long userId) { return communityService.getMerchantByUserId(userId); } @ApiOperation(value = "编辑便民服务商家") @PutMapping("/merchant/put") public R putMerchant(@RequestBody @Validated(PutGroup.class) ConvenientMerchantDTO convenientMerchantDTO) { springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/api/ConvenientApi.java
@@ -369,6 +369,17 @@ } /** * 获取便民服务商家详情 * * @param userId * @return */ @GetMapping("/merchant/getMerchantByUserId") public R getMerchantByUserId(@RequestParam("userId") Long userId) { return convenientMerchantService.getMerchantByUserId(userId); } /** * 禁用/启用便民服务商家 * * @param disableOrEnableConvenientMerchantDTO springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/api/ShopFlowerApi.java
@@ -403,6 +403,30 @@ } /** * 微信支付订单回调 * * @param wxPayNotifyOrderDTO * 订单支付回调参数 */ @PostMapping("/wxOrderPayNotify") public void wxOrderPayNotify(@RequestBody WxPayNotifyOrderDTO wxPayNotifyOrderDTO) { comShopFlowerOrderService.wxOrderPayNotify(wxPayNotifyOrderDTO); } /** * 点击去支付订单 * * @param orderPayDTO * 请求参数 * @return 支付对象 */ @PostMapping("/wxPay") public R wxPay(@RequestBody OrderPayDTO orderPayDTO) { return comShopFlowerOrderService.wxPay(orderPayDTO); } /** * 统计用户订单数量 * * @param userId springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/dao/ComShopFlowerRefundOrderDAO.java
@@ -1,15 +1,29 @@ package com.panzhihua.service_community.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.panzhihua.common.model.dtos.shop.PageComOrderRefundDTO; import com.panzhihua.common.model.vos.shop.ComShopFlowerRefundOrderVO; import com.panzhihua.service_community.model.dos.ComShopFlowerRefundOrderDO; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; /** * @ClassName: ComShopFlowerRefundOrderMapper * @ClassName: ComShopFlowerRefundOrderMapper * @Author: yh * @Date: 2022/11/9 16:46 * @Description: TODO */ @Mapper public interface ComShopFlowerRefundOrderDAO extends BaseMapper<ComShopFlowerRefundOrderDO> { /** * 分页查询 * @param page * @param pageComOrderRefundDTO * @return */ IPage<ComShopFlowerRefundOrderVO> pageRefundOrder(@Param("page") Page page, @Param("pageComOrderRefundDTO") PageComOrderRefundDTO pageComOrderRefundDTO); } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/dao/ConvenientMerchantDAO.java
@@ -55,6 +55,13 @@ */ ConvenientMerchantVO selectMerchantById(@Param("merchantId") Long merchantId); /** * 根据后台用户id查询 * @param userId * @return */ ConvenientMerchantVO selectMerchantByUserId(@Param("userId") Long userId); List<ConvenientMerchantVO> selectMerchantByName(@Param("communityId") Long communityId, @Param("currentMon") String currentMon); /** springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/dos/ComShopFlowerOrderPayDO.java
@@ -8,14 +8,14 @@ import java.util.Date; /** * @ClassName: ComShopFlowerOrderPay * @ClassName: ComShopFlowerOrderPay * @Author: yh * @Date: 2022/11/9 16:46 * @Description: 花城订单支付记录表 */ @TableName(value = "com_shop_flower_order_pay") @Data public class ComShopFlowerOrderPayDO implements Serializable { public class ComShopFlowerOrderPayDO implements Serializable { private static final long serialVersionUID = 1L; /** * 主键id @@ -68,14 +68,39 @@ /** * 创建时间 */ @TableField(value = "create_at",fill = FieldFill.INSERT) @TableField(value = "create_at", fill = FieldFill.INSERT) private Date createAt; /** * 修改时间 */ @TableField(value = "update_at",fill = FieldFill.UPDATE) @TableField(value = "update_at", fill = FieldFill.UPDATE) private Date updateAt; /** * 商家id */ private Long storeId; /** * 配送方式(1.自提 2.快递) */ private Integer deliveryType; /** * 原始订单id */ private String orderId; /** * 退款订单号 */ private String refundOrderNo; /** * 退款状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中) */ private String refundStatus; /** * 类型(1.支付 2.退款 3.取消) */ private String payType; /** * 支付状态(1.未支付 2.已支付) @@ -84,4 +109,25 @@ int no = 1; int yes = 2; } /** * 退款状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中) */ public interface refundStatus { int clz = 1; int tkcg = 2; int tksb = 3; int yqx = 4; int tkz = 5; } /** * 类型(1.支付 2.退款 3.取消) */ public interface payType { int zf = 1; int tk = 2; int qx = 3; } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/model/dos/ComShopFlowerRefundOrderDO.java
@@ -114,7 +114,7 @@ private Date refundTime; /** * 处理结果 * 处理结果(1.同意 2.拒绝) */ @TableField(value = "handle_result") private String handleResult; @@ -125,4 +125,31 @@ @TableField(value = "remark") private String remark; /** * 订单状态(1.处理中 2.退款成功 3.退款失败 4.已取消 5.退款中) */ public interface status{ int clz = 1; int tkcg = 2; int tksb = 3; int yqx = 4; int kkz = 5; } /** * 删除状态(1.未删除 2.已删除) */ public interface deleteStatus { int no = 1; int yes = 2; } /** * 处理结果(1.同意 2.拒绝) */ public interface handleResult{ String agree = "1"; String refuse = "2"; } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/ComShopFlowerRefundOrderService.java
New file @@ -0,0 +1,37 @@ package com.panzhihua.service_community.service; import com.baomidou.mybatisplus.extension.service.IService; import com.panzhihua.common.model.dtos.shop.ComShopFlowerRefundOrderDTO; import com.panzhihua.common.model.dtos.shop.PageComOrderRefundDTO; import com.panzhihua.common.model.vos.R; import com.panzhihua.service_community.model.dos.ComShopFlowerRefundOrderDO; /** * @ClassName: ComShopFlowerRefundOrderService * @Author: yh * @Date: 2022/11/16 14:35 * @Description: 退款订单 */ public interface ComShopFlowerRefundOrderService extends IService<ComShopFlowerRefundOrderDO> { /** * 创建退款订单 * @param comShopFlowerRefundOrderDTO * @return */ R createRefundOrder(ComShopFlowerRefundOrderDTO comShopFlowerRefundOrderDTO); /** * 分页查询 * @param pageComOrderRefundDTO * @return */ R pageRefundOrder(PageComOrderRefundDTO pageComOrderRefundDTO); /** * 修改退款订单 * @param comShopFlowerRefundOrderDTO * @return */ R updateRefundOrder(ComShopFlowerRefundOrderDTO comShopFlowerRefundOrderDTO); } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/ConvenientMerchantService.java
@@ -146,4 +146,11 @@ * @return */ Boolean checkStoreIsValid(Long userId); /** * 根据后台用户id查询 * @param userId * @return */ R getMerchantByUserId(Long userId); } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/impl/ComShopFlowerOrderServiceImpl.java
@@ -67,21 +67,16 @@ private ComShopFlowerEvaluateDAO comShopFlowerEvaluateDAO; @Value("${min.app.isTest}") @Value("${hc_min.app.isTest}") private Boolean isTest; @Value("${min.app.appid}") @Value("${hc_min.app.appid}") private String appid; @Value("${min.app.payKey}") @Value("${hc_min.app.payKey}") private String payKey; @Value("${min.app.mchId}") @Value("${hc_min.app.mchId}") private String mchId; @Value("${min.app.notifyUrl}") @Value("${hc_min.app.notifyUrl}") private String notifyUrl; public static void main(String[] args) { BigDecimal one = BigDecimal.valueOf(Double.valueOf("1") / 100); System.out.println(); } /** * 订单预览 springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/impl/ComShopFlowerRefundOrderServiceImpl.java
New file @@ -0,0 +1,109 @@ package com.panzhihua.service_community.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.panzhihua.common.model.dtos.shop.ComShopFlowerRefundOrderDTO; import com.panzhihua.common.model.dtos.shop.PageComOrderRefundDTO; import com.panzhihua.common.model.vos.R; import com.panzhihua.common.model.vos.shop.ComShopFlowerRefundOrderVO; import com.panzhihua.common.utlis.OrderNoUtils; import com.panzhihua.common.utlis.WxPayUtils; import com.panzhihua.common.utlis.wx.WXPayUtil; import com.panzhihua.service_community.dao.ComShopFlowerOrderDAO; import com.panzhihua.service_community.dao.ComShopFlowerRefundOrderDAO; import com.panzhihua.service_community.model.dos.ComShopFlowerOrderDO; import com.panzhihua.service_community.model.dos.ComShopFlowerRefundOrderDO; import com.panzhihua.service_community.service.ComShopFlowerRefundOrderService; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.Date; import java.util.Objects; /** * @ClassName: ComShopFlowerRefundOrderServiceImpl * @Author: yh * @Date: 2022/11/16 14:36 * @Description: 退款订单 */ @Slf4j @Service public class ComShopFlowerRefundOrderServiceImpl extends ServiceImpl<ComShopFlowerRefundOrderDAO, ComShopFlowerRefundOrderDO> implements ComShopFlowerRefundOrderService { @Value("${hc_min.app.isTest}") private Boolean isTest; @Value("${hc_min.app.appid}") private String appid; @Value("${hc_min.app.payKey}") private String payKey; @Value("${hc_min.app.mchId}") private String mchId; @Value("${hc_min.app.notifyUrl}") private String notifyUrl; @Resource private ComShopFlowerOrderDAO comShopFlowerOrderDAO; @Override public R createRefundOrder(ComShopFlowerRefundOrderDTO comShopFlowerRefundOrderDTO) { ComShopFlowerRefundOrderDO comShopFlowerRefundOrderDO = new ComShopFlowerRefundOrderDO(); BeanUtils.copyProperties(comShopFlowerRefundOrderDTO, comShopFlowerRefundOrderDO); // 生成退款订单号 String refundOrderNo = OrderNoUtils.NextOrderNo(comShopFlowerRefundOrderDTO.getUserId()); comShopFlowerRefundOrderDO.setRefundOrderNo(refundOrderNo); comShopFlowerRefundOrderDO.setStatus(ComShopFlowerRefundOrderDO.status.clz); comShopFlowerRefundOrderDO.setDeleteStatus(ComShopFlowerRefundOrderDO.deleteStatus.no); this.baseMapper.insert(comShopFlowerRefundOrderDO); return R.ok(); } @Override public R pageRefundOrder(PageComOrderRefundDTO pageComOrderRefundDTO) { Page page = new Page<>(pageComOrderRefundDTO.getPageNum(), pageComOrderRefundDTO.getPageSize()); IPage<ComShopFlowerRefundOrderVO> pages = this.baseMapper.pageRefundOrder(page, pageComOrderRefundDTO); return R.ok(pages); } @Override public R updateRefundOrder(ComShopFlowerRefundOrderDTO comShopFlowerRefundOrderDTO) { ComShopFlowerRefundOrderDO comShopFlowerRefundOrderDO = this.baseMapper.selectById(comShopFlowerRefundOrderDTO.getId()); if (Objects.isNull(comShopFlowerRefundOrderDO)) { return R.fail("不存在该退款订单"); } if (ComShopFlowerRefundOrderDO.handleResult.agree.equals(comShopFlowerRefundOrderDTO.getHandleResult())) { //处理退款事宜 comShopFlowerRefundOrderDO.setRefundTime(new Date()); comShopFlowerRefundOrderDO.setHandleTime(new Date()); //微信处理退款 try { String refundNo = WXPayUtil.generateNonceStr(); ComShopFlowerOrderDO comShopFlowerOrderDO = comShopFlowerOrderDAO.selectById(comShopFlowerRefundOrderDO.getOrderId()); String refundStr = WxPayUtils.refund(appid, mchId, comShopFlowerOrderDO.getWxTardeNo(), comShopFlowerRefundOrderDO.getPayAmount(), comShopFlowerRefundOrderDO.getRefundAmount(), refundNo, isTest); log.info(refundStr); comShopFlowerRefundOrderDO.setStatus(ComShopFlowerRefundOrderDO.status.tkcg); comShopFlowerRefundOrderDO.setHandleResult(ComShopFlowerRefundOrderDO.handleResult.agree); } catch (Exception e) { log.error(e.getMessage()); e.printStackTrace(); } } else if (ComShopFlowerRefundOrderDO.handleResult.refuse.equals(comShopFlowerRefundOrderDTO.getHandleResult())) { comShopFlowerRefundOrderDO.setHandleTime(new Date()); comShopFlowerRefundOrderDO.setStatus(ComShopFlowerRefundOrderDO.status.tksb); comShopFlowerRefundOrderDO.setHandleResult(ComShopFlowerRefundOrderDO.handleResult.refuse); } this.baseMapper.updateById(comShopFlowerRefundOrderDO); return R.ok(); } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/java/com/panzhihua/service_community/service/impl/ConvenientMerchantServiceImpl.java
@@ -469,4 +469,14 @@ } return true; } @Override public R getMerchantByUserId(Long userId) { ConvenientMerchantVO convenientMerchantVO = this.baseMapper.selectMerchantByUserId(userId); if (nonNull(convenientMerchantVO)){ List<Long> serviceIds = convenientServiceCategoryDAO.selectServiceIdsForMerchant(convenientMerchantVO.getId()); convenientMerchantVO.setServiceIds(serviceIds); } return R.ok(convenientMerchantVO); } } springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/resources/mapper/ComShopFlowerOrderPayDAO.xml
@@ -14,6 +14,12 @@ <result column="pay_time" jdbcType="TIMESTAMP" property="payTime" /> <result column="create_at" jdbcType="TIMESTAMP" property="createAt" /> <result column="update_at" jdbcType="TIMESTAMP" property="updateAt" /> <result column="store_id" property="storeId" /> <result column="delivery_type" property="deliveryType" /> <result column="order_id" property="orderId" /> <result column="refund_order_no" property="refundOrderNo" /> <result column="refund_status" property="refundStatus" /> <result column="pay_type" property="payType" /> </resultMap> <sql id="Base_Column_List"> <!--@mbg.generated--> springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/resources/mapper/ComShopFlowerRefundOrderDAO.xml
@@ -29,4 +29,16 @@ pay_amount, refund_amount, refund_reason, refund_pic, create_at, update_at, handle_time, refund_time, handle_result, remark </sql> <select id="pageRefundOrder" resultType="com.panzhihua.common.model.vos.shop.ComShopFlowerRefundOrderVO"> select * from com_shop_flower_refund_order where 1=1 <if test="pageComOrderRefundDTO.status != null"> and status = #{pageComOrderRefundDTO.status} </if> <if test="pageComOrderRefundDTO.storeId != null"> and store_id = #{pageComOrderRefundDTO.storeId} </if> <if test="pageComOrderRefundDTO.userId != null"> and user_id = #{pageComOrderRefundDTO.userId} </if> </select> </mapper> springcloud_k8s_panzhihuazhihuishequ/service_community/src/main/resources/mapper/ConvenientMerchantMapper.xml
@@ -75,6 +75,13 @@ WHERE ccm.id = #{merchantId} </select> <select id="selectMerchantByUserId" resultType="com.panzhihua.common.model.vos.community.convenient.ConvenientMerchantVO"> SELECT ccm.*, su.account, su.status AS accountStatus FROM com_convenient_merchants ccm LEFT JOIN sys_user su ON ccm.user_id = su.user_id WHERE ccm.user_id = #{userId} </select> <select id="selectMerchantByName" resultType="com.panzhihua.common.model.vos.community.convenient.ConvenientMerchantVO"> SELECT temp.id,