木邻有你前端代码仓库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

290 lines
6.7 KiB

1 month ago
  1. <template>
  2. <view class="login-container">
  3. <!-- 背景图 -->
  4. <image class="bg-image" :src="configParamImage('config_login_bg')" mode="aspectFill"></image>
  5. <!-- 内容区域 -->
  6. <view class="content">
  7. <!-- 标题图片 -->
  8. <view class="title-section">
  9. <!-- <image class="title-image" src="/subPages/static/登录_标题.png" mode="widthFix"></image> -->
  10. <view class="login-title">{{ configParamText('config_login_title') }}</view>
  11. </view>
  12. <!-- 按钮区域 -->
  13. <view class="button-section">
  14. <!-- 授权手机号登录按钮 -->
  15. <view class="login-btn primary" @click="phoneLogin">
  16. <text class="btn-text">授权手机号登录</text>
  17. </view>
  18. <!-- 取消登录按钮 -->
  19. <view class="login-btn secondary" @click="cancelLogin">
  20. <text class="btn-text">取消登录</text>
  21. </view>
  22. <!-- 协议文字 -->
  23. <view class="agreement-text-container">
  24. <view class="agreement-checkbox-row">
  25. <view class="custom-checkbox" @click="toggleAgreement">
  26. <uv-icon
  27. v-if="!isAgreed"
  28. name="checkmark-circle"
  29. size="20"
  30. color="#cccccc">
  31. </uv-icon>
  32. <uv-icon
  33. v-else
  34. name="checkmark-circle-fill"
  35. size="20"
  36. color="#1488DB">
  37. </uv-icon>
  38. </view>
  39. <view class="agreement-text-content">
  40. <text class="agreement-text">阅读并同意我们的 </text>
  41. <text class="agreement-link" @click="showPolicy">服务协议与隐私条款</text>
  42. <text class="agreement-text"> 以及 </text>
  43. <text class="agreement-link" @click="showPrivacy">个人信息保护指引</text>
  44. </view>
  45. </view>
  46. </view>
  47. </view>
  48. </view>
  49. <uv-modal ref="modalPolicy" title="服务协议与隐私条款">
  50. <view class="slot-content">
  51. <rich-text :nodes="configParamTextarea('config_login_policy')"></rich-text>
  52. </view>
  53. </uv-modal>
  54. <uv-modal ref="modalPrivacy" title="个人信息保护指引">
  55. <view class="slot-content">
  56. <rich-text :nodes="configParamTextarea('config_login_privacy')"></rich-text>
  57. </view>
  58. </uv-modal>
  59. </view>
  60. </template>
  61. <script>
  62. export default {
  63. name: 'Login',
  64. data() {
  65. return {
  66. isAgreed: false
  67. }
  68. },
  69. methods: {
  70. // 切换协议同意状态
  71. toggleAgreement() {
  72. this.isAgreed = !this.isAgreed;
  73. console.log('协议同意状态:', this.isAgreed);
  74. },
  75. // 手机号授权登录
  76. phoneLogin() {
  77. if (!this.isAgreed) {
  78. uni.showToast({
  79. title: '请先同意协议条款',
  80. icon: 'none'
  81. });
  82. return;
  83. }
  84. uni.login({
  85. provider: 'weixin',
  86. success: async (loginRes) => {
  87. const res = await this.$api.login.login({
  88. code: loginRes.code
  89. })
  90. uni.setStorageSync('token', res.result.token)
  91. const userInfo = res.result.userInfo
  92. if (!userInfo.headImage || !userInfo.nickName || !userInfo.phone) {
  93. uni.showToast({
  94. title: '请先完善个人信息',
  95. icon: 'none'
  96. })
  97. setTimeout(() => {
  98. uni.navigateTo({
  99. url: '/subPages/login/userInfo'
  100. })
  101. }, 500)
  102. }else {
  103. uni.showToast({
  104. title: '登录成功',
  105. icon: 'success'
  106. })
  107. setTimeout(() => {
  108. uni.switchTab({
  109. url: '/pages/index/index'
  110. })
  111. }, 500)
  112. }
  113. },
  114. fail: (error) => {
  115. uni.showToast({
  116. title: `${error.errMsg}`,
  117. icon: 'none'
  118. })
  119. }
  120. })
  121. },
  122. // 取消登录
  123. cancelLogin() {
  124. console.log('取消登录');
  125. // 重定向到首页
  126. uni.switchTab({
  127. url: '/pages/index/index'
  128. })
  129. },
  130. // 显示服务协议
  131. showPolicy() {
  132. this.$refs.modalPolicy.open()
  133. },
  134. // 显示隐私条款
  135. showPrivacy() {
  136. this.$refs.modalPrivacy.open()
  137. }
  138. }
  139. }
  140. </script>
  141. <style lang="scss" scoped>
  142. .login-container {
  143. position: relative;
  144. width: 100vw;
  145. height: 100vh;
  146. overflow: hidden;
  147. }
  148. .bg-image {
  149. position: absolute;
  150. top: 0;
  151. left: 0;
  152. width: 100%;
  153. height: 40%;
  154. z-index: 1;
  155. }
  156. .content {
  157. position: relative;
  158. z-index: 2;
  159. height: 100%;
  160. display: flex;
  161. flex-direction: column;
  162. padding: 0 40rpx;
  163. }
  164. .title-section {
  165. flex: 1;
  166. display: flex;
  167. align-items: flex-end;
  168. justify-content: center;
  169. padding: 120rpx;
  170. .login-title{
  171. color: #1488db;
  172. font-size: 48rpx;
  173. font-weight: bold;
  174. position: relative;
  175. }
  176. .login-title::after{
  177. content: '';
  178. position: absolute;
  179. left: 20rpx;
  180. bottom: -8rpx;
  181. width: 100%;
  182. height: 24rpx;
  183. border-radius: 50%;
  184. background: linear-gradient(to bottom, #0085e4, transparent);
  185. }
  186. }
  187. // .welcome-section {
  188. // display: flex;
  189. // justify-content: center;
  190. // margin-bottom: 100rpx;
  191. // .welcome-box {
  192. // border: 2rpx dashed #1488DB;
  193. // border-radius: 10rpx;
  194. // padding: 20rpx 40rpx;
  195. // background: rgba(255, 255, 255, 0.9);
  196. // .welcome-text {
  197. // font-size: 28rpx;
  198. // color: #1488DB;
  199. // font-weight: 500;
  200. // }
  201. // }
  202. // }
  203. .button-section {
  204. flex: 1;
  205. margin-bottom: 60rpx;
  206. align-items: flex-start;
  207. .login-btn {
  208. width: 100%;
  209. height: 88rpx;
  210. border-radius: 44rpx;
  211. display: flex;
  212. align-items: center;
  213. justify-content: center;
  214. margin-bottom: 30rpx;
  215. &.primary {
  216. background: #1488DB;
  217. .btn-text {
  218. color: #ffffff;
  219. font-size: 32rpx;
  220. font-weight: 500;
  221. }
  222. }
  223. &.secondary {
  224. background: rgba(255, 255, 255, 0.9);
  225. border: 2rpx solid #cccccc;
  226. .btn-text {
  227. color: #666666;
  228. font-size: 32rpx;
  229. }
  230. }
  231. }
  232. .agreement-text-container {
  233. margin-top: 40rpx;
  234. .agreement-checkbox-row {
  235. display: flex;
  236. align-items: center;
  237. justify-content: center;
  238. .custom-checkbox {
  239. margin-right: 10rpx;
  240. display: flex;
  241. align-items: center;
  242. }
  243. .agreement-text-content {
  244. flex: 1;
  245. text-align: left;
  246. .agreement-text {
  247. font-size: 24rpx;
  248. color: #666666;
  249. }
  250. .agreement-link {
  251. font-size: 24rpx;
  252. color: #1488DB;
  253. text-decoration: underline;
  254. }
  255. }
  256. }
  257. }
  258. }
  259. </style>