my.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826
  1. <template>
  2. <view class="my-container">
  3. <view class="user-info" v-if="isLogin">
  4. <image class="avatar" :src="userInfo.avatar || '/static/avatar.png'"></image>
  5. <view class="user-details">
  6. <text class="username">{{ userInfo.username }}</text>
  7. <!-- <text class="user-id">ID: {{ userInfo.userId }}</text> -->
  8. <text class="user-phone" v-if="userInfo.phone">手机: {{ formatPhone(userInfo.phone) }}</text>
  9. </view>
  10. </view>
  11. <view class="user-info" v-else @click="wxLogin">
  12. <image class="avatar" src="/static/avatar.png"></image>
  13. <view class="user-details">
  14. <text class="username">点击登录</text>
  15. <text class="user-id">登录后查看更多信息</text>
  16. </view>
  17. </view>
  18. <view class="menu-list">
  19. <view class="menu-item" v-for="(item, index) in menuItems" :key="index" @click="handleMenuClick(item)">
  20. <view class="menu-item-left">
  21. <text class="iconfont" :class="item.icon"></text>
  22. <text class="menu-text">{{ item.title }}</text>
  23. </view>
  24. <text class="iconfont icon-right"></text>
  25. </view>
  26. </view>
  27. <view class="logout-btn" @click="handleLogout" v-if="isLogin">
  28. <text>退出登录</text>
  29. </view>
  30. <!-- 添加一个隐藏的授权按钮,在需要时显示 -->
  31. <view class="auth-modal" v-if="showAuthModal">
  32. <view class="auth-content">
  33. <text class="auth-title">微信授权登录</text>
  34. <text class="auth-desc">请授权获取您的微信头像和昵称</text>
  35. <button class="auth-btn" @tap="getUserProfile">确认授权</button>
  36. <button class="auth-cancel" @tap="cancelAuth">取消</button>
  37. </view>
  38. </view>
  39. <!-- 添加获取手机号按钮 -->
  40. <button
  41. v-if="isLogin && !userInfo.phone"
  42. open-type="getPhoneNumber"
  43. @getphonenumber="getPhoneNumber"
  44. class="get-phone-btn">
  45. 绑定手机号
  46. </button>
  47. </view>
  48. </template>
  49. <script>
  50. // 直接导入所有需要的 API 函数
  51. import { log } from 'util';
  52. import { wxLogin, getUserInfo, getUserPhoneNumber, logout } from '../../api/user.js';
  53. export default {
  54. data() {
  55. return {
  56. isLogin: false,
  57. userInfo: {
  58. username: '',
  59. userId: '',
  60. avatar: ''
  61. },
  62. menuItems: [
  63. { title: '个人资料', icon: 'icon-user', action: 'profile' },
  64. // { title: '我的订单', icon: 'icon-order', action: 'orders' },
  65. // { title: '我的收藏', icon: 'icon-star', action: 'favorites' },
  66. { title: '设置', icon: 'icon-settings', action: 'settings' },
  67. { title: '帮助中心', icon: 'icon-help', action: 'help' }
  68. ],
  69. showAuthModal: false,
  70. wxLoginCode: '' // 存储微信登录code
  71. }
  72. },
  73. onShow() {
  74. // 每次显示页面时检查登录状态
  75. this.checkLoginStatus();
  76. },
  77. methods: {
  78. // 检查登录状态
  79. checkLoginStatus() {
  80. try {
  81. const token = uni.getStorageSync('token');
  82. const userInfoStr = uni.getStorageSync('userInfo');
  83. if (token && userInfoStr) {
  84. const userInfo = JSON.parse(userInfoStr);
  85. // 检查登录是否过期(可选:如果需要登录有效期)
  86. const loginTime = userInfo.loginTime || 0;
  87. const currentTime = new Date().getTime();
  88. const loginExpireTime = 7 * 24 * 60 * 60 * 1000; // 例如7天过期
  89. if (currentTime - loginTime > loginExpireTime) {
  90. console.log('登录已过期,需要重新登录');
  91. this.handleLogout(false); // 静默登出,不显示提示
  92. return;
  93. }
  94. // 设置登录状态
  95. this.isLogin = true;
  96. this.userInfo = userInfo;
  97. // 可选:每次打开页面时刷新用户信息
  98. this.fetchUserDetail();
  99. } else {
  100. // 未登录状态
  101. this.isLogin = false;
  102. this.userInfo = {
  103. username: '',
  104. userId: '',
  105. avatar: '',
  106. phone: ''
  107. };
  108. }
  109. } catch (e) {
  110. console.error('获取登录状态失败', e);
  111. this.isLogin = false;
  112. }
  113. },
  114. // 前往登录页
  115. goLogin() {
  116. // 显示登录方式选择
  117. uni.showActionSheet({
  118. itemList: ['账号密码登录', '微信登录'],
  119. success: (res) => {
  120. if (res.tapIndex === 0) {
  121. // 账号密码登录
  122. uni.navigateTo({
  123. url: '/pages/login/login'
  124. });
  125. } else if (res.tapIndex === 1) {
  126. // 微信登录
  127. this.wxLogin();
  128. }
  129. }
  130. });
  131. },
  132. // 微信登录
  133. wxLogin() {
  134. // #ifdef MP-WEIXIN
  135. this.getWxLoginCode();
  136. // #endif
  137. // #ifndef MP-WEIXIN
  138. uni.showToast({
  139. title: '请在微信环境中使用微信登录',
  140. icon: 'none'
  141. });
  142. // #endif
  143. },
  144. // 获取微信登录 code
  145. getWxLoginCode() {
  146. uni.showLoading({ title: '登录中...' });
  147. // 每次都重新获取 code
  148. uni.login({
  149. provider: 'weixin',
  150. success: (loginRes) => {
  151. console.log('获取微信登录code成功:', loginRes.code);
  152. // 保存code,并显示授权弹窗
  153. this.wxLoginCode = loginRes.code;
  154. uni.hideLoading();
  155. this.showAuthModal = true;
  156. },
  157. fail: (err) => {
  158. uni.hideLoading();
  159. console.error('获取微信登录code失败:', err);
  160. uni.showToast({
  161. title: '微信登录失败',
  162. icon: 'none'
  163. });
  164. }
  165. });
  166. },
  167. // 用户点击授权按钮时调用
  168. getUserProfile() {
  169. // 这个方法直接绑定到按钮的点击事件
  170. wx.getUserProfile({
  171. desc: '用于完善用户资料',
  172. success: (profileRes) => {
  173. console.log('获取用户信息成功:', profileRes);
  174. // 准备完整的登录参数
  175. const loginParams = {
  176. code: this.wxLoginCode,
  177. userInfo: profileRes.userInfo,
  178. signature: profileRes.signature,
  179. rawData: profileRes.rawData,
  180. encryptedData: profileRes.encryptedData,
  181. iv: profileRes.iv
  182. };
  183. // 隐藏授权弹窗
  184. this.showAuthModal = false;
  185. // 发送登录请求
  186. this.wxLoginRequest(loginParams);
  187. },
  188. fail: (err) => {
  189. console.error('获取用户信息失败:', err);
  190. this.showAuthModal = false;
  191. // 如果用户拒绝授权,仍然可以使用code登录,但没有用户信息
  192. this.wxLoginRequest({
  193. code: this.wxLoginCode,
  194. userInfo: {
  195. nickName: '微信用户',
  196. avatarUrl: '',
  197. gender: 0,
  198. province: '',
  199. city: '',
  200. country: ''
  201. }
  202. });
  203. }
  204. });
  205. },
  206. // 取消授权
  207. cancelAuth() {
  208. this.showAuthModal = false;
  209. // 使用code进行静默登录
  210. this.wxLoginRequest({
  211. code: this.wxLoginCode,
  212. userInfo: {
  213. nickName: '微信用户',
  214. avatarUrl: '',
  215. gender: 0,
  216. province: '',
  217. city: '',
  218. country: ''
  219. }
  220. });
  221. },
  222. // 头像选择回调
  223. onChooseAvatar(e) {
  224. const { avatarUrl } = e.detail;
  225. // 这里可以将头像上传到服务器或进行其他处理
  226. console.log('用户选择的头像:', avatarUrl);
  227. },
  228. // 发送微信登录请求并处理结果
  229. async wxLoginRequest(loginParams) {
  230. try {
  231. uni.showLoading({ title: '登录中...' });
  232. console.log('发送登录请求,参数:', loginParams);
  233. // 发送登录请求
  234. const data = await wxLogin(loginParams);
  235. console.log('登录成功,返回数据:', data);
  236. // 构建用户信息对象
  237. const userData = this.buildUserData(data, loginParams);
  238. // 保存登录状态
  239. this.saveLoginState(data, userData);
  240. // 步骤6: 获取用户详细信息 - 如果需要的话
  241. if (userData.userId) {
  242. this.fetchUserDetail();
  243. } else {
  244. console.log('无法获取用户ID,跳过获取详细信息');
  245. }
  246. // 检查是否需要获取手机号
  247. if (!userData.phone) {
  248. console.log('用户未绑定手机号,可以提示用户绑定');
  249. // 这里可以显示提示或自动弹出获取手机号的按钮
  250. }
  251. } catch (error) {
  252. this.handleLoginError(error, loginParams);
  253. }
  254. },
  255. /**
  256. * 构建用户数据对象
  257. * @param {Object} data - 后端返回的数据
  258. * @param {Object} loginParams - 登录参数
  259. * @returns {Object} - 构建的用户数据
  260. */
  261. buildUserData(data, loginParams) {
  262. console.log('构建用户数据,服务器返回:', data);
  263. // 处理不同的返回格式
  264. let userData = {
  265. // 用户基本信息 - 优先使用服务器返回的数据
  266. username: data.username || data.nickName ||
  267. (loginParams.userInfo ? loginParams.userInfo.nickName : '微信用户'),
  268. // 用户ID可能在不同字段
  269. userId: data.userId || data.user_id || data.id || data.openid || '',
  270. // 头像可能在不同字段
  271. avatar: data.avatar || data.avatarUrl ||
  272. (loginParams.userInfo ? loginParams.userInfo.avatarUrl : '/static/avatar.png'),
  273. // 用户详细信息
  274. phone: data.phone || data.mobile || '',
  275. gender: data.gender || (loginParams.userInfo ? loginParams.userInfo.gender : 0),
  276. // 微信相关信息
  277. openid: data.openid || '',
  278. unionid: data.unionid || '',
  279. session_key: data.session_key || '',
  280. // 是否新用户
  281. is_new_user: data.is_new_user || false,
  282. // 登录时间
  283. loginTime: new Date().getTime()
  284. };
  285. console.log('构建的用户数据:', userData);
  286. return userData;
  287. },
  288. /**
  289. * 保存登录状态和用户信息
  290. * @param {Object} data - 后端返回的数据
  291. * @param {Object} userData - 构建的用户数据
  292. */
  293. saveLoginState(data, userData) {
  294. // 保存token - 可能在不同字段
  295. const token = data.token || data.session_key || '';
  296. if (token) {
  297. uni.setStorageSync('token', token);
  298. console.log('Token已保存:', token);
  299. }
  300. // 保存用户信息
  301. uni.setStorageSync('userInfo', JSON.stringify(userData));
  302. console.log('用户信息已保存');
  303. // 更新页面状态
  304. this.isLogin = true;
  305. this.userInfo = userData;
  306. // 显示成功提示
  307. uni.hideLoading();
  308. uni.showToast({
  309. title: '登录成功',
  310. icon: 'success'
  311. });
  312. },
  313. /**
  314. * 处理登录错误
  315. * @param {Error} error - 错误对象
  316. * @param {Object} loginParams - 登录参数
  317. */
  318. handleLoginError(error, loginParams) {
  319. uni.hideLoading();
  320. // 检查是否是 code 无效错误
  321. if (error.message && (
  322. error.message.includes('code无效') ||
  323. error.message.includes('已过期') ||
  324. error.message.includes('已被使用') ||
  325. error.status === 999)) {
  326. console.error('微信登录code无效,重新获取:', error);
  327. uni.showToast({
  328. title: 'code已过期,请重试',
  329. icon: 'none',
  330. duration: 2000
  331. });
  332. // 延迟一下再重新获取code,避免频繁调用
  333. setTimeout(() => {
  334. this.getWxLoginCode();
  335. }, 1000);
  336. return;
  337. }
  338. // 其他错误处理保持不变
  339. if (error.code === 10001) {
  340. // 微信未绑定账号,跳转到绑定页面
  341. uni.navigateTo({
  342. url: '/pages/bind/bind?code=' + (loginParams.code || '')
  343. });
  344. } else if (error.message && error.message.includes('CSRF')) {
  345. // CSRF 错误处理
  346. console.error('CSRF验证失败:', error);
  347. uni.showToast({
  348. title: 'CSRF验证失败,请刷新页面重试',
  349. icon: 'none',
  350. duration: 2000
  351. });
  352. setTimeout(() => this.refreshCSRFToken(), 2000);
  353. } else {
  354. // 其他错误
  355. console.error('微信登录失败:', error);
  356. uni.showToast({
  357. title: error.message || '登录失败',
  358. icon: 'none'
  359. });
  360. }
  361. },
  362. /**
  363. * 获取用户详细信息
  364. * 步骤6: 获取并更新用户详细信息
  365. */
  366. async fetchUserDetail() {
  367. try {
  368. if (!this.isLogin) return;
  369. // 获取用户ID
  370. const userId = this.userInfo.userId;
  371. // 调用获取用户详情API
  372. const userDetail = await getUserInfo(userId);
  373. console.log('获取用户详细信息成功:', userDetail);
  374. if (userDetail) {
  375. // 更新用户信息
  376. this.updateUserInfo(userDetail);
  377. }
  378. } catch (error) {
  379. console.error('获取用户详细信息失败:', error);
  380. }
  381. },
  382. /**
  383. * 更新用户信息
  384. * @param {Object} userDetail - 用户详细信息
  385. */
  386. updateUserInfo(userDetail) {
  387. // 合并现有信息和新获取的详细信息
  388. const updatedUserInfo = {
  389. ...this.userInfo,
  390. // 更新基本信息
  391. username: userDetail.username || userDetail.nickName || this.userInfo.username,
  392. avatar: userDetail.avatar || userDetail.avatarUrl || this.userInfo.avatar,
  393. phone: userDetail.phone || userDetail.mobile || this.userInfo.phone,
  394. // 更新详细信息
  395. email: userDetail.email || '',
  396. address: userDetail.address || '',
  397. birthday: userDetail.birthday || '',
  398. // 其他字段
  399. ...userDetail
  400. };
  401. // 更新状态和存储
  402. this.userInfo = updatedUserInfo;
  403. uni.setStorageSync('userInfo', JSON.stringify(updatedUserInfo));
  404. console.log('用户详细信息已更新');
  405. },
  406. /**
  407. * 获取用户手机号
  408. * @param {Object} e - 事件对象
  409. */
  410. async getPhoneNumber(e) {
  411. console.log('获取手机号事件:', e);
  412. // 检查是否成功获取
  413. if (e.detail.errMsg !== 'getPhoneNumber:ok') {
  414. console.error('用户拒绝授权手机号');
  415. uni.showToast({
  416. title: '获取手机号失败',
  417. icon: 'none'
  418. });
  419. return;
  420. }
  421. try {
  422. uni.showLoading({ title: '获取手机号中...' });
  423. // 需要重新获取登录code
  424. const loginResult = await new Promise((resolve, reject) => {
  425. uni.login({
  426. provider: 'weixin',
  427. success: resolve,
  428. fail: reject
  429. });
  430. });
  431. // 准备请求参数
  432. const params = {
  433. code: loginResult.code,
  434. encryptedData: e.detail.encryptedData,
  435. iv: e.detail.iv,
  436. openid: JSON.parse(uni.getStorageSync('userInfo')).openid
  437. };
  438. console.log('获取手机号请求参数:', JSON.parse(uni.getStorageSync('userInfo')).openid);
  439. // 调用获取手机号API
  440. const phoneData = await getUserPhoneNumber(params);
  441. console.log('获取手机号成功:', phoneData);
  442. // 更新用户信息
  443. if (phoneData && phoneData.phoneNumber) {
  444. const updatedUserInfo = {
  445. ...this.userInfo,
  446. phone: phoneData.phoneNumber
  447. };
  448. // 更新状态和存储
  449. this.userInfo = updatedUserInfo;
  450. uni.setStorageSync('userInfo', JSON.stringify(updatedUserInfo));
  451. uni.showToast({
  452. title: '手机号绑定成功',
  453. icon: 'success'
  454. });
  455. } else {
  456. throw new Error('未能获取到手机号');
  457. }
  458. } catch (error) {
  459. console.error('获取手机号失败:', error);
  460. uni.showToast({
  461. title: error.message || '获取手机号失败',
  462. icon: 'none'
  463. });
  464. } finally {
  465. uni.hideLoading();
  466. }
  467. },
  468. // 添加刷新 CSRF token 的方法
  469. refreshCSRFToken() {
  470. // 这里实现获取新的 CSRF token 的逻辑
  471. // 可能需要调用特定的 API 或刷新页面
  472. uni.request({
  473. url: 'your-api-endpoint/csrf-token', // 替换为获取 CSRF token 的 API
  474. method: 'GET',
  475. success: (res) => {
  476. if (res.data && res.data.csrfToken) {
  477. uni.setStorageSync('csrfToken', res.data.csrfToken);
  478. console.log('CSRF token 已刷新');
  479. }
  480. },
  481. fail: (err) => {
  482. console.error('获取 CSRF token 失败', err);
  483. }
  484. });
  485. },
  486. handleMenuClick(item) {
  487. // 检查是否需要登录
  488. const needLogin = ['profile', 'orders', 'favorites'];
  489. if (needLogin.includes(item.action) && !this.isLogin) {
  490. uni.showToast({
  491. title: '请先登录',
  492. icon: 'none'
  493. });
  494. setTimeout(() => {
  495. this.wxLogin()
  496. //this.goLogin();
  497. }, 1500);
  498. return;
  499. }
  500. // 根据action跳转到对应页面
  501. switch(item.action) {
  502. case 'profile':
  503. uni.navigateTo({ url: '/pages/profile/profile' });
  504. break;
  505. case 'orders':
  506. uni.navigateTo({ url: '/pages/orders/orders' });
  507. break;
  508. case 'favorites':
  509. uni.navigateTo({ url: '/pages/favorites/favorites' });
  510. break;
  511. case 'settings':
  512. uni.navigateTo({ url: '/pages/settings/settings' });
  513. break;
  514. case 'help':
  515. uni.navigateTo({ url: '/pages/help/help' });
  516. break;
  517. default:
  518. uni.showToast({
  519. title: `点击了${item.title}`,
  520. icon: 'none'
  521. });
  522. }
  523. },
  524. // 处理退出登录 - 增强版
  525. handleLogout(showConfirm = true) {
  526. const doLogout = () => {
  527. // 调用登出 API
  528. logout().then(() => {
  529. // 清除登录信息
  530. try {
  531. uni.removeStorageSync('token');
  532. uni.removeStorageSync('userInfo');
  533. // 更新状态
  534. this.isLogin = false;
  535. this.userInfo = {
  536. username: '',
  537. userId: '',
  538. avatar: '',
  539. phone: ''
  540. };
  541. // 显示提示(如果需要)
  542. if (showConfirm) {
  543. uni.showToast({
  544. title: '已退出登录',
  545. icon: 'success'
  546. });
  547. }
  548. } catch (e) {
  549. console.error('退出登录失败', e);
  550. if (showConfirm) {
  551. uni.showToast({
  552. title: '退出登录失败',
  553. icon: 'none'
  554. });
  555. }
  556. }
  557. }).catch(err => {
  558. console.error('退出登录请求失败', err);
  559. // 即使 API 请求失败,也清除本地登录状态
  560. uni.removeStorageSync('token');
  561. uni.removeStorageSync('userInfo');
  562. this.isLogin = false;
  563. if (showConfirm) {
  564. uni.showToast({
  565. title: err.message || '退出登录失败',
  566. icon: 'none'
  567. });
  568. }
  569. });
  570. };
  571. // 是否需要显示确认对话框
  572. if (showConfirm) {
  573. uni.showModal({
  574. title: '提示',
  575. content: '确定要退出登录吗?',
  576. success: (res) => {
  577. if (res.confirm) {
  578. doLogout();
  579. }
  580. }
  581. });
  582. } else {
  583. // 直接登出,不显示确认
  584. doLogout();
  585. }
  586. },
  587. // 格式化手机号,例如:188****8888
  588. formatPhone(phone) {
  589. if (!phone || phone.length < 11) return phone;
  590. return phone.substring(0, 3) + '****' + phone.substring(7);
  591. }
  592. }
  593. }
  594. </script>
  595. <style>
  596. .my-container {
  597. padding: 20rpx;
  598. background-color: #f5f5f5;
  599. min-height: 100vh;
  600. }
  601. .user-info {
  602. display: flex;
  603. align-items: center;
  604. background-color: #ffffff;
  605. padding: 30rpx;
  606. border-radius: 12rpx;
  607. margin-bottom: 20rpx;
  608. }
  609. .avatar {
  610. width: 120rpx;
  611. height: 120rpx;
  612. border-radius: 60rpx;
  613. margin-right: 20rpx;
  614. }
  615. .user-details {
  616. display: flex;
  617. flex-direction: column;
  618. }
  619. .username {
  620. font-size: 36rpx;
  621. font-weight: bold;
  622. margin-bottom: 10rpx;
  623. }
  624. .user-id {
  625. font-size: 24rpx;
  626. color: #999;
  627. }
  628. .user-phone {
  629. font-size: 24rpx;
  630. color: #666;
  631. margin-top: 6rpx;
  632. }
  633. .menu-list {
  634. background-color: #ffffff;
  635. border-radius: 12rpx;
  636. margin-bottom: 20rpx;
  637. }
  638. .menu-item {
  639. display: flex;
  640. justify-content: space-between;
  641. align-items: center;
  642. padding: 30rpx;
  643. border-bottom: 1rpx solid #f5f5f5;
  644. }
  645. .menu-item:last-child {
  646. border-bottom: none;
  647. }
  648. .menu-item-left {
  649. display: flex;
  650. align-items: center;
  651. }
  652. .menu-text {
  653. margin-left: 20rpx;
  654. font-size: 28rpx;
  655. }
  656. .logout-btn {
  657. background-color: #ffffff;
  658. border-radius: 12rpx;
  659. padding: 30rpx;
  660. text-align: center;
  661. color: #ff0000;
  662. font-size: 32rpx;
  663. }
  664. /* 这里应该引入iconfont,但为了简化,我们先不添加 */
  665. .iconfont {
  666. font-size: 36rpx;
  667. color: #007AFF;
  668. }
  669. .icon-right {
  670. color: #cccccc;
  671. }
  672. /* 授权弹窗样式 */
  673. .auth-modal {
  674. position: fixed;
  675. top: 0;
  676. left: 0;
  677. right: 0;
  678. bottom: 0;
  679. background-color: rgba(0, 0, 0, 0.5);
  680. display: flex;
  681. justify-content: center;
  682. align-items: center;
  683. z-index: 999;
  684. }
  685. .auth-content {
  686. width: 80%;
  687. background-color: #fff;
  688. border-radius: 12rpx;
  689. padding: 40rpx;
  690. display: flex;
  691. flex-direction: column;
  692. align-items: center;
  693. }
  694. .auth-title {
  695. font-size: 36rpx;
  696. font-weight: bold;
  697. margin-bottom: 20rpx;
  698. }
  699. .auth-desc {
  700. font-size: 28rpx;
  701. color: #666;
  702. margin-bottom: 40rpx;
  703. text-align: center;
  704. }
  705. .auth-btn {
  706. width: 100%;
  707. height: 80rpx;
  708. line-height: 80rpx;
  709. background-color: #07c160;
  710. color: #fff;
  711. border-radius: 8rpx;
  712. margin-bottom: 20rpx;
  713. }
  714. .auth-cancel {
  715. width: 100%;
  716. height: 80rpx;
  717. line-height: 80rpx;
  718. background-color: #f5f5f5;
  719. color: #333;
  720. border-radius: 8rpx;
  721. }
  722. /* 添加获取手机号按钮样式 */
  723. .get-phone-btn {
  724. margin-top: 20rpx;
  725. background-color: #07c160;
  726. color: #fff;
  727. border-radius: 8rpx;
  728. font-size: 28rpx;
  729. padding: 16rpx 0;
  730. }
  731. </style>