- 注册微信商户
- 下载微信支付的 SDK
- 打开idea打开微信支付的sdk复制到自己的项目中
- 在项目里创建配置类,继承WXPayConfig类,在里面添加商户信息
public class MyWxPayConfig extends WXPayConfig{ @Override String getAppID() { return "商户appid"; } @Override String getMchID() { return "商户号"; } @Override String getKey() { return "证书秘钥"; } @Override InputStream getCertStream() { return null; } @Override IWXPayDomain getWXPayDomain() { MyWXPayDomain domain=new MyWXPayDomain(); return domain; } }
- 在项目中创建一个类实现IWXPayDomain接口
@Override public void report(String domain, long elapsedTimeMillis, Exception ex) { } @Override public DomainInfo getDomain(WXPayConfig config) { DomainInfo info=new DomainInfo("api.mch.weixin.qq.com",true); return info; }
- 编写场景类支付
public class TestPay { public static void main(String[] args) throws Exception { MyWxPayConfig config = new MyWxPayConfig(); WXPay wxpay = new WXPay(config); Map<String, String> data = new HashMap<String, String>(); data.put("body", "腾讯充值中心-QQ会员充值"); data.put("out_trade_no", "2022050719401100000012"); data.put("device_info", ""); data.put("fee_type", "CNY"); data.put("total_fee", "1"); data.put("spbill_create_ip", "123.12.12.123"); data.put("notify_url", "http://www.example.com/wxpay/notify"); data.put("trade_type", "NATIVE"); // 此处指定为扫码支付 data.put("product_id", "12"); try { Map<String, String> resp = wxpay.unifiedOrder(data); System.out.println(resp); } catch (Exception e) { e.printStackTrace(); } } }
- 内网穿透
网址 natapp.cn,注册登录完成实名,然后购买免费隧道,复制token,下载客户端,在exe当前目录打开cmd,输入 natapp -authtoken=token - 回应消息给微信后台
@RequestMapping("/notify_url") public void doPayNotify(HttpServletRequest request, HttpServletResponse response) throws IOException { ServletInputStream inputStream = request.getInputStream(); byte[] buffer=new byte[1024]; int len=0; while( (len= inputStream.read(buffer))!=-1 ){ System.out.println(new String(buffer,0,len)); } response.getWriter().write("<xml>\n" + " <return_code><![CDATA[SUCCESS]]></return_code>\n" + " <return_msg><![CDATA[OK]]></return_msg>\n" + "</xml>"); }
- zxing二维码生成
<!--zxing二维码生成--> <!-- https://mvnrepository.com/artifact/com.google.zxing/core --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>core</artifactId> <version>3.3.3</version> </dependency> <!--zxing二维码生成--> <!-- https://mvnrepository.com/artifact/com.google.zxing/javase --> <dependency> <groupId>com.google.zxing</groupId> <artifactId>javase</artifactId> <version>3.4.0</version> </dependency>
- 绘制二维码
// 绘制二维码 @RequestMapping("/qrcode") public void qrcode(HttpServletResponse response)throws URISyntaxException, IOException { //二维码需要包含的文本内容 String uri ="http://www.baidu.com"; HashMap<EncodeHintType,Object> hints=new HashMap<>(); hints.put(EncodeHintType.CHARACTER_SET,"UTF-8"); hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); hints.put(EncodeHintType.MARGIN,2); try { BitMatrix bitMatrix=new MultiFormatWriter().encode(uri, BarcodeFormat.QR_CODE,200,200,hints); MatrixToImageWriter.writeToStream(bitMatrix,"PNG",response.getOutputStream()); System.out.println("创建二维码完成");} catch(Exception e){ e.printStackTrace(); } }
- goeasy异步调用
goeasy:网址:https://www.goeasy.io/
加依赖<!-- goeasy 异步 --> <dependency> <groupId>io.goeasy</groupId> <artifactId>goeasy-sdk</artifactId> <version>0.3.16</version> </dependency>
在 goeasy创建应用,获取Common key及hangzhou.goeasy.io
在微信支付通知的控制层新增
GoEasy goEasy = new GoEasy( "http://rest-hangzhou.goeasy.io/v2/pubsub/publish", "BC-3d456eb942cc4926b807cdb77dfb5216"); goEasy.publish("wxpay", "success");
下单页面
<script src="http://hangzhou.goeasy.io/goeasy.js"></script> <script> //初始化 var goeasy = new GoEasy({ host:"hangzhou.goeasy.io", //若是新加坡区域:singapore.goeasy.io appkey:"BC-3d456eb942cc4926b807cdb77dfb5216", modules:['pubsub']//根据需要,传入‘pubsub’或'im’,或数组方式同时传入 }) var pubsub = goeasy.pubsub; goeasy.subscribe({ channel: "wxpay",//替换为您自己的channel onMessage: function (message) { alert("收到:"+message.content); console.log("Channel:" + message.channel + " content:" + message.content); } }); </script>
shiro依赖
<!--shiro--> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-web-starter</artifactId> <version>1.8.0</version> </dependency> <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> <version>1.4.0</version> </dependency>
数据库设计
drop database if exists springboot_shiro; create database if not exists springboot_shiro; use springboot_shiro; create table shiro_user( id int auto_increment primary key , username varchar(50), password varchar(50), salt varchar(50) )charset=utf8;
shiro 框架相关的配置类 (更多…)
upload工具类
public class UploadUtils { // 生成带有UUID新的文件名 public static String newFileName(String filename){ return UUID.randomUUID().toString().replaceAll("-","")+"_"+filename; } // 生成二级、三级目录 public static String newFilePath(String basePath,String fileName){ int hashCode = fileName.hashCode(); int path1=hashCode&15; int path2=(hashCode>>4)&15; String newPath=basePath+ File.separator+path1+File.separator+path2; File file=new File(newPath); if (!file.exists()) { file.mkdirs(); } return newPath; } }
rpm –checksig package_name.rpm
rpm –checksig mysql-community-server-5.7.38-1.el8.x86_64.rpm
gpg –export -a 3a79bd29 > 3a79bd29.asc
rpm –import 3a79bd29.asc
rpm –import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022
一、RabbitMQ 介绍
1.1 引言
- 模块之间的耦合过高,导致一个模块宕机后,全部功能都不能用了
- 同步通讯的成本偏高
1.2 RabbitMQ的介绍
市面上比较火爆的几款MQ:
ActiveMQ,RocketMQ,Kafka,RabbitMQ。
- 语言的支持:ActiveMQ,RocketMQ只支持Java语言,Kafka可以支持多门语言,RabbitMQ支持多种语言
- 效率问题:ActiveMQ,RocketMQ,Kafka效率都是毫秒级别的,RabbitMQ是微秒级别的
- 消息丢失,消息重复问题:RabbitMQ针对消息的持久化,和重复问题都有比较成熟的解决方案
- 学习成本:RabbitMQ非常简单
RabbitMQ 是由Rabbit公司去研发和维护的,最终是在Pivotal。
RabbitMQ 严格遵循AMQP协议,高级消息队列协议,帮助我们在进程之间传递异步消息。 (更多…)
启动Linux上面的服务报错
[root@iZ25n5kdt0kZ ~]# service mysqld stop
Redirecting to /bin/systemctl stop mysqld.service
解决方案:
首先使用cd命令切换目录,例:cd bin,根据具体的报错提示在对应目录下面操作mysql
1.使用如下命令操作mysql:
systemctl restart mysqld.service
systemctl start mysqld.service
systemctl stop mysqld.service
- 内嵌 WXS 脚本
xxx.wxml<view>{{m1.toUpper(username)}}</view><wxs module=”m1″>module.exports.toUpper=function(e){return e.toUpperCase()}</wxs>xxx.js
data: {username:”username”}, - 定义外联 WXS 脚本
在 tools文件夹下新建文件为 tools.wxsfunction toLower(str){return str.toLowerCase()}module.exports={toLower:toLower} - 使用外联 WXS 脚本
在WXML 中引入外联的wxs脚本时,必须为 wxs 标签添加 module 和 src 属性,其中:
module 用来指定模块的名称
src 用来指定要引入的脚本的绝对路径
- 监听页面的下拉刷新事件
在页面的.js 文件中,通过 onPullDownRefresh() 函数即可监听当前页面的下拉刷新事件 - 停止下拉刷新事件
当处理完下拉刷新后,下拉刷新的 loading 效果会一直显示,不会主动消失。
调用wx.stopPullDownRefresh() 可以停止当前页面的下拉刷新 - 监听上拉触底事件
在页面的.js 文件中,通过 onReachBottom() 函数即可监听当前页面的上拉触底事件 - 添加loading效果
- 对上拉触底进行节流处理
data:{
isLoding:false
}
getColor:{
this.setData({
isLoding:true
})
wx.request(){
success下面
complete:()=>{
wx.hideLoading()
this.setData({
isLoding:false
})
}
}
}
onReachBottom:function(){
if(this.data.isLoading) return
this.getColors()
}
- 声明式导航传参
navigator组件的url属性用来指定将要跳转到的页面的路径。同时,路径的后面还可以携带参数。
参数与路径之间使用?分隔
参数键与参数值用=相连
不同参数用&分隔
代码示例如下:
<navigator url=”/pages/info/info?username=zs&age=22″>导航传参</navigator> - 编程式导航传参
- 在 onLoad 中接收导航参数
通过声明式或编程式导航传参所携带的参数,可以直接在 onLoad 事件中 直接获取到。示例代码
- 小程序中实现页面导航的两种方式
1、声明式导航:在页面上声明一个 navigator 导航组件,通过点击 navigator 组件实现页面跳转
2、编程式导航:调用小程序的导航API,实现页面的跳转 - 声明式导航
tabBar页面指的是被配置为tabBar的页面
在使用 navigator 组件跳转到指定的 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中
url 表示要跳转的页面的地址,必须以 / 开头
open-type 表示跳转的方式,必须为 switchTab
示例代码:
<navigator url=”/pages/massage/message” open-type=”switchTab”>导航到消息页面</navigator> - 导航到非 tabBar页面
非tabBar页面指的是没有配置tabBar的页面
在使用 navigator 组件跳转到普通的非 tabBar 页面时,需要指定 url 属性和 open-type 属性,其中
url 表示要跳转的页面的地址,必须以 / 开头
open-type 表示跳转的方式,必须为 navigate
示例代码:
<navigator url=”/pages/massage/message” open-type=”navigate”>导航到消息页面</navigator> - 后退导航
如果要后退上一页面或多级页面,则需要指定 open-type 属性 和 delta 属性,其中:
open-type 的值必须是 navigateBack,表示要进行后退导航
dalta 的值必须是数字,表示要后退的层级
示例代码:
<navigator open-type=”navigateBack” delta=”1″>返回上一页</navigator>
注意:可以省略 delta,默认值是1
1. 编程式导航
1、导航到tabBar页面
调用 wx.switchTab(Object obj)方法,可以跳转到 tabBar页面。其中Object 参数对象的属性列表如下:
2. 导航到非 tabBar页面
调用 wx.navigateTo(Object obj)方法,可以跳转到非tabBar页面。其中Object 参数对象的属性列表如下:
3. 后退导航
调用wx.navigateBack(Object obj)方法,可以返回上一级或多级页面,其中 Object参数对象 可选的属性列表如下:
微信小程序之九宫格布局
页面:
- 小程序中网络数据请求的限制
出于安全性方面的考虑,小程序官方对数据接口的请求做出了如下两个限制:
1、只能请求 https 类型的接口
2、必须将接口的域名添加到信任列表里(右上角详情—>项目配置–>域名信息) - 发起GET请求
调用微信小程序提供的 wx.request() 方法,可以发起 GET数据请求,代码如下:
xxx.wxml
xxx.wxml
此时需要在页面的 onLoad 事件中调用获取数据的函数,代码如下:
此时为了不耽误开发的进度,我们可以在微信开发者工具中,临时开启「开发环境不校验请求域名、TLS 版本及HTTPS证书 选项
跳过request合法域名的校验。

- 什么是tabBar
tabBar 是移动端应用常见的页面效果,用于实现多页面的快速切换。
小程序中通常将其分为:底部 tabBar、顶部 tabBar
注意:tabBar 中只能配置 最少2个,最多5个tab页签,当渲染顶部 tabBar时,不显示 icon,只显示文本 - tabBar 的6个组成部分
- tabBar 节点的配置项
- 每个tab项的配置选项
app.json:
“tabBar”: {“list”: [{“pagePath”: “pages/home/home”,“iconPath”: “/images/home.png”,“selectedIconPath”: “/images/home-active.png”,“text”: “首页”},{“pagePath”: “pages/message/message”,“iconPath”: “/images/message.png”,“selectedIconPath”: “/images/message-active.png”,“text”: “消息”},{“pagePath”: “pages/contact/contact”,“iconPath”: “/images/contact.png”,“selectedIconPath”: “/images/contact-active.png”,“text”: “联系我们”}]},
- 全局配置文件及常用的配置项
小程序根目录下的 app.json 文件是小程序的全局配置文件。常用的配置项如下:
1:pages:记录当前小程序所有的页面存放路径
2、window:全局设置小程序窗口的外观
3、tabBar:设置小程序底部的 tabBar 效果
4、style:是否启用新版的组件样式 - 全局配置-window
1、小程序窗口的组成部分
2、 了解 window 节点 常用的配置项
3、设置导航栏的标题
设置步骤:app.json–>window–>navigationBarTitleText
演示:把导航条上的标题,从默认的 WeChat 修改为 我的第一个微信小程序,效果如图
4、设置导航栏的背景色
设置步骤:app.json–>window–>navigationBarBackgroundColor
演示:把导航栏标题的背景色,从默认的 #fff 修改为 #994855,效果如图
5、设置导航栏的标题颜色
设置步骤:app/json–>window–>navigationBarTextStyle
演示:把导航条上的标题,从默认的 black 修改为 white ,效果如图
6、全局开启下拉刷新功能
设置步骤:app.json–>window–>把 enablePullDownRefresh 设为 true,效果如图
7、 设置下拉刷新时背景颜色
当全局开启下拉刷新功能之后,默认的窗口背景为白色,如果自定义下拉刷新窗口背景色
设置步骤:app.json–>window–>为 backgroundColor 指定16进制的颜色值 #9e9e9e,效果如下
8、 设置下拉刷新时 loading 的样式
当全局开启下拉刷新功能之后,默认窗口的 loading 样式为白色,如果要更改 loading 样式的效果
设置步骤:app.json–>window–>为 backgroundTextStyle 指定 dark 值
可选值为 light 和 dark
9、设置上拉触底的距离
概念:上拉加载更多数据
设置步骤:app.json–>window–>为 onReachBottomDistance 设置新值。默认50px,px可省略
- 全局样式
定义在 app.wxss 中的样式为全局样式,作用于每一个页面 - 局部样式
在页面的.wxss 中的样式为局部样式,作用于当前页面
- 什么是WXSS
WXSS(WeiXin Style Sheets)是一套样式语言,用于美化 WXML 的组件样式,类似于网页开发中的 CSS - WXSS 与 CSS 的 关系
WXSS具有Css大部分特性,同时,WXSS 还对 CSS 进行了扩充以及修改,以适应微信小程序的开发。
与 CSS 相比,WXSS 扩展的特性有:
1、rpx 尺寸单位 2、@import 样式导入 - 什么是 rpx 尺寸单位
rpx (responsive pixel) 是微信小程序独有的,用来解决屏适配的尺寸单位。 - rpx 实现原理
rpx的实现原理非常简单:鉴于不同设备屏幕的大小不同,为了实现屏幕的自动适配,rpx把所有设备的屏幕,在宽度上等分为 750 份(即:当前屏幕的总宽度为750rpx)。
小程序在不同设备上运行的时候,会自动把rpx的样式单位换算成对应的像素单位来渲染,从而实现屏幕适配。 - 样式导入
使用WXSS 提供的 @import 语法,可以导入外联的样式表 - @import 的语法格式
@import 后跟需要导入的外联样式表的相对路径,用 ; 表示语句结束。示例:
@import “xxx.wxss”;
1.wx:for
通过 wx:for 可以根据指定的数组,循环渲染重复的组件结构,语法如下:
js里data:
1.wx:if
在小程序中,使用 wx:if=”{{condition}}” 来判断是否需要渲染该代码块
在 data里 设置属性 sex: 1
true显示,false隐藏
通过 bindinput 可以为文本框绑定输入事件