五、完善交互
我们将下单页面完整的展示出来了,那么我们接下里就是将列表的数据改为动态交互
剩下的API接口都是和PC端一样的可以直接copy pc端项目的api文件夹
创建api请求
商品请求
// axios 发送ajax请求 import request from '@/utils/request'; //查询商品列表 export function getProductList() { return request({ url: '/api/product/productList', method: 'get' }); }
编写发送请求 获取商品列表
import { getProductList } from "../../api/product"; // 获取商品列表 const selectProductList = async () => { const { data } = await getProductList() productList.value = data payOrder.value.productId = data[0].id }
编写生命周期
我们知道Vue有自己的生命周期UniApp也有,详细文档参考: https://uniapp.dcloud.net.cn/collocation/App.html#applifecycle
import { onLoad, onShow } from '@dcloudio/uni-app' // ==========================生命周期========================== onLoad(() => { // 只会加载一次 console.log("onLoad") selectProductList() }) onShow(() => { // 每次都会加载 })
我们列表不需要重复去请求只需要一次就行了
测试查看
有那个味道了芜湖~
六、小程序下单前置准备授权
搭建微信授权登录
模态框
<img src="https://foruda.gitee.com/images/1693410126019383931/327436ed\\_5151444.png" alt="输入图片说明" title="屏幕截图" style="zoom:50%;" />
编写变量存储用户名称和用户头像显示
// 登录授权 let modal = ref({ show: false, // 是否显示 content: '请点击头像和昵称填充信息获取完整的微信支付服务!', code: '', // 登录授权Code avatarUrl: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0', oldAvatarUrl: 'https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0', nickName: '',// 昵称 })
编写 模态框
⚠️注意:微信在多少版本就不支持授权返回用户名称和头像了只能用户自己上传和输入昵称
登录授权获取头像
// 登录授权 - 设置头像 const onChooseAvatar = (e) => { console.log("onChooseAvatar", e); const { avatarUrl } = e.detail modal.value.avatarUrl = avatarUrl uni.setStorageSync('avatarUrl', avatarUrl) }
登录授权获取昵称
// 登录授权 - 设置昵称 const changeName = (e) => { modal.value.nickName = e.detail.value }
校验是否授权
使用生命周期 onShow
可以每次访问页面的时候触发
onShow(() => { // 首先去获取是否授权登录了 const storageSync = uni.getStorageSync('token'); const nickName = uni.getStorageSync('nickName'); const avatarUrl = uni.getStorageSync('avatarUrl'); // 如果没有则弹出要求授权登录 if ([ null, undefined, '' ].includes(storageSync)) { modal.value.show = true } else { modal.value.nickName = nickName modal.value.avatarUrl = avatarUrl } })
测试头像获取和昵称
将头像和昵称填写完毕将会自动弹出现授权按钮
授权提交
可以看到我们将头像和昵称填写完毕后出现了提交按钮
登录原型需求分析的时候我们解析过下单需要 OpenId
我我滴妈样式变咯
获取OPENID
流程 uniapp ---> 小程序登录授权 ---> 获取到Code码 ---> 根据Code码去后端请求获取OpenId
说明
- 调用 wx.login() 获取 临时登录凭证code ,并回传到开发者服务器。
- 调用 auth.code2Session 接口,换取 用户唯一标识 OpenID 、 用户在微信开放平台账号下的唯一标识UnionID(若当前小程序已绑定到微信开放平台账号) 和 会话密钥 session_key。
之后开发者服务器可以根据用户标识来生成自定义登录态,用于后续业务逻辑中前后端交互时识别用户身份。
注意事项
- 会话密钥
session_key
是对用户数据进行 加密签名 的密钥。为了应用自身的数据安全,开发者服务器不应该把会话密钥下发到小程序,也不应该对外提供这个密钥。 - 临时登录凭证 code 只能使用一次
授权提交获取Code
下面截图当中的代码都是需要同学们自己打
Uni-app小程序授权文档: https://uniapp.dcloud.net.cn/api/plugins/login.html#login
发送请求到后端获取OpenId
修改 wechatPay.js
新增请求接口 注意 url和你自己后端一致
传递的参数是 code
、nickName 昵称主要用来区分是小程序用户下单的
// 登录方法获取openId export function loginOrRegister(data) { return request({ url: '/api/wx-pay/js-api/loginOrRegister', method: 'post', data }) }
后端微信授权接口
小程序登录详细文档: https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/user-login/code2Session.html
我们接收到 code
码之后直接访问微信服务器去拉授权信息
创建 WechatUniAppJsApiController
后端我就不细说了我相信都是大佬来的 😄
package com.yby6.controller; import cn.hutool.http.HttpUtil; import cn.hutool.json.JSONObject; import cn.hutool.json.JSONUtil; import com.yby6.config.WxPayConfig; import com.yby6.domain.wechat.LoginUser; import com.yby6.reponse.R; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; import java.util.Map; /** * 微信小程序JS API 支付 * * @author Yang Shuai * Create By 2023/9/9 */ @Slf4j @RestController @RequestMapping("/api/wx-pay/js-api") @RequiredArgsConstructor public class WechatUniAppJsApiController { private final WxPayConfig wxPayConfig; /** * 微信小程序登录接口 (登录or注册) * * @param loginUser 必填 code */ @PostMapping("loginOrRegister") public R loginOrRegister(@RequestBody LoginUser loginUser) { return R.ok(getOpenId(loginUser.getCode())); } /** * 获取微信唯一凭证 * * @param code 代码 * @return {@link String} */ private String getOpenId(String code) { String url = "https://api.weixin.qq.com/sns/jscode2session"; Map<String, Object> map = new HashMap<>(); map.put("appId", wxPayConfig.getAppid()); map.put("secret", wxPayConfig.getSecret()); map.put("js_code", code); map.put("grant_type", "authorization_code"); String post = HttpUtil.post(url, map); log.info("微信返回: {}", post); JSONObject obj = JSONUtil.parseObj(post); String openid = obj.getStr("openid"); if (StringUtils.isNoneBlank(openid)) { return openid; } throw new RuntimeException("临时登录凭证错误"); } }
测试小程序授权
启动后端程序,打开小程序清空全部缓存重新编译
将会弹出授权窗口,填写完毕后将会获取到code发送给后端获取openid
返回的OpenId 我们也存入了本地缓存当中