硅谷课堂笔记(中)
文章目錄
- 復習SpringCloud
- 后臺開發-訂單管理模塊
- 整合網關Gateway
- 網關bug
- 網關Gateway解決跨域
- 修改前端配置文件
- 后臺開發-訂單管理模塊
- 需求概述
- 基礎環境搭建
- 開發訂單列表接口
- 集成訂單前端頁面
- 啟動測試
- 后臺開發-營銷管理模塊
- 基礎環境搭建
- 創建用戶模塊
- 創建遠程調用模塊
- 開發相關接口
- 整合營銷管理前端頁面
- 微信公眾號
- 測試公眾號(重要)
- 開發業務介紹
- 后臺管理系統-公眾號菜單管理
- 需求分析
- 管理頁面
- 后端基礎環境搭建
- 公眾號管理接口開發
- 公眾號菜單同步
- 同步菜單(獲取access_token)
- 文檔查看
- service_wechat添加配置
- 添加工具類
- 復制相關工具類
- 添加Menucontroller方法
- 同步菜單(功能實現)
- 添加配置類
- 同步方法編寫
- 整合前端
- 測試
- 公眾號普通消息
- 需求分析
- 后臺消息接入
- 消息接入
- 后端接口開發
- 消息校驗接口
- 消息接收接口
- 配置內網穿透
- 何為內網穿透
- 配置內網穿透ngrok(不好用)
- 免費內網穿透花生殼(用這個)
- 內網穿透測試
- 后臺開發-消息業務實現
- 業務流程
- 開發接口
- 遠程調用模塊構建
- 公眾號模塊引入遠程調用
- 測試
- 公眾號模板消息
- 正式公眾號模板申請
- 查看模板樣式
- 公眾號測試號申請模板消息
- 公眾號后臺設置
- 后端相應接口
- 測試
- 微信授權登陸
- 需求分析
- 授權登錄介紹
- 公眾號正式號配置
- 公眾號測試號配置
- 部署前端頁面
- 前端處理
- 授權登錄接口開發
- 測試
- Token(重要)
- JWT介紹
- JWT原理
- 看看Token長什么樣子
- 整合JWT
- 公眾號點播課程
- 需求分析
- 分頁展示接口開發
- 整合前端
- 點播視頻播放接口開發
- 整合前端
- 付費觀看點播課程接口
- Feign創建獲取課程信息接口
- Feign創建獲取優惠卷操作接口
- 獲取當前用戶id
- 生成訂單
復習SpringCloud
也是這里篇幅比較多,我單獨開一篇去復習
復習SpringCloud
SpringCloud系列學習:
Spring Cloud 上
Spring Cloud 中
Spring Cloud 下 (SpringCloud alibaba)
后臺開發-訂單管理模塊
引入Nacos,把之前的注解打開
配置Nacos客戶端的pom依賴
提前引入微服務相關依賴,具體的版本控制:
配置service_vod
配置application.properties,在客戶端微服務中添加注冊Nacos服務的配置信息
添加Nacos客戶端注解
在service_vod微服務啟動類中添加注解
@EnableDiscoveryClient
再次啟動服務就會發現,新的服務已經注冊進入Nacos了
整合網關Gateway
網關也是一種服務,所以這里也要建設一個模塊,整合網關服務
POM文件
<dependencies><!--工具服務引入,包括里面的全局異常處理等--><dependency><groupId>com.cc</groupId><artifactId>service_utils</artifactId><version>0.0.1-SNAPSHOT</version></dependency><!-- 網關 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId></dependency><!-- 服務注冊 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency></dependencies>創建啟動類并且添加注解
網關bug
網關啟動類要和跨域配置類放在一個包下,而且啟動網關一定要提前啟動nacos,不然啟動不起來
把配置文件寫一下,application.properties
# 服務端口 server.port=8333# 服務名 spring.application.name=service-gateway# nacos服務地址 spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848#使用服務發現路由 spring.cloud.gateway.discovery.locator.enabled=true#service-vod模塊配置 #設置路由id,也就是Nacos里面注冊的服務名字 spring.cloud.gateway.routes[0].id=service-vod #設置路由的uri lb:load Balance 負載均衡 spring.cloud.gateway.routes[0].uri=lb://service-vod #設置路由斷言,代理servicerId為auth-service的/auth/路徑 #實際上斷言就是路徑匹配 /a/vod/b/c/d... spring.cloud.gateway.routes[0].predicates= Path=/*/vod/**網關Gateway解決跨域
跨域概述
跨域本質是瀏覽器對于ajax請求的一種安全限制:一個頁面發起的ajax請求,只能是與當前頁域名相同的路徑,這能有效的阻止跨站攻擊。因此:跨域問題 是針對ajax的一種限制。但是這卻給我們的開發帶來了不便,而且在實際生產環境中,肯定會有很多臺服務器之間交互,地址和端口都可能不同。
之前我們通過服務器添加注解實現,現在我們跨域通過網關來解決跨域問題。
創建配置類
這里配置好了跨域,之前的跨域注解一定去掉,如果沒去掉就相當于跨域跨進去了再跨出來,就相當于沒跨
**注意:**目前我們已經在網關做了跨域處理,那么service服務就不需要再做跨域處理了,將之前在controller類上添加過@CrossOrigin標簽的去掉==
修改前端配置文件
找到那個開發文件配置
修改接口為網關地址,讓服務請求先打到網關上
后臺開發-訂單管理模塊
需求概述
這個模塊很簡單,只有一個訂單的分頁處理,把已有的訂單展示一下就好了
基礎環境搭建
在網關模塊的配置文件中,把訂單模塊劃入網關進行治理
相關表數據庫:
訂單信息
訂單詳情
這倆表是一對一的關系
創建訂單模塊
service模塊下創建service_order模塊
用MP的代碼生成器生成一下相關表的內容,就用之前模塊下面的代碼生成器就可以了,改一遍包路徑和表
生成相關代碼和啟動類
記得在service父模塊把子模塊的信息添加進去,要不然沒依賴
在訂單模塊里,也要改一下,不改默認是吧最頂層的onlineClass作為父模塊依賴
添加配置文件application.properties
# 服務端口 server.port=8302# 服務名 spring.application.name=service-order# 環境設置:dev、test、prod spring.profiles.active=dev# mysql數據庫連接 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3307/glkt_order?characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456#返回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.StdOutImplmybatis-plus.mapper-locations=classpath:com/service_order/mapper/xml/*.xml分頁插件配置類
到這,基礎環境搭建完畢,開始開發
開發訂單列表接口
Controller位置:
ServiceImpl位置:
用Map封裝的結果數據
前端解析好的數據
集成訂單前端頁面
在API目錄下,新建Order文件夾,創建Order.js
把路由創建好
最后整合頁面
創建views -> order -> orderInfo -> list.vue
CV樣式
啟動測試
先啟動nacos
三個服務也都啟動
后臺開發-營銷管理模塊
基礎環境搭建
相關數據庫
coupon info 優惠卷信息
coupon use 優惠卷使用情況
新建工程
父工程依賴修改
子模塊POM
代碼生成器生成相關類
創建配置文件
GateWay網關注冊相關信息
創建分頁配置類
因為涉及到優惠卷的使用情況,所以要把用戶信息拿到,才能知道這個優惠卷的使用情況如何。所以需要Nacos管理服務+Fegin遠程接口調用
創建用戶模塊
這個模塊只負責遠程調用
用戶表
創建模塊、生成代碼、配置文件、配置網關,這些就不多贅述了,弄好之后是這樣的
這里已經寫好了關于用戶返回的Controller,可以注意到,已經不是返回Result了,已經是返回UserInfo了
這寫完了,就得創建遠程調用的模塊了
創建遠程調用模塊
次級父模塊service_client的依賴如下
創建完就是這樣的
創建遠程調用接口,和被調用接口進行講解
最后,把這個模塊在需要被調用的接口通過pom進行引入,最好是把他放在服務的父工程中,這樣下面的下屬子模塊就不需要去再重復引入依賴了
能這么調用的前提是,你在對應的pom里有這樣一段標簽,相當于這個模塊被調用時的 “標簽” ,否則調用不了
還要在需要進行調用的模塊主啟動類上加入注解
現在就可以進行遠程調用了
配好了直接注入就能用!
最好是在Service模塊把這個遠程調用模塊的接口整體注入進父模塊下,這樣就不用Service下屬子模塊都跟著引入相關依賴了,非常的方便~
開發相關接口
Controller位置:
ServiceImpl位置:
這里解釋一下,有個繼承類
其他參數就是擴展類
優惠卷這個實體類在最后的一步有個集成用戶信息的步驟,就是通過實體類擴展實現的,getParam也就對應了BaseMapper中的para Map屬性
具體可以在代碼查看,這里篇幅有限
這些都寫完,記得把這個服務注冊進路由
#service-activity模塊配置 #設置路由id spring.cloud.gateway.routes[4].id=service-activity #設置路由的uri spring.cloud.gateway.routes[4].uri=lb://service-activity #設置路由斷言,代理servicerId為auth-service的/auth/路徑 spring.cloud.gateway.routes[4].predicates= Path=/*/activity/**整合營銷管理前端頁面
定義JS的API
創建api -> activity -> couponInfo.js**
把路由修改好
router -> index.js定義路由
定義好的樣式
粘貼頁面樣式
最終頁面效果
微信公眾號
簡介
微信公眾平臺:https://mp.weixin.qq.com/
硅谷課堂要求基于H5,具有微信支付等高級功能的,因此需要注冊服務號,訂閱號不具備支付功能。
注冊步驟參考官方注冊文檔:https://kf.qq.com/faq/120911VrYVrA151013MfYvYV.html
注冊過程僅做了解,有公司運營負責申請與認證。
如果只是日常簡單的推送文章,就像我們關注的大多數公眾號一樣,那確實不需要技術人員去開發;但是,如果你想將你們的網站嵌入進去公眾號菜單里(這里指的是把前端項目的首頁鏈接配置在自定義菜單),并且實現微信端的獨立登錄認證、獲取微信用戶信息、微信支付等高級功能,或者覺得UI交互的配置方式無法滿足你的需求,你需要更加自由、隨心所欲的操作,那么我們就必須啟用開發者模式了,通過技術人員的手段去靈活控制公眾號。
這里有一點需要注意,如果我們決定技術人員開發公眾號,必須啟用服務器配置,而這將導致UI界面設置的自動回復和自定義菜單失效!
我們在 設置與開發 - 基本配置 - 服務器配置 中點擊啟用:
測試公眾號(重要)
前面說了,個人無法去申請服務號,必須企業,但是我們可以通過測試賬戶進行學習
微信公眾平臺接口測試帳號:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login&token=399029368&lang=zh_CN
查看測試號管理
(1)其中appID和appsecret用于后面菜單開發使用
(2)其中URL是開發者用來接收微信消息和事件的接口URL。Token可由開發者可以任意填寫,用作生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性)。本地測試,url改為內網穿透地址。
關注公眾號
開發業務介紹
硅谷課堂涉及的微信公眾號功能模塊:自定義菜單、消息、微信支付、授權登錄等
后臺管理系統-公眾號菜單管理
需求分析
微信自定義菜單說明
微信自定義菜單文檔地址:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
微信自定義菜單注意事項:
在線課堂自定義菜單
一級菜單:直播、課程、我的
二級菜單:根據一級菜單動態設置二級菜單,直播(近期直播課程),課程(課程分類),我的(我的訂單、我的課程、我的優惠券及關于我們)
說明:
? 1、二級菜單可以是網頁類型,點擊跳轉H5頁面
? 2、二級菜單可以是消息類型,點擊返回消息
數據格式
自定義菜單通過后臺管理設置到數據庫表,數據配置好后,通過微信接口推送菜單數據到微信平臺。
管理頁面
如圖所示
(1)頁面功能“列表、添加、修改與刪除”是對menu表的操作
(2)頁面功能“同步菜單與刪除菜單”是對微信平臺接口操作
后端基礎環境搭建
表結構(menu):
新建模塊
這里就不多說了,文件夾,注冊網關,主啟動類,代碼生成、修改POM這些上面都有
配置文件
# 服務端口 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:3307/glkt_wechat?characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456#返回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.StdOutImplmybatis-plus.mapper-locations=classpath:src/main/java/com/service_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公眾號管理接口開發
除了常見的接口以外,這里有兩個比較重要的接口
一個是獲取一級菜單
另一個是獲取全部菜單
位置:
公眾號菜單同步
同步菜單(獲取access_token)
文檔查看
(1)進行菜單同步時候,需要獲取到公眾號的access_token,通過access_token進行菜單同步
接口文檔:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Get_access_token.html
(2)調用方式
service_wechat添加配置
這個是老師的測試號,當然可以換成自己的!
# 硅谷課堂微信公眾平臺appId wechat.mpAppId: wx09f201e9013e81d8 # 硅谷課堂微信公眾平臺api秘鑰 wechat.mpAppSecret: 6c999765c12c51850d28055e8b6e2eda添加工具類
讀取公眾號API的工具
@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;@Overridepublic void afterPropertiesSet() throws Exception {ACCESS_KEY_ID = appid;ACCESS_KEY_SECRET = appsecret;} }復制相關工具類
添加Menucontroller方法
在Controller中添加方法,返回token使用
同步菜單(功能實現)
接口文檔:https://developers.weixin.qq.com/doc/offiaccount/Custom_Menus/Creating_Custom-Defined_Menu.html
接口調用請求說明
http請求方式:POST(請使用https協議) https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN
weixin-java-mp是封裝好了的微信接口客戶端,使用起來很方便,后續我們就使用weixin-java-mp處理微信平臺接口。
添加配置類
添加微信相關配置類
同步方法編寫
還是在Controller
要求的數據格式
service實現層
為什么直接用了JSON數組,是因為這里直接對接公眾號的數據
不再有Controller的JSON轉換解析,所以這里直接做成JSON
一層一層向上封裝的
/*** 說明:* 自定義菜單最多包括3個一級菜單,每個一級菜單最多包含5個二級菜單。* 一級菜單最多4個漢字,二級菜單最多8個漢字,多出來的部分將會以“...”代替。* 創建自定義菜單后,菜單的刷新策略是,在用戶進入公眾號會話頁或公眾號profile頁時,* 如果發現上一次拉取菜單的請求在5分鐘以前,就會拉取一下菜單,如果菜單有更新,就會刷新客戶端的菜單。* 測試時可以嘗試取消關注公眾賬號后再次關注,則可以看到創建后的效果。* 實際上就是把自己菜單的JSON格式轉換成微信認識的格式*/@SneakyThrows@Overridepublic void syncMenu() {List<MenuVo> menuVoList = this.findMenuInfo();//菜單,創建一個JSON格式數組,這里為什么用了JSON數組,是因為這里直接對接公眾號//不再有Controller的JSON轉換解析,所以這里直接做成JSONJSONArray buttonList = new JSONArray();//一級菜單for(MenuVo oneMenuVo : menuVoList) {JSONObject one = new JSONObject();//name是一級菜單的固定名稱one.put("name", oneMenuVo.getName());//二級菜單JSONArray subButton = new JSONArray();for(MenuVo twoMenuVo : oneMenuVo.getChildren()) {JSONObject view = new JSONObject();//type是二級菜單的固定名稱view.put("type", twoMenuVo.getType());//根據type的值進行判斷,是按鈕還是關鍵詞觸發返回信息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);}//封裝二級菜單,固定叫sub_buttonone.put("sub_button", subButton);//封裝一級菜單buttonList.add(one);}//菜單整體封裝,一級+二級 一起叫buttonJSONObject button = new JSONObject();button.put("button", buttonList);this.wxMpService.getMenuService().menuCreate(button.toJSONString());}整合前端
src -> router -> index.js添加路由
src -> api -> wechat -> menu.js定義接口
創建views -> wechat -> menu -> list.vue CV頁面
最終樣式
測試
關注測試公眾號,電腦登陸公眾號,就可以進行測試了
數據就同步上來了
如果更換了配置信息,就要在這里同步一下,不同步菜單的話數據上不來,因為微信公眾號是不會主動請求更新的,需要咱們主動數據推送
公眾號普通消息
需求分析
輸入特定詞語,返回消息
1、“硅谷課堂”公眾號實現根據關鍵字搜索相關課程,如:輸入“java”,可返回java相關的一個課程;
2、“硅谷課堂”公眾號點擊菜單“關于我們”,返回關于我們的介紹
3、關注或取消關注等
后臺消息接入
消息接入
參考文檔:https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html
接入微信公眾平臺開發,開發者需要按照如下步驟完成:
1、填寫服務器配置
2、驗證服務器地址的有效性
3、依據接口文檔實現業務邏輯
公眾號服務器配置
在測試管理 -> 接口配置信息,點擊“修改”按鈕,填寫服務器地址(URL)和Token,其中URL是開發者用來接收微信消息和事件的接口URL。Token可由開發者可以任意填寫,用作生成簽名(該Token會和接口URL中包含的Token進行比對,從而驗證安全性)
說明:本地測試,url改為內網穿透地址,這個內網穿透在后面會仔細講解
驗證來自微信服務器消息
(1)概述
開發者提交信息后,微信服務器將發送GET請求到填寫的服務器地址URL上,GET請求攜帶參數如下表所示:
| signature | 微信加密簽名,signature結合了開發者填寫的token參數和請求中的timestamp參數、nonce參數。 |
| timestamp | 時間戳 |
| nonce | 隨機數 |
| echostr | 隨機字符串 |
開發者通過檢驗signature對請求進行校驗(下面有校驗方式)。若確認此次GET請求來自微信服務器,請原樣返回echostr參數內容,則接入生效,成為開發者成功,否則接入失敗。加密/校驗流程如下:
1、將token、timestamp、nonce三個參數進行字典序排序
2、將三個參數字符串拼接成一個字符串進行sha1加密
3、開發者獲得加密后的字符串可與signature對比,標識該請求來源于微信
消息接收流程
后端接口開發
消息校驗接口
實際上就是接收四個參數,而且使用HttpRequest對象來接收
接口位置
定義好Token,方便和微信后臺設置的內容校驗
兩個方法名
/*** 服務器有效性驗證* @param request* @return*/public String verifyToken(HttpServletRequest request) {private boolean checkSignature(String signature, String timestamp, String nonce)完成之后,我們的校驗接口就算是開發完成了。接下來就可以開發消息接收接口了。
消息接收接口
接下來我們來開發消息接收接口,消息接收接口和上面的服務器校驗接口地址是一樣的,都是我們一開始在公眾號后臺配置的地址。只不過消息接收接口是一個 POST 請求。
在公眾號后臺配置的時候,消息加解密方式選擇了明文模式,這樣在后臺收到的消息直接就可以處理了。微信服務器給我發來的普通文本消息格式如下:
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId> </xml>| ToUserName | 開發者微信號 |
| FromUserName | 發送方帳號(一個OpenID) |
| CreateTime | 消息創建時間 (整型) |
| MsgType | 消息類型,文本為text |
| Content | 文本消息內容 |
| MsgId | 消息id,64位整型 |
看到這里,大家心里大概就有數了,當我們收到微信服務器發來的消息之后,我們就進行 XML 解析,提取出來我們需要的信息,去做相關的查詢操作,再將查到的結果返回給微信服務器。
這里我們先來個簡單的,我們將收到的消息解析并打印出來:
還是在同一個Controller里
配置內網穿透
何為內網穿透
前面已經說過了,要微信服務器和本地的服務器進行通信。
我們可以找到微信服務器,但是微信服務器找不到我們的本地主機
這個時候就需要內網穿透幫忙了
所謂的開通一個隧道,就是申請一個域名,讓微信服務器可以通過這個域名(隧道)訪問到你本地
配置內網穿透ngrok(不好用)
注冊用戶
網址:https://ngrok.cc/login/register
實名認證
(1)注冊成功之后,登錄系統,進行實名認證,認證費2元,認證通過后才能開通隧道
開通隧道
(1)選擇隧道管理 -> 開通隧道
最后一個是免費服務器,建議選擇付費服務器,10元/月,因為免費服務器使用人數很多,經常掉線
(2)點擊立即購買 -> 輸入相關信息
(3)開通成功后,查看開通的隧道
這里開通了兩個隧道,一個用于后端接口調用,一個用于公眾號前端調用
啟動隧道
(1)下載客戶端工具
(2)選擇windows版本
(3)解壓,找到bat文件,雙擊啟動
(4)輸入隧道id,多個使用逗號隔開,最后回車就可以啟動
tnnd,連不上
正常如果連上了應該是這個樣子
免費內網穿透花生殼(用這個)
花生殼官網 花生殼打錢!
注冊下載什么的我就不說了,安裝好配置一下
這樣就可以使用了!
一共要生成兩個,一個給前端做隧道,另一個給后端做穿透
畢竟兩個項目都在本地跑,想讓外網訪問不用隧道穿透肯定是不行的
但是如果想用HTTP服務必須花錢,再開一個,如果是學生的話可以免費開通
我認證了一下,就可以免費用兩個HTTP了,TCP連前端連不上
快說,謝謝花生殼~
回到公眾號這里,再來捋一遍,先看看自己的公眾測試號
微信公眾平臺測試號后臺
URL就不說了,就是配置好的內網穿透地址+后端服務器有效性驗證 的路徑
Token可以看后端代碼
內網穿透測試
向測試公眾號里發一個消息,看看后臺是否可以接收到
可以看到,已經接受到了結構化的數據了
后臺開發-消息業務實現
業務流程
開發接口
根據課程名稱返回課程信息,就是根據課程名稱進行模糊查詢
service_vod模塊創建接口
(1)創建CourseApiController方法,根據課程關鍵字查詢課程信息
遠程調用模塊構建
創建模塊定義接口
service_client下創建子模塊service_course_client,改Pom之類的就不多說了
把課程查詢的遠程調用整合到一個單獨的遠程調用子模塊中
公眾號模塊引入遠程調用
主啟動類
service_wechat引入更改寫好的遠程調用依賴
<dependency><artifactId>service_course_client</artifactId><groupId>com.courseFeginService</groupId><version>0.0.1-SNAPSHOT</version></dependency>創建消息處理接口
將微信模塊的MessageController方法進行更改,根據關鍵字內容進行校驗
具體的消息結果處理在MessageServiceImpl,根據關鍵字返回比較固定,把這個基本代碼改改就可以用了
測試
把Nacos、內網隧道、服務都啟動
(1)點擊個人 -> 關于我們,返回關于我們的介紹
(2)在公眾號輸入關鍵字,返回搜索的課程信息
公眾號模板消息
正式公眾號模板申請
這種是非測試公眾號的申請,測試公眾號則不需要
實現目標
購買課程支付成功微信推送消息
模板消息實現
接口文檔:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Interface.html
申請模板消息
首先我們需要知道,模板消息是需要申請的。
但是我們在申請時還是有一些東西要注意,這個在官方的文檔有非常詳細的說明。
https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Template_Message_Operation_Specifications.html
這個大家好好看看。選擇行業的時候可要謹慎些,因為這個一個月只可以修改一次。
下面看看在哪里申請,硅谷課堂已經申請過,忽略
申請之后就耐心等待,審核通過之后就會出現“廣告與服務”模板消息的菜單。
添加模板消息
審核通過之后,我們就可以添加模板消息,進行開發了。
我們點擊模板消息進入后,直接在模板庫中選擇你需要的消息模板添加就可以了,添加之后就會在我的模板中。會有一個模板id,這個模板id在我們發送消息的時候會用到。
模板消息如下:
查看模板樣式
模板樣式在一個word里面,下載下來
這里是截取一部分的內容
公眾號測試號申請模板消息
模板消息長這個樣子
公眾號后臺設置
點擊新增模板
從上面的模板示例中,拿到需要使用的模板,填寫進去
添加成功就是這個樣子
后端相應接口
MessageController
添加方法
service接口
MessageService
service接口實現
(1)MessageServiceImpl類
(2)openid值和模板Id
測試
訪問一下這個接口,直接讓他在公眾號里推送模板信息
測試通過,推送成功
微信授權登陸
需求分析
根據流程圖通過菜單進入的頁面都要授權登錄
授權登錄介紹
接口文檔:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html
說明:
? 1、嚴格按照接口文檔實現;
? 2、應用授權作用域scope:scope為snsapi_userinfo
配置授權回調域名
公眾號正式號配置
這個是有企業注冊了公眾號的情況,個人是看不到這個頁面的,只能拿本地測試玩玩
在微信公眾號請求用戶網頁授權之前,開發者需要先到公眾平臺官網中的“設置與開發 - 接口權限 - 網頁服務 - 網頁帳號 - 網頁授權獲取用戶基本信息”的配置選項中,修改授權回調域名。請注意,這里填寫的是域名(是一個字符串),而不是URL,因此請勿加 http:// 等協議頭;
本地測試配置內網穿透地址
公眾號測試號配置
這樣的話就可以把本地服務器上運行的前端頁面在公網進行訪問了,也就是公眾號開啟新頁面,可以訪問
部署前端頁面
直接復制進工程中,資料里的前端頁面叫
修改訪問路徑到你的內網隧道
啟動公眾號頁面項目 這個直接運行就可以了 npm run serve
如果啟動的時候報錯看看這個文章
https://blog.csdn.net/m0_37629753/article/details/125199185
跑起來的樣子
前端處理
(1)全局處理授權登錄,處理頁面:/src/App.vue
說明1:訪問頁面時首先判斷是否有token信息,如果沒有跳轉到授權登錄接口
說明2:通過localStorage存儲token信息
在HTML5中,加入了一個localStorage特性,這個特性主要是用來作為本地存儲來使用的,解決了cookie存儲空間不足的問題(cookie中每條cookie的存儲空間很小,只有幾K),localStorage中一般瀏覽器支持的是5M大小,這個在不同的瀏覽器中localStorage會有所不同。它只能存儲字符串格式的數據,所以最好在每次存儲時把數據轉換成json格式,取出的時候再轉換回來。
(2)前端代碼實現
wechatLogin() {// 處理微信授權登錄let token = this.getQueryString('token') || '';if(token != '') {window.localStorage.setItem('token', token);}// 所有頁面都必須登錄,兩次調整登錄,這里與接口返回208狀態token = window.localStorage.getItem('token') || '';if (token == '') {let url = window.location.href.replace('#', 'guiguketan')window.location = 'http://glkt.atguigu.cn/api/user/wechat/authorize?returnUrl=' + url}console.log('token2:'+window.localStorage.getItem('token'));},授權登錄接口開發
操作模塊:service-user
引入微信依賴
在配置文件中添加配置
#公眾號id和秘鑰 # 硅谷課堂微信公眾平臺appId wechat.mpAppId: wx09f201e9013e81d8 ## 硅谷課堂微信公眾平臺api秘鑰 wechat.mpAppSecret: 6c999765c12c51850d28055e8b6e2eda # 授權回調獲取用戶信息接口地址 wechat.userInfoUrl: http://內網隧道地址/api/user/wechat/userInfo添加了一個工具類來讀取配置文件的賬戶密碼信息
另一個是微信的配置類
測試
我這里實在連不上內網穿透了…
沒做出來…
希望有小伙伴能留言給我講講QAQ
Token(重要)
通過token傳遞用戶信息
JWT介紹
JWT工具
JWT(Json Web Token)是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放標準。
JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便于從資源服務器獲取資源。比如用在用戶登錄上
JWT最重要的作用就是對 token信息的防偽作用。
JWT原理
一個JWT由三個部分組成:公共部分、私有部分、簽名部分。最后由這三者組合進行base64編碼得到JWT。
(1)公共部分
主要是該JWT的相關配置參數,比如簽名的加密算法、格式類型、過期時間等等。
(2)私有部分
用戶自定義的內容,根據實際需要真正要封裝的信息。
userInfo{用戶的Id,用戶的昵稱nickName}
(3)簽名部分
SaltiP: 當前服務器的Ip地址!{linux 中配置代理服務器的ip}
主要用戶對JWT生成字符串的時候,進行加密{鹽值}
base64編碼,并不是加密,只是把明文信息變成了不可見的字符串。但是其實只要用一些工具就可以把base64編碼解成明文,所以不要在JWT中放入涉及私密的信息。
看看Token長什么樣子
一個長Token一共三部分,每部分都用點.來分割
整合JWT
(1)在service_utils模塊添加依賴
<dependencies><dependency><groupId>org.apache.httpcomponents</groupId><artifactId>httpclient</artifactId></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId></dependency> </dependencies>(2)添加JWT工具類
公眾號點播課程
由于從微信用不了了,所以我這里就用本地前端工程做了
需求分析
點擊 去看看,進入課程詳情頁面
分頁展示接口開發
在VOD模塊下
創建CourseApiController
編寫CourseService
編寫CourseServiceImpl
這里用到了Mapper,因為要多表查詢
值得注意的點:
拿一個左外連接查詢來說,這種重復性的SQL是可以進行復用的
用一個標簽來進行復用
<sql id="唯一id">course cLEFT JOIN teacher t ON c.teacher_id = t.idLEFT JOIN subject s1 ON c.subject_parent_id = s1.idLEFT JOIN subject s2 ON c.subject_id = s2.id</sql>怎么用?
在需要使用復用標簽的地方加入這個標簽
整合前端
修改路由
創建js文件定義接口
編寫頁面
點播視頻播放接口開發
還是在VOD模塊下,新建VodApi控制器,來接收前端的請求
在配置文件中加入
application.properties添加tencent.video.appid=騰訊云播放器ID
如圖找ID
整合前端
整合點播視頻播放前端
創建js定義接口
courseInfo.vue修改play方法
index.html引入文件
把播放器樣式引入
創建play.vue頁面
付費觀看點播課程接口
提交訂單接口
創建Controller對象
編寫OrderInfoService和OrderInfoServiceImpl
OrderInfoService
//生成點播課程訂單 Long submitOrder(OrderFormVo orderFormVo);不過這里得等等,因為下訂單這個操作需要聯動優惠卷和課程ID,所以還需要遠程調用一下接口 一個是根據當前課程ID來拿到課程
另一個是操作優惠卷的(獲取+優惠卷使用更新)
Feign創建獲取課程信息接口
先獲取課程信息
操作service_vod模塊
添加課程信息獲取方法
遠程調用接口你把上面的根據ID拿課程的接口定義好
Feign創建獲取優惠卷操作接口
操作service_activity模塊
提前把要操作的接口準備好
對應的Service,更改為1就代表這個優惠卷已經被使用了
為上面的優惠卷接口創建一個遠程調用接口,建Module過程我就不多說了,一遍又一遍的沒必要多說了
到這里遠程調用就算結束了,一會會回到上面的課程接口信息
獲取當前用戶id
(1)common模塊引入依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency><!-- spring2.X集成redis所需common-pool2--> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version> </dependency>拷貝相關工具類
之前不是說過,LocalStorage是前端的一種存儲方式,所以就可以從前端的LocalStorage里拿到對象ID
前端實現方式
生成訂單
回到訂單模塊
所有準備工作完成,準備接上面的內容,調用相關遠程服務接口生成微服務
service_order引入依賴
這三個都是遠程Feign調用的
訂單業務具體工程實現 OrderInfoServiceImpl
@Autowired private CourseFeignClient courseFeignClient;@Autowired private UserInfoFeignClient userInfoFeignClient;@Autowired private CouponInfoFeignClient couponInfoFeignClient;//生成點播課程訂單 @Override public Long submitOrder(OrderFormVo orderFormVo) {Long userId = AuthContextHolder.getUserId();Long courseId = orderFormVo.getCourseId();Long couponId = orderFormVo.getCouponId();//查詢當前用戶是否已有當前課程的訂單LambdaQueryWrapper<OrderDetail> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(OrderDetail::getCourseId, courseId);queryWrapper.eq(OrderDetail::getUserId, userId);OrderDetail orderDetailExist = orderDetailService.getOne(queryWrapper);if(orderDetailExist != null){return orderDetailExist.getId(); //如果訂單已存在,則直接返回訂單id}//查詢課程信息Course course = courseFeignClient.getById(courseId);if (course == null) {throw new GlktException(ResultCodeEnum.DATA_ERROR.getCode(),ResultCodeEnum.DATA_ERROR.getMessage());}//查詢用戶信息UserInfo userInfo = userInfoFeignClient.getById(userId);if (userInfo == null) {throw new GlktException(ResultCodeEnum.DATA_ERROR.getCode(),ResultCodeEnum.DATA_ERROR.getMessage());}//優惠券金額BigDecimal couponReduce = new BigDecimal(0);if(null != couponId) {CouponInfo couponInfo = couponInfoFeignClient.getById(couponId);couponReduce = couponInfo.getAmount();}//創建訂單OrderInfo orderInfo = new OrderInfo();orderInfo.setUserId(userId);orderInfo.setNickName(userInfo.getNickName());orderInfo.setPhone(userInfo.getPhone());orderInfo.setProvince(userInfo.getProvince());orderInfo.setOriginAmount(course.getPrice());orderInfo.setCouponReduce(couponReduce);orderInfo.setFinalAmount(orderInfo.getOriginAmount().subtract(orderInfo.getCouponReduce()));orderInfo.setOutTradeNo(OrderNoUtils.getOrderNo());orderInfo.setTradeBody(course.getTitle());orderInfo.setOrderStatus("0");this.save(orderInfo);OrderDetail orderDetail = new OrderDetail();orderDetail.setOrderId(orderInfo.getId());orderDetail.setUserId(userId);orderDetail.setCourseId(courseId);orderDetail.setCourseName(course.getTitle());orderDetail.setCover(course.getCover());orderDetail.setOriginAmount(course.getPrice());orderDetail.setCouponReduce(new BigDecimal(0));orderDetail.setFinalAmount(orderDetail.getOriginAmount().subtract(orderDetail.getCouponReduce()));orderDetailService.save(orderDetail);//更新優惠券狀態if(null != orderFormVo.getCouponUseId()) {couponInfoFeignClient.updateCouponInfoUseStatus(orderFormVo.getCouponUseId(), orderInfo.getId());}return orderInfo.getId(); }到這里期內容就結束了~
來我主頁看看下一部分把~
硅谷課堂筆記下
總結
- 上一篇: nodejs+vue+elementui
- 下一篇: 前端学习笔记 - 移动端Web开发