|
|
@@ -4,7 +4,7 @@
|
|
|
<!-- Logo -->
|
|
|
<view class="brand">
|
|
|
<view class="brand-mark"></view>
|
|
|
- <text class="brand-name">自助洗车</text>
|
|
|
+ <text class="brand-name">超级进化</text>
|
|
|
<text class="brand-sub">运营管理平台</text>
|
|
|
</view>
|
|
|
|
|
|
@@ -38,6 +38,13 @@
|
|
|
/>
|
|
|
</view>
|
|
|
|
|
|
+ <view class="remember-row" @click="rememberMe = !rememberMe">
|
|
|
+ <view class="remember-check" :class="{ checked: rememberMe }">
|
|
|
+ <text v-if="rememberMe" class="remember-tick">✓</text>
|
|
|
+ </view>
|
|
|
+ <text class="remember-label">记住密码</text>
|
|
|
+ </view>
|
|
|
+
|
|
|
<button class="submit-btn" @click="handleLogin" :disabled="loading">
|
|
|
{{ loading ? '登录中...' : '登录' }}
|
|
|
</button>
|
|
|
@@ -54,6 +61,7 @@ import { storage, showToast } from '../../utils/index.js'
|
|
|
import JSEncrypt from 'jsencrypt'
|
|
|
|
|
|
const loading = ref(false)
|
|
|
+const rememberMe = ref(false)
|
|
|
const loginForm = ref({
|
|
|
mobilePhone: '',
|
|
|
password: ''
|
|
|
@@ -66,6 +74,17 @@ const encryptData = (str) => {
|
|
|
return encryptor.encrypt(str)
|
|
|
}
|
|
|
|
|
|
+const REMEMBER_KEY = 'remembered_login'
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ const saved = storage.get(REMEMBER_KEY)
|
|
|
+ if (saved) {
|
|
|
+ loginForm.value.mobilePhone = saved.mobilePhone || ''
|
|
|
+ loginForm.value.password = saved.password || ''
|
|
|
+ rememberMe.value = true
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
const loadDictionaries = async () => {
|
|
|
await loadDicts()
|
|
|
}
|
|
|
@@ -94,6 +113,15 @@ const handleLogin = async () => {
|
|
|
const res = await login(phone, encryptedPassword)
|
|
|
|
|
|
if (res && res.code === 200) {
|
|
|
+ if (rememberMe.value) {
|
|
|
+ storage.set(REMEMBER_KEY, {
|
|
|
+ mobilePhone: phone,
|
|
|
+ password: loginForm.value.password
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ storage.remove(REMEMBER_KEY)
|
|
|
+ }
|
|
|
+
|
|
|
storage.set('token', res.data.accessToken)
|
|
|
storage.set('userInfo', {
|
|
|
id: res.data.id,
|
|
|
@@ -215,6 +243,42 @@ const handleLogin = async () => {
|
|
|
color: #B0B0B0;
|
|
|
}
|
|
|
|
|
|
+/* Remember Me */
|
|
|
+.remember-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 14rpx;
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.remember-check {
|
|
|
+ width: 36rpx;
|
|
|
+ height: 36rpx;
|
|
|
+ border-radius: 8rpx;
|
|
|
+ border: 2rpx solid #CCCCCC;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ transition: all 0.2s;
|
|
|
+}
|
|
|
+
|
|
|
+.remember-check.checked {
|
|
|
+ background: #C6171E;
|
|
|
+ border-color: #C6171E;
|
|
|
+}
|
|
|
+
|
|
|
+.remember-tick {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #FFFFFF;
|
|
|
+ font-weight: 700;
|
|
|
+ line-height: 1;
|
|
|
+}
|
|
|
+
|
|
|
+.remember-label {
|
|
|
+ font-size: 26rpx;
|
|
|
+ color: #666666;
|
|
|
+}
|
|
|
+
|
|
|
/* Button */
|
|
|
.submit-btn {
|
|
|
width: 100%;
|
|
|
@@ -226,6 +290,9 @@ const handleLogin = async () => {
|
|
|
font-size: 30rpx;
|
|
|
font-weight: 600;
|
|
|
margin-top: 16rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
}
|
|
|
|