login.vue 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <view class="container">
  3. <!-- 顶部 Banner 区域 -->
  4. <view class="banner-area">
  5. <image class="banner-img" src="/static/header.png" mode="widthFix"></image>
  6. </view>
  7. <!-- 白色内容卡片 -->
  8. <view class="content-card">
  9. <!-- 悬浮 Logo -->
  10. <view class="logo-wrapper">
  11. <image class="logo-img" src="/static/logo.png" mode="widthFix"></image>
  12. </view>
  13. <!-- 登录 Tab 切换 -->
  14. <view class="tabs">
  15. <view
  16. class="tab-item"
  17. :class="{ active: currentTab === 0 }"
  18. @click="currentTab = 0"
  19. >
  20. <text class="tab-text">免密登录</text>
  21. <view class="tab-indicator" v-if="currentTab === 0"></view>
  22. </view>
  23. <view class="divider"></view>
  24. <view
  25. class="tab-item"
  26. :class="{ active: currentTab === 1 }"
  27. @click="currentTab = 1"
  28. >
  29. <text class="tab-text">密码登录</text>
  30. <view class="tab-indicator" v-if="currentTab === 1"></view>
  31. </view>
  32. </view>
  33. <!-- 表单区域 -->
  34. <view class="form-area">
  35. <!-- 手机号 (通用) -->
  36. <view class="input-group">
  37. <view class="area-code">
  38. <text>+86</text>
  39. <text class="arrow">﹀</text>
  40. </view>
  41. <input
  42. class="input"
  43. type="number"
  44. placeholder="手机号"
  45. placeholder-style="color: #ccc"
  46. v-model="mobile"
  47. maxlength="11"
  48. />
  49. </view>
  50. <!-- 免密登录: 验证码 -->
  51. <view class="input-group" v-if="currentTab === 0">
  52. <input
  53. class="input"
  54. type="number"
  55. placeholder="验证码"
  56. placeholder-style="color: #ccc"
  57. v-model="code"
  58. maxlength="6"
  59. />
  60. <view class="get-code-btn" @click="getVerifyCode">
  61. <text class="code-text">{{ countDown > 0 ? `${countDown}s后重试` : '获取验证码' }}</text>
  62. </view>
  63. </view>
  64. <!-- 密码登录: 密码框 -->
  65. <view class="input-group" v-if="currentTab === 1">
  66. <input
  67. class="input"
  68. :password="!showPassword"
  69. type="text"
  70. placeholder="请输入密码"
  71. placeholder-style="color: #ccc"
  72. v-model="password"
  73. />
  74. <view class="eye-icon" @click="showPassword = !showPassword">
  75. <template v-if="showPassword">
  76. <!-- 睁眼线框图标 -->
  77. <svg class="svg-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  78. <path d="M12 4.5C7 4.5 2.73 7.61 1 12C2.73 16.39 7 19.5 12 19.5C17 19.5 21.27 16.39 23 12C21.27 7.61 17 4.5 12 4.5ZM12 17C9.24 17 7 14.76 7 12C7 9.24 9.24 7 12 7C14.76 7 17 9.24 17 12C17 14.76 14.76 17 12 17ZM12 9C10.34 9 9 10.34 9 12C9 13.66 10.34 15 12 15C13.66 15 15 13.66 15 12C15 10.34 13.66 9 12 9Z" fill="#CCCCCC"/>
  79. </svg>
  80. </template>
  81. <template v-else>
  82. <!-- 闭眼线框图标 (带睫毛) -->
  83. <svg class="svg-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
  84. <path d="M12 7C7 7 2.73 10.11 1 14.5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  85. <path d="M23 14.5C21.27 10.11 17 7 12 7" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  86. <path d="M12 7V4" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  87. <path d="M16 8L18 5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  88. <path d="M8 8L6 5" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  89. <path d="M20 10L22 8" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  90. <path d="M4 10L2 8" stroke="#CCCCCC" stroke-width="2" stroke-linecap="round"/>
  91. </svg>
  92. </template>
  93. </view>
  94. </view>
  95. <!-- 忘记密码 -->
  96. <view class="forgot-pwd" v-if="currentTab === 1">
  97. <text @click="goToForgotPwd">忘记密码?</text>
  98. </view>
  99. <!-- 登录按钮 -->
  100. <button class="login-btn" @click="handleLogin">登 录</button>
  101. <!-- 协议 -->
  102. <view class="agreement">
  103. <view class="checkbox" :class="{ checked: isAgreed }" @click="isAgreed = !isAgreed">
  104. <text v-if="isAgreed" class="check-mark">✓</text>
  105. </view>
  106. <text class="agree-text">
  107. 我已经阅读并同意 <text class="link" @click.stop="showAgreement(1)">《用户服务协议》</text> 和 <text class="link" @click.stop="showAgreement(2)">《隐私政策》</text>
  108. </text>
  109. </view>
  110. </view>
  111. <!-- 底部招募入口 (固定底部) -->
  112. <view class="footer-recruit" @click="goToRecruit">
  113. <view class="recruit-badge">
  114. <!-- 旗帜线框图标 -->
  115. <svg class="svg-icon flag-icon" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" style="width:30rpx; height:30rpx;">
  116. <path d="M4 14V4H18L17 9L18 14H4Z" stroke="#FF5722" stroke-width="2" stroke-linejoin="round"/>
  117. <path d="M4 22V14" stroke="#FF5722" stroke-width="2" stroke-linecap="round"/>
  118. </svg>
  119. <text> 宠宝履约者招募</text>
  120. </view>
  121. </view>
  122. <!-- 协议弹窗 组件化 -->
  123. <privacy-popup
  124. :visible="showAgreementModal"
  125. :title="agreementTitle"
  126. :content="agreementContent"
  127. @close="showAgreementModal = false"
  128. >
  129. </privacy-popup>
  130. </view>
  131. </view>
  132. </template>
  133. <script>
  134. // 使用脚本文件
  135. import logic from './logic.js';
  136. import PrivacyPopup from '@/components/privacy-popup/privacy-popup.vue';
  137. export default {
  138. ...logic,
  139. components: {
  140. PrivacyPopup
  141. }
  142. }
  143. </script>
  144. <style>
  145. /* 引用样式文件 */
  146. @import './style.css';
  147. </style>