index.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <view class="container">
  3. <!-- 顶部导航 -->
  4. <view class="nav-bar">
  5. <view class="back" @click="goBack">
  6. <text class="iconfont">←</text>
  7. </view>
  8. <!-- <text class="title">登录2</text> -->
  9. <view class="more-options">
  10. <text class="iconfont">→</text>
  11. </view>
  12. </view>
  13. <!-- 头像授权 -->
  14. <view class="avatar-section">
  15. <button class="avatar-button" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
  16. <image class="avatar" :src="userInfo.avatarUrl || '/static/icons/user_icon.png'" mode="aspectFill"></image>
  17. </button>
  18. <text class="avatar-text" v-if="isShow">授权头像</text>
  19. </view>
  20. <!-- 昵称输入 -->
  21. <view class="form">
  22. <view class="form-item">
  23. <text class="label">昵称</text>
  24. <input name="nickName" type="nickname" placeholder="请填写昵称" class="input" v-model="userInfo.nickName" />
  25. </view>
  26. </view>
  27. <!-- 微信一键登录按钮 -->
  28. <button class="wx-login-btn" @tap="loginWithWeChat" :loading="loading" :disabled="loading">
  29. <image class="wx-icon" src="/static/wechat-icon.png" mode="widthFix" />
  30. 微信一键授权登录
  31. </button>
  32. <!-- 提示文字 -->
  33. <text class="tip-text">微信授权登录后才可进行更多操作哦</text>
  34. </view>
  35. </template>
  36. <script setup>
  37. import { ref, reactive } from 'vue'
  38. import { uploadInfo } from "@/api/services/connect.js"
  39. import storage from "@/utils/storage.js"
  40. // 响应式数据
  41. const isShow = ref(true)
  42. const userInfo = reactive({
  43. avatarUrl: '',
  44. nickName: '',
  45. openId: ''
  46. })
  47. const loading = ref(false)
  48. // 获取微信头像
  49. const onChooseAvatar = (e) => {
  50. userInfo.avatarUrl = e.detail.avatarUrl
  51. console.log("eeee", e)
  52. }
  53. // 返回上一页
  54. const goBack = () => {
  55. uni.navigateBack()
  56. }
  57. // 请求用户资料
  58. const requestProfile = async () => {
  59. try {
  60. const res = await uni.getUserProfile({
  61. desc: '用于完善会员资料',
  62. })
  63. Object.assign(userInfo, res.userInfo)
  64. } catch (err) {
  65. uni.showToast({
  66. icon: 'none',
  67. title: '授权失败',
  68. })
  69. }
  70. }
  71. // 微信登录
  72. const loginWithWeChat = async () => {
  73. // 防止进入后重复点击(双保险)
  74. if (loading.value) return
  75. if (!userInfo.nickName) {
  76. uni.showToast({
  77. title: '请先授权头像昵称',
  78. icon: 'none'
  79. })
  80. return
  81. }
  82. loading.value = true
  83. try {
  84. // TODO: 调用后端接口完成注册/登录
  85. // 原因: 当前使用的是 uploadInfo 接口,需要确认是否为正确的注册/登录接口
  86. // 推荐: 确认后端接口文档,使用正确的注册或登录接口
  87. const res = await uploadInfo(userInfo)
  88. console.log("res", res)
  89. if (res.data.code == 200) {
  90. storage.setUserInfo(res.data.data)
  91. }
  92. uni.showToast({
  93. title: '登录成功',
  94. })
  95. // 成功跳转页面
  96. uni.switchTab({
  97. url: '/pages/user/index'
  98. })
  99. } catch (err) {
  100. console.log("err", err)
  101. uni.showToast({
  102. icon: 'none',
  103. title: '登录失败,请重试',
  104. })
  105. } finally {
  106. loading.value = false
  107. }
  108. }
  109. // uni-app 生命周期 - onLoad
  110. onLoad((options) => {
  111. console.log("options", options)
  112. userInfo.openId = options.openId || ''
  113. })
  114. </script>
  115. <style>
  116. .container {
  117. background-color: #fff;
  118. height: 100vh;
  119. padding: 0 20rpx;
  120. box-sizing: border-box;
  121. }
  122. .nav-bar {
  123. display: flex;
  124. align-items: center;
  125. justify-content: space-between;
  126. padding: 40rpx 0 20rpx;
  127. }
  128. .back,
  129. .more-options {
  130. width: 60rpx;
  131. text-align: center;
  132. }
  133. .title {
  134. font-size: 36rpx;
  135. font-weight: bold;
  136. }
  137. .avatar-section {
  138. display: flex;
  139. flex-direction: column;
  140. align-items: center;
  141. margin-top: 60rpx;
  142. }
  143. .avatar-button {
  144. padding: 0;
  145. margin: 0;
  146. border: none;
  147. background-color: transparent;
  148. border-radius: 50%;
  149. overflow: hidden;
  150. }
  151. .avatar {
  152. width: 120rpx;
  153. height: 120rpx;
  154. border-radius: 50%;
  155. background-color: #f5f5f5;
  156. }
  157. .avatar-text {
  158. margin-top: 20rpx;
  159. font-size: 28rpx;
  160. color: #888;
  161. }
  162. .form {
  163. margin: 60rpx 0 40rpx;
  164. }
  165. .form-item {
  166. display: flex;
  167. align-items: center;
  168. border-bottom: 1px solid #eee;
  169. padding-bottom: 20rpx;
  170. }
  171. .label {
  172. width: 100rpx;
  173. font-size: 28rpx;
  174. color: #333;
  175. }
  176. .input {
  177. flex: 1;
  178. font-size: 28rpx;
  179. padding-left: 20rpx;
  180. }
  181. .wx-login-btn {
  182. display: flex;
  183. align-items: center;
  184. justify-content: center;
  185. background-color: #1aad19;
  186. color: #fff;
  187. border-radius: 100rpx;
  188. height: 88rpx;
  189. font-size: 30rpx;
  190. margin-top: 40rpx;
  191. }
  192. .wx-icon {
  193. width: 40rpx;
  194. margin-right: 20rpx;
  195. }
  196. .tip-text {
  197. margin-top: 20rpx;
  198. font-size: 24rpx;
  199. color: #999;
  200. text-align: center;
  201. }
  202. </style>