diff --git a/user-service/pom.xml b/user-service/pom.xml index 6b4935d..cdbff64 100644 --- a/user-service/pom.xml +++ b/user-service/pom.xml @@ -16,7 +16,6 @@ 1.8 - Hoxton.SR3 @@ -186,18 +185,15 @@ 3.2.1 + + + com.github.binarywang + weixin-java-mp + 4.6.7.B + + + - - - - org.springframework.cloud - spring-cloud-dependencies - ${spring-cloud.version} - pom - import - - - diff --git a/user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java b/user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java index f6074d8..bda0bd8 100644 --- a/user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java +++ b/user-service/src/main/java/com/mh/user/config/RestTemplateConfig.java @@ -1,14 +1,21 @@ package com.mh.user.config; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.web.client.RestTemplate; /** * @author ljf * @title : - * @description : redis配置 + * @description : 缓存配置 * @updateTime 2020-08-20 * @throws : */ @Configuration public class RestTemplateConfig { + + @Bean + public RestTemplate restTemplate() { + return new RestTemplate(); + } } diff --git a/user-service/src/main/java/com/mh/user/config/WebSecurityConfig.java b/user-service/src/main/java/com/mh/user/config/WebSecurityConfig.java index 6732f53..637a2f6 100644 --- a/user-service/src/main/java/com/mh/user/config/WebSecurityConfig.java +++ b/user-service/src/main/java/com/mh/user/config/WebSecurityConfig.java @@ -42,36 +42,36 @@ public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { // 禁用 csrf, 由于使用的是JWT,我们这里不需要csrf - System.out.println("test0"); - http.cors().and().csrf().disable() - .authorizeRequests() - // 跨域预检请求 - .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() - // web jars - .antMatchers("/webjars/**").permitAll() - // 查看SQL监控(druid) - .antMatchers("/druid/**").permitAll() - // 首页和登录页面 - .antMatchers("/").permitAll() - .antMatchers("/login").permitAll() - // swagger - .antMatchers("/swagger-ui.html").permitAll() - .antMatchers("/swagger-resources/**").permitAll() - .antMatchers("/v2/api-docs").permitAll() - .antMatchers("/webjars/springfox-swagger-ui/**").permitAll() - // 验证码 - .antMatchers("/captcha.jpg**").permitAll() - // 服务监控 - .antMatchers("/actuator/**").permitAll() - // 其他所有请求需要身份认证 - .anyRequest().authenticated(); - // 退出登录处理器 - http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); - // token验证过滤器 - http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); - System.out.println("test0_1"); +// System.out.println("test0"); +// http.cors().and().csrf().disable() +// .authorizeRequests() +// // 跨域预检请求 +// .antMatchers(HttpMethod.OPTIONS, "/**").permitAll() +// // web jars +// .antMatchers("/webjars/**").permitAll() +// // 查看SQL监控(druid) +// .antMatchers("/druid/**").permitAll() +// // 首页和登录页面 +// .antMatchers("/").permitAll() +// .antMatchers("/login").permitAll() +// // swagger +// .antMatchers("/swagger-ui.html").permitAll() +// .antMatchers("/swagger-resources/**").permitAll() +// .antMatchers("/v2/api-docs").permitAll() +// .antMatchers("/webjars/springfox-swagger-ui/**").permitAll() +// // 验证码 +// .antMatchers("/captcha.jpg**").permitAll() +// // 服务监控 +// .antMatchers("/actuator/**").permitAll() +// // 其他所有请求需要身份认证 +// .anyRequest().authenticated(); +// // 退出登录处理器 +// http.logout().logoutSuccessHandler(new HttpStatusReturningLogoutSuccessHandler()); +// // token验证过滤器 +// http.addFilterBefore(new JwtAuthenticationFilter(authenticationManager()), UsernamePasswordAuthenticationFilter.class); +// System.out.println("test0_1"); // 禁用token验证 -// http.csrf().disable().authorizeRequests().anyRequest().permitAll().and().logout().permitAll(); + http.csrf().disable().authorizeRequests().anyRequest().permitAll().and().logout().permitAll(); } @Bean diff --git a/user-service/src/main/java/com/mh/user/config/wechat/WechatMpConfig.java b/user-service/src/main/java/com/mh/user/config/wechat/WechatMpConfig.java new file mode 100644 index 0000000..2411235 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/config/wechat/WechatMpConfig.java @@ -0,0 +1,94 @@ +package com.mh.user.config.wechat; + +import me.chanjar.weixin.mp.api.WxMpService; +import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl; +import me.chanjar.weixin.mp.config.WxMpConfigStorage; +import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.stereotype.Component; + +import java.net.URLEncoder; + +/** + * @author chison + * @date 2020-04-03 15:42 + * @Description 微信网页授权信息配置类 + */ +@Component +@Configuration +public class WechatMpConfig { + + @Value("${wechat.mpAppId}") + private String mpAppId; + @Value("${wechat.mpAppSecret}") + private String mpAppSecret; + @Value("${wechat.redirectUri}") + private String redirectUri; + @Value("${wechat.authorizedUrl}") + private String authorizedUrl; + @Value("${wechat.access_token}") + private String accessToken; + @Value("${wechat.userinfo}") + private String userinfo; + @Value("${wechat.pushUrl}") + private String pushUrl; + @Value("${wechat.baseUrl}") + private String baseUrl; + + public String getBaseUrl() { + return baseUrl; + } + + public void setBaseUrl(String baseUrl) { + this.baseUrl = baseUrl; + } + + public String getAuthorizedUrl() { + return authorizedUrl.replace("mpAppId", mpAppId).replace("REDIRECT_URI", URLEncoder.encode(redirectUri)); + } + + public String getAccessTokenUrl() { + return accessToken.replace("APPID", mpAppId).replace("SECRET", mpAppSecret); + } + + public String getUserInfo(String accessToken, String openId) { + return userinfo.replace("ACCESS_TOKEN", accessToken).replace("OPENID", openId); + } + + public String getPushMsgUrl(String accessToken) { + return pushUrl.replace("ACCESS_TOKEN", accessToken); + } + + public String getMpAppId() { + return mpAppId; + } + + public String getMpAppSecret() { + return mpAppSecret; + } + + /** + * 配置WxMpService所需信息 + * + * @return + */ + @Bean // 此注解指定在Spring容器启动时,就执行该方法并将该方法返回的对象交由Spring容器管理 + public WxMpService wxMpService() { + WxMpService wxMpService = new WxMpServiceImpl(); + // 设置配置信息的存储位置 + wxMpService.setWxMpConfigStorage(wxMpConfigStorage()); + + return wxMpService; + } + + public WxMpConfigStorage wxMpConfigStorage() { + // 使用这个实现类则表示将配置信息存储在内存中 + WxMpDefaultConfigImpl wxMpInMemoryConfigStorage = new WxMpDefaultConfigImpl(); + wxMpInMemoryConfigStorage.setAppId(getMpAppId()); + wxMpInMemoryConfigStorage.setSecret(getMpAppSecret()); + + return wxMpInMemoryConfigStorage; + } +} diff --git a/user-service/src/main/java/com/mh/user/config/wechat/WechatSignUtil.java b/user-service/src/main/java/com/mh/user/config/wechat/WechatSignUtil.java new file mode 100644 index 0000000..ae78415 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/config/wechat/WechatSignUtil.java @@ -0,0 +1,62 @@ +package com.mh.user.config.wechat; + +import lombok.extern.slf4j.Slf4j; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; +import java.util.Map; +import java.util.TreeMap; + +/** + * @Author : Rainbow + * @date : 2024-09-14 + */ +@Slf4j +public class WechatSignUtil { + + /** + * SHA-1加密 + * @param params + * @return + */ + public static String generateSignature(Map params) { + // 使用TreeMap进行自然排序(按照key的ASCII码排序) + TreeMap sortedParams = new TreeMap<>(params); + + // 拼接字符串 + StringBuilder stringBuilder = new StringBuilder(); + for (Map.Entry entry : sortedParams.entrySet()) { + if (stringBuilder.length() > 0) { + stringBuilder.append("&"); + } + stringBuilder.append(entry.getKey()).append("=").append(entry.getValue()); + } + String string1 = stringBuilder.toString(); + + // SHA-1加密 + try { + // 获取SHA-1实例 + MessageDigest digest = MessageDigest.getInstance("SHA-1"); + + // 将输入字符串转换为字节数组 + byte[] encodedHash = digest.digest(string1.getBytes()); + + // 可选:将字节数组转换为Base64字符串,便于显示和传输 + String base64Encoded = Base64.getEncoder().encodeToString(encodedHash); + log.info("SHA-1 (Base64 Encoded): {}", base64Encoded); + + // 或者,直接以16进制形式输出 + StringBuilder hexString = new StringBuilder(); + for (byte b : encodedHash) { + String hex = Integer.toHexString(0xff & b); + if(hex.length() == 1) hexString.append('0'); + hexString.append(hex); + } + log.info("SHA-1 (Hexadecimal): {}", hexString); + return hexString.toString(); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("SHA-1 algorithm not found", e); + } + } +} diff --git a/user-service/src/main/java/com/mh/user/controller/wechat/WechatController.java b/user-service/src/main/java/com/mh/user/controller/wechat/WechatController.java new file mode 100644 index 0000000..b55932a --- /dev/null +++ b/user-service/src/main/java/com/mh/user/controller/wechat/WechatController.java @@ -0,0 +1,119 @@ +package com.mh.user.controller.wechat; + +import com.alibaba.fastjson2.JSONObject; +import com.github.benmanes.caffeine.cache.Cache; +import com.mh.user.config.wechat.WechatMpConfig; +import com.mh.user.service.wechat.WechatUserInfoService; +import com.mh.user.utils.CacheUtil; +import com.mh.user.utils.SignUtil; +import lombok.extern.slf4j.Slf4j; +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 org.springframework.web.client.RestTemplate; + +import java.util.concurrent.TimeUnit; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信相关接口 + * @date 2024-11-27 15:37:57 + */ +@Slf4j +@Controller +@RequestMapping("/wechat") +public class WechatController { + + @Autowired + private WechatMpConfig wechatMpConfig; + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private WechatUserInfoService wechatUserInfoService; + + /** + * 微信校验 + * + * @param signature + * @param timestamp + * @param nonce + * @param echostr + * @return + */ + @GetMapping("/checkToken") + @ResponseBody + public String checkSignature(@RequestParam("signature") String signature, + @RequestParam("timestamp") String timestamp, + @RequestParam("nonce") String nonce, + @RequestParam("echostr") String echostr) { + if (SignUtil.checkSignature(signature, timestamp, nonce)) { + return echostr; + } else { + return null; + } + } + + @GetMapping("/authorize") + @ResponseBody + public String authorize() { + log.info("进入authorize,redirect:{}", wechatMpConfig.getAuthorizedUrl()); + return "redirect:" + wechatMpConfig.getAuthorizedUrl(); + } + + @GetMapping("/userInfo") + @ResponseBody + public String userInfo(@RequestParam("code") String code, @RequestParam("state") String returnUrl) { + try { + // {"access_token":"86_OnLuaNu9da1Xeh3Q4PE77sLaX_CQQFNY5rvnWTK6o_-vhIeb74rydT93HCowiVKkYUAWPG8186mvQaP55Cy47Xtuo4EkqOSyiagyW1q4mVU","expires_in":7200,"refresh_token":"86_6YSDe0P0KkFnJH0KnJzvtodh9z62GdDbdl8aG-VF7Rn46DKsWvQOuES3EluhDUQ38uUboZNr9a5wU9LvoI9HDqhkWm9hoE-1T8vUPfjoLhc","openid":"o0qeN5lw4JquQy_H9Rk5QN-CyMRU","scope":"snsapi_userinfo"} + // 判断cache中是否存在access_token +// CacheUtil instance = CacheUtil.getInstance(); +// Cache cache = instance.getCache("accessToken"); + String accessToken = ""; + String openId = ""; +// if (cache != null ) { +// log.info("cache中存在access_token,直接使用"); +// accessToken = cache.getIfPresent("accessToken").toString(); +// } else { + + // 使用code换取access_token信息 + String getAccessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?" + + "appid=" + wechatMpConfig.getMpAppId() + "&secret=" + wechatMpConfig.getMpAppSecret() + "&" + + "code=" + code + "&grant_type=authorization_code"; + String tokenResult = restTemplate.getForObject(getAccessTokenUrl, String.class); + JSONObject jsonObj = JSONObject.parseObject(tokenResult); + if (jsonObj == null || !jsonObj.containsKey("access_token")) { + return "获取access_token失败"; + } + log.info("获取access_token==>{}", jsonObj.toJSONString()); + accessToken = jsonObj.get("access_token").toString(); + openId = jsonObj.get("openid").toString(); + // 存储access_token到缓存中 +// instance.createCache("accessToken", 6000, TimeUnit.SECONDS); +// } + + String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?" + + "access_token=" + accessToken + "&openid=" + openId + "&lang=zh_CN"; + String userInfoResult = restTemplate.getForObject(getUserInfoUrl, String.class); + userInfoResult = new String(userInfoResult.getBytes("ISO-8859-1"), "utf-8"); + System.out.println(userInfoResult); + // 判断用户是否存在 0:不存在;1:存在 + int exist = wechatUserInfoService.existsUser(JSONObject.parseObject(userInfoResult)); + System.out.println("exist: " + exist); + // 重定向到我们要跳转的页面 + String result = ""; + result = "redirect:" + wechatMpConfig.getBaseUrl() + "/#/?openId=" + openId; + return result; + } catch (Exception e) { + e.printStackTrace(); + return e.getMessage(); + } + } + +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/First.java b/user-service/src/main/java/com/mh/user/entity/wechat/First.java new file mode 100644 index 0000000..d768122 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/First.java @@ -0,0 +1,35 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 10:59 + * @Description + */ +public class First { + public String value; + public String color; + + public First() { + } + + public First(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Key1.java b/user-service/src/main/java/com/mh/user/entity/wechat/Key1.java new file mode 100644 index 0000000..b90cf80 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Key1.java @@ -0,0 +1,35 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 10:59 + * @Description + */ +public class Key1 { + public String value; + public String color; + + public Key1() { + } + + public Key1(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Key2.java b/user-service/src/main/java/com/mh/user/entity/wechat/Key2.java new file mode 100644 index 0000000..a3d61d0 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Key2.java @@ -0,0 +1,36 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 10:59 + * @Description + */ +public class Key2 { + + public String value; + public String color; + + public Key2() { + } + + public Key2(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Key3.java b/user-service/src/main/java/com/mh/user/entity/wechat/Key3.java new file mode 100644 index 0000000..68a389d --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Key3.java @@ -0,0 +1,36 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 11:00 + * @Description + */ +public class Key3 { + + public String value; + public String color; + + public Key3() { + } + + public Key3(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Key4.java b/user-service/src/main/java/com/mh/user/entity/wechat/Key4.java new file mode 100644 index 0000000..25c6bb6 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Key4.java @@ -0,0 +1,36 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 11:00 + * @Description + */ +public class Key4 { + + public String value; + public String color; + + public Key4() { + } + + public Key4(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Key5.java b/user-service/src/main/java/com/mh/user/entity/wechat/Key5.java new file mode 100644 index 0000000..abccb10 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Key5.java @@ -0,0 +1,36 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 11:00 + * @Description + */ +public class Key5 { + + public String value; + public String color; + + public Key5() { + } + + public Key5(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/PushMsgEntity.java b/user-service/src/main/java/com/mh/user/entity/wechat/PushMsgEntity.java new file mode 100644 index 0000000..bd3fbef --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/PushMsgEntity.java @@ -0,0 +1,115 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 10:58 + * @Description 推送消息实体类 + */ +public class PushMsgEntity { + public String touser; //接收人 + public String templateId; //微信提供模板id + public String url; //消息推送消息url + public First first; //消息头消息 + public Key1 key1; + public Key2 key2; + public Key3 key3; + public Key4 key4; + public Key5 key5; + public Remark remark; + + public String getTouser() { + return touser; + } + + public void setTouser(String touser) { + this.touser = touser; + } + + public String getTemplateId() { + return templateId; + } + + public void setTemplateId(String templateId) { + this.templateId = templateId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public First getFirst() { + return first; + } + + public void setFirst(First first) { + this.first = first; + } + + public Key1 getKey1() { + return key1; + } + + public void setKey1(Key1 key1) { + this.key1 = key1; + } + + public Key2 getKey2() { + return key2; + } + + public void setKey2(Key2 key2) { + this.key2 = key2; + } + + public Key3 getKey3() { + return key3; + } + + public void setKey3(Key3 key3) { + this.key3 = key3; + } + + public Key4 getKey4() { + return key4; + } + + public void setKey4(Key4 key4) { + this.key4 = key4; + } + + public Key5 getKey5() { + return key5; + } + + public void setKey5(Key5 key5) { + this.key5 = key5; + } + + public Remark getRemark() { + return remark; + } + + public void setRemark(Remark remark) { + this.remark = remark; + } + + @Override + public String toString() { + return "PushMsgEntity{" + + "touser='" + touser + '\'' + + ", templateId='" + templateId + '\'' + + ", url='" + url + '\'' + + ", first=" + first + + ", key1=" + key1 + + ", key2=" + key2 + + ", key3=" + key3 + + ", key4=" + key4 + + ", key5=" + key5 + + ", remark=" + remark + + '}'; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/Remark.java b/user-service/src/main/java/com/mh/user/entity/wechat/Remark.java new file mode 100644 index 0000000..736d060 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/Remark.java @@ -0,0 +1,36 @@ +package com.mh.user.entity.wechat; + +/** + * @author chison + * @date 2020-09-14 15:47 + * @Description + */ +public class Remark { + + public String value; + public String color; + + public Remark() { + } + + public Remark(String value, String color) { + this.value = value; + this.color = color; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + + public void setColor(String color) { + this.color = color; + } +} diff --git a/user-service/src/main/java/com/mh/user/entity/wechat/WechatUserInfoEntity.java b/user-service/src/main/java/com/mh/user/entity/wechat/WechatUserInfoEntity.java new file mode 100644 index 0000000..282b35e --- /dev/null +++ b/user-service/src/main/java/com/mh/user/entity/wechat/WechatUserInfoEntity.java @@ -0,0 +1,172 @@ +package com.mh.user.entity.wechat; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; + +import java.util.Date; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信用户实体类 + * @date 2024-11-27 16:58:55 + */ +@TableName("wechat_user_info") +public class WechatUserInfoEntity { + + @TableId(value = "id", type = IdType.AUTO) + private Long id; + + private String userName; + + private String telNum; + + private String openId; + + private String nickName; + + private int sex; + + private String province; + + private String city; + + private String country; + + private String headimgurl; + + private int isStatus; + + private Date createTime; + + private Date updateTime; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getTelNum() { + return telNum; + } + + public void setTelNum(String telNum) { + this.telNum = telNum; + } + + public String getOpenId() { + return openId; + } + + public void setOpenId(String openId) { + this.openId = openId; + } + + public String getNickName() { + return nickName; + } + + public void setNickName(String nickName) { + this.nickName = nickName; + } + + public int getSex() { + return sex; + } + + public void setSex(Integer sex) { + this.sex = sex; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + public void setSex(int sex) { + this.sex = sex; + } + + public String getHeadimgurl() { + return headimgurl; + } + + public void setHeadimgurl(String headimgurl) { + this.headimgurl = headimgurl; + } + + public int getIsStatus() { + return isStatus; + } + + public void setIsStatus(int isStatus) { + this.isStatus = isStatus; + } + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + @Override + public String toString() { + return "WechatUserInfoEntity{" + + "id=" + id + + ", userName='" + userName + '\'' + + ", telNum='" + telNum + '\'' + + ", openId='" + openId + '\'' + + ", nickName='" + nickName + '\'' + + ", sex=" + sex + + ", province='" + province + '\'' + + ", city='" + city + '\'' + + ", country='" + country + '\'' + + ", headimgurl='" + headimgurl + '\'' + + ", isStatus=" + isStatus + + ", createTime=" + createTime + + ", updateTime=" + updateTime + + '}'; + } +} diff --git a/user-service/src/main/java/com/mh/user/job/PushDataToWechatJob.java b/user-service/src/main/java/com/mh/user/job/PushDataToWechatJob.java new file mode 100644 index 0000000..f5e0f39 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/job/PushDataToWechatJob.java @@ -0,0 +1,49 @@ +package com.mh.user.job; + +import com.mh.user.entity.EnergyDataEntity; +import com.mh.user.entity.ProjectInfoEntity; +import com.mh.user.service.EnergyDataService; +import com.mh.user.service.ProjectInfoService; +import com.mh.user.utils.DateUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.List; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 推送给微信公众号 + * @date 2024-11-28 16:39:33 + */ +@Slf4j +@Component +public class PushDataToWechatJob { + + @Autowired + private ProjectInfoService projectInfoService; + + @Autowired + private EnergyDataService energyDataService; + + @Scheduled(cron = "25 0/2 * * * ?") //每2分钟一次 + public void pushDataToWechat() { + log.info("推送给微信公众号"); + String curDate = DateUtil.dateToString(DateUtil.getNowDate(), "yyyy-MM-dd"); + // 查询有多少项目 + List projectInfoEntities = projectInfoService.queryProjectInfo("1"); + for (ProjectInfoEntity projectInfoEntity : projectInfoEntities) { + EnergyDataEntity energyDataEntity = energyDataService.queryEnergyDataByDate(curDate, String.valueOf(projectInfoEntity.getId())); + if (energyDataEntity == null) { + log.info("没有数据"); + } else { + log.info("有数据"); + // 开始推送数据 + } + } + } + +} diff --git a/user-service/src/main/java/com/mh/user/mapper/EnergyDataMapper.java b/user-service/src/main/java/com/mh/user/mapper/EnergyDataMapper.java index 07176f8..6bd1865 100644 --- a/user-service/src/main/java/com/mh/user/mapper/EnergyDataMapper.java +++ b/user-service/src/main/java/com/mh/user/mapper/EnergyDataMapper.java @@ -141,4 +141,22 @@ public interface EnergyDataMapper extends BaseMapper { @Param("lastStartDate") String lastStartDate, @Param("lastEndDate") String lastEndDate, @Param("dateType") String dateType); + + @Select("select top 1 edd.*,pi.project_name from energy_data_day edd " + + " left join project_info pi on edd.project_id = pi.id " + + " where cur_date = #{curDate} and project_id = #{projectId} ") + @Results({ + @Result(property = "id", column = "id"), + @Result(property = "curDate", column = "cur_date"), + @Result(property = "ambTemp", column = "amb_temp"), + @Result(property = "humidity", column = "humidity"), + @Result(property = "water", column = "water"), + @Result(property = "elect", column = "elect"), + @Result(property = "cl", column = "cl"), + @Result(property = "cop", column = "cop"), + @Result(property = "projectId", column = "project_id"), + @Result(property = "projectName", column = "project_name") + }) + EnergyDataEntity queryEnergyDataByDate(@Param("curDate") String curDate, + @Param("projectId") String projectId); } diff --git a/user-service/src/main/java/com/mh/user/mapper/wechat/WechatUserInfoMapper.java b/user-service/src/main/java/com/mh/user/mapper/wechat/WechatUserInfoMapper.java new file mode 100644 index 0000000..5179dbf --- /dev/null +++ b/user-service/src/main/java/com/mh/user/mapper/wechat/WechatUserInfoMapper.java @@ -0,0 +1,16 @@ +package com.mh.user.mapper.wechat; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.mh.user.entity.wechat.WechatUserInfoEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信用户mapper类 + * @date 2024-11-27 17:02:40 + */ +@Mapper +public interface WechatUserInfoMapper extends BaseMapper { +} diff --git a/user-service/src/main/java/com/mh/user/service/EnergyDataService.java b/user-service/src/main/java/com/mh/user/service/EnergyDataService.java index c91b760..757eae2 100644 --- a/user-service/src/main/java/com/mh/user/service/EnergyDataService.java +++ b/user-service/src/main/java/com/mh/user/service/EnergyDataService.java @@ -1,8 +1,6 @@ package com.mh.user.service; -import com.github.pagehelper.PageInfo; import com.mh.common.page.PageResult; -import com.mh.user.dto.EnergyMomYoyDataDTO; import com.mh.user.entity.EnergyDataEntity; import com.mh.user.model.EnergyModel; import java.util.List; @@ -16,4 +14,6 @@ public interface EnergyDataService { PageResult queryMomEnergyData(EnergyModel energyModel); PageResult queryYoyEnergyData(EnergyModel energyModel); + + EnergyDataEntity queryEnergyDataByDate(String curDate, String projectId); } diff --git a/user-service/src/main/java/com/mh/user/service/impl/EnergyDataServiceImpl.java b/user-service/src/main/java/com/mh/user/service/impl/EnergyDataServiceImpl.java index cb0e832..effb179 100644 --- a/user-service/src/main/java/com/mh/user/service/impl/EnergyDataServiceImpl.java +++ b/user-service/src/main/java/com/mh/user/service/impl/EnergyDataServiceImpl.java @@ -337,4 +337,9 @@ public class EnergyDataServiceImpl implements EnergyDataService { dateType); return MybatisPageHelper.getPageResult(pageRequest, new PageInfo<>(resultList)); } + + @Override + public EnergyDataEntity queryEnergyDataByDate(String curDate, String projectId) { + return energyDataMapper.queryEnergyDataByDate(curDate, projectId); + } } diff --git a/user-service/src/main/java/com/mh/user/service/wechat/WechatService.java b/user-service/src/main/java/com/mh/user/service/wechat/WechatService.java new file mode 100644 index 0000000..6e2423b --- /dev/null +++ b/user-service/src/main/java/com/mh/user/service/wechat/WechatService.java @@ -0,0 +1,14 @@ +package com.mh.user.service.wechat; + +import com.mh.user.entity.wechat.PushMsgEntity; + +/** + * @author chison + * @date 2020-09-14 10:48 + * @Description 微信业务 + */ +public interface WechatService { + + void PushMsg(PushMsgEntity pushMsgEntity); + +} diff --git a/user-service/src/main/java/com/mh/user/service/wechat/WechatUserInfoService.java b/user-service/src/main/java/com/mh/user/service/wechat/WechatUserInfoService.java new file mode 100644 index 0000000..b84a530 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/service/wechat/WechatUserInfoService.java @@ -0,0 +1,21 @@ +package com.mh.user.service.wechat; + +import com.alibaba.fastjson2.JSONObject; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信用户服务类 + * @date 2024-11-27 17:03:34 + */ +public interface WechatUserInfoService { + + /** + * 判断是否存在用户信息 + * @param jsonObject + * @return + */ + int existsUser(JSONObject jsonObject); + +} diff --git a/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatServiceImpl.java b/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatServiceImpl.java new file mode 100644 index 0000000..9a53c61 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatServiceImpl.java @@ -0,0 +1,73 @@ +package com.mh.user.service.wechat.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.github.benmanes.caffeine.cache.Cache; +import com.mh.user.config.wechat.WechatMpConfig; +import com.mh.user.entity.wechat.PushMsgEntity; +import com.mh.user.service.wechat.WechatService; +import com.mh.user.utils.CacheUtil; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.stereotype.Service; +import org.springframework.web.client.RestTemplate; + +import java.util.concurrent.TimeUnit; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信服务类 + * @date 2024-11-28 17:05:16 + */ +@Slf4j +@Service +public class WechatServiceImpl implements WechatService { + + @Autowired + private RestTemplate restTemplate; + + @Autowired + private WechatMpConfig wechatMpConfig; + + @Override + public void PushMsg(PushMsgEntity pushMsgEntity) { + // 判断cache中是否存在access_token + CacheUtil instance = CacheUtil.getInstance(); + Cache cache = instance.getCache("accessToken"); + String accessToken = ""; + if (cache != null ) { + log.info("cache中存在access_token,直接使用"); + accessToken = cache.getIfPresent("accessToken").toString(); + } else { + String tokenResult = restTemplate.getForObject(wechatMpConfig.getAccessTokenUrl(),String.class); + JSONObject jsonObj = JSONObject.parseObject(tokenResult); + if (jsonObj == null || !jsonObj.containsKey("access_token")) { + return; + } + accessToken = jsonObj.get("access_token").toString(); + instance.createCache("accessToken", 6000, TimeUnit.SECONDS); + } + // 封装推送内容 + JSONObject jsonObject = new JSONObject(); + jsonObject.put("touser",pushMsgEntity.getTouser()); + jsonObject.put("template_id",pushMsgEntity.getTemplateId()); + jsonObject.put("url",pushMsgEntity.getUrl()); + JSONObject data = new JSONObject(); + data.put("first",pushMsgEntity.getFirst()); + data.put("keyword1",pushMsgEntity.getKey1()); + data.put("keyword2",pushMsgEntity.getKey2()); + data.put("keyword3",pushMsgEntity.getKey3()); + data.put("keyword4",pushMsgEntity.getKey4()); + data.put("keyword5",pushMsgEntity.getKey5()); + data.put("remark",pushMsgEntity.getRemark()); + jsonObject.put("data",data); + HttpHeaders headers = new HttpHeaders(); + headers.add("Content-Type", "application/json"); + HttpEntity entity = new HttpEntity(jsonObject, headers); + String result = restTemplate.postForObject(wechatMpConfig.getPushMsgUrl(accessToken),entity,String.class); + log.info("推送结果:{}", result); + } +} diff --git a/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatUserInfoServiceImpl.java b/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatUserInfoServiceImpl.java new file mode 100644 index 0000000..27621df --- /dev/null +++ b/user-service/src/main/java/com/mh/user/service/wechat/impl/WechatUserInfoServiceImpl.java @@ -0,0 +1,55 @@ +package com.mh.user.service.wechat.impl; + +import com.alibaba.fastjson2.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.mh.user.entity.wechat.WechatUserInfoEntity; +import com.mh.user.mapper.wechat.WechatUserInfoMapper; +import com.mh.user.service.wechat.WechatUserInfoService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信服务实体实现类 + * @date 2024-11-27 17:03:56 + */ +@Service +public class WechatUserInfoServiceImpl implements WechatUserInfoService { + + @Autowired + private WechatUserInfoMapper wechatUserInfoMapper; + + @Transactional + @Override + public int existsUser(JSONObject jsonObject) { + if (jsonObject == null || !jsonObject.containsKey("openid")) return 0; + String openId = jsonObject.get("openid").toString(); + // 根据openId判断用户是否存在 + long count = wechatUserInfoMapper.selectCount(new QueryWrapper().eq("open_id", openId)); + // count:0:未找到用户,1:有用户但未完成注册 + if (count != 0) { + // 0:未注册;1:完成注册 + return 0; + } + + WechatUserInfoEntity userEntity = new WechatUserInfoEntity(); + userEntity.setIsStatus(2); + userEntity.setOpenId(openId); + userEntity.setNickName(jsonObject.containsKey("nickname") ? jsonObject.get("nickname").toString() : null); + if (jsonObject.containsKey("sex")) { + userEntity.setSex(Integer.parseInt(jsonObject.get("sex").toString())); + } else { + userEntity.setSex(null); + } + userEntity.setProvince(jsonObject.containsKey("province") ? jsonObject.get("province").toString() : null); + userEntity.setCountry(jsonObject.containsKey("country") ? jsonObject.get("country").toString() : null); + userEntity.setCity(jsonObject.containsKey("city") ? jsonObject.get("city").toString() : null); + userEntity.setHeadimgurl(jsonObject.containsKey("headimgurl") ? jsonObject.get("headimgurl").toString() : null); + //用户不存在基本信息先入库 + wechatUserInfoMapper.insert(userEntity); + return 0; + } +} diff --git a/user-service/src/main/java/com/mh/user/utils/CacheUtil.java b/user-service/src/main/java/com/mh/user/utils/CacheUtil.java new file mode 100644 index 0000000..bff3467 --- /dev/null +++ b/user-service/src/main/java/com/mh/user/utils/CacheUtil.java @@ -0,0 +1,90 @@ +package com.mh.user.utils; + +import com.github.benmanes.caffeine.cache.Cache; +import com.github.benmanes.caffeine.cache.Caffeine; + +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 缓存工具类 + * @date 2024-11-28 09:42:14 + */ +public class CacheUtil { + + private static class Holder { + private static final CacheUtil INSTANCE = new CacheUtil(); + } + + public static CacheUtil getInstance() { + return Holder.INSTANCE; + } + + private final ConcurrentHashMap> caches = new ConcurrentHashMap<>(); + private final AtomicLong cacheIdCounter = new AtomicLong(0); + + private CacheUtil() { + // 私有构造函数,防止外部实例化 + } + + /** + * 创建一个带有指定过期时间的缓存实例 + * + * @param expireAfterWrite 过期时间(写后) + * @param unit 时间单位 + * @return 缓存ID + */ + public void createCache(String key, long expireAfterWrite, TimeUnit unit) { + Cache cache = Caffeine.newBuilder() + .expireAfterWrite(expireAfterWrite, unit) + .build(); + caches.put(key, cache); + } + + /** + * 通过缓存ID获取缓存实例 + * + * @param cacheId 缓存ID + * @return 缓存实例 + */ + public Cache getCache(String cacheId) { + return caches.get(cacheId); + } + + /** + * 将键值对放入缓存 + * + * @param cache 缓存实例 + * @param key 键 + * @param value 值 + */ + public void put(Cache cache, Object key, Object value) { + cache.put(key, value); + } + + /** + * 从缓存中获取值 + * + * @param cache 缓存实例 + * @param key 键 + * @return 值 + */ + public Object get(Cache cache, Object key) { + return cache.getIfPresent(key); + } + + /** + * 从缓存中移除键值对 + * + * @param cache 缓存实例 + * @param key 键 + */ + public void remove(Cache cache, Object key) { + cache.invalidate(key); + } + +} diff --git a/user-service/src/main/java/com/mh/user/utils/SignUtil.java b/user-service/src/main/java/com/mh/user/utils/SignUtil.java new file mode 100644 index 0000000..51218bf --- /dev/null +++ b/user-service/src/main/java/com/mh/user/utils/SignUtil.java @@ -0,0 +1,70 @@ +package com.mh.user.utils; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Arrays; + +/** + * @author chison + * @date 2020-04-03 11:40 + * @Description 工具类 + */ +public class SignUtil { + /**与微信配置保持一致*/ + private static String token = "WechatTest"; + + /** + * 校验签名 + * @param signature + * @param timestamp + * @param nonce + * @return + */ + public static boolean checkSignature(String signature,String timestamp,String nonce) { + String checktext = null; + if (null != signature) { + //对ToKen,timestamp,nonce 按字典排序 + String[] paramArr = new String[]{token,timestamp,nonce}; + Arrays.sort(paramArr); + //将排序后的结果拼成一个字符串 + String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]); + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + //对接后的字符串进行sha1加密 + byte[] digest = md.digest(content.toString().getBytes()); + checktext = byteToStr(digest); + } catch (NoSuchAlgorithmException e){ + e.printStackTrace(); + } + } + //将加密后的字符串与signature进行对比 + return checktext !=null ? checktext.equals(signature.toUpperCase()) : false; + } + + /** + * 将字节数组转化成16进制字符串 + * @param byteArrays + * @return + */ + private static String byteToStr(byte[] byteArrays){ + String str = ""; + for (int i = 0; i < byteArrays.length; i++) { + str += byteToHexStr(byteArrays[i]); + } + return str; + } + + /** + * 将字节转化为十六进制字符串 + * @param myByte + * @return + */ + private static String byteToHexStr(byte myByte) { + char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; + char[] tampArr = new char[2]; + tampArr[0] = Digit[(myByte >>> 4) & 0X0F]; + tampArr[1] = Digit[myByte & 0X0F]; + String str = new String(tampArr); + return str; + } +} diff --git a/user-service/src/main/resources/static/MP_verify_KpSSuYz7qGU2WuoM.txt b/user-service/src/main/resources/static/MP_verify_KpSSuYz7qGU2WuoM.txt new file mode 100644 index 0000000..e5b9516 --- /dev/null +++ b/user-service/src/main/resources/static/MP_verify_KpSSuYz7qGU2WuoM.txt @@ -0,0 +1 @@ +KpSSuYz7qGU2WuoM \ No newline at end of file diff --git a/user-service/src/test/java/com/mh/user/DealDataTest.java b/user-service/src/test/java/com/mh/user/DealDataTest.java index aca9ed3..dfa2fdd 100644 --- a/user-service/src/test/java/com/mh/user/DealDataTest.java +++ b/user-service/src/test/java/com/mh/user/DealDataTest.java @@ -56,10 +56,11 @@ public class DealDataTest extends UserServiceApplicationTests { EnergyModel energyModel = new EnergyModel(); energyModel.setPage(1); energyModel.setLimit(10); - energyModel.setStartDate("2024-07"); + energyModel.setStartDate("2023"); + energyModel.setEndDate("2024"); energyModel.setProjectId("3"); energyModel.setQueryType(0); - energyModel.setType(3); + energyModel.setType(5); PageResult pageResult = energyDataService.queryMomEnergyData(energyModel); System.out.println(pageResult); diff --git a/user-service/src/test/java/com/mh/user/WechatTest.java b/user-service/src/test/java/com/mh/user/WechatTest.java new file mode 100644 index 0000000..2daa4f6 --- /dev/null +++ b/user-service/src/test/java/com/mh/user/WechatTest.java @@ -0,0 +1,41 @@ +package com.mh.user; + +import com.alibaba.fastjson2.JSONObject; +import com.google.gson.JsonObject; +import com.mh.user.service.wechat.WechatUserInfoService; +import lombok.extern.slf4j.Slf4j; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * @author LJF + * @version 1.0 + * @project mh_esi + * @description 微信测试 + * @date 2024-11-28 14:03:01 + */ +@Slf4j +public class WechatTest extends UserServiceApplicationTests{ + + @Autowired + private WechatUserInfoService wechatUserInfoService; + + @Test + public void testInertWechatUserInfo() + { + String test = "{" + + " \"openid\": \"o0qeN5lw4JquQy_H9Rk5QN-CyMRU\"," + + " \"nickname\": \"道法自然\"," + + " \"sex\": 0," + + " \"language\": \"\"," + + " \"city\": \"\"," + + " \"province\": \"\"," + + " \"country\": \"\"," + + " \"headimgurl\": \"https://thirdwx.qlogo.cn/mmopen/vi_32/PiajxSqBRaEI5eF3IWJv4l884KWkjngFSE5VQdlHzZ5YqYAHE7eticnZVyBhPDuObiawraByzMHDY5e8YiboprN9kljwIUYdehiaxkjsKGgpFicM2rtZQk9Q7dBw/132\"," + + " \"privilege\": []" + + "}"; + JSONObject jsonObject = JSONObject.parseObject(test); + wechatUserInfoService.existsUser(jsonObject); + + } +} diff --git a/user-service/src/test/java/com/mh/user/device/CRC16Test.java b/user-service/src/test/java/com/mh/user/device/CRC16Test.java index d4fdf20..e75dffe 100644 --- a/user-service/src/test/java/com/mh/user/device/CRC16Test.java +++ b/user-service/src/test/java/com/mh/user/device/CRC16Test.java @@ -5,6 +5,7 @@ import com.mh.user.utils.ExchangeStringUtil; import java.io.IOException; import java.math.BigDecimal; import java.math.RoundingMode; +import java.time.LocalDate; /** * @Classname CRC16Test @@ -83,22 +84,49 @@ public class CRC16Test { // String checkWord = ExchangeStringUtil.getStrCRC16(str); //CRC16校验 // str = str + checkWord; // System.out.println(str); - String receiveData = "04030202CDB4B1"; - String dataLength = receiveData.substring(4, 6); - int dataLengthInt = Integer.parseInt(dataLength, 16); - // 截取数据域 - String data = receiveData; - data = receiveData.substring(6, 6 + dataLengthInt * 2); - System.out.println(data); - String sValue = ExchangeStringUtil.hexToDec(data); - System.out.println(ExchangeStringUtil.hexToDec(data)); - System.out.println(ExchangeStringUtil.rightAddZeroForNum("1", 2+1)); - BigDecimal test1 = new BigDecimal(ExchangeStringUtil.rightAddZeroForNum("1", 2+1)); - System.out.println(test1); - sValue = (new BigDecimal(sValue)).divide(test1, 2, RoundingMode.HALF_UP).toString(); - System.out.println(sValue); - String test = String.valueOf(Math.abs(ExchangeStringUtil.hexToSingle(data))); - System.out.println(test); +// String receiveData = "04030202CDB4B1"; +// String dataLength = receiveData.substring(4, 6); +// int dataLengthInt = Integer.parseInt(dataLength, 16); +// // 截取数据域 +// String data = receiveData; +// data = receiveData.substring(6, 6 + dataLengthInt * 2); +// System.out.println(data); +// String sValue = ExchangeStringUtil.hexToDec(data); +// System.out.println(ExchangeStringUtil.hexToDec(data)); +// System.out.println(ExchangeStringUtil.rightAddZeroForNum("1", 2+1)); +// BigDecimal test1 = new BigDecimal(ExchangeStringUtil.rightAddZeroForNum("1", 2+1)); +// System.out.println(test1); +// sValue = (new BigDecimal(sValue)).divide(test1, 2, RoundingMode.HALF_UP).toString(); +// System.out.println(sValue); +// String test = String.valueOf(Math.abs(ExchangeStringUtil.hexToSingle(data))); +// System.out.println(test); + // 假设传入的时间格式为 "2023" + String yearStr = "2023"; + + // 1. 获取当前年份 + int year = Integer.parseInt(yearStr); + + // 2. 计算今年的开始月份 + int startMonth = 1; + + // 3. 获取当前月份 + LocalDate now = LocalDate.now(); + int currentMonth = now.getMonthValue(); + + // 4. 计算环比月份 + int yearForComparison = year; + int monthForComparison = currentMonth - 1; + + if (monthForComparison == 0) { + monthForComparison = 12; + yearForComparison = year - 1; + } + + // 输出结果 + System.out.println("当前年份: " + year); + System.out.println("今年的开始月份: " + startMonth); + System.out.println("当前月份: " + currentMonth); + System.out.println("环比月份: " + yearForComparison + "-" + monthForComparison); } diff --git a/微信用户信息表.sql b/微信用户信息表.sql new file mode 100644 index 0000000..ac5b985 --- /dev/null +++ b/微信用户信息表.sql @@ -0,0 +1,30 @@ +create table wechat_user_info +( + id int identity(1,1) not null, + user_name varchar(100) collate chinese_prc_ci_as null, + tel_num varchar(50) collate chinese_prc_ci_as null, + open_id varchar(100) collate chinese_prc_ci_as not null, + nick_name varchar(100) collate chinese_prc_ci_as null, + sex int null, + province varchar(50) collate chinese_prc_ci_as null, + city varchar(50) collate chinese_prc_ci_as null, + country varchar(50) collate chinese_prc_ci_as null, + headimgurl varchar(500) collate chinese_prc_ci_as null, + is_status int not null, + create_time datetime default getdate() not null, + update_time datetime not null +); +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'微信用户信息表', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'编号', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'id'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'用户名', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'user_name'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'手机号码', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'tel_num'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'openid', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'open_id'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'昵称', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'nick_name'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'性别', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'sex'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'省份', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'province'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'城市', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'city'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'国家', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'country'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'头像', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'headimgurl'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'状态标识', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'is_status'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'创建时间', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'create_time'; +EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'更新时间', @level0type=N'Schema', @level0name=N'dbo', @level1type=N'Table', @level1name=N'wechat_user_info', @level2type=N'Column', @level2name=N'update_time';