微信公众号之灵活自定义菜单显示包含数据库结构设计
前言
Github:https://github.com/HealerJean
前段时间,开发特别着急,所以对于自定义菜单的设置是以代码为基准编写的在,不能实现高可用。现在我将自定义菜单制作成数据表中,通过读取数据库表来进行创建自定义菜单
1、数据库表
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import org.hibernate.annotations.UpdateTimestamp;
import javax.persistence.*;
import java.util.Date;
/**
* @Desc: 子菜单Url
* @Author HealerJean
* @Date 2018/6/1 下午5:45.
*/
@Entity
@Table(name="wechat_menu")
@Data
@Accessors(chain = true)
public class WeChatMenu {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ApiModelProperty(value = "微信公众号 主键")
private Long wechatBusinessNoId ;
@ApiModelProperty(value = "菜单对应的eventkey")
private String eventkey ;
@ApiModelProperty(value = "view菜单对应的url或者是图片对应的url")
private String url;
@ApiModelProperty("菜单的名字")
private String name; //菜单名字
@ApiModelProperty(value = "包含图片和media以及返回菜单的文字内容")
private String value ; //菜单内容
@Temporal(TemporalType.TIMESTAMP)
@Column(columnDefinition="TIMESTAMP DEFAULT CURRENT_TIMESTAMP",insertable = true,updatable = false)
private Date cdate;
@UpdateTimestamp
@Temporal(TemporalType.TIMESTAMP)
private Date udate;
@ApiModelProperty(value = "从左到右顺序 , 1 2 3")
private Integer wOrder;
@ApiModelProperty(value = "从上到下顺序,如果是底部菜单名字 则是0")
private Integer hOrder;
@ApiModelProperty(value = "菜单类型 0 底部菜单 1 url类型 ,2 回复文字类型,3 回复图片类型")
private Integer type ;
@ApiModelProperty(value = "1表示作为子菜单,2表示作为其他选项")
private Integer useType ;
@ApiModelProperty(value = "菜单是否删除")
private Integer status ;
}
CREATE TABLE `wechat_menu` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`wechatBusinessNoId` bigint(20) DEFAULT NULL,
`url` varchar(500) COLLATE utf8mb4_bin DEFAULT NULL,
`eventkey` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
`name` varchar(50) COLLATE utf8mb4_bin DEFAULT NULL,
`value` varchar(1000) COLLATE utf8mb4_bin DEFAULT '',
`wOrder` int(11) DEFAULT '0',
`hOrder` int(11) DEFAULT '0',
`status` int(11) DEFAULT '0',
`type` int(11) DEFAULT '0',
`cdate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`udate` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`useType` int(11) DEFAULT '1' COMMENT '1表示作为子菜单,2表示作为其他选项',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
2、开始创建自定义菜单
@Slf4j
@Service
public class MenuServiceImpl implements MenuService{
@Resource
private WeChatMenuRepository weChatMenuRepository;
@Override
public String byControllerSetMenu(WeChatBusinessNo weChatBusinessNo) {
/**
ViewButton todayYouHui = new ViewButton();
todayYouHui.setName(todayYouHuiWeChatMenu.getName());
todayYouHui.setUrl(todayYouHuiWeChatMenu.getUrl());
todayYouHui.setType(WechatMenuParams.VIEW);
ClickButton FIND_CREDITS = new ClickButton();
FIND_CREDITS.setName(WechatMenuParams.YOUHUI_FIND_CREDITS);
FIND_CREDITS.setKey(WechatMenuParams.YOUHUI_FIND_CREDITS_EVENT_KEY);
FIND_CREDITS.setType(WechatMenuParams.CLICK);
BasicButton basicToday = new BasicButton();
basicToday.setName("免单活动");
basicToday.setSub_button(new BasicButton[]{ACTIVITY_INTRODUCTION,FIND_CREDITS,INVITE_QR_IMAGE,FREE_CHANGE,contactManager});
*/
List<WeChatMenu> weChatMenus = weChatMenuRepository.findByWechatBusinessNoIdAndStatusAndUseType(weChatBusinessNo.getId(), EnumDelete.可用.status, EnumGeneral.壹.status);
Menu menu = new Menu();
List<BasicButton> menuBasicButton = new ArrayList<>(); //底部菜单
Map<Integer, List<WeChatMenu>> weightMenu = weChatMenus.stream().sorted(Comparator.comparing(WeChatMenu::getWOrder)).collect(Collectors.groupingBy(WeChatMenu::getWOrder));
for(Integer wOrder:weightMenu.keySet()){
BasicButton basicButton = new BasicButton(); //纵向菜单
List<BasicButton> basicButtons = new ArrayList<>();
boolean isOnlyOne = false ; // 底部菜单是不是只有一个,false表示不是只有一个 true表示底部菜单只有一个,记得加上底部菜单的名字哦
if(weightMenu.get(wOrder).size()==2){
isOnlyOne = true ;
}
boolean finalIsOnlyOne = isOnlyOne;
weightMenu.get(wOrder).stream().sorted(Comparator.comparing(WeChatMenu::getHOrder)).forEach(
weChatMenu -> {
switch (weChatMenu.getType()){
case 0:
basicButton.setName(weChatMenu.getName().substring(weChatMenu.getName().indexOf("_")+1));
break;
case 1://1 url类型
ViewButton viewButton = new ViewButton();
viewButton.setName(weChatMenu.getName());
viewButton.setUrl(weChatMenu.getUrl());
viewButton.setType(WechatMenuParams.VIEW);
if(finalIsOnlyOne ==false){
basicButtons.add(viewButton);
}else {
menuBasicButton.add(viewButton);
break; //直接进入下一个
}
break;
case 2://2 回复文字类型
case 3://3 回复图片类型
ClickButton clickButton = new ClickButton();
clickButton.setName(weChatMenu.getName());
clickButton.setKey(weChatMenu.getEventkey());
clickButton.setType(WechatMenuParams.CLICK);
if(finalIsOnlyOne ==false){
basicButtons.add(clickButton);
}else {
menuBasicButton.add(clickButton);
break; //直接进入下一个
}
break;
default:
break;
}
}
);
if(finalIsOnlyOne==false){
basicButton.setSub_button( basicButtons.stream().toArray(BasicButton[]::new));
menuBasicButton.add(basicButton);
}
}
menu.setButton(menuBasicButton.stream().toArray(BasicButton[]::new));
String menuJson = JSONObject.fromObject(menu).toString();
log.info(menuJson);
//此处改为自己想要的结构体,替换即可
String access_token= AccessToakeUtil.getAccessToaken(weChatBusinessNo);
String createMenuUrl = WechatMenuParams.CREATE_MENU_URL+access_token;
String body = SdkHttpHelper.doJsonPost(createMenuUrl,menuJson);
log.info("创建自定义菜单 返回结果"+body);
String result = JSONObject.fromObject(body).getString("errmsg");
if(StringUtils.equals(result,"ok")){
log.info("创建自定义菜单成功");
return result;
}else{
log.error("创建创建自定义菜单失败自定义菜单失败");
}
return "创建失败";
}