| @@ -12,6 +12,10 @@ | |||||
| <artifactId>mallinkAdmin</artifactId> | <artifactId>mallinkAdmin</artifactId> | ||||
| <properties> | |||||
| <weixin-java-open.version>3.2.0</weixin-java-open.version> | |||||
| </properties> | |||||
| <dependencies> | <dependencies> | ||||
| <dependency> | <dependency> | ||||
| <groupId>com.iformall</groupId> | <groupId>com.iformall</groupId> | ||||
| @@ -23,6 +27,11 @@ | |||||
| <artifactId>mybatis-multi-tenancy</artifactId> | <artifactId>mybatis-multi-tenancy</artifactId> | ||||
| <version>1.0</version> | <version>1.0</version> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>com.github.binarywang</groupId> | |||||
| <artifactId>weixin-java-open</artifactId> | |||||
| <version>${weixin-java-open.version}</version> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -0,0 +1,124 @@ | |||||
| package com.iformall.config; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| import redis.clients.jedis.JedisPoolConfig; | |||||
| import redis.clients.jedis.Protocol; | |||||
| import javax.net.ssl.HostnameVerifier; | |||||
| import javax.net.ssl.SSLParameters; | |||||
| import javax.net.ssl.SSLSocketFactory; | |||||
| /** | |||||
| * Stormeye | |||||
| */ | |||||
| @ConfigurationProperties(prefix = "wechat.redis") | |||||
| public class RedisProperies extends JedisPoolConfig { | |||||
| private String host = Protocol.DEFAULT_HOST; | |||||
| private int port = Protocol.DEFAULT_PORT; | |||||
| private String password; | |||||
| private int database = 1; | |||||
| private int connectionTimeout = Protocol.DEFAULT_TIMEOUT; | |||||
| private int soTimeout = Protocol.DEFAULT_TIMEOUT; | |||||
| private String clientName; | |||||
| private boolean ssl; | |||||
| private SSLSocketFactory sslSocketFactory; | |||||
| private SSLParameters sslParameters; | |||||
| private HostnameVerifier hostnameVerifier; | |||||
| public boolean isSsl() { | |||||
| return ssl; | |||||
| } | |||||
| public void setSsl(boolean ssl) { | |||||
| this.ssl = ssl; | |||||
| } | |||||
| public SSLSocketFactory getSslSocketFactory() { | |||||
| return sslSocketFactory; | |||||
| } | |||||
| public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) { | |||||
| this.sslSocketFactory = sslSocketFactory; | |||||
| } | |||||
| public SSLParameters getSslParameters() { | |||||
| return sslParameters; | |||||
| } | |||||
| public void setSslParameters(SSLParameters sslParameters) { | |||||
| this.sslParameters = sslParameters; | |||||
| } | |||||
| public HostnameVerifier getHostnameVerifier() { | |||||
| return hostnameVerifier; | |||||
| } | |||||
| public void setHostnameVerifier(HostnameVerifier hostnameVerifier) { | |||||
| this.hostnameVerifier = hostnameVerifier; | |||||
| } | |||||
| public String getHost() { | |||||
| return host; | |||||
| } | |||||
| public void setHost(String host) { | |||||
| if (host == null || "".equals(host)) { | |||||
| host = Protocol.DEFAULT_HOST; | |||||
| } | |||||
| this.host = host; | |||||
| } | |||||
| public int getPort() { | |||||
| return port; | |||||
| } | |||||
| public void setPort(int port) { | |||||
| this.port = port; | |||||
| } | |||||
| public String getPassword() { | |||||
| return password; | |||||
| } | |||||
| public void setPassword(String password) { | |||||
| if ("".equals(password)) { | |||||
| password = null; | |||||
| } | |||||
| this.password = password; | |||||
| } | |||||
| public int getDatabase() { | |||||
| return database; | |||||
| } | |||||
| public void setDatabase(int database) { | |||||
| this.database = database; | |||||
| } | |||||
| public String getClientName() { | |||||
| return clientName; | |||||
| } | |||||
| public void setClientName(String clientName) { | |||||
| if ("".equals(clientName)) { | |||||
| clientName = null; | |||||
| } | |||||
| this.clientName = clientName; | |||||
| } | |||||
| public int getConnectionTimeout() { | |||||
| return connectionTimeout; | |||||
| } | |||||
| public void setConnectionTimeout(int connectionTimeout) { | |||||
| this.connectionTimeout = connectionTimeout; | |||||
| } | |||||
| public int getSoTimeout() { | |||||
| return soTimeout; | |||||
| } | |||||
| public void setSoTimeout(int soTimeout) { | |||||
| this.soTimeout = soTimeout; | |||||
| } | |||||
| } | |||||
| @@ -116,6 +116,7 @@ public class ShiroConfig { | |||||
| // } | // } | ||||
| filterChainDefinitionMap.put("/swagger-ui.html", "anon"); | filterChainDefinitionMap.put("/swagger-ui.html", "anon"); | ||||
| filterChainDefinitionMap.put("/wxPay/notify/**", "anon"); | filterChainDefinitionMap.put("/wxPay/notify/**", "anon"); | ||||
| filterChainDefinitionMap.put("/wxOpen/**", "anon"); | |||||
| filterChainDefinitionMap.put("/wxPayBill/notify/**", "anon"); | filterChainDefinitionMap.put("/wxPayBill/notify/**", "anon"); | ||||
| filterChainDefinitionMap.put("/v2/**", "anon"); | filterChainDefinitionMap.put("/v2/**", "anon"); | ||||
| filterChainDefinitionMap.put("/swagger-resources/**", "anon"); | filterChainDefinitionMap.put("/swagger-resources/**", "anon"); | ||||
| @@ -0,0 +1,69 @@ | |||||
| package com.iformall.config; | |||||
| import org.apache.commons.lang3.builder.ToStringBuilder; | |||||
| import org.apache.commons.lang3.builder.ToStringStyle; | |||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | |||||
| /** | |||||
| * Stormeye | |||||
| */ | |||||
| @ConfigurationProperties(prefix = "wechat.open") | |||||
| public class WechatOpenProperties { | |||||
| /** | |||||
| * 设置微信三方平台的appid | |||||
| */ | |||||
| private String componentAppId; | |||||
| /** | |||||
| * 设置微信三方平台的app secret | |||||
| */ | |||||
| private String componentSecret; | |||||
| /** | |||||
| * 设置微信三方平台的token | |||||
| */ | |||||
| private String componentToken; | |||||
| /** | |||||
| * 设置微信三方平台的EncodingAESKey | |||||
| */ | |||||
| private String componentAesKey; | |||||
| public String getComponentAppId() { | |||||
| return componentAppId; | |||||
| } | |||||
| public void setComponentAppId(String componentAppId) { | |||||
| this.componentAppId = componentAppId; | |||||
| } | |||||
| public String getComponentSecret() { | |||||
| return componentSecret; | |||||
| } | |||||
| public void setComponentSecret(String componentSecret) { | |||||
| this.componentSecret = componentSecret; | |||||
| } | |||||
| public String getComponentToken() { | |||||
| return componentToken; | |||||
| } | |||||
| public void setComponentToken(String componentToken) { | |||||
| this.componentToken = componentToken; | |||||
| } | |||||
| public String getComponentAesKey() { | |||||
| return componentAesKey; | |||||
| } | |||||
| public void setComponentAesKey(String componentAesKey) { | |||||
| this.componentAesKey = componentAesKey; | |||||
| } | |||||
| @Override | |||||
| public String toString() { | |||||
| return ToStringBuilder.reflectionToString(this, | |||||
| ToStringStyle.MULTI_LINE_STYLE); | |||||
| } | |||||
| } | |||||
| @@ -114,7 +114,7 @@ public class UploadController extends BaseController { | |||||
| @PostMapping(value = "/awsFileUpload", consumes = "multipart/*", headers = "content-type=multipart/form-data") | @PostMapping(value = "/awsFileUpload", consumes = "multipart/*", headers = "content-type=multipart/form-data") | ||||
| @ApiOperation("上传文件") | @ApiOperation("上传文件") | ||||
| public ResultData awsfileUpload(@RequestParam("file") MultipartFile multiReq) { | public ResultData awsfileUpload(@RequestParam("file") MultipartFile multiReq) { | ||||
| logger.debug("[" + getIpAddr() + "] UploadController::awsfileUpload"); | |||||
| logger.info("[" + getIpAddr() + "] UploadController::awsfileUpload"); | |||||
| ResultData data = new ResultData(); | ResultData data = new ResultData(); | ||||
| @@ -141,7 +141,12 @@ public class UploadController extends BaseController { | |||||
| .build(); | .build(); | ||||
| String fileName = UUID.randomUUID().toString(); | String fileName = UUID.randomUUID().toString(); | ||||
| int dot = multiReq.getOriginalFilename().lastIndexOf('.'); | int dot = multiReq.getOriginalFilename().lastIndexOf('.'); | ||||
| fileName = getTenantId() + "/" + fileName + multiReq.getOriginalFilename().substring(dot, multiReq.getOriginalFilename().length()); | |||||
| if (dot >= 0) { | |||||
| fileName = getTenantId() + "/" + fileName + multiReq.getOriginalFilename().substring(dot, multiReq.getOriginalFilename().length()); | |||||
| } else { | |||||
| fileName = getTenantId() + "/" + fileName; | |||||
| } | |||||
| s3.putObject( | s3.putObject( | ||||
| new PutObjectRequest(awsProperty.getBucketName(), fileName, multiReq.getInputStream(), metadata) | new PutObjectRequest(awsProperty.getBucketName(), fileName, multiReq.getInputStream(), metadata) | ||||
| @@ -0,0 +1,72 @@ | |||||
| package com.iformall.controller; | |||||
| import com.iformall.service.WxOpenService; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult; | |||||
| import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.stereotype.Controller; | |||||
| import org.springframework.web.bind.annotation.GetMapping; | |||||
| import org.springframework.web.bind.annotation.RequestMapping; | |||||
| import org.springframework.web.bind.annotation.RequestParam; | |||||
| import org.springframework.web.bind.annotation.ResponseBody; | |||||
| import javax.servlet.http.HttpServletRequest; | |||||
| import javax.servlet.http.HttpServletResponse; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * Stormeye Wu | |||||
| */ | |||||
| @Controller | |||||
| @RequestMapping("/wtauth") | |||||
| public class WechatApiController { | |||||
| private final Logger logger = LoggerFactory.getLogger(getClass()); | |||||
| @Autowired | |||||
| private WxOpenService wxOpenService; | |||||
| @GetMapping("/goto_auth_url_show") | |||||
| @ResponseBody | |||||
| public String gotoPreAuthUrlShow() { | |||||
| return "<a href='goto_auth_url'>go</a>"; | |||||
| } | |||||
| @GetMapping("/goto_auth_url") | |||||
| public void gotoPreAuthUrl(HttpServletRequest request, HttpServletResponse response) { | |||||
| String host = request.getHeader("host"); | |||||
| String url = "http://" + host + "/api/auth/jump"; | |||||
| try { | |||||
| url = wxOpenService.getWxOpenComponentService().getPreAuthUrl(url); | |||||
| response.sendRedirect(url); | |||||
| } catch (WxErrorException | IOException e) { | |||||
| logger.error("gotoPreAuthUrl", e); | |||||
| throw new RuntimeException(e); | |||||
| } | |||||
| } | |||||
| @GetMapping("/jump") | |||||
| @ResponseBody | |||||
| public WxOpenQueryAuthResult jump(@RequestParam("auth_code") String authorizationCode) { | |||||
| try { | |||||
| WxOpenQueryAuthResult queryAuthResult = wxOpenService.getWxOpenComponentService().getQueryAuth(authorizationCode); | |||||
| logger.info("getQueryAuth", queryAuthResult); | |||||
| return queryAuthResult; | |||||
| } catch (WxErrorException e) { | |||||
| logger.error("gotoPreAuthUrl", e); | |||||
| throw new RuntimeException(e); | |||||
| } | |||||
| } | |||||
| @GetMapping("/get_authorizer_info") | |||||
| @ResponseBody | |||||
| public WxOpenAuthorizerInfoResult getAuthorizerInfo(@RequestParam String appId) { | |||||
| try { | |||||
| return wxOpenService.getWxOpenComponentService().getAuthorizerInfo(appId); | |||||
| } catch (WxErrorException e) { | |||||
| logger.error("getAuthorizerInfo", e); | |||||
| throw new RuntimeException(e); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,108 @@ | |||||
| package com.iformall.controller; | |||||
| import com.iformall.service.WxOpenService; | |||||
| import me.chanjar.weixin.common.error.WxErrorException; | |||||
| import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage; | |||||
| import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; | |||||
| import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; | |||||
| import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.web.bind.annotation.*; | |||||
| @RestController | |||||
| @RequestMapping("wxOpen") | |||||
| public class WechatCalllbackController extends BaseController { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| protected WxOpenService wxOpenService; | |||||
| @RequestMapping("/notify") | |||||
| public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp, | |||||
| @RequestParam("nonce") String nonce, @RequestParam("signature") String signature, | |||||
| @RequestParam(name = "encrypt_type", required = false) String encType, | |||||
| @RequestParam(name = "msg_signature", required = false) String msgSignature) { | |||||
| logger.info( | |||||
| "\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}]," | |||||
| + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", | |||||
| signature, encType, msgSignature, timestamp, nonce, requestBody); | |||||
| if (!StringUtils.equalsIgnoreCase("aes", encType) | |||||
| || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { | |||||
| throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); | |||||
| } | |||||
| // aes加密的消息 | |||||
| WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody, | |||||
| wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); | |||||
| this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); | |||||
| try { | |||||
| String out = wxOpenService.getWxOpenComponentService().route(inMessage); | |||||
| this.logger.debug("\n组装回复信息:{}", out); | |||||
| } catch (WxErrorException e) { | |||||
| this.logger.error("notify", e); | |||||
| } | |||||
| return "success"; | |||||
| } | |||||
| @RequestMapping("callback/{appId}") | |||||
| public Object callback(@RequestBody(required = false) String requestBody, | |||||
| @PathVariable("appId") String appId, | |||||
| @RequestParam("signature") String signature, | |||||
| @RequestParam("timestamp") String timestamp, | |||||
| @RequestParam("nonce") String nonce, | |||||
| @RequestParam("openid") String openid, | |||||
| @RequestParam("encrypt_type") String encType, | |||||
| @RequestParam("msg_signature") String msgSignature) { | |||||
| logger.info( | |||||
| "\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}]," | |||||
| + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", | |||||
| appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody); | |||||
| if (!StringUtils.equalsIgnoreCase("aes", encType) | |||||
| || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) { | |||||
| throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); | |||||
| } | |||||
| String out = ""; | |||||
| // aes加密的消息 | |||||
| WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody, | |||||
| wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature); | |||||
| this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); | |||||
| // 全网发布测试用例 | |||||
| if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) { | |||||
| try { | |||||
| if (StringUtils.equals(inMessage.getMsgType(), "text")) { | |||||
| if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) { | |||||
| out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml( | |||||
| WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback") | |||||
| .fromUser(inMessage.getToUser()) | |||||
| .toUser(inMessage.getFromUser()) | |||||
| .build(), | |||||
| wxOpenService.getWxOpenConfigStorage() | |||||
| ); | |||||
| } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) { | |||||
| String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api"; | |||||
| WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build(); | |||||
| wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); | |||||
| } | |||||
| } else if (StringUtils.equals(inMessage.getMsgType(), "event")) { | |||||
| WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build(); | |||||
| wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage); | |||||
| } | |||||
| } catch (WxErrorException e) { | |||||
| logger.error("callback", e); | |||||
| } | |||||
| } else { | |||||
| WxMpXmlOutMessage outMessage = wxOpenService.getWxOpenMessageRouter().route(inMessage, appId); | |||||
| if (outMessage != null) { | |||||
| out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage()); | |||||
| } | |||||
| } | |||||
| return out; | |||||
| } | |||||
| } | |||||
| @@ -1,6 +1,7 @@ | |||||
| package com.iformall.controller; | package com.iformall.controller; | ||||
| import com.alibaba.fastjson.JSON; | import com.alibaba.fastjson.JSON; | ||||
| import com.alibaba.fastjson.JSONArray; | |||||
| import com.alibaba.fastjson.JSONObject; | import com.alibaba.fastjson.JSONObject; | ||||
| import com.iformall.common.ErrorCode; | import com.iformall.common.ErrorCode; | ||||
| import com.iformall.common.ResultData; | import com.iformall.common.ResultData; | ||||
| @@ -9,6 +10,7 @@ import com.iformall.domain.po.*; | |||||
| import com.iformall.domain.vo.WxCouponCarVo; | import com.iformall.domain.vo.WxCouponCarVo; | ||||
| import com.iformall.enums.EnumCarVendor; | import com.iformall.enums.EnumCarVendor; | ||||
| import com.iformall.enums.EnumCouponStatus; | import com.iformall.enums.EnumCouponStatus; | ||||
| import com.iformall.enums.EnumETCPCode; | |||||
| import com.iformall.service.*; | import com.iformall.service.*; | ||||
| import com.iformall.utils.ETCPUtil; | import com.iformall.utils.ETCPUtil; | ||||
| import com.iformall.utils.TJDCarUtil; | import com.iformall.utils.TJDCarUtil; | ||||
| @@ -334,5 +336,58 @@ public class WxCarController extends BaseController { | |||||
| } | } | ||||
| @ApiOperation(value = "停车场状态") | |||||
| @GetMapping("/getParkStatus") | |||||
| public ResultData getParkStatus() { | |||||
| MallUserInfo user = getUser(); | |||||
| /// 1, get mall's park | |||||
| WxPark park = getCurrentPark(user); | |||||
| if (park.getVendorType() == EnumCarVendor.CAR_ETCP.getCode()) { | |||||
| String params = park.getVendorParams(); | |||||
| JSONObject objParams = JSON.parseObject(params); | |||||
| String url = objParams.getString("url"); | |||||
| String merchantNo = objParams.getString("merchantNo"); | |||||
| String merchantKey = objParams.getString("merchantKey"); | |||||
| String version = objParams.getString("version"); | |||||
| if (park.getParkingId() == null) { | |||||
| String lat = objParams.getString("lat"); | |||||
| String lon = objParams.getString("lon"); | |||||
| String radius = objParams.getString("radius"); | |||||
| String ret = etcp.parkingInfo(url, merchantNo, merchantKey, version, lat, lon, radius); | |||||
| logger.info(ret); | |||||
| JSONObject retObj = JSON.parseObject(ret); | |||||
| if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) { | |||||
| JSONObject retData = retObj.getJSONObject("data"); | |||||
| if (retData != null) { | |||||
| JSONArray retDataList = retData.getJSONArray("list"); | |||||
| if (retDataList != null) { | |||||
| JSONObject parkData = retDataList.getJSONObject(0); | |||||
| if (parkData != null) { | |||||
| String parkId = parkData.getString("id"); | |||||
| objParams.put("parkId", parkId); | |||||
| params = JSON.toJSONString(objParams); | |||||
| park.setVendorParams(params); | |||||
| park.setParkingId(parkId); | |||||
| wxParkService.saveOrUpdate(park); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| if (park.getParkingId() != null) { | |||||
| String ret = etcp.parkingStatus(url, merchantNo, merchantKey, version, park.getParkingId()); | |||||
| JSONObject retObj = JSON.parseObject(ret); | |||||
| if (retObj.getIntValue("code") == EnumETCPCode.SUCCESS.getCode()) { | |||||
| if (retObj.get("data") != null) { | |||||
| return new ResultData(retObj.getJSONObject("data")); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| return new ResultData(ErrorCode.CAR_VENDOR_NOT_SUPPORT.getCode(), "车场不支持"); | |||||
| } | |||||
| } | } | ||||
| @@ -9,6 +9,7 @@ import com.iformall.domain.po.WxCoupon; | |||||
| import com.iformall.domain.po.WxCouponChannel; | import com.iformall.domain.po.WxCouponChannel; | ||||
| import com.iformall.domain.po.WxMerchant; | import com.iformall.domain.po.WxMerchant; | ||||
| import com.iformall.enums.EnumCouponStatus; | import com.iformall.enums.EnumCouponStatus; | ||||
| import com.iformall.enums.EnumCouponValidType; | |||||
| import com.iformall.enums.EnumMerchantStatus; | import com.iformall.enums.EnumMerchantStatus; | ||||
| import com.iformall.service.WxCouponChannelService; | import com.iformall.service.WxCouponChannelService; | ||||
| import com.iformall.service.WxCouponService; | import com.iformall.service.WxCouponService; | ||||
| @@ -119,6 +120,12 @@ public class WxCouponController extends BaseController { | |||||
| } | } | ||||
| wxCoupon.setTenantId(getUser().getTenantId()); | wxCoupon.setTenantId(getUser().getTenantId()); | ||||
| wxCoupon.setChannels(""); | wxCoupon.setChannels(""); | ||||
| if (wxCoupon.getValidType().equals(EnumCouponValidType.DAYS_AFTER_RECEIVING)) { | |||||
| wxCoupon.setValidStartDate(null); | |||||
| wxCoupon.setValidEndDate(null); | |||||
| } else if (wxCoupon.getValidType().equals(EnumCouponValidType.BETWEEN_TWO_TIME)) { | |||||
| wxCoupon.setValidDays(null); | |||||
| } | |||||
| Long id = wxCouponService.saveOrUpdate(wxCoupon); | Long id = wxCouponService.saveOrUpdate(wxCoupon); | ||||
| return new ResultData(id); | return new ResultData(id); | ||||
| } | } | ||||
| @@ -134,6 +141,12 @@ public class WxCouponController extends BaseController { | |||||
| String[] arys = wxCoupon.getBusiness().split(","); | String[] arys = wxCoupon.getBusiness().split(","); | ||||
| wxCoupon.setBusiness(JSON.toJSONString(arys)); | wxCoupon.setBusiness(JSON.toJSONString(arys)); | ||||
| } | } | ||||
| if (wxCoupon.getValidType().equals(EnumCouponValidType.DAYS_AFTER_RECEIVING)) { | |||||
| wxCoupon.setValidStartDate(null); | |||||
| wxCoupon.setValidEndDate(null); | |||||
| } else if (wxCoupon.getValidType().equals(EnumCouponValidType.BETWEEN_TWO_TIME)) { | |||||
| wxCoupon.setValidDays(null); | |||||
| } | |||||
| return wxCouponService.updateCoupon(wxCoupon); | return wxCouponService.updateCoupon(wxCoupon); | ||||
| } | } | ||||
| @@ -0,0 +1,65 @@ | |||||
| package com.iformall.service; | |||||
| import com.iformall.config.RedisProperies; | |||||
| import com.iformall.config.WechatOpenProperties; | |||||
| import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage; | |||||
| import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter; | |||||
| import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.boot.context.properties.EnableConfigurationProperties; | |||||
| import org.springframework.stereotype.Service; | |||||
| import redis.clients.jedis.JedisPool; | |||||
| import javax.annotation.PostConstruct; | |||||
| /** | |||||
| * @author <a href="https://github.com/007gzs">007</a> | |||||
| */ | |||||
| @Service | |||||
| @EnableConfigurationProperties({WechatOpenProperties.class, RedisProperies.class}) | |||||
| public class WxOpenService extends WxOpenServiceImpl { | |||||
| private Logger logger = LoggerFactory.getLogger(getClass()); | |||||
| @Autowired | |||||
| private WechatOpenProperties wechatOpenProperties; | |||||
| @Autowired | |||||
| private RedisProperies redisProperies; | |||||
| private static JedisPool pool; | |||||
| private WxOpenMessageRouter wxOpenMessageRouter; | |||||
| @PostConstruct | |||||
| public void init() { | |||||
| WxOpenInRedisConfigStorage inRedisConfigStorage = new WxOpenInRedisConfigStorage(getJedisPool()); | |||||
| inRedisConfigStorage.setComponentAppId(wechatOpenProperties.getComponentAppId()); | |||||
| inRedisConfigStorage.setComponentAppSecret(wechatOpenProperties.getComponentSecret()); | |||||
| inRedisConfigStorage.setComponentToken(wechatOpenProperties.getComponentToken()); | |||||
| inRedisConfigStorage.setComponentAesKey(wechatOpenProperties.getComponentAesKey()); | |||||
| setWxOpenConfigStorage(inRedisConfigStorage); | |||||
| wxOpenMessageRouter = new WxOpenMessageRouter(this); | |||||
| wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> { | |||||
| logger.info("\n接收到 {} 公众号请求消息,内容:{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage); | |||||
| return null; | |||||
| }).next(); | |||||
| } | |||||
| public WxOpenMessageRouter getWxOpenMessageRouter() { | |||||
| return wxOpenMessageRouter; | |||||
| } | |||||
| private JedisPool getJedisPool() { | |||||
| if (pool == null) { | |||||
| synchronized (WxOpenService.class) { | |||||
| if (pool == null) { | |||||
| pool = new JedisPool(redisProperies, redisProperies.getHost(), | |||||
| redisProperies.getPort(), redisProperies.getConnectionTimeout(), | |||||
| redisProperies.getSoTimeout(), redisProperies.getPassword(), | |||||
| redisProperies.getDatabase(), redisProperies.getClientName(), | |||||
| redisProperies.isSsl(), redisProperies.getSslSocketFactory(), | |||||
| redisProperies.getSslParameters(), redisProperies.getHostnameVerifier()); | |||||
| } | |||||
| } | |||||
| } | |||||
| return pool; | |||||
| } | |||||
| } | |||||
| @@ -67,6 +67,27 @@ aws: | |||||
| access: ENC(3gx5ghDFBqGrEhO3Wf8aYmXsnwHO7Cj3HNKJGOeUj0o=) | access: ENC(3gx5ghDFBqGrEhO3Wf8aYmXsnwHO7Cj3HNKJGOeUj0o=) | ||||
| secret: ENC(HVKIJwCJKVXLlUpGlQPwNqJOlnpxn4xYuy91SH0seTSm2uAttIQHvA49fXWWax90v5wloIk0QuU=) | secret: ENC(HVKIJwCJKVXLlUpGlQPwNqJOlnpxn4xYuy91SH0seTSm2uAttIQHvA49fXWWax90v5wloIk0QuU=) | ||||
| wechat: | |||||
| open: | |||||
| componentAppId: "wx897e4673286c915d" | |||||
| componentSecret: "cdfdfda65c45689beb6766c4c427eed2" | |||||
| componentToken: "formall2018" | |||||
| componentAesKey: "htKq8EjBMPNndfZQK9JiFojFaqFwFpw42VfeWFtx7HN" | |||||
| redis: | |||||
| host: 202.165.179.86 | |||||
| port: 6379 | |||||
| password: ENC(aYJ3Wr2UWtkORRQjjrWWpz2ZeTISsHOA) | |||||
| timeout: 3600 | |||||
| expire: 1800 #30分钟 | |||||
| database: 1 | |||||
| defaultExpiration: 2592000 # 默认生命周期30天 | |||||
| jedis: | |||||
| pool: | |||||
| max-active: 100 | |||||
| max-idle: 500 | |||||
| max-wait: -1 | |||||
| min-idle: 10 | |||||
| jasypt: | jasypt: | ||||
| encryptor: | encryptor: | ||||
| password: oRqdnDbK5pj3eMmB | password: oRqdnDbK5pj3eMmB | ||||
| @@ -1,9 +1,12 @@ | |||||
| package com.iformall.domain.po; | package com.iformall.domain.po; | ||||
| import software.amazon.ion.Decimal; | |||||
| import javax.persistence.Id; | import javax.persistence.Id; | ||||
| import javax.persistence.Table; | import javax.persistence.Table; | ||||
| import javax.persistence.Transient; | import javax.persistence.Transient; | ||||
| import java.io.Serializable; | import java.io.Serializable; | ||||
| import java.math.BigDecimal; | |||||
| import java.text.DecimalFormat; | import java.text.DecimalFormat; | ||||
| import java.util.Date; | import java.util.Date; | ||||
| import java.util.List; | import java.util.List; | ||||
| @@ -298,8 +301,7 @@ public class WxCoupon implements Serializable { | |||||
| public String getUsePriceStr() { | public String getUsePriceStr() { | ||||
| if(usePrice!=null) { | if(usePrice!=null) { | ||||
| DecimalFormat df=new DecimalFormat("0.00"); | |||||
| usePriceStr = df.format((float)usePrice/100); | |||||
| usePriceStr = new BigDecimal(usePrice).divide(new BigDecimal(100)).toString(); | |||||
| } | } | ||||
| return usePriceStr; | return usePriceStr; | ||||
| } | } | ||||
| @@ -310,8 +312,7 @@ public class WxCoupon implements Serializable { | |||||
| public String getPriceStr() { | public String getPriceStr() { | ||||
| if(price!=null) { | if(price!=null) { | ||||
| DecimalFormat df=new DecimalFormat("0.00"); | |||||
| priceStr = df.format((float)price/100); | |||||
| priceStr = new BigDecimal(price).divide(new BigDecimal(100)).toString(); | |||||
| } | } | ||||
| return priceStr; | return priceStr; | ||||
| } | } | ||||
| @@ -616,18 +616,16 @@ public class DataTowerServiceImpl implements DataTowerService { | |||||
| @Override | @Override | ||||
| public Map<String, Object> queryCustomer(String tenantId) { | public Map<String, Object> queryCustomer(String tenantId) { | ||||
| WxWiWideInfo wiWideInfo = new WxWiWideInfo(); | WxWiWideInfo wiWideInfo = new WxWiWideInfo(); | ||||
| wiWideInfo.setTenantId(tenantId); | wiWideInfo.setTenantId(tenantId); | ||||
| List<WxWiWideInfo> list = wxWiwideInfoMapper.findList(wiWideInfo); | List<WxWiWideInfo> list = wxWiwideInfoMapper.findList(wiWideInfo); | ||||
| wiWideInfo = list.get(0); | |||||
| String wiwideUrl = wiWideInfo.getWiwideUrl(); | |||||
| Map<String, Object> datamap = new HashMap<>(2); | Map<String, Object> datamap = new HashMap<>(2); | ||||
| datamap.put("token", getWiwideToken(wiWideInfo)); | |||||
| datamap.put("url", wiwideUrl); | |||||
| if(list.size()>0){ | |||||
| wiWideInfo = list.get(0); | |||||
| String wiwideUrl = wiWideInfo.getWiwideUrl(); | |||||
| datamap.put("token", getWiwideToken(wiWideInfo)); | |||||
| datamap.put("url", wiwideUrl); | |||||
| } | |||||
| return datamap; | return datamap; | ||||
| } | } | ||||
| @@ -95,7 +95,7 @@ public class PushLimitServiceImpl implements PushLimitService { | |||||
| // 2. check time | // 2. check time | ||||
| boolean isInDate = DateUtils.isInDate(curDate, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | boolean isInDate = DateUtils.isInDate(curDate, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | ||||
| if (!isInDate) { | if (!isInDate) { | ||||
| logger.error("短信已达到每天上限"); | |||||
| logger.error("不在疲劳度允许的时间段"); | |||||
| throw new MallinkException(ErrorCode.PUSH_LIMIT_NOT_INRANG); | throw new MallinkException(ErrorCode.PUSH_LIMIT_NOT_INRANG); | ||||
| } | } | ||||
| return isInDate; | return isInDate; | ||||
| @@ -109,7 +109,7 @@ public class PushLimitServiceImpl implements PushLimitService { | |||||
| // 2. check time | // 2. check time | ||||
| boolean isInDate = DateUtils.isInDate(curDate, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | boolean isInDate = DateUtils.isInDate(curDate, pushLimit.getTimeStart(), pushLimit.getTimeEnd()); | ||||
| if (!isInDate) { | if (!isInDate) { | ||||
| logger.error("短信已达到每天上限"); | |||||
| logger.error("不在疲劳度允许的时间段"); | |||||
| throw new MallinkException(ErrorCode.PUSH_LIMIT_NOT_INRANG); | throw new MallinkException(ErrorCode.PUSH_LIMIT_NOT_INRANG); | ||||
| } | } | ||||
| // TODO 3. check phone had up to limit | // TODO 3. check phone had up to limit | ||||