木邻有你前端代码仓库
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.

303 lines
7.0 KiB

1 month ago
  1. <template>
  2. <view class="login-container">
  3. <!-- 背景图 -->
  4. <image class="bg-image" :src="appBg" 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">{{ loginTitle }}</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="loginPolicy"></rich-text>
  52. </view>
  53. </uv-modal>
  54. <uv-modal ref="modalPrivacy" title="个人信息保护指引">
  55. <view class="slot-content">
  56. <rich-text :nodes="loginPrivacy"></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. computed:{
  70. appBg(){
  71. return this.$store.state.configList['config_login_bg'].paramImage
  72. },
  73. loginTitle(){
  74. return this.$store.state.configList['config_login_title'].paramText
  75. },
  76. loginPolicy(){
  77. return this.$store.state.configList['config_login_policy'].paramTextarea
  78. },
  79. loginPrivacy(){
  80. return this.$store.state.configList['config_login_privacy'].paramTextarea
  81. },
  82. },
  83. methods: {
  84. // 切换协议同意状态
  85. toggleAgreement() {
  86. this.isAgreed = !this.isAgreed;
  87. console.log('协议同意状态:', this.isAgreed);
  88. },
  89. // 手机号授权登录
  90. phoneLogin() {
  91. if (!this.isAgreed) {
  92. uni.showToast({
  93. title: '请先同意协议条款',
  94. icon: 'none'
  95. });
  96. return;
  97. }
  98. uni.login({
  99. provider: 'weixin',
  100. success: async (loginRes) => {
  101. const res = await this.$api.login.login({
  102. code: loginRes.code
  103. })
  104. uni.setStorageSync('token', res.result.token)
  105. const userInfo = res.result.userInfo
  106. if (!userInfo.headImage || !userInfo.nickName || !userInfo.phone) {
  107. uni.showToast({
  108. title: '请先完善个人信息',
  109. icon: 'none'
  110. })
  111. setTimeout(() => {
  112. uni.navigateTo({
  113. url: '/subPages/login/userInfo'
  114. })
  115. }, 500)
  116. }else {
  117. uni.showToast({
  118. title: '登录成功',
  119. icon: 'success'
  120. })
  121. setTimeout(() => {
  122. uni.switchTab({
  123. url: '/pages/index/index'
  124. })
  125. }, 500)
  126. }
  127. },
  128. fail: (error) => {
  129. uni.showToast({
  130. title: `${error.errMsg}`,
  131. icon: 'none'
  132. })
  133. }
  134. })
  135. },
  136. // 取消登录
  137. cancelLogin() {
  138. console.log('取消登录');
  139. // 重定向到首页
  140. uni.switchTab({
  141. url: '/pages/index/index'
  142. })
  143. },
  144. // 显示服务协议
  145. showPolicy() {
  146. this.$refs.modalPolicy.open()
  147. },
  148. // 显示隐私条款
  149. showPrivacy() {
  150. this.$refs.modalPrivacy.open()
  151. }
  152. }
  153. }
  154. </script>
  155. <style lang="scss" scoped>
  156. .login-container {
  157. position: relative;
  158. width: 100vw;
  159. height: 100vh;
  160. overflow: hidden;
  161. }
  162. .bg-image {
  163. position: absolute;
  164. top: 0;
  165. left: 0;
  166. width: 100%;
  167. height: 40%;
  168. z-index: 1;
  169. }
  170. .content {
  171. position: relative;
  172. z-index: 2;
  173. height: 100%;
  174. display: flex;
  175. flex-direction: column;
  176. padding: 0 40rpx;
  177. }
  178. .title-section {
  179. flex: 1;
  180. display: flex;
  181. align-items: flex-end;
  182. justify-content: center;
  183. padding: 120rpx;
  184. .login-title{
  185. color: #1488db;
  186. font-size: 48rpx;
  187. font-weight: bold;
  188. position: relative;
  189. }
  190. .login-title::after{
  191. content: '';
  192. position: absolute;
  193. left: 20rpx;
  194. bottom: -8rpx;
  195. width: 100%;
  196. height: 24rpx;
  197. border-radius: 50%;
  198. background: linear-gradient(to bottom, #0085e4, transparent);
  199. }
  200. }
  201. // .welcome-section {
  202. // display: flex;
  203. // justify-content: center;
  204. // margin-bottom: 100rpx;
  205. // .welcome-box {
  206. // border: 2rpx dashed #1488DB;
  207. // border-radius: 10rpx;
  208. // padding: 20rpx 40rpx;
  209. // background: rgba(255, 255, 255, 0.9);
  210. // .welcome-text {
  211. // font-size: 28rpx;
  212. // color: #1488DB;
  213. // font-weight: 500;
  214. // }
  215. // }
  216. // }
  217. .button-section {
  218. flex: 1;
  219. margin-bottom: 60rpx;
  220. align-items: flex-start;
  221. .login-btn {
  222. width: 100%;
  223. height: 88rpx;
  224. border-radius: 44rpx;
  225. display: flex;
  226. align-items: center;
  227. justify-content: center;
  228. margin-bottom: 30rpx;
  229. &.primary {
  230. background: #1488DB;
  231. .btn-text {
  232. color: #ffffff;
  233. font-size: 32rpx;
  234. font-weight: 500;
  235. }
  236. }
  237. &.secondary {
  238. background: rgba(255, 255, 255, 0.9);
  239. border: 2rpx solid #cccccc;
  240. .btn-text {
  241. color: #666666;
  242. font-size: 32rpx;
  243. }
  244. }
  245. }
  246. .agreement-text-container {
  247. margin-top: 40rpx;
  248. .agreement-checkbox-row {
  249. display: flex;
  250. align-items: center;
  251. justify-content: center;
  252. .custom-checkbox {
  253. margin-right: 10rpx;
  254. display: flex;
  255. align-items: center;
  256. }
  257. .agreement-text-content {
  258. flex: 1;
  259. text-align: left;
  260. .agreement-text {
  261. font-size: 24rpx;
  262. color: #666666;
  263. }
  264. .agreement-link {
  265. font-size: 24rpx;
  266. color: #1488DB;
  267. text-decoration: underline;
  268. }
  269. }
  270. }
  271. }
  272. }
  273. </style>