✨ 特殊日功能
This commit is contained in:
parent
15bef06adb
commit
1d557e75ee
5
pom.xml
5
pom.xml
@ -180,6 +180,11 @@
|
|||||||
<artifactId>weixin-java-open</artifactId>
|
<artifactId>weixin-java-open</artifactId>
|
||||||
<version>3.7.0</version>
|
<version>3.7.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
<artifactId>java-emoji-converter</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
44
src/main/java/com/rymcu/vertical/entity/SpecialDay.java
Normal file
44
src/main/java/com/rymcu/vertical/entity/SpecialDay.java
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package com.rymcu.vertical.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table(name="vertical_special_day")
|
||||||
|
public class SpecialDay implements Serializable,Cloneable{
|
||||||
|
/** */
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@GeneratedValue(generator = "JDBC")
|
||||||
|
private Integer idSpecialDay;
|
||||||
|
/** 名称 */
|
||||||
|
private String specialDayName;
|
||||||
|
/** 权重/优先级,小数优秀 */
|
||||||
|
private Integer weights;
|
||||||
|
/** 开始时间 */
|
||||||
|
private Date startTime;
|
||||||
|
/** 过期时间 */
|
||||||
|
private Date expirationTime;
|
||||||
|
/** 是否重复 */
|
||||||
|
private Integer repeat;
|
||||||
|
/** 重复周期 */
|
||||||
|
private Integer repeatCycle;
|
||||||
|
/** 0:天1:周2:月3:年 */
|
||||||
|
private Integer repeatCycleUnit;
|
||||||
|
/** 创建时间 */
|
||||||
|
private Date createdTime;
|
||||||
|
/** 图片路径 */
|
||||||
|
private String imgUrl;
|
||||||
|
/** 执行全局样式 */
|
||||||
|
private String cssStyle;
|
||||||
|
|
||||||
|
}
|
49
src/main/java/com/rymcu/vertical/entity/WxUser.java
Normal file
49
src/main/java/com/rymcu/vertical/entity/WxUser.java
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package com.rymcu.vertical.entity;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Table(name = "vertical_wx_user")
|
||||||
|
public class WxUser {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column(name = "id")
|
||||||
|
@GeneratedValue(generator = "JDBC")
|
||||||
|
private Integer idWxUser;
|
||||||
|
|
||||||
|
private Boolean subscribe;
|
||||||
|
|
||||||
|
private String openId;
|
||||||
|
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
private String sexDesc;
|
||||||
|
|
||||||
|
private Integer sex;
|
||||||
|
|
||||||
|
private String language;
|
||||||
|
|
||||||
|
private String city;
|
||||||
|
|
||||||
|
private String province;
|
||||||
|
|
||||||
|
private String country;
|
||||||
|
|
||||||
|
private String headImgUrl;
|
||||||
|
|
||||||
|
private Long subscribeTime;
|
||||||
|
|
||||||
|
private String unionId;
|
||||||
|
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
private String actToken;
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.rymcu.vertical.mapper;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.mapper.Mapper;
|
||||||
|
import com.rymcu.vertical.entity.SpecialDay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
public interface SpecialDayMapper extends Mapper<SpecialDay> {
|
||||||
|
}
|
10
src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java
Normal file
10
src/main/java/com/rymcu/vertical/mapper/WxUserMapper.java
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
package com.rymcu.vertical.mapper;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.mapper.Mapper;
|
||||||
|
import com.rymcu.vertical.entity.WxUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
public interface WxUserMapper extends Mapper<WxUser> {
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.rymcu.vertical.service;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.service.Service;
|
||||||
|
import com.rymcu.vertical.entity.SpecialDay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
public interface SpecialDayService extends Service<SpecialDay> {
|
||||||
|
}
|
14
src/main/java/com/rymcu/vertical/service/WxUserService.java
Normal file
14
src/main/java/com/rymcu/vertical/service/WxUserService.java
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package com.rymcu.vertical.service;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.service.Service;
|
||||||
|
import com.rymcu.vertical.entity.WxUser;
|
||||||
|
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
public interface WxUserService extends Service<WxUser> {
|
||||||
|
|
||||||
|
WxUser saveUser(WxMpUser wxMpUser, String appId);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package com.rymcu.vertical.service.impl;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.service.AbstractService;
|
||||||
|
import com.rymcu.vertical.entity.SpecialDay;
|
||||||
|
import com.rymcu.vertical.mapper.SpecialDayMapper;
|
||||||
|
import com.rymcu.vertical.service.SpecialDayService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class SpecialDayServiceImpl extends AbstractService<SpecialDay> implements SpecialDayService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SpecialDayMapper specialDayMapper;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.rymcu.vertical.service.impl;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.core.service.AbstractService;
|
||||||
|
import com.rymcu.vertical.entity.WxUser;
|
||||||
|
import com.rymcu.vertical.mapper.WxUserMapper;
|
||||||
|
import com.rymcu.vertical.service.WxUserService;
|
||||||
|
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author ronger
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class WxUserServiceImpl extends AbstractService<WxUser> implements WxUserService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private WxUserMapper wxUserMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxUser saveUser(WxMpUser wxMpUser, String appId) {
|
||||||
|
WxUser searchWxUser = new WxUser();
|
||||||
|
if (StringUtils.isBlank(wxMpUser.getUnionId())) {
|
||||||
|
searchWxUser.setUnionId(wxMpUser.getUnionId());
|
||||||
|
} else {
|
||||||
|
searchWxUser.setAppId(appId);
|
||||||
|
searchWxUser.setOpenId(searchWxUser.getOpenId());
|
||||||
|
}
|
||||||
|
List<WxUser> wxUsers = wxUserMapper.select(searchWxUser);
|
||||||
|
WxUser wxUser;
|
||||||
|
if (wxUsers.isEmpty()) {
|
||||||
|
wxUser = new WxUser();
|
||||||
|
wxUser.setAppId(appId);
|
||||||
|
wxUser = copyWxUser(wxMpUser,wxUser);
|
||||||
|
wxUserMapper.insertSelective(wxUser);
|
||||||
|
} else {
|
||||||
|
wxUser = wxUsers.get(0);
|
||||||
|
wxUser = copyWxUser(wxMpUser,wxUser);
|
||||||
|
wxUserMapper.updateByPrimaryKeySelective(wxUser);
|
||||||
|
}
|
||||||
|
return wxUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
private WxUser copyWxUser(WxMpUser wxMpUser, WxUser wxUser) {
|
||||||
|
wxUser.setNickname(wxMpUser.getNickname());
|
||||||
|
wxUser.setHeadImgUrl(wxMpUser.getHeadImgUrl());
|
||||||
|
wxUser.setCountry(wxMpUser.getCountry());
|
||||||
|
wxUser.setProvince(wxMpUser.getProvince());
|
||||||
|
wxUser.setCity(wxMpUser.getCity());
|
||||||
|
wxUser.setSex(wxMpUser.getSex());
|
||||||
|
wxUser.setSubscribe(wxMpUser.getSubscribe());
|
||||||
|
wxUser.setSubscribeTime(wxMpUser.getSubscribeTime());
|
||||||
|
wxUser.setUnionId(wxMpUser.getUnionId());
|
||||||
|
wxUser.setOpenId(wxMpUser.getOpenId());
|
||||||
|
wxUser.setLanguage(wxMpUser.getLanguage());
|
||||||
|
wxUser.setSexDesc(wxMpUser.getSexDesc());
|
||||||
|
return wxUser;
|
||||||
|
}
|
||||||
|
}
|
@ -6,14 +6,8 @@ import com.rymcu.vertical.core.result.GlobalResult;
|
|||||||
import com.rymcu.vertical.core.result.GlobalResultGenerator;
|
import com.rymcu.vertical.core.result.GlobalResultGenerator;
|
||||||
import com.rymcu.vertical.dto.admin.TopicTagDTO;
|
import com.rymcu.vertical.dto.admin.TopicTagDTO;
|
||||||
import com.rymcu.vertical.dto.admin.UserRoleDTO;
|
import com.rymcu.vertical.dto.admin.UserRoleDTO;
|
||||||
import com.rymcu.vertical.entity.Role;
|
import com.rymcu.vertical.entity.*;
|
||||||
import com.rymcu.vertical.entity.Tag;
|
import com.rymcu.vertical.service.*;
|
||||||
import com.rymcu.vertical.entity.Topic;
|
|
||||||
import com.rymcu.vertical.entity.User;
|
|
||||||
import com.rymcu.vertical.service.RoleService;
|
|
||||||
import com.rymcu.vertical.service.TagService;
|
|
||||||
import com.rymcu.vertical.service.TopicService;
|
|
||||||
import com.rymcu.vertical.service.UserService;
|
|
||||||
import com.rymcu.vertical.util.Utils;
|
import com.rymcu.vertical.util.Utils;
|
||||||
import org.apache.commons.lang.StringUtils;
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@ -39,6 +33,8 @@ public class AdminController {
|
|||||||
private TopicService topicService;
|
private TopicService topicService;
|
||||||
@Resource
|
@Resource
|
||||||
private TagService tagService;
|
private TagService tagService;
|
||||||
|
@Resource
|
||||||
|
private SpecialDayService specialDayService;
|
||||||
|
|
||||||
@GetMapping("/users")
|
@GetMapping("/users")
|
||||||
public GlobalResult<Map<String, Object>> users(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows){
|
public GlobalResult<Map<String, Object>> users(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows){
|
||||||
@ -47,10 +43,7 @@ public class AdminController {
|
|||||||
PageInfo<User> pageInfo = new PageInfo<>(list);
|
PageInfo<User> pageInfo = new PageInfo<>(list);
|
||||||
Map<String, Object> map = new HashMap<String, Object>(2);
|
Map<String, Object> map = new HashMap<String, Object>(2);
|
||||||
map.put("users", pageInfo.getList());
|
map.put("users", pageInfo.getList());
|
||||||
Map<String, Number> pagination = new HashMap<>(3);
|
Map pagination = Utils.getPagination(pageInfo);
|
||||||
pagination.put("pageSize",pageInfo.getPageSize());
|
|
||||||
pagination.put("total",pageInfo.getTotal());
|
|
||||||
pagination.put("currentPage",pageInfo.getPageNum());
|
|
||||||
map.put("pagination", pagination);
|
map.put("pagination", pagination);
|
||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
@ -204,4 +197,16 @@ public class AdminController {
|
|||||||
return GlobalResultGenerator.genSuccessResult(map);
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/special-days")
|
||||||
|
public GlobalResult<Map> specialDays(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "10") Integer rows) {
|
||||||
|
PageHelper.startPage(page, rows);
|
||||||
|
List<SpecialDay> list = specialDayService.findAll();
|
||||||
|
PageInfo<SpecialDay> pageInfo = new PageInfo<>(list);
|
||||||
|
Map<String, Object> map = new HashMap<>(2);
|
||||||
|
map.put("specialDays", pageInfo.getList());
|
||||||
|
Map pagination = Utils.getPagination(pageInfo);
|
||||||
|
map.put("pagination", pagination);
|
||||||
|
return GlobalResultGenerator.genSuccessResult(map);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,147 @@
|
|||||||
|
package com.rymcu.vertical.wx.miniapp.config;
|
||||||
|
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.api.impl.WxMaServiceImpl;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaTemplateData;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
|
||||||
|
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
|
||||||
|
import cn.binarywang.wx.miniapp.message.WxMaMessageHandler;
|
||||||
|
import cn.binarywang.wx.miniapp.message.WxMaMessageRouter;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableConfigurationProperties(WxMaProperties.class)
|
||||||
|
public class WxMaConfiguration {
|
||||||
|
private WxMaProperties properties;
|
||||||
|
|
||||||
|
private static Map<String, WxMaMessageRouter> routers = Maps.newHashMap();
|
||||||
|
private static Map<String, WxMaService> maServices = Maps.newHashMap();
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
public WxMaConfiguration(WxMaProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WxMaService getMaService(String appid) {
|
||||||
|
WxMaService wxService = maServices.get(appid);
|
||||||
|
if (wxService == null) {
|
||||||
|
throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid));
|
||||||
|
}
|
||||||
|
|
||||||
|
return wxService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static WxMaMessageRouter getRouter(String appid) {
|
||||||
|
return routers.get(appid);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
List<WxMaProperties.Config> configs = this.properties.getConfigs();
|
||||||
|
if (configs == null) {
|
||||||
|
throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!");
|
||||||
|
}
|
||||||
|
|
||||||
|
maServices = configs.stream()
|
||||||
|
.map(a -> {
|
||||||
|
WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
|
||||||
|
config.setAppid(a.getAppId());
|
||||||
|
config.setSecret(a.getSecret());
|
||||||
|
config.setToken(a.getToken());
|
||||||
|
config.setAesKey(a.getAesKey());
|
||||||
|
config.setMsgDataFormat(a.getMsgDataFormat());
|
||||||
|
|
||||||
|
WxMaService service = new WxMaServiceImpl();
|
||||||
|
service.setWxMaConfig(config);
|
||||||
|
routers.put(a.getAppId(), this.newRouter(service));
|
||||||
|
return service;
|
||||||
|
}).collect(Collectors.toMap(s -> s.getWxMaConfig().getAppid(), a -> a));
|
||||||
|
}
|
||||||
|
|
||||||
|
private WxMaMessageRouter newRouter(WxMaService service) {
|
||||||
|
final WxMaMessageRouter router = new WxMaMessageRouter(service);
|
||||||
|
router
|
||||||
|
.rule().handler(logHandler).next()
|
||||||
|
.rule().async(false).content("模板").handler(templateMsgHandler).end()
|
||||||
|
.rule().async(false).content("文本").handler(textHandler).end()
|
||||||
|
.rule().async(false).content("图片").handler(picHandler).end()
|
||||||
|
.rule().async(false).content("二维码").handler(qrcodeHandler).end();
|
||||||
|
return router;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final WxMaMessageHandler templateMsgHandler = (wxMessage, context, service, sessionManager) -> {
|
||||||
|
service.getMsgService().sendTemplateMsg(WxMaTemplateMessage.builder()
|
||||||
|
.templateId("此处更换为自己的模板id")
|
||||||
|
.formId("自己替换可用的formid")
|
||||||
|
.data(Lists.newArrayList(
|
||||||
|
new WxMaTemplateData("keyword1", "339208499", "#173177")))
|
||||||
|
.toUser(wxMessage.getFromUser())
|
||||||
|
.build());
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final WxMaMessageHandler logHandler = (wxMessage, context, service, sessionManager) -> {
|
||||||
|
System.out.println("收到消息:" + wxMessage.toString());
|
||||||
|
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("收到信息为:" + wxMessage.toJson())
|
||||||
|
.toUser(wxMessage.getFromUser()).build());
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final WxMaMessageHandler textHandler = (wxMessage, context, service, sessionManager) -> {
|
||||||
|
service.getMsgService().sendKefuMsg(WxMaKefuMessage.newTextBuilder().content("回复文本消息")
|
||||||
|
.toUser(wxMessage.getFromUser()).build());
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final WxMaMessageHandler picHandler = (wxMessage, context, service, sessionManager) -> {
|
||||||
|
try {
|
||||||
|
WxMediaUploadResult uploadResult = service.getMediaService()
|
||||||
|
.uploadMedia("image", "png",
|
||||||
|
ClassLoader.getSystemResourceAsStream("tmp.png"));
|
||||||
|
service.getMsgService().sendKefuMsg(
|
||||||
|
WxMaKefuMessage
|
||||||
|
.newImageBuilder()
|
||||||
|
.mediaId(uploadResult.getMediaId())
|
||||||
|
.toUser(wxMessage.getFromUser())
|
||||||
|
.build());
|
||||||
|
} catch (WxErrorException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
private final WxMaMessageHandler qrcodeHandler = (wxMessage, context, service, sessionManager) -> {
|
||||||
|
try {
|
||||||
|
final File file = service.getQrcodeService().createQrcode("123", 430);
|
||||||
|
WxMediaUploadResult uploadResult = service.getMediaService().uploadMedia("image", file);
|
||||||
|
service.getMsgService().sendKefuMsg(
|
||||||
|
WxMaKefuMessage
|
||||||
|
.newImageBuilder()
|
||||||
|
.mediaId(uploadResult.getMediaId())
|
||||||
|
.toUser(wxMessage.getFromUser())
|
||||||
|
.build());
|
||||||
|
} catch (WxErrorException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,45 @@
|
|||||||
|
package com.rymcu.vertical.wx.miniapp.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "wx.miniapp")
|
||||||
|
public class WxMaProperties {
|
||||||
|
|
||||||
|
private List<Config> configs;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class Config {
|
||||||
|
/**
|
||||||
|
* 设置微信小程序的appid
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置微信小程序的Secret
|
||||||
|
*/
|
||||||
|
private String secret;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置微信小程序消息服务器配置的token
|
||||||
|
*/
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置微信小程序消息服务器配置的EncodingAESKey
|
||||||
|
*/
|
||||||
|
private String aesKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息格式,XML或者JSON
|
||||||
|
*/
|
||||||
|
private String msgDataFormat;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.rymcu.vertical.wx.miniapp.controller;
|
||||||
|
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.io.Files;
|
||||||
|
import com.rymcu.vertical.wx.miniapp.config.WxMaConfiguration;
|
||||||
|
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
import org.springframework.web.multipart.MultipartHttpServletRequest;
|
||||||
|
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 小程序临时素材接口
|
||||||
|
* Created by BinaryWang on 2017/6/16.
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/wx/media/{appId}")
|
||||||
|
public class WxMaMediaController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传临时素材
|
||||||
|
*
|
||||||
|
* @return 素材的media_id列表,实际上如果有的话,只会有一个
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public List<String> uploadMedia(@PathVariable String appId, HttpServletRequest request) throws WxErrorException {
|
||||||
|
final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
||||||
|
|
||||||
|
CommonsMultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext());
|
||||||
|
|
||||||
|
if (!resolver.isMultipart(request)) {
|
||||||
|
return Lists.newArrayList();
|
||||||
|
}
|
||||||
|
|
||||||
|
MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest) request;
|
||||||
|
Iterator<String> it = multiRequest.getFileNames();
|
||||||
|
List<String> result = Lists.newArrayList();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
try {
|
||||||
|
MultipartFile file = multiRequest.getFile(it.next());
|
||||||
|
File newFile = new File(Files.createTempDir(), file.getOriginalFilename());
|
||||||
|
this.logger.info("filePath is :" + newFile.toString());
|
||||||
|
file.transferTo(newFile);
|
||||||
|
WxMediaUploadResult uploadResult = wxService.getMediaService().uploadMedia(WxMaConstants.KefuMsgType.IMAGE, newFile);
|
||||||
|
this.logger.info("media_id : " + uploadResult.getMediaId());
|
||||||
|
result.add(uploadResult.getMediaId());
|
||||||
|
} catch (IOException e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下载临时素材
|
||||||
|
*/
|
||||||
|
@GetMapping("/download/{mediaId}")
|
||||||
|
public File getMedia(@PathVariable String appId, @PathVariable String mediaId) throws WxErrorException {
|
||||||
|
final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
||||||
|
|
||||||
|
return wxService.getMediaService().getMedia(mediaId);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
package com.rymcu.vertical.wx.miniapp.controller;
|
||||||
|
|
||||||
|
import cn.binarywang.wx.miniapp.api.WxMaService;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
|
||||||
|
import cn.binarywang.wx.miniapp.bean.WxMaUserInfo;
|
||||||
|
import com.rymcu.vertical.wx.miniapp.config.WxMaConfiguration;
|
||||||
|
import com.rymcu.vertical.wx.miniapp.utils.JsonUtils;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信小程序用户接口
|
||||||
|
*
|
||||||
|
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/wx/user/{appId}")
|
||||||
|
public class WxMaUserController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登陆接口
|
||||||
|
*/
|
||||||
|
@GetMapping("/login")
|
||||||
|
public String login(@PathVariable String appId, String code) {
|
||||||
|
if (StringUtils.isBlank(code)) {
|
||||||
|
return "empty jscode";
|
||||||
|
}
|
||||||
|
|
||||||
|
final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
||||||
|
|
||||||
|
try {
|
||||||
|
WxMaJscode2SessionResult session = wxService.getUserService().getSessionInfo(code);
|
||||||
|
this.logger.info(session.getSessionKey());
|
||||||
|
this.logger.info(session.getOpenid());
|
||||||
|
//TODO 可以增加自己的逻辑,关联业务相关数据
|
||||||
|
return JsonUtils.toJson(session);
|
||||||
|
} catch (WxErrorException e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
return e.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 获取用户信息接口
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@GetMapping("/info")
|
||||||
|
public String info(@PathVariable String appId, String sessionKey,
|
||||||
|
String signature, String rawData, String encryptedData, String iv) {
|
||||||
|
final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
||||||
|
|
||||||
|
// 用户信息校验
|
||||||
|
if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
|
||||||
|
return "user check failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密用户信息
|
||||||
|
WxMaUserInfo userInfo = wxService.getUserService().getUserInfo(sessionKey, encryptedData, iv);
|
||||||
|
|
||||||
|
return JsonUtils.toJson(userInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 获取用户绑定手机号信息
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@GetMapping("/phone")
|
||||||
|
public String phone(@PathVariable String appId, String sessionKey, String signature,
|
||||||
|
String rawData, String encryptedData, String iv) {
|
||||||
|
final WxMaService wxService = WxMaConfiguration.getMaService(appId);
|
||||||
|
|
||||||
|
// 用户信息校验
|
||||||
|
if (!wxService.getUserService().checkUserInfo(sessionKey, rawData, signature)) {
|
||||||
|
return "user check failed";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解密
|
||||||
|
WxMaPhoneNumberInfo phoneNoInfo = wxService.getUserService().getPhoneNoInfo(sessionKey, encryptedData, iv);
|
||||||
|
|
||||||
|
return JsonUtils.toJson(phoneNoInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package com.rymcu.vertical.wx.miniapp.utils;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author <a href="https://github.com/binarywang">Binary Wang</a>
|
||||||
|
*/
|
||||||
|
public class JsonUtils {
|
||||||
|
private static final ObjectMapper JSON = new ObjectMapper();
|
||||||
|
|
||||||
|
static {
|
||||||
|
JSON.setSerializationInclusion(Include.NON_NULL);
|
||||||
|
JSON.configure(SerializationFeature.INDENT_OUTPUT, Boolean.TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String toJson(Object obj) {
|
||||||
|
try {
|
||||||
|
return JSON.writeValueAsString(obj);
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -46,9 +46,9 @@ public class WxMenuController {
|
|||||||
public String menuCreateSample(@PathVariable String appId) throws WxErrorException, MalformedURLException {
|
public String menuCreateSample(@PathVariable String appId) throws WxErrorException, MalformedURLException {
|
||||||
WxMenu menu = new WxMenu();
|
WxMenu menu = new WxMenu();
|
||||||
WxMenuButton button1 = new WxMenuButton();
|
WxMenuButton button1 = new WxMenuButton();
|
||||||
button1.setType(MenuButtonType.CLICK);
|
button1.setType(MenuButtonType.VIEW);
|
||||||
button1.setName("今日歌曲");
|
button1.setName("官方网站");
|
||||||
button1.setKey("V1001_TODAY_MUSIC");
|
button1.setUrl("https://rymcu.com");
|
||||||
|
|
||||||
// WxMenuButton button2 = new WxMenuButton();
|
// WxMenuButton button2 = new WxMenuButton();
|
||||||
// button2.setType(WxConsts.BUTTON_MINIPROGRAM);
|
// button2.setType(WxConsts.BUTTON_MINIPROGRAM);
|
||||||
@ -58,7 +58,7 @@ public class WxMenuController {
|
|||||||
// button2.setUrl("http://mp.weixin.qq.com");
|
// button2.setUrl("http://mp.weixin.qq.com");
|
||||||
|
|
||||||
WxMenuButton button3 = new WxMenuButton();
|
WxMenuButton button3 = new WxMenuButton();
|
||||||
button3.setName("菜单");
|
button3.setName("学习教程");
|
||||||
|
|
||||||
menu.getButtons().add(button1);
|
menu.getButtons().add(button1);
|
||||||
// menu.getButtons().add(button2);
|
// menu.getButtons().add(button2);
|
||||||
@ -66,38 +66,26 @@ public class WxMenuController {
|
|||||||
|
|
||||||
WxMenuButton button31 = new WxMenuButton();
|
WxMenuButton button31 = new WxMenuButton();
|
||||||
button31.setType(MenuButtonType.VIEW);
|
button31.setType(MenuButtonType.VIEW);
|
||||||
button31.setName("搜索");
|
button31.setName("51单片机");
|
||||||
button31.setUrl("http://www.soso.com/");
|
button31.setUrl("https://rymcu.com/article/27");
|
||||||
|
|
||||||
WxMenuButton button32 = new WxMenuButton();
|
// WxMenuButton button34 = new WxMenuButton();
|
||||||
button32.setType(MenuButtonType.VIEW);
|
// button34.setType(MenuButtonType.VIEW);
|
||||||
button32.setName("视频");
|
// button34.setName("获取用户信息");
|
||||||
button32.setUrl("http://v.qq.com/");
|
//
|
||||||
|
// ServletRequestAttributes servletRequestAttributes =
|
||||||
WxMenuButton button33 = new WxMenuButton();
|
// (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
||||||
button33.setType(MenuButtonType.CLICK);
|
// if (servletRequestAttributes != null) {
|
||||||
button33.setName("赞一下我们");
|
// HttpServletRequest request = servletRequestAttributes.getRequest();
|
||||||
button33.setKey("V1001_GOOD");
|
// URL requestURL = new URL(request.getRequestURL().toString());
|
||||||
|
// String url = this.wxService.switchoverTo(appId).oauth2buildAuthorizationUrl(
|
||||||
WxMenuButton button34 = new WxMenuButton();
|
// String.format("%s://%s/wx/redirect/%s/greet", requestURL.getProtocol(), requestURL.getHost(), appId),
|
||||||
button34.setType(MenuButtonType.VIEW);
|
// WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
|
||||||
button34.setName("获取用户信息");
|
// button34.setUrl(url);
|
||||||
|
// }
|
||||||
ServletRequestAttributes servletRequestAttributes =
|
|
||||||
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
|
|
||||||
if (servletRequestAttributes != null) {
|
|
||||||
HttpServletRequest request = servletRequestAttributes.getRequest();
|
|
||||||
URL requestURL = new URL(request.getRequestURL().toString());
|
|
||||||
String url = this.wxService.switchoverTo(appId).oauth2buildAuthorizationUrl(
|
|
||||||
String.format("%s://%s/wx/redirect/%s/greet", requestURL.getProtocol(), requestURL.getHost(), appId),
|
|
||||||
WxConsts.OAuth2Scope.SNSAPI_USERINFO, null);
|
|
||||||
button34.setUrl(url);
|
|
||||||
}
|
|
||||||
|
|
||||||
button3.getSubButtons().add(button31);
|
button3.getSubButtons().add(button31);
|
||||||
button3.getSubButtons().add(button32);
|
// button3.getSubButtons().add(button34);
|
||||||
button3.getSubButtons().add(button33);
|
|
||||||
button3.getSubButtons().add(button34);
|
|
||||||
|
|
||||||
this.wxService.switchover(appId);
|
this.wxService.switchover(appId);
|
||||||
return this.wxService.getMenuService().menuCreate(menu);
|
return this.wxService.getMenuService().menuCreate(menu);
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.rymcu.vertical.wx.mp.controller;
|
package com.rymcu.vertical.wx.mp.controller;
|
||||||
|
|
||||||
|
import com.rymcu.vertical.service.WxUserService;
|
||||||
import com.rymcu.vertical.util.ContextHolderUtils;
|
import com.rymcu.vertical.util.ContextHolderUtils;
|
||||||
import me.chanjar.weixin.common.api.WxConsts;
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
import me.chanjar.weixin.common.bean.WxJsapiSignature;
|
||||||
@ -23,6 +24,8 @@ public class WxoAuthController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private WxMpService wxMpService;
|
private WxMpService wxMpService;
|
||||||
|
@Resource
|
||||||
|
private WxUserService wxUserService;
|
||||||
|
|
||||||
@Value("${resource.domain}")
|
@Value("${resource.domain}")
|
||||||
private String domain;
|
private String domain;
|
||||||
@ -56,6 +59,7 @@ public class WxoAuthController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
WxMpUser wxMpUser =wxMpService.getUserService().userInfo(oAuth2AccessToken.getOpenId());
|
WxMpUser wxMpUser =wxMpService.getUserService().userInfo(oAuth2AccessToken.getOpenId());
|
||||||
|
wxUserService.saveUser(wxMpUser,appId);
|
||||||
ContextHolderUtils.getSession2().setAttribute("wxUser", wxMpUser);
|
ContextHolderUtils.getSession2().setAttribute("wxUser", wxMpUser);
|
||||||
return "redirect:" + redirectUrl;
|
return "redirect:" + redirectUrl;
|
||||||
}
|
}
|
||||||
|
17
src/main/java/mapper/SpecialDayMapper.xml
Normal file
17
src/main/java/mapper/SpecialDayMapper.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="com.rymcu.vertical.mapper.SpecialDayMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="com.rymcu.vertical.entity.SpecialDay">
|
||||||
|
<id column="id" property="idSpecialDay"></id>
|
||||||
|
<result column="special_day_name" property="specialDayName"></result>
|
||||||
|
<result column="weights" property="weights"></result>
|
||||||
|
<result column="start_time" property="startTime"></result>
|
||||||
|
<result column="expiration_time" property="expirationTime"></result>
|
||||||
|
<result column="repeat" property="repeat"></result>
|
||||||
|
<result column="repeat_cycle" property="repeatCycle"></result>
|
||||||
|
<result column="repeat_cycle_unit" property="repeatCycleUnit"></result>
|
||||||
|
<result column="created_time" property="createdTime"></result>
|
||||||
|
<result column="img_url" property="imgUrl"></result>
|
||||||
|
<result column="css_style" property="cssStyle"></result>
|
||||||
|
</resultMap>
|
||||||
|
</mapper>
|
21
src/main/java/mapper/WxUserMapper.xml
Normal file
21
src/main/java/mapper/WxUserMapper.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
|
||||||
|
<mapper namespace="com.rymcu.vertical.mapper.WxUserMapper">
|
||||||
|
<resultMap id="BaseResultMap" type="com.rymcu.vertical.entity.WxUser">
|
||||||
|
<id column="id" property="idWxUser"></id>
|
||||||
|
<result column="nickname" property="nickname"></result>
|
||||||
|
<result column="nickname" property="unionId"></result>
|
||||||
|
<result column="nickname" property="appId"></result>
|
||||||
|
<result column="nickname" property="openId"></result>
|
||||||
|
<result column="nickname" property="sex"></result>
|
||||||
|
<result column="nickname" property="sexDesc"></result>
|
||||||
|
<result column="nickname" property="headImgUrl"></result>
|
||||||
|
<result column="nickname" property="country"></result>
|
||||||
|
<result column="nickname" property="province"></result>
|
||||||
|
<result column="nickname" property="city"></result>
|
||||||
|
<result column="nickname" property="actToken"></result>
|
||||||
|
<result column="nickname" property="subscribe"></result>
|
||||||
|
<result column="nickname" property="subscribeTime"></result>
|
||||||
|
<result column="nickname" property="language"></result>
|
||||||
|
</resultMap>
|
||||||
|
</mapper>
|
Loading…
x
Reference in New Issue
Block a user