如何在项目中整合微信公众号开发 - 上篇

Springboot+Vue整合笔记【超详细】 | 作者:江夏 | 微信公众号:1024笔记 | 知乎:https://www.zhihu.com/people/qing-ni-chi-you-zi-96 | GitHub:https://github.com/JiangXia-1024?tab=repositories Part 1 目前很多公司的开发模式都是前后的分离的分工模式,这样能够做到各司其职,提高开发的效率。之前也有文章介绍了springboot项目和vue创建一个简单的前端项目,这篇文章则是将springboot和vue进行简单的整合,实现 阅读详情

目录

一、配置微信公众号测试号

二、配置weixin-java-mp

2.1 在application-dev.yml中添加配置

2.2 引入依赖

2.3 添加工具类和配置类

三、添加自定义菜单

3.1 menuController中定义方法 

3.2 menuService中重写该方法 

四、 配置内网穿透

4.1 开通隧道(需实名认证)

4.2 配置“授权回调页面域名”

4.3 配置授权回调获取用户信息接口地址 

五、编写后端接口

六、前端修改(基于vue)


最近在写web项目的过程中接触到公众号开发,在这码一码整个开发的流程

一、配置微信公众号测试号

微信测试号平台链接微信公众平台微信公众平台,给个人、企业和组织提供业务服务与用户管理能力的全新服务平台。icon-default.png?t=N7T8https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index
扫描登录进入,获取测试号信息:appID与appsecret,这两个很重要!!页面下方的二维码就是我们本次项目中使用到的测试号,可以自己扫码关注一下

​

如下是官方的开发文档,感兴趣的可以看看 微信公众平台开发概述 | 微信开放文档 (qq.com)icon-default.png?t=N7T8https://developers.weixin.qq.com/doc/offiaccount/Getting_Started/Overview.html在本项目中采用的是weixin-java-mp工具进行开发,下面对其进行配置。

二、配置weixin-java-mp

2.1 在application-dev.yml中添加配置

# 注意不是在spring下!!!
wechat:
  mpAppId: # 上面提到的两个属性复制粘贴进去
  mpAppSecret: 

2.2 引入依赖

在项目pom文件中引入依赖,记得更新重启一下项目😄

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

2.3 添加工具类和配置类

工具类

package com.oa.wechat.config;

/**
 * @author Charles
 * @create 2023-05-15-13:05
 */

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Data
@Component
@ConfigurationProperties(prefix = "wechat") //读取配置配置中写的值
public class WechatAccountConfig {
    private String mpAppId;

    private String mpAppSecret;
}

配置类

package com.oa.wechat.config;

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.stereotype.Component;

@Component
public class WeChatMpConfig {

    @Autowired
    private WechatAccountConfig wechatAccountConfig;

    @Bean
    public WxMpService wxMpService(){
        WxMpService wxMpService = new WxMpServiceImpl();
        wxMpService.setWxMpConfigStorage(wxMpConfigStorage());
        return wxMpService;
    }

    @Bean
    public WxMpConfigStorage wxMpConfigStorage(){
        WxMpDefaultConfigImpl wxMpConfigStorage = new WxMpDefaultConfigImpl();
        wxMpConfigStorage.setAppId(wechatAccountConfig.getMpAppId());
        wxMpConfigStorage.setSecret(wechatAccountConfig.getMpAppSecret());
        return wxMpConfigStorage;
    }
}

后续通过这里配置的WxMpService来操作微信公众号

三、添加自定义菜单

一个公众号肯定少不了相关的菜单栏,这里步里会讲述如何添加自定义菜单
下图是微信官方指定的菜单格式,由于官方只认这一个格式,所以我们需要将从数据库获取到的数据转换成该格式

3.1 menuController中定义方法 

@PreAuthorize("hasAuthority('bnt.menu.syncMenu')") //权限控制
@ApiOperation(value = "同步菜单")
@GetMapping("syncMenu")
public Result syncMenu() {
    menuService.syncMenu();
    return Result.success();
}

3.2 menuService中重写该方法 

@Service
public void menuServiceImpl(){
    @Autowired
    private WxMpService wxMpService;

    //获取菜单树形结构
    @Override
    public List<MenuVo> findMenuInfo() {
        List<Menu> menus = weChatMenuMapper.selectList(null);

        //获取到所有的父级菜单
        List<Menu> menusParent = menus.stream().filter(menu -> menu.getParentId().longValue() == 0)
                .collect(Collectors.toList());

        List<MenuVo> menuVoList = new ArrayList<>();
        for(Menu menu : menusParent){
            MenuVo menuVo = new MenuVo();
            BeanUtils.copyProperties(menu,menuVo);

            //获取到所有的二级目录
            List<Menu> subMenuList = menus.stream().filter(myMenu -> myMenu.getParentId().longValue() == menu.getId())
                    .sorted(Comparator.comparing(Menu::getSort))
                    .collect(Collectors.toList());
            //遍历转换
            List<MenuVo> children = new ArrayList<>();
            for(Menu menu1 : subMenuList){
                MenuVo myMenuVo  = new MenuVo();
                BeanUtils.copyProperties(menu1,myMenuVo);
                children.add(myMenuVo);
            }

            menuVo.setChildren(children);
            menuVoList.add(menuVo);
        }

        return menuVoList;
    }
    
    @Override
    public void syncMenu() {
        //将数据库中存储的数据封装为层级关系
        List<MenuVo> menuVoList = this.findMenuInfo();
        //菜单
        JSONArray buttonList = new JSONArray();
        for(MenuVo oneMenuVo : menuVoList) {
            JSONObject one = new JSONObject();
            one.put("name", oneMenuVo.getName());
            if(CollectionUtils.isEmpty(oneMenuVo.getChildren())) {
                one.put("type", oneMenuVo.getType());
                one.put("url", "http://oa.charles.vip.tunnel/#"+oneMenuVo.getUrl());
            } else {
                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());
                        //H5页面地址 这里队应的是内网穿透的地址 后面会讲
                        view.put("url", "http://oa.charles.vip.tunnel/#"+twoMenuVo.getUrl())
                    } else {
                        view.put("name", twoMenuVo.getName());
                        view.put("key", twoMenuVo.getMeunKey());
                    }
                    subButton.add(view);
                }
                one.put("sub_button", subButton);
            }
            buttonList.add(one);
        }
        //菜单
        JSONObject button = new JSONObject();
        button.put("button", buttonList);
        try {
            //固定格式 调用方法来生成菜单
            wxMpService.getMenuService().menuCreate(button.toJSONString());
        } catch (WxErrorException e) {
            throw new RuntimeException(e);
        }
    }
}

 最终效果如下图所示

四、 配置内网穿透

前面我们完成配置公众号的菜单,当点击菜单的时候会跳转到我们本地的页面中,但是由于是内网,外网无法直接访问。这时候可以采用内网穿透技术或者ip来实现功能,当然注册域名更好😁 这里以ngrok为例子进行内网穿透 ngrok.cc内网转发一条命令解决的外网访问内网问题,无需任何配置,下载客户端之后直接一条命令让外网访问您的内网不再是距离icon-default.png?t=N7T8https://ngrok.ccngrok.cc

4.1 开通隧道(需实名认证)

配置好本地端口,由于我们有两个端口所以需要两条隧道(前端页面,后端接口)

开通成功后会看到隧道id,通过下载客户端然后启动当前隧道就ok了

4.2 配置“授权回调页面域名”

在网页服务-网页账号-修改 处修改,配置的地址为后端接口的地址,比如我后端接口8080对应地址oa.charles.vip.tunnel.com (即复制该地址上去 注意无需前缀http://)

4.3 配置授权回调获取用户信息接口地址 

wechat:
      # 跟着前面配置过的myAppId等
  # 授权回调获取用户信息接口地址
  userInfoUrl: http://oa.charles.vip.tunnel.com/admin/wechat/userInfo

五、编写后端接口

在controller中我们需要定义三个方法,分别是
userInfo -- 获取用户信息 OpenId为微信的唯一标识

@GetMapping("/userInfo")
public String userInfo(@RequestParam("code") String code,
                       @RequestParam("state") String returnUrl) throws Exception {
    
    System.out.println("code " + code);
    System.out.println("returnUrl " + returnUrl);
    //获取认证token
    WxOAuth2AccessToken accessToken = wxMpService.getOAuth2Service().getAccessToken(code);
    //从token中获取openId
    String openId = accessToken.getOpenId();

    //查找user表中是否存在该openId
    LambdaQueryWrapper<SysUser> lambdaQueryWrapper = new LambdaQueryWrapper<SysUser>();
    lambdaQueryWrapper.eq(SysUser::getOpenId,openId);
    SysUser sysUser = sysUserService.getOne(lambdaQueryWrapper);

    //最终前端都是通过token来判断
    String token = "";
    //null != sysUser 说明已经绑定,反之为建立账号绑定,去页面建立账号绑定
    if(null != sysUser) {
        token = JWTHelper.createToken(sysUser.getId(), sysUser.getUsername());
        System.out.println("token " + token);
    }
    if(returnUrl.indexOf("?") == -1) {
        return "redirect:" + returnUrl + "?token=" + token + "&openId=" + openId;
    } else {
        return "redirect:" + returnUrl + "&token=" + token + "&openId=" + openId;
    }
}

authorize -- 授权登录 

@GetMapping("/authorize")
public String authorize(@RequestParam("returnUrl") String returnUrl, HttpServletRequest request) {
    //设置回调URL
    /* 1. 获取info信息地址
     *  2. 定义URL类型,这里是UserInfo
     *  3. 回调地址
    **/
    System.out.println("InfoUrl  "  + InfoUrl);
    System.out.println("returnUrl " + returnUrl);
    String redirectUrl = "";
    try {
        redirectUrl = wxMpService.getOAuth2Service().buildAuthorizationUrl(InfoUrl,
                WxConsts.OAuth2Scope.SNSAPI_USERINFO,
                URLEncoder.encode(returnUrl.replace("guiguoa", "#"), "utf-8"));
        System.out.println("微信网页端回调地址 "+redirectUrl);
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
    }

    //跳转
    return "redirect:" + redirectUrl;
}

bindPhone -- 当成功授权后,如果微信号是第一次登录,需要提供窗口给用户用户手机号绑定 

@ApiOperation(value = "微信账号绑定手机")
@PostMapping("/bindPhone")
@ResponseBody
public Result bindPhone(@RequestBody BindPhoneVo bindPhoneVo) {
    String phone = bindPhoneVo.getPhone();

    //查找user表中是否有当前记录
    SysUser sysUser = sysUserService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhone, phone));

    if(null != sysUser){
        //如果用户存在则绑定当前手机号
        sysUser.setOpenId(bindPhoneVo.getOpenId());
        sysUserService.updateById(sysUser);
    }else
        return Result.fail("找不到当前号码,请联系管理员");

    return Result.success(JWTHelper.createToken(sysUser.getId(),sysUser.getUsername()));
}

当然如果项目中配置了SpringSecurity 还需要在config中排除上述三个方法的路径

六、前端修改(基于vue)

前端的项目中主要修改两个地方,一个是src/App.vue 可以直接copy一下

<template>
  <div id="app">
    <router-view />
    <el-dialog title="绑定手机" :visible.sync="dialogVisible" width="80%" >
      <el-form ref="dataForm" :model="bindPhoneVo" size="small">
        <h4>绑定你的手机号</h4>
        <el-form-item label="手机号码">
          <el-input v-model="bindPhoneVo.phone"/>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" icon="el-icon-check" @click="saveBind()" size="small">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>

import userInfoApi from '@/api/userInfo'
export default {
  data() {
    return {
      show: true,
      dialogVisible: false,
      bindPhoneVo: {
        openId: '',
        phone: ''
      }
    };
  },
  
  created() {
    // 处理微信授权登录
    this.wechatLogin();
  },

  methods: {
    wechatLogin() {
      // 处理微信授权登录
      let token = this.getQueryString('token') || '';
      let openId = this.getQueryString('openId') || '';
      // token === '' && openId != '' 只要这种情况,未绑定账号
      if(token === '' && openId != '') {
        // 绑定账号
        this.bindPhoneVo.openId = openId
        this.dialogVisible = true
      } else {
        // 如果绑定了,授权登录直接返回token
        if(token !== '') {
          window.localStorage.setItem('token', token);
        }

        token = window.localStorage.getItem('token') || '';
        if (token == '') {
          window.location = 'http://oa.charles.vip.tunnel.com/admin/wechat/authorize?returnUrl=' + url
        }
      }
    },

    saveBind() {
      if(this.bindPhoneVo.phone.length != 11) {
        alert('手机号码格式不正确')
        return
      }

      userInfoApi.bindPhone(this.bindPhoneVo).then(response => {
        window.localStorage.setItem('token', response.data);
        this.dialogVisible = false
        window.location = 'http://oa.charles.free.idcfengye.com'
      })
    },

    getQueryString (paramName) {
      if(window.location.href.indexOf('?') == -1) return '';
      let searchString = window.location.href.split('?')[1];
      let i, val, params = searchString.split("&");
      for (i=0;i<params.length;i++) {
        val = params[i].split("=");
        if (val[0] == paramName) {
          return val[1];
        }
      }
      return '';
    }
  }
};
</script>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  color: #2c3e50;
}
</style>

另一个是src/utils/request.js 

// 创建axios实例
const service = axios.create({
  baseURL: "http://oa.charles.vip.tunnel.com", // api 的 base_url
  timeout: 30000 // 请求超时时间
});

// http response 拦截器
service.interceptors.response.use(response => {
    if (response.data.code == 208) { //登录失败

      window.location = 'http://oa.charles.vip.tunnel.com/admin/wechat/authorize?returnUrl=' + url
    } else {
      if (response.data.code == 200) {
        return response.data;
      } else {
        // 209没有权限 系统会自动跳转授权登录的,已在App.vue处理过,不需要提示
        if (response.data.code != 209) {
          alert(response.data.message || "error");
        }
        return Promise.reject(response);
      }
    }
  },
  error => {
    return Promise.reject(error.response);   // 返回接口返回的错误信息
  });

 由于篇幅过长,我将会在下一篇中讲述如何进行公众号消息推送,感谢各位看到这里🎉

微信公众号后台开发总结 微信公众号后台开发总结一、项目简介当前需要做一个公众号后台,前期需要实现的功能有:(1)      在用户关注公众号时便获取用户的信息同时还要将用户信息存入数据库。(2)      在用户给公众号发送消息时,后台能够对消息的类型进行识别同时进行回复。        从要实现的功能数量上来讲,这的确很少,但是却牵涉到很多的东西,包括后台开发环境的搭建(使用的框架、数据库选择、服务器、前端页面的选择)... 阅读详情

相关推荐

Java开发微信公众号之整合weixin-java-tools框架开发微信公众号

微信开发者接入文档 :https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1421135319 一、前言 在要做微信项目开发前,大家都会去了解微信公众号的类型和注册流程,以及不同公众号的功能使用权限,这个我前面文章也有过介绍,做微信开发公众号最起码得是一个已认证的服务号,这里我是指企业项目哈,当然如果是自己学习研究的话,直接去...

Thinkingcao的专栏 2万+

使用 weixin-java-mp(weixin-java-tools) 实现微信授权 spring boot

1.了解微信授权官方文档,微信的开发文档非常全面。 2.在微信的开发文档中,可申请测试授权账号,可以得到各自的appId 与appsecret 3.在项目pom.xml中引入weixin-java-mp ,这是别人写好的微信开发封装,我们可以直接使用 4,接下来需要做配置,如果你只是学习了解下的话,可以不用写在配置中,但我们还是正规一点,在配置文件中将你得到的appId与ap...

weixin_40703574的博客 2万+

SpringBoot 系列教程(六十五):Spring Boot整合WxJava开发微信公众号

一、前言 做微信公众号开发项目以及近两年整了,积累了一点微薄的行业经验,既然开了微信开发专栏博客,那么今天就来回忆回忆,从零开始搭建一个微信公众号开发的框架,可以用于企业级项目开发的脚手架,同时搭配博客讲解,带着大家学习,让刚接触微信开发行业的小伙伴们第一次看到我的文章时能有一种打开大门的感觉,不那么生涩,也能够看两眼我的博客,自己搭建一套自己公司或者自己学习的微信开发基础框架,这就是我的目的。 ...

Thinkingcao的专栏 7581

微信小程序生态8-基于weixin-java-mp实现微信公众号被动回复消息

在微信里有这样一个公众号【华为运动健康】,当点击最新排行的时候,公众号就会发送今天最新的运动步数给你。如下图:这里有两种格式的消息1、有头像框,有聊天框——普通消息2、消息有样式、颜色等——模板消息本篇文章主要介绍的就是如何让微信公众号自动回复消息参考文档链接:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Passive_user_reply_message.html开发之前,给大家介绍一个weixin-java-to

summon的博客 1万+

springboot整合微信公众号实现模版消息推送

本文将详细介绍如何使用Spring Boot整合微信公众号,实现模版消息推送。我们将从项目的搭建开始,逐步讲解每个步骤,并通过示例代码帮助读者更好地理解和实现这一功能。无论你是新手还是有经验的开发者,都能从中找到实用的技巧和方法。

todoitbo的博客 1万+

Java接入微信公众号weixin-java-mp-demo-springboot-master

基于Spring Boot 和 WxJava 实现的微信公众号Java后端Demo,支持多公众号

如何在项目中整合微信公众号开发 - 下篇

结合上篇的内容,我们基本实现了整合微信公众号的开发以用户提交申请为例,最好的情况下审批人应该能够看到公众号发过来的推送!!!所以下面我们来实现一下消息推送功能。

PleaseBeStrong的博客 495

weixin-java-mp-demo-springmvc:基于Spring MVC 和 WxJava 实现的微信公众号Java后端Demo

本Demo使用Spring MVC 框架实现微信公众号开发功能。 本项目为WxJava的Demo演示程序,更多Demo请 。 如果想支持多公众号,请参考spring boot版本的demo: 使用步骤: 新手遇到问题,请务必先阅读的常见问题部分,可以少走很多弯路,节省不少时间。 还有其他问题的,请 提问讨论; 配置: 复制 /src/main/resources/wx.properties.template 或者修改其扩展名生成 wx.properties 文件,填写相关配置; 使用maven运行demo程序: mvn jetty:run 或者自己打war包发布到tomcat运行; 配置微信公众号中的接口地址(微信公众平台 服务器配置 -> 服务器地址(URL)): (注意XXX需要是外网可访问的域名,需要符合微信官方的要求); 根据自己需要修改各个handler的实现,加入自己的业务

基于Vue+SpringCloudAlibaba微服务电商项目实战-技术选型-004:快速整合微信公众号开发

004:快速整合微信公众号开发1 微信公众号开发项目演示2 微信公众号开发设计原理3 基于natapp将本地项目发布到外网4 对接微信公众号测试平台5 第三方微信框架快速实现微信开发6 微信公众号数据库关键词表设计7 调用天气预报接口查询当前城市实时天气 1 微信公众号开发项目演示 今日课程任务 微信公众号架构设计原理 微信公众号如何本地开发测试 快速构建微信公众号服务项目 构建微信关键字回复内容 实现微信公众号实时查询城市温度 2 微信公众号开发设计原理 微信公众号开发的原理 当我们在微信客户端中,

枫火的博客 724

weixin-java-mp-2.8.0-API文档-中文版.zip

赠送jar包:weixin-java-mp-2.8.0.jar; 赠送原API文档:weixin-java-mp-2.8.0-javadoc.jar; 赠送源代码:weixin-java-mp-2.8.0-sources.jar; 赠送Maven依赖信息文件:weixin-java-mp-2.8.0.pom; 包含翻译后的API文档:weixin-java-mp-2.8.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.github.binarywang:weixin-java-mp:2.8.0; 标签:github、binarywang、weixin、java、mp、中文文档、jar包; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

weixin-java-mp-3.5.0-API文档-中文版.zip

赠送jar包:weixin-java-mp-3.5.0.jar; 赠送原API文档:weixin-java-mp-3.5.0-javadoc.jar; 赠送源代码:weixin-java-mp-3.5.0-sources.jar; 赠送Maven依赖信息文件:weixin-java-mp-3.5.0.pom; 包含翻译后的API文档:weixin-java-mp-3.5.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.github.binarywang:weixin-java-mp:3.5.0; 标签:github、binarywang、weixin、java、mp、中文文档、jar包; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和结构保持不变,注释和说明精准翻译,请放心使用。

Claudian 终极排查指南:Obsidian 嵌入 AI 编码助手装不上、找不到 CLI 等高频痛点快速解决

Claudian 是一个把 Claude Code、Codex、Grok 等 AI 编码助手嵌入 Obsidian 知识库的插件,让笔记库直接成为助手的工作目录。安装卡壳、CLI 找不到、Node 路径不匹配,是新手最常撞上的三堵墙。本文按「现象 → 原因 → 处理」逐条给出可落地的排查路径,并附数据流向说明,帮你一次装通、快速用起来。 [![Claudian 插件在 Obsidian 知识库中

gitblog_00753的博客 584

01_MySQL下载、安装与配置(以MySQL8.0.31版本为例)

1.点击下载好的mysql安装包 进入到mysql installer界面。2.选择MySQL Servers选项 一直下拉。

4819

WxJava微信公众号开发实战

本文从本人博客搬运,原文格式更加美观,可以移步原文阅读:WxJava微信公众号开发实战 之前我们介绍了Java如何进行微信公众号开发,阅读本文前小伙伴们可以先去了解下Java微信公众号开发 之前我们开发微信公众号时,都是要手动自己实现微信接收、响应消息的封装,消息类型的判断,access_token的过期时间管理等等,还是比较麻烦的。有没有已经封装好的开源项目来简化开发呢?这里推荐WxJava,它的地址如下: github:https://github.com/Wechat-Group/WxJava

baobao的博客 2万+

UI-TARS本地部署

UI-TARS是一个用于本地部署的交互控制模型,支持桌面应用的自动化操作。部署步骤包括:首先,从官方GitHub仓库下载项目源码和模型checkpoint;其次,使用vLLM框架进行本地模型部署,启动API服务;最后,通过客户端调用API实现功能。部署过程中可能遇到pynvml模块或模型配置问题,提供了相应的解决方案。此外,还支持通过UI-TARS-Desktop客户端进行本地桌面应用的交互控制。整体流程旨在帮助用户快速实现UI-TARS的本地部署与应用。

DYF的博客 2531

PADS Layout差分对布线实战:从规则设置到高速信号优化

本文详细讲解了在PADS Layout中进行差分对布线的完整实战流程。从在Layout中定义差分对网络,到进入Router配置线宽、间距等关键规则,再到布线实战技巧与高速信号完整性优化,系统阐述了如何确保差分信号(如USB、HDMI)的稳定传输,是高速PCB设计的核心技能。

weixin_29274969的博客 522

java整合WxJava框架,开发微信公众号

测试账号会分配一个appId和appsecret 我在这块使用的是NETAPP将内网映射为外网https://natapp.cn/ 4. 填写URL和Token,URL是微信的回调地址,Token自定义,URL为我的NetApp域名,后面跟mp中WxMpPortalController的路径 5. 这块使用的微信开发框架为WxJava框架 https://github.com/Wechat...

dawn_li的博客 1978

STM32F030F4P6实战:LL库+DMA驱动WS2812全流程(附避坑指南)

本文详细介绍了如何使用STM32F030F4P6的LL库和DMA驱动WS2812 LED灯带的全流程,包括硬件选型、CubeMX配置、LL库与DMA关键实现、数据格式转换及调试技巧。特别提供了避坑指南,帮助开发者避免常见错误,提升开发效率。

weixin_29194693的博客 484

微信公众号的整合

整合微信公众号实现第三方平台调用 因为个体公众号的权限很少,所以本文使用微信测试号来做示例 1、申请一个测试号:申请地址 2、配置服务器:用户从公众号和你自己的服务器进行交互的时候中间要经过微信的服务器,也就是 用户消息->微信服务器->自己服务器 这么一个过程,那么要让你写的代码可以和微信服务器打交道首先要先建立起你自己服务器和微信服务器之间的联系。 在你的测试号页面中的这个配置就是用来将微信服务器和你自己的服务器进行关联的,微信服务器会将请求全都发送到你填写的URL这个地址,url中得

木仕的博客 1733

RK3588上跑通Zipformer语音识别的3个坑与填坑实录(附完整编译命令)

本文详细记录了在RK3588开发板上部署Zipformer语音识别模型时遇到的三个典型问题及其解决方案,包括静态库版本冲突、编译脚本配置错误以及模型转换精度调优。文章提供了完整的编译命令和实战步骤,帮助开发者快速在边缘设备上实现高效的语音识别应用。

l6m7n8的博客 715

Vue3 - [兼容PC和手机H5] 详细监听浏览器刷新 / 关闭 / 前进后退事件,用户点击关闭和刷新页面前 “拦截“ 操作并弹出提示框(实时监听用户关闭或刷新网页,触发时文字提醒并执行自定义操作)

vue3监听页面关闭和刷新,vue3中如何监听页面刷新和关闭事件,vue3中监听浏览器窗口关闭事件,并在窗口关闭进行操作,vue3怎么只在某个页面监听,其他页面不监听,vue3监听刷新和关闭怎么离开页面时注销释放,vue3怎么阻止浏览器前进和后退并提示,页面跳转离开后依旧可以监听到刷新和关闭,vue3怎么知道用户关闭了网页,vue3如何监听刷新网页操作并截断,vue3移动端手机h5网页手机网站监听浏览器刷新关闭,vue3当页面关闭或刷新时怎么提示用户离开不保存数据,vue3项目监听浏览器窗口或标签页关闭,并

🏆 前端领域优质创作者 1万+

SpringBoot整合微信支付开发在线教育视频站点教程

SpringBoot整合微信支付开发在线教育视频站点教程

FlyingSnails的博客 594

本地快速部署谷歌开放模型Gemma教程(基于Ollama)

谷歌最近发布了新一代开源AI模型Gemma,此次发布的 Gemma 相比自家的 Gemini 更加轻量级,模型权重也一并开源。不仅可以在笔记本电脑上运行,而且还免费可商用,支持中文。运行速度飞快。

特立独行的博客 6716

微信公众号开发系列-13、基于RDIFramework.NET框架整合微信开发应用效果展示

1、前言 通过前面一系列文章的学习,我们对微信公众号开发已经有了一个比较深入和全面的了解。 微信公众号开发为企业解决那些问题呢? 我们经常看到微信公众号定制开发、微信公众平台定制开发,都不知道这些能给企业带来什么,让很多人产生疑惑,那么下面就来给你解答。 我们都知道微信公众号是微信推出的一款提资讯和服务的平台应用,但却需要通过微信公众号开发技术来真正实现平台化。那么,作为想通过移动互联网来发展业务...

.NET快速开发框架 1089

基于深度学习的茶叶等级检测识别系统:YOLOv8 + UI界面 + 数据集完整实现

随着深度学习技术的不断进步,基于计算机视觉的茶叶等级检测系统可以大大提高检测效率,提供客观一致的评估标准。本系统将利用YOLOv8进行茶叶等级的检测与识别,通过图形用户界面(UI)实现与用户的交互,提供茶叶等级分类的实时反馈。本文将详细介绍如何使用YOLOv8结合UI界面,建立一个完整的茶叶等级检测与识别系统,包括数据集的准备、模型的训练、UI的设计及完整的代码实现。本系统的目标是通过深度学习技术,结合YOLOv8模型和图形用户界面(UI),实现对茶叶等级的自动化检测与识别。

YOLO 972

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

上一篇: 解决security报错 - There is no PasswordEncoder mapped for the id “null“
下一篇: 如何在项目中整合微信公众号开发 - 下篇
美味不是堡
博客等级 码龄6年 2009粉丝 64原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值