login.vue 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. <template>
  2. <view class="container">
  3. <view class="login-header">
  4. <image class="logo" src="/static/logo.png" mode="aspectFit"></image>
  5. <text class="title">快与慢充电桩</text>
  6. <text class="subtitle">智能视觉零售柜</text>
  7. </view>
  8. <view class="login-content">
  9. <!-- 账号密码登录表单 -->
  10. <view class="form-item">
  11. <input
  12. class="input"
  13. type="number"
  14. placeholder="请输入手机号"
  15. v-model="loginForm.phone"
  16. maxlength="11"
  17. />
  18. </view>
  19. <view class="form-item">
  20. <input
  21. class="input"
  22. type="password"
  23. placeholder="请输入密码"
  24. v-model="loginForm.password"
  25. />
  26. </view>
  27. <button class="login-btn" @click="onPasswordLogin">
  28. 立即登录
  29. </button>
  30. <!-- 微信手机号一键登录 (个人版小程序暂不可用,已注释) -->
  31. <!--
  32. <button
  33. class="login-btn wechat-btn"
  34. open-type="getPhoneNumber"
  35. @getphonenumber="onGetPhoneNumber"
  36. >
  37. 微信手机号一键登录
  38. </button>
  39. -->
  40. <view class="agreement">
  41. 登录即代表您同意<text class="link">《用户协议》</text>和<text class="link">《隐私政策》</text>
  42. </view>
  43. </view>
  44. </view>
  45. </template>
  46. <script setup lang="ts">
  47. import { ref, reactive } from 'vue';
  48. import { onLoad } from '@dcloudio/uni-app';
  49. import { loginByPassword } from '@/api/user';
  50. import { setToken, setUserInfo } from '@/utils/auth';
  51. // import { loginByWechatPhone } from '@/api/user';
  52. const loginForm = reactive({
  53. phone: '',
  54. password: ''
  55. });
  56. // 登录后跳转的页面
  57. const redirectUrl = ref('');
  58. // 页面加载时获取redirect参数
  59. onLoad((options: any) => {
  60. if (options.redirect) {
  61. redirectUrl.value = decodeURIComponent(options.redirect);
  62. }
  63. });
  64. const onPasswordLogin = async () => {
  65. if (!loginForm.phone || loginForm.phone.length !== 11) {
  66. uni.showToast({ title: '请输入正确的手机号', icon: 'none' });
  67. return;
  68. }
  69. if (!loginForm.password) {
  70. uni.showToast({ title: '请输入密码', icon: 'none' });
  71. return;
  72. }
  73. uni.showLoading({ title: '登录中...' });
  74. try {
  75. const res = await loginByPassword({
  76. phone: loginForm.phone,
  77. password: loginForm.password
  78. });
  79. handleLoginSuccess(res);
  80. } catch (error) {
  81. console.error('登录失败', error);
  82. } finally {
  83. uni.hideLoading();
  84. }
  85. };
  86. /**
  87. * 微信手机号快捷登录 (已禁用)
  88. */
  89. /*
  90. const onGetPhoneNumber = async (e: any) => {
  91. if (e.detail.errMsg !== 'getPhoneNumber:ok') {
  92. uni.showToast({
  93. title: '登录失败,请重试',
  94. icon: 'none'
  95. });
  96. return;
  97. }
  98. const { code, encryptedData, iv } = e.detail;
  99. uni.showLoading({ title: '登录中...' });
  100. try {
  101. const res = await loginByWechatPhone({ code, encryptedData, iv });
  102. handleLoginSuccess(res);
  103. } catch (error) {
  104. console.error('登录失败', error);
  105. } finally {
  106. uni.hideLoading();
  107. }
  108. };
  109. */
  110. const handleLoginSuccess = (res: any) => {
  111. // 使用auth工具保存token和用户信息
  112. setToken(res.token);
  113. setUserInfo(res.userInfo);
  114. uni.showToast({
  115. title: '登录成功',
  116. icon: 'success'
  117. });
  118. // 根据redirect参数跳转
  119. setTimeout(() => {
  120. if (redirectUrl.value) {
  121. uni.reLaunch({ url: redirectUrl.value });
  122. } else {
  123. // 返回上一页或首页
  124. const pages = getCurrentPages();
  125. if (pages.length > 1) {
  126. uni.navigateBack();
  127. } else {
  128. uni.reLaunch({ url: '/pages/index/index' });
  129. }
  130. }
  131. }, 1000);
  132. };
  133. </script>
  134. <style lang="scss">
  135. .container {
  136. display: flex;
  137. flex-direction: column;
  138. align-items: center;
  139. padding: 100rpx 40rpx;
  140. min-height: 100vh;
  141. background-color: #fff;
  142. }
  143. .login-header {
  144. display: flex;
  145. flex-direction: column;
  146. align-items: center;
  147. margin-top: 100rpx;
  148. margin-bottom: 150rpx;
  149. .logo {
  150. width: 160rpx;
  151. height: 160rpx;
  152. margin-bottom: 30rpx;
  153. }
  154. .title {
  155. font-size: 40rpx;
  156. font-weight: bold;
  157. color: #333;
  158. margin-bottom: 10rpx;
  159. }
  160. .subtitle {
  161. font-size: 28rpx;
  162. color: #999;
  163. }
  164. }
  165. .login-content {
  166. width: 100%;
  167. .form-item {
  168. width: 100%;
  169. margin-bottom: 30rpx;
  170. .input {
  171. width: 100%;
  172. height: 90rpx;
  173. padding: 0 30rpx;
  174. background-color: #f5f5f5;
  175. border-radius: 45rpx;
  176. font-size: 28rpx;
  177. box-sizing: border-box;
  178. }
  179. }
  180. .login-btn {
  181. width: 100%;
  182. height: 90rpx;
  183. line-height: 90rpx;
  184. background-color: #FFD700;
  185. color: #333;
  186. border-radius: 45rpx;
  187. font-size: 32rpx;
  188. font-weight: bold;
  189. margin-top: 40rpx;
  190. margin-bottom: 40rpx;
  191. border: none;
  192. &::after {
  193. border: none;
  194. }
  195. &.wechat-btn {
  196. background-color: #07c160;
  197. color: #fff;
  198. }
  199. }
  200. .agreement {
  201. font-size: 24rpx;
  202. color: #999;
  203. text-align: center;
  204. .link {
  205. color: #576b95;
  206. }
  207. }
  208. }
  209. </style>