Просмотр исходного кода

feat:修改登录样式,修改个人寄件跳转路径

颜琼丽 2 дней назад
Родитель
Сommit
ff85831b3e

+ 31 - 14
jd_logistics-app/pages/index/components/PersonalExpressDialog.vue

@@ -13,17 +13,15 @@
 				<!-- 顺丰选项 -->
 				<view class="express-option sf-option" :class="{ 'selected': selectedExpress === '顺丰' }"
 					@click="selectExpress('顺丰')">
-					<image class="option-icon" src="/static/img/icon-logo-sf.png"
-						mode="aspectFit" />
+					<image class="option-icon" src="/static/img/icon-logo-sf.png" mode="aspectFit" />
 					<text class="option-text">顺丰物流</text>
-					
+
 				</view>
 
 				<!-- 京东选项 -->
 				<view class="express-option jd-option" :class="{ 'selected': selectedExpress === '京东' }"
 					@click="selectExpress('京东')">
-					<image class="option-icon" src="/static/img/icon-logo-jd.png"
-						mode="aspectFit" />
+					<image class="option-icon" src="/static/img/icon-logo-jd.png" mode="aspectFit" />
 					<text class="option-text">京东物流</text>
 				</view>
 			</view>
@@ -67,7 +65,9 @@
 				fail: () => {}
 			})
 		}
-	}, { immediate: true }) // immediate 确保组件初始化时如果 visible 为 true 也能正确隐藏
+	}, {
+		immediate: true
+	}) // immediate 确保组件初始化时如果 visible 为 true 也能正确隐藏
 
 	// 组件卸载时恢复 tabBar 显示(避免状态残留)
 	onUnmounted(() => {
@@ -78,15 +78,31 @@
 
 	const selectExpress = (company) => {
 		selectedExpress.value = company
-	
+
 		emit('select', company)
 		emit('update:visible', false)
 		// 延时关闭并传递选择结果
 		setTimeout(() => {
-			const url = encodeURIComponent(company == '京东' ? "https://www.jdl.com/" : "https://www.sf-express.com/chn/sc")
+			// const url = encodeURIComponent(company == '京东' ? "https://rjsd.mychery.com/jd.html" : "https://rjsd.mychery.com/sf.html")
+			const url = encodeURIComponent(company == '京东' ? "https://rjsd.mychery.com/jd" : "https://rjsd.mychery.com/sf")
 			uni.navigateTo({
 				url: '/pages/webView/webView?title=个人寄件&url=' + url
 			})
+			
+			return
+
+			const appId = company == '京东' ? "wx73247c7819d61796" : "wxd4185d00bf7e08ac"
+			wx.navigateToMiniProgram({
+				appId: appId, // 必填
+				envVersion: 'release', // 打开正式版
+				success(res) {
+					console.log("跳转成功", res);
+				},
+				fail(err) {
+					console.error("跳转失败", err);
+				}
+			});
+
 			selectedExpress.value = ''
 		}, 50)
 	}
@@ -140,14 +156,14 @@
 			border-radius: 32rpx;
 			border: 2rpx solid #C1D5FF;
 		}
-		
-		
+
+
 		.option-icon {
 			width: 88rpx;
 			height: 88rpx;
 			margin-bottom: 8rpx;
 		}
-		
+
 		.option-text {
 			font-size: 28rpx;
 			font-weight: 500;
@@ -158,8 +174,9 @@
 
 	.popup-footer {
 		margin-top: 44rpx;
-		
-		
+		margin-bottom: 44rpx;
+
+
 		.cancel-btn {
 			width: 100%;
 			height: 88rpx;
@@ -172,7 +189,7 @@
 			text-align: center;
 			font-style: normal;
 			text-transform: none;
-		
+
 		}
 	}
 

+ 1 - 1
jd_logistics-app/pages/index/index.vue

@@ -111,7 +111,7 @@
 	  }
 	 if (item.linkUrl.startsWith('http://') || item.linkUrl.startsWith('https://')) {
 		uni.navigateTo({
-		  url: `/pages/webview/webview?url=${encodeURIComponent(item.linkUrl)}`
+		  url: `/pages/webView/webView?url=${encodeURIComponent(item.linkUrl)}`
 		})
 	  } else {
 		uni.showToast({ title: '链接格式不支持', icon: 'none' })

+ 319 - 0
jd_logistics-app/pages/mine/login.vue

@@ -0,0 +1,319 @@
+<!-- pages/mine/login.vue -->
+<template>
+	<view class="login-page">
+		<!-- 标题图片占位区 -->
+		<view class="logo-placeholder">
+			<image src="/static/img/logo.png"></image>
+		</view>
+
+		<!-- 账号密码登录区域(根据模式显示) -->
+		<template v-if="loginMode === 'password'">
+			<!-- 手机号输入框 -->
+			<view class="input-wrapper">
+				<input v-model="phone" type="number" maxlength="11" class="input-field" placeholder="请输入帐号"
+					placeholder-style="color: #999;" confirm-type="done" />
+			</view>
+
+			<!-- 密码输入框 -->
+			<view class="input-wrapper">
+				<input v-model="password" :password="true" maxlength="20" class="input-field" placeholder="请输入密码"
+					placeholder-style="color: #999;" confirm-type="done" />
+			</view>
+		</template>
+
+		<!-- 协议同意行 -->
+		<view class="agreement-row">
+			<checkbox-group @change="onAgreeChange">
+				<checkbox :value="'agree'" :checked="agree" class="agree-checkbox" color="#007AFF">
+					我已阅读并同意
+				</checkbox>
+			</checkbox-group>
+			<text class="agree-text"></text>
+			<text class="link-text" @click.stop="toUserAgreement">《用户协议》</text>
+			<text class="link-text" @click.stop="toPrivacyPolicy">《隐私政策》</text>
+		</view>
+
+		<!-- 密码登录按钮(密码模式显示) -->
+		<button v-if="loginMode === 'password'" class="btn login-btn" @click="handlePhoneLogin">登录</button>
+
+		<!-- 微信快捷登录按钮(快捷模式显示) -->
+		<button v-if="loginMode === 'quick'" class="btn wechat-btn" open-type="getPhoneNumber"
+			@getphonenumber="handleWechatLogin" :loading="wechatLoading" :disabled="wechatLoading">快捷登录</button>
+
+		<!-- 登录方式切换链接 - 放在按钮正下方 -->
+		<view class="toggle-mode" @click="toggleMode">
+			{{ loginMode === 'quick' ? '账号密码登录' : '快捷登录' }}
+		</view>
+	</view>
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import { quickLogin, telEncrypt } from '@/utils/util.js'
+import { getLoginByPwdApi } from '@/api/user.js'
+import { useAppStore } from '@/stores/app'
+
+const appStore = useAppStore()
+const phone = ref('')          // 手机号
+const password = ref('')       // 密码
+const agree = ref(false)       // 协议勾选状态
+const wechatLoading = ref(false) // 微信登录loading
+const loginMode = ref('quick')  // 登录模式:quick-快捷登录,password-密码登录
+
+// 复选框组变化处理
+const onAgreeChange = (e) => {
+	agree.value = e.detail.value.includes('agree')
+}
+
+// 切换登录模式
+const toggleMode = () => {
+	loginMode.value = loginMode.value === 'quick' ? 'password' : 'quick'
+}
+
+// 手机号密码登录
+const handlePhoneLogin = async () => {
+	if (!phone.value) {
+		uni.showToast({ title: '请输入帐号', icon: 'none' })
+		return
+	}
+	if (!password.value) {
+		uni.showToast({ title: '请输入密码', icon: 'none' })
+		return
+	}
+	if (!agree.value) {
+		uni.showToast({ title: '请先同意用户协议和隐私政策', icon: 'none' })
+		return
+	}
+	const params = {
+		username: phone.value,
+		password: password.value
+	}
+	try {
+		const res = await getLoginByPwdApi(params)
+		if (res.code == 200) {
+			uni.showToast({ title: '登录成功~', icon: 'none' })
+			appStore.UPDATE_TOKEN(res.data.access_token || res.data);
+			setTimeout(() => {
+				uni.navigateBack()
+			}, 200)
+		} else {
+			uni.showToast({ title: res.msg, icon: 'none' })
+		}
+	} catch (err) {
+		console.error('登录接口异常', err)
+		uni.showToast({ title: err, icon: 'none' })
+	}
+}
+
+// 微信快捷登录
+const handleWechatLogin = async (e) => {
+	// 检查协议同意
+	if (!agree.value) {
+		uni.showToast({ title: '请先同意用户协议和隐私政策', icon: 'none' })
+		return
+	}
+	if (wechatLoading.value) return
+	wechatLoading.value = true
+	uni.showLoading({ title: '登录中...', mask: true })
+
+	try {
+		await quickLogin(e, {
+			onSuccess: (result) => {
+				console.log('登录成功', result)
+				if (result.data) {
+					appStore.UPDATE_USERINFO(result.data)
+				}
+				uni.hideLoading()
+				uni.showToast({ title: '登录成功', icon: 'success' })
+				setTimeout(() => {
+					uni.navigateBack()
+				}, 1500)
+			},
+			onFail: (error) => {
+				console.error('登录失败', error)
+				uni.hideLoading()
+				let msg = error.message || '登录失败'
+				if (error.type === 'auth_denied') {
+					msg = '您拒绝了授权,无法登录'
+					uni.showModal({
+						title: '提示',
+						content: '需要手机号授权才能正常使用,请点击右上角菜单,选择「重新进入小程序」后重新授权',
+						showCancel: false
+					})
+				} else {
+					uni.showToast({ title: msg, icon: 'none' })
+				}
+			}
+		})
+	} catch (err) {
+		console.error('quickLogin 异常', err)
+		uni.hideLoading()
+		uni.showToast({ title: '登录异常', icon: 'none' })
+	} finally {
+		wechatLoading.value = false
+	}
+}
+
+// 跳转用户协议
+const toUserAgreement = () => {
+	uni.navigateTo({
+		url: '/pages/webView/webView?title=用户协议&url=' + encodeURIComponent('https://rjsd.mychery.com/user_agreement.html')
+	});
+}
+
+// 跳转隐私政策
+const toPrivacyPolicy = () => {
+	uni.navigateTo({
+		url: '/pages/webView/webView?title=隐私政策&url=' + encodeURIComponent('https://rjsd.mychery.com/privacy_policy.html')
+	});
+}
+</script>
+
+<style scoped lang="less">
+/* 页面容器 */
+.login-page {
+	width: 100%;
+	min-height: 100vh;
+	background: linear-gradient(135deg, #CFE9FF 0%, #F5F7FA 50.86%);
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	padding: 40rpx 80rpx;
+	box-sizing: border-box;
+}
+
+.logo-placeholder {
+	width: 100%;
+	margin: 120rpx 0rpx 90rpx 0rpx;
+	display: flex;
+	justify-content: center;
+
+	image {
+		width: 425rpx;
+		height: 100rpx;
+	}
+}
+
+/* 通用输入框包装 */
+.input-wrapper {
+	width: 100%;
+	padding: 24rpx 32rpx;
+	height: 88rpx;
+	background: #FFFFFF;
+	border-radius: 44rpx;
+	box-sizing: border-box;
+	display: flex;
+	align-items: center;
+	transition: border-color 0.2s;
+	margin-bottom: 32rpx;
+
+	&:focus-within {
+		border-color: #007AFF;
+	}
+}
+
+.input-field {
+	flex: 1;
+	font-size: 28rpx;
+	color: #333;
+	background-color: transparent;
+	height: 88rpx;
+	line-height: 88rpx;
+	padding: 0;
+}
+
+/* 协议行 */
+.agreement-row {
+	width: 100%;
+	display: flex;
+	align-items: center;
+	flex-wrap: wrap;
+	margin-bottom: 20rpx;
+	font-size: 28rpx;
+	color: #4a5568;
+
+	checkbox-group {
+		display: flex;
+		align-items: center;
+	}
+}
+
+.agree-checkbox {
+	transform: scale(0.9);
+	margin-right: 8rpx;
+}
+
+/* 覆盖 checkbox 样式 */
+::v-deep .agree-checkbox .wx-checkbox-input,
+::v-deep .agree-checkbox .uni-checkbox-input {
+	border-radius: 50%;
+	width: 36rpx;
+	height: 36rpx;
+	background-color: #ffffff;
+	border: 2rpx solid #ccc;
+}
+
+::v-deep .agree-checkbox .wx-checkbox-input.wx-checkbox-input-checked,
+::v-deep .agree-checkbox .uni-checkbox-input.uni-checkbox-input-checked {
+	background-color: #007AFF !important;
+	border-color: #007AFF !important;
+}
+
+::v-deep .agree-checkbox .wx-checkbox-input.wx-checkbox-input-checked::before,
+::v-deep .agree-checkbox .uni-checkbox-input.uni-checkbox-input-checked::before {
+	color: #ffffff !important;
+}
+
+.link-text {
+	color: #007AFF;
+	display: inline-block;
+}
+
+/* 登录方式切换链接 - 按钮正下方 */
+.toggle-mode {
+	width: 100%;
+	text-align: right;
+	color: #007AFF;
+	font-size: 28rpx;
+	margin-top: 30rpx;        /* 与按钮保持适当间距 */
+	margin-bottom: 0;
+	padding: 10rpx 0;
+}
+
+/* 按钮基础样式 */
+.btn {
+	width: 100%;
+	height: 88rpx;
+	border-radius: 44rpx;
+	font-size: 32rpx;
+	font-weight: bold;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border: none;
+	color: #ffffff;
+	margin-bottom: 32rpx;
+	box-shadow: 0 8rpx 20rpx rgba(0, 122, 255, 0.25);
+	transition: opacity 0.2s;
+
+	&.login-btn {
+		background-color: #007AFF;
+	}
+
+	&.wechat-btn {
+		background-color: #2DAB6C;
+	}
+}
+
+/* 重置按钮默认样式 */
+button {
+	padding: 0;
+	margin: 0;
+	line-height: 1.5;
+	background: none;
+	box-shadow: none;
+}
+button::after {
+	border: none;
+}
+</style>

BIN
jd_logistics-app/static/img/translte-3.png