From b7d451c91ec40bee70f23b1e2cf6a8797643faef Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期六, 25 四月 2026 15:18:58 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/master'

---
 app/pages/login/login.vue |  157 +++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 136 insertions(+), 21 deletions(-)

diff --git a/app/pages/login/login.vue b/app/pages/login/login.vue
index 2ba2d47..753391a 100644
--- a/app/pages/login/login.vue
+++ b/app/pages/login/login.vue
@@ -24,7 +24,7 @@
 				<view class="login-card__form">
 					<view v-if="activeTab === 'account'" class="login-card__group">
 						<view class="login-card__field">
-							<input v-model="form.mobile" class="login-card__input" type="number" placeholder="璇疯緭鍏ユ墜鏈哄彿" placeholder-style="color: #c5cad4;" />
+							<input v-model="form.telephone" class="login-card__input" type="number" placeholder="璇疯緭鍏ユ墜鏈哄彿" placeholder-style="color: #c5cad4;" />
 						</view>
 						<view class="login-card__field">
 							<input v-model="form.password" class="login-card__input" password placeholder="璇疯緭鍏ュ瘑鐮�" placeholder-style="color: #c5cad4;" />
@@ -33,19 +33,21 @@
 
 					<view v-else class="login-card__group">
 						<view class="login-card__field">
-							<input v-model="form.mobile" class="login-card__input" type="number" placeholder="璇疯緭鍏ユ墜鏈哄彿" placeholder-style="color: #c5cad4;" />
+							<input v-model="form.telephone" class="login-card__input" type="number" placeholder="璇疯緭鍏ユ墜鏈哄彿" placeholder-style="color: #c5cad4;" />
 						</view>
 						<view class="login-card__field login-card__field--code">
 							<input v-model="form.code" class="login-card__input" type="number" placeholder="璇疯緭鍏ラ獙璇佺爜" placeholder-style="color: #c5cad4;" />
-							<text class="login-card__code-btn">鑾峰彇楠岃瘉鐮�</text>
+							<text class="login-card__code-btn" @click="sendCode">{{ countdown > 0 ? countdown + 's' : '鑾峰彇楠岃瘉鐮�' }}</text>
 						</view>
 					</view>
 
 					<button class="login-card__submit" hover-class="login-card__submit--hover" @click="login">鐧诲綍</button>
 				</view>
 
-				<view class="login-card__agreement">
-					<view class="login-card__agreement-icon"></view>
+				<view class="login-card__agreement" @click="toggleAgreement">
+					<view class="login-card__agreement-icon" :class="{ 'login-card__agreement-icon--checked': isAgreed }">
+						<text v-if="isAgreed" class="login-card__check">鉁�</text>
+					</view>
 					<text class="login-card__agreement-text">鐧诲綍鍗充唬琛ㄦ偍鍚屾剰<text>銆婄敤鎴峰崗璁��</text>鍙�<text>銆婄敤鎴烽殣绉佹斂绛栥��</text></text>
 				</view>
 			</view>
@@ -54,6 +56,8 @@
 </template>
 
 <script>
+	import { mapState } from 'vuex';
+
 	export default {
 		data() {
 			return {
@@ -63,11 +67,22 @@
 					{ label: '楠岃瘉鐮佺櫥褰�', value: 'code' }
 				],
 				form: {
-					mobile: '',
+					telephone: '',
 					password: '',
 					code: ''
-				}
+				},
+				isAgreed: false,
+				countdown: 0,
+				countdownTimer: null
 			};
+		},
+		computed: {
+			...mapState(['token'])
+		},
+		onLoad() {
+			if (this.token) {
+				uni.switchTab({ url: '/pages/index/index' })
+			}
 		},
 		methods: {
 			returnBackgroundImg(value, active) {
@@ -81,10 +96,107 @@
 					return "url('/static/image/login_ic_code_sel@2x.png')"
 				}
 			},
+			toggleAgreement() {
+				this.isAgreed = !this.isAgreed;
+			},
+			sendCode() {
+				if (this.countdown > 0) return;
+				
+				if (!this.form.telephone) {
+					uni.showToast({ title: '璇疯緭鍏ユ墜鏈哄彿', icon: 'none' });
+					return;
+				}
+				if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
+					uni.showToast({ title: '鎵嬫満鍙锋牸寮忎笉姝g‘', icon: 'none' });
+					return;
+				}
+				
+				this.$u.api.sendCode({ telephone: this.form.telephone }).then(res => {
+					if (res.code === 200) {
+						uni.showToast({ title: '楠岃瘉鐮佸凡鍙戦��', icon: 'success' });
+						this.countdown = 60;
+						this.countdownTimer = setInterval(() => {
+							this.countdown--;
+							if (this.countdown <= 0) {
+								clearInterval(this.countdownTimer);
+								this.countdownTimer = null;
+							}
+						}, 1000);
+					} else {
+						uni.showToast({ title: res.msg || '鍙戦�佸け璐�', icon: 'none' });
+					}
+				}).catch(err => {
+					uni.showToast({ title: '鍙戦�佸け璐�', icon: 'none' });
+				});
+			},
 			login() {
-				uni.switchTab({
-					url: '/pages/index/index'
-				})
+				if (!this.isAgreed) {
+					uni.showToast({ title: '璇峰厛鍚屾剰鐢ㄦ埛鍗忚', icon: 'none' });
+					return;
+				}
+				if (this.activeTab === 'account') {
+					if (!this.form.telephone) {
+						uni.showToast({ title: '璇疯緭鍏ユ墜鏈哄彿', icon: 'none' });
+						return;
+					}
+					if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
+						uni.showToast({ title: '鎵嬫満鍙锋牸寮忎笉姝g‘', icon: 'none' });
+						return;
+					}
+					if (!this.form.password) {
+						uni.showToast({ title: '璇疯緭鍏ュ瘑鐮�', icon: 'none' });
+						return;
+					}
+					
+					this.$u.api.login(this.form).then(res => {
+						if (res.code === 200) {
+							this.$store.commit('setToken', res.data.token);
+							this.$u.api.verifyDetail().then(user => {
+								if (user.code === 200) {
+									uni.showToast({ title: '鐧诲綍鎴愬姛', icon: 'success' });
+									this.$store.commit('setUserInfo', user.data);
+									setTimeout(() => {
+										uni.switchTab({ url: '/pages/index/index' });
+									}, 1500);
+								}
+							})
+						}
+					})
+				} else {
+					if (!this.form.telephone) {
+						uni.showToast({ title: '璇疯緭鍏ユ墜鏈哄彿', icon: 'none' });
+						return;
+					}
+					if (!/^1[3-9]\d{9}$/.test(this.form.telephone)) {
+						uni.showToast({ title: '鎵嬫満鍙锋牸寮忎笉姝g‘', icon: 'none' });
+						return;
+					}
+					if (!this.form.code) {
+						uni.showToast({ title: '璇疯緭鍏ラ獙璇佺爜', icon: 'none' });
+						return;
+					}
+					
+					this.$u.api.register({ telephone: this.form.telephone, code: this.form.code }).then(res => {
+						if (res.code === 200) {
+							this.$store.commit('setToken', res.data.token);
+							this.$u.api.verifyDetail().then(user => {
+								if (user.code === 200) {
+									uni.showToast({ title: '鐧诲綍鎴愬姛', icon: 'success' });
+									this.$store.commit('setUserInfo', user.data);
+									setTimeout(() => {
+										uni.switchTab({ url: '/pages/index/index' });
+									}, 1500);
+								}
+							})
+						}
+					})
+				}
+			}
+		},
+		beforeDestroy() {
+			if (this.countdownTimer) {
+				clearInterval(this.countdownTimer);
+				this.countdownTimer = null;
 			}
 		}
 	};
@@ -261,21 +373,24 @@
 			height: 28rpx;
 			margin-top: 8rpx;
 			border-radius: 50%;
-			background: #1f74ff;
+			background: #ffffff;
+			border: 2rpx solid #cccccc;
+			display: flex;
+			align-items: center;
+			justify-content: center;
 
-			&::after {
-				content: '';
-				position: absolute;
-				left: 8rpx;
-				top: 4rpx;
-				width: 9rpx;
-				height: 13rpx;
-				border-right: 3rpx solid #ffffff;
-				border-bottom: 3rpx solid #ffffff;
-				transform: rotate(38deg);
+			&--checked {
+				background: #1f74ff;
+				border-color: #1f74ff;
 			}
 		}
 
+		&__check {
+			font-size: 20rpx;
+			color: #ffffff;
+			font-weight: bold;
+		}
+
 		&__agreement-text {
 			font-size: 24rpx;
 			line-height: 1.6;

--
Gitblit v1.9.3