Java项目硅谷课堂学习笔记-P10-后台系统公众号部分

1.公众号菜单管理

1.1创建模块service_wechat

在service下创建子模块service_wechat
在这里插入图片描述

1.2引入依赖

<dependencies>
    <dependency>
        <groupId>com.github.binarywang</groupId>
        <artifactId>weixin-java-mp</artifactId>
        <version>4.1.0</version>
    </dependency>
</dependencies>

1.3生成菜单相关代码

在这里插入图片描述

1.4创建启动类和配置文件

1.4.1启动类

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.atguigu")
@MapperScan("com.atguigu.ggkt.wechat.mapper")
@ComponentScan(basePackages = "com.atguigu")
public class ServiceWechatApplication {
    public static void main(String[] args) {
        SpringApplication.run(ServiceWechatApplication.class, args);
    }
}

1.4.2配置文件

# 服务端口
server.port=8305
# 服务名
spring.application.name=service-wechat

# 环境设置:dev、test、prod
spring.profiles.active=dev

# mysql数据库连接
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/glkt_wechat?characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

#返回json的全局时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#mybatis日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

mybatis-plus.mapper-locations=classpath:com/atguigu/ggkt/wechat/mapper/xml/*.xml

# nacos服务地址
spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848

#公众号id和秘钥
# 硅谷课堂微信公众平台appId
wechat.mpAppId: wx09f201e9013e81d8
# 硅谷课堂微信公众平台api秘钥
wechat.mpAppSecret: 6c999765c12c51850d28055e8b6e2eda

1.5配置网关

#service-wechat模块配置
#设置路由id
spring.cloud.gateway.routes[4].id=service-wechat
#设置路由的uri
spring.cloud.gateway.routes[4].uri=lb://service-wechat
#设置路由断言,代理servicerId为auth-service的/auth/路径
spring.cloud.gateway.routes[4].predicates= Path=/*/wechat/**

1.6开发菜单管理接口

1.6.1编写MenuController

@RestController
@RequestMapping("/admin/wechat/menu")
public class MenuController {

    @Autowired
    private MenuService menuService;

    //获取所有菜单,按照一级和二级菜单封装
    @GetMapping("findMenuInfo")
    public Result findMenuInfo() {
        List<MenuVo> list = menuService.findMenuInfo();
        return Result.ok(list);
    }

    //获取所有一级菜单
    @GetMapping("findOneMenuInfo")
    public Result findOneMenuInfo() {
        List<Menu> list = menuService.findMenuOneInfo();
        return Result.ok(list);
    }

    @ApiOperation(value = "获取")
    @GetMapping("get/{id}")
    public Result get(@PathVariable Long id) {
        Menu menu = menuService.getById(id);
        return Result.ok(menu);
    }

    @ApiOperation(value = "新增")
    @PostMapping("save")
    public Result save(@RequestBody Menu menu) {
        menuService.save(menu);
        return Result.ok(null);
    }

    @ApiOperation(value = "修改")
    @PutMapping("update")
    public Result updateById(@RequestBody Menu menu) {
        menuService.updateById(menu);
        return Result.ok(null);
    }

    @ApiOperation(value = "删除")
    @DeleteMapping("remove/{id}")
    public Result remove(@PathVariable Long id) {
        menuService.removeById(id);
        return Result.ok(null);
    }

    @ApiOperation(value = "根据id列表删除")
    @DeleteMapping("batchRemove")
    public Result batchRemove(@RequestBody List<Long> idList) {
        menuService.removeByIds(idList);
        return Result.ok(null);
    }
}

1.6.2serviceImpl层

package com.jq.wechat.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jq.model.wechat.Menu;
import com.jq.vo.wechat.MenuVo;
import com.jq.wechat.mapper.MenuMapper;
import com.jq.wechat.service.MenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 订单明细 订单明细 服务实现类
 * </p>
 *
 * @author CJQ
 * @since 2022-09-04
 */
@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    //获取所有一级菜单
    @Override
    public List<Menu> findMenuOneInfo() {
        QueryWrapper<Menu>wrapper =new QueryWrapper<>();
        wrapper.eq("parent_id",0);
        List<Menu> list = baseMapper.selectList(wrapper);
        return list;
    }
    //获取所有菜单,按照一级和二级菜单封装
    @Override
    public List<MenuVo> findMenuInfo() {
        //1.创建list数据集合,用于最终数据封装
        List<MenuVo>finalMenuList=new ArrayList<>();

        //2.查询所有菜单数据(包含一级和二级)
        List<Menu> menuList = baseMapper.selectList(null);

        // 3.从所有菜单数据中获取所有一级菜单数据(parent_id=0)
        List<Menu> oneMenuList = menuList.stream()
                                            .filter(menu -> menu.getParentId().longValue() == 0)
                                            .collect(Collectors.toList());
        //4. 封装一级菜单数据,封装到最终数据list集合
        //遍历一级菜单集合做转换
        for (Menu oneMenu :oneMenuList){
            //Menu-->MenuVo
            MenuVo oneMenuVo = new MenuVo();
            BeanUtils.copyProperties(oneMenu,oneMenuVo);

            //5. 封装二级菜单数据,(判断一级菜单和二级菜单parent_id是否相同)
            //如果相同,把二级菜单数据放到一级菜单里面

            List<Menu> twoMenuList = menuList.stream()
                    .filter(menu -> menu.getParentId().longValue() == oneMenu.getId())
                    .collect(Collectors.toList());
            //List<Menu> -->List<MenuVo>
            List<MenuVo>children=new ArrayList<>();
            for (Menu twoMenu :twoMenuList){
                MenuVo twoMenuVo = new MenuVo();
                BeanUtils.copyProperties(twoMenu,twoMenuVo);
                children.add(twoMenuVo);
            }
            //把二级菜单数据放到一级菜单里面
            oneMenuVo.setChildren(children);
            //把oneMenuVo放入最终list集合中
            finalMenuList.add(oneMenuVo);
        }


      return finalMenuList;
    }
}

1.7同步菜单(获取access_token)

  1. 调用微信接口,获取access_token
  2. 拿着access_token调用微信接口,公众号菜单同步

1.7.1接口文档

进行菜单同步时候,需要获取到公众号的access_token通过access_token进行菜单同步
接口文档

1.7.2service_wechat添加配置

# 硅谷课堂微信公众平台appId
wechat.mpAppId:
# 硅谷课堂微信公众平台api秘钥
wechat.mpAppSecret: 

1.7.3添加工具类

@Component
public class ConstantPropertiesUtil implements InitializingBean {

    @Value("${wechat.mpAppId}")
    private String appid;

    @Value("${wechat.mpAppSecret}")
    private String appsecret;

    public static String ACCESS_KEY_ID;
    public static String ACCESS_KEY_SECRET;

    @Override
    public void afterPropertiesSet() throws Exception {
        ACCESS_KEY_ID = appid;
        ACCESS_KEY_SECRET = appsecret;
    }
}

1.7.4获取access_token的controller

    //获取access_token
    @GetMapping("getAccessToken")
    public Result getAccessToken(){
        //拼接请求地址
        StringBuffer buffer = new StringBuffer();
        buffer.append("https://api.weixin.qq.com/cgi-bin/token");
        buffer.append("?grant_type=client_credential");
        buffer.append("&appid=%s");
        buffer.append("&secret=%s");

        //设置路径中的参数
        String url = String.format(buffer.toString(),
                ConstantPropertiesUtil.ACCESS_KEY_ID,
                ConstantPropertiesUtil.ACCESS_KEY_SECRET);
        try {
            String tokenString = HttpClientUtils.get(url);
            //获取access_token
            JSONObject jsonObject = JSONObject.parseObject(tokenString);
            String access_token = jsonObject.getString("access_token");
            return Result.ok(access_token);
        } catch (Exception e) {
            e.printStackTrace();
            throw new GgktException(20001,"获取access_token失败");
        }

    }

1.7.5添加配置类

package com.jq.wechat.config;

import com.jq.wechat.utils.ConstantPropertiesUtil;
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.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;

@Component
@Configuration
public class WeChatMpConfig {

    @Autowired
    private ConstantPropertiesUtil constantPropertiesUtil;

    @Bean
    public WxMpService wxMpService(){
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
    }
    @Bean
    public WxMpConfigStorage wxMpConfigStorage(){
        WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
        wxMpConfigStorage.setAppId(ConstantPropertiesUtil.ACCESS_KEY_ID);
        wxMpConfigStorage.setSecret(ConstantPropertiesUtil.ACCESS_KEY_SECRET);
        return wxMpConfigStorage;
    }
}

1.7.6同步菜单方法controller

@ApiOperation(value = "同步菜单")
@GetMapping("syncMenu")
public Result createMenu() throws WxErrorException {
    menuService.syncMenu();
    return Result.ok(null);
}

1.7.7同步菜单方法serviceImpl层

在这里插入图片描述


    //同步菜单方法
    @Override
    public void syncMenu() {
        //获取所有菜单数据
        List<MenuVo> menuVoList = this.findMenuInfo();
        //封装button里面结构,数组格式
        JSONArray buttonList = new JSONArray();
        for(MenuVo oneMenuVo:menuVoList){
            //json对象 一级菜单
            JSONObject one =new JSONObject();
            one.put("name",oneMenuVo.getName());

            //json数组,封住二级菜单
            JSONArray subButton =new JSONArray();
            for (MenuVo twoMenuVo:oneMenuVo.getChildren()) {
                JSONObject view = new JSONObject();
                view.put("type", twoMenuVo.getType());
                if(twoMenuVo.getType().equals("view")) {
                    view.put("name", twoMenuVo.getName());
                    view.put("url", "http://ggkt2.vipgz1.91tunnel.com/#"
                            +twoMenuVo.getUrl());
                } else {
                    view.put("name", twoMenuVo.getName());
                    view.put("key", twoMenuVo.getMeunKey());
                }
                subButton.add(view);
            }
            one.put("sub_button",subButton);
            buttonList.add(one);
        }
        //封装最外层的button部分
        JSONObject button =new JSONObject();
        button.put("button",buttonList);
        try {
            String menuId = this.wxMpService.getMenuService().menuCreate(button.toJSONString());
            System.out.println(menuId);
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new GgktException(20001,"公众号菜单同步失败");
        }
    }

1.8公众号菜单删除


    //公众号菜单删除
    @Override
    public void removeMenu() {
        try {
            wxMpService.getMenuService().menuDelete();
        } catch (WxErrorException e) {
            e.printStackTrace();
            throw new GgktException(20001,"公众号菜单删除失败");
        }
    }

1.9前端

1.9.1添加路由

src -> router -> index.js添加路由

1.9.2定义接口

src -> api -> wechat -> menu.js定义接口

1.9.3编写页面

创建views -> wechat -> menu -> list.vue

2.公众号普通消息

3.微信授权登录

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值