index.vue 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. <!-- components/login-modal.vue -->
  2. <template>
  3. <uni-popup ref="popup" type="bottom" :safe-area="false">
  4. <view class="login-modal">
  5. <text class="title">请先登录以查看消息</text>
  6. <button
  7. open-type="getUserInfo"
  8. @getuserinfo="handleAuth"
  9. class="auth-btn">微信一键登录</button>
  10. <view class="close" @click="close">稍后再说</view>
  11. </view>
  12. </uni-popup>
  13. </template>
  14. <script>
  15. export default {
  16. created() {
  17. uni.$on('show-login-modal', this.show)
  18. },
  19. beforeDestroy() {
  20. uni.$off('show-login-modal')
  21. },
  22. methods: {
  23. show() {
  24. if (!this.$refs.popup.isOpened) {
  25. this.$refs.popup.open()
  26. }
  27. },
  28. close() {
  29. this.$refs.popup.close()
  30. },
  31. async handleAuth(e) {
  32. if (e.detail.errMsg === 'getUserInfo:ok') {
  33. try {
  34. const { code } = await uni.login({ provider: 'weixin' })
  35. // 发送登录请求(复用之前的登录逻辑)
  36. const res = await uni.request({
  37. url: '/api/login',
  38. method: 'POST',
  39. data: {
  40. code,
  41. encryptedData: e.detail.encryptedData,
  42. iv: e.detail.iv
  43. }
  44. })
  45. if (res.data.token) {
  46. uni.setStorageSync('token', res.data.token)
  47. this.close()
  48. uni.$emit('login-success') // 通知其他页面
  49. }
  50. } catch (err) {
  51. uni.showToast({ title: '登录失败', icon: 'none' })
  52. }
  53. } else {
  54. uni.showToast({ title: '授权失败', icon: 'none' })
  55. }
  56. }
  57. }
  58. }
  59. </script>
  60. <style scoped>
  61. .login-modal {
  62. background: #fff;
  63. padding: 40rpx;
  64. border-radius: 24rpx 24rpx 0 0;
  65. text-align: center;
  66. }
  67. .title {
  68. font-size: 32rpx;
  69. display: block;
  70. margin-bottom: 40rpx;
  71. }
  72. .auth-btn {
  73. background: #07c160;
  74. color: white;
  75. border-radius: 48rpx;
  76. margin-bottom: 20rpx;
  77. }
  78. .close {
  79. color: #666;
  80. padding: 20rpx;
  81. font-size: 28rpx;
  82. }
  83. </style>