|
|
@@ -1,5 +1,6 @@
|
|
|
<template>
|
|
|
<view class="login-page">
|
|
|
+ <nav-bar title="登录" bgColor="transparent" color="#fff"></nav-bar>
|
|
|
<!-- 顶部渐变装饰区 -->
|
|
|
<view class="hero-bg">
|
|
|
<view class="deco-circle c1"></view>
|
|
|
@@ -30,7 +31,8 @@
|
|
|
<view class="input-icon-wrap">
|
|
|
<uni-icons type="person" size="18" color="#ffc837"></uni-icons>
|
|
|
</view>
|
|
|
- <input class="custom-input" v-model="username" placeholder="请输入登录账号" placeholder-class="input-placeholder" />
|
|
|
+ <input class="custom-input" v-model="username" placeholder="请输入登录账号"
|
|
|
+ placeholder-class="input-placeholder" />
|
|
|
</view>
|
|
|
|
|
|
<!-- 密码输入框 -->
|
|
|
@@ -38,7 +40,8 @@
|
|
|
<view class="input-icon-wrap">
|
|
|
<uni-icons type="locked" size="18" color="#ffc837"></uni-icons>
|
|
|
</view>
|
|
|
- <input class="custom-input" v-model="password" type="password" placeholder="请输入密码" placeholder-class="input-placeholder" />
|
|
|
+ <input class="custom-input" v-model="password" type="password" placeholder="请输入密码"
|
|
|
+ placeholder-class="input-placeholder" />
|
|
|
</view>
|
|
|
|
|
|
<!-- 提示信息 -->
|
|
|
@@ -53,9 +56,9 @@
|
|
|
<label class="agree-label">
|
|
|
<checkbox :checked="checked" color="#ffc837" style="transform: scale(0.7);" />
|
|
|
<text class="agree-text">我已阅读并同意</text>
|
|
|
- <text class="text-link" @click.stop="showAgreement('隐私政策')">《隐私政策》</text>
|
|
|
+ <text class="text-link" @click.stop="showAgreement(2)">《隐私政策》</text>
|
|
|
<text class="agree-text">和</text>
|
|
|
- <text class="text-link" @click.stop="showAgreement('商家托运协议')">《托运协议》</text>
|
|
|
+ <text class="text-link" @click.stop="showAgreement(4)">《托运协议》</text>
|
|
|
</label>
|
|
|
</checkbox-group>
|
|
|
</view>
|
|
|
@@ -68,15 +71,27 @@
|
|
|
<view class="footer-hint">
|
|
|
<text>安全加密 · 保护您的账号信息</text>
|
|
|
</view>
|
|
|
+
|
|
|
+ <!-- 隐私政策/托运协议弹窗 -->
|
|
|
+ <policy-dialog v-model:visible="dialogVisible" :title="dialogTitle" :content="dialogContent"></policy-dialog>
|
|
|
</view>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
import { ref } from 'vue'
|
|
|
+import navBar from '@/components/nav-bar/index.vue'
|
|
|
+import policyDialog from '@/components/policy-dialog/index.vue'
|
|
|
+import { login } from '@/api/auth'
|
|
|
+import { getAgreement } from '@/api/system/agreement'
|
|
|
+import { AgreementType } from '@/enums/agreementType'
|
|
|
+import { DEFAULT_HEADERS } from '@/utils/config'
|
|
|
|
|
|
const username = ref('')
|
|
|
const password = ref('')
|
|
|
const checked = ref(false)
|
|
|
+const dialogVisible = ref(false)
|
|
|
+const dialogTitle = ref('')
|
|
|
+const dialogContent = ref('')
|
|
|
|
|
|
const onClickLeft = () => uni.navigateBack()
|
|
|
|
|
|
@@ -84,7 +99,7 @@ const onCheckChange = () => {
|
|
|
checked.value = !checked.value
|
|
|
}
|
|
|
|
|
|
-const onSubmit = () => {
|
|
|
+const onSubmit = async () => {
|
|
|
if (!username.value) {
|
|
|
uni.showToast({ title: '请填写账号', icon: 'none' })
|
|
|
return
|
|
|
@@ -97,40 +112,240 @@ const onSubmit = () => {
|
|
|
uni.showToast({ title: '请先阅读并勾选协议', icon: 'none' })
|
|
|
return
|
|
|
}
|
|
|
- uni.showToast({ title: '登录成功 (模拟)', icon: 'success' })
|
|
|
- setTimeout(() => {
|
|
|
- uni.reLaunch({ url: '/pages/index/index' })
|
|
|
- }, 1000)
|
|
|
+
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: '登录中...' })
|
|
|
+ const res = await login({
|
|
|
+ userSource: 0,
|
|
|
+ username: username.value,
|
|
|
+ password: password.value,
|
|
|
+ clientId: DEFAULT_HEADERS.clientid,
|
|
|
+ grantType: 'password',
|
|
|
+ source: 1
|
|
|
+ })
|
|
|
+
|
|
|
+ if (res.access_token) {
|
|
|
+ uni.setStorageSync('token', res.access_token)
|
|
|
+ uni.showToast({ title: '登录成功', icon: 'success' })
|
|
|
+ setTimeout(() => {
|
|
|
+ uni.reLaunch({ url: '/pages/index/index' })
|
|
|
+ }, 1000)
|
|
|
+ } else {
|
|
|
+ uni.showToast({ title: '登录异常:未获取到Token', icon: 'none' })
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('Login error:', error)
|
|
|
+ // 注意这里的提示也可以通过request.js自带去提示,这里静默或者输出
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading()
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
-const showAgreement = (name) => {
|
|
|
- uni.showToast({ title: `查看 ${name} 详情 (演示)`, icon: 'none' })
|
|
|
+const showAgreement = async (agreementId) => {
|
|
|
+ try {
|
|
|
+ uni.showLoading({ title: '加载中...' })
|
|
|
+ const res = await getAgreement(agreementId)
|
|
|
+
|
|
|
+ if (res && res.title) {
|
|
|
+ dialogTitle.value = res.title || '协议详情'
|
|
|
+ dialogContent.value = res.content || '暂无内容'
|
|
|
+ dialogVisible.value = true
|
|
|
+ } else {
|
|
|
+ console.warn('接口返回数据格式异常:', res)
|
|
|
+ uni.showToast({ title: '数据格式异常', icon: 'none' })
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ console.error('获取协议失败:', error)
|
|
|
+ uni.showToast({ title: '加载失败,请稍后重试', icon: 'none' })
|
|
|
+ } finally {
|
|
|
+ uni.hideLoading()
|
|
|
+ }
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
-.login-page { min-height: 100vh; background: #f2f3f7; display: flex; flex-direction: column; }
|
|
|
-.hero-bg { background: linear-gradient(150deg, #ffd53f 0%, #ff9500 100%); padding: 0 40rpx 140rpx; position: relative; overflow: hidden; min-height: 560rpx; display: flex; flex-direction: column; justify-content: flex-end; }
|
|
|
-.deco-circle { position: absolute; border-radius: 50%; background: rgba(255, 255, 255, 0.12); }
|
|
|
-.c1 { width: 400rpx; height: 400rpx; top: -160rpx; right: -120rpx; }
|
|
|
-.c2 { width: 260rpx; height: 260rpx; top: 80rpx; left: -100rpx; }
|
|
|
-.c3 { width: 160rpx; height: 160rpx; bottom: 80rpx; right: 80rpx; }
|
|
|
-.back-btn { position: absolute; top: calc(var(--status-bar-height, 44px) + 20rpx); left: 32rpx; width: 72rpx; height: 72rpx; border-radius: 50%; background: rgba(255, 255, 255, 0.25); display: flex; align-items: center; justify-content: center; }
|
|
|
-.hero-content { position: relative; z-index: 2; }
|
|
|
-.logo-wrap { width: 140rpx; height: 140rpx; background: rgba(255, 255, 255, 0.25); border-radius: 44rpx; display: flex; align-items: center; justify-content: center; margin-bottom: 28rpx; }
|
|
|
-.brand-name { display: block; font-size: 52rpx; font-weight: 800; color: #fff; margin-bottom: 8rpx; }
|
|
|
-.brand-desc { display: block; font-size: 28rpx; color: rgba(255, 255, 255, 0.8); letter-spacing: 4rpx; }
|
|
|
-.form-card { background: #fff; border-radius: 56rpx 56rpx 0 0; margin-top: -60rpx; padding: 60rpx 48rpx 40rpx; flex: 1; position: relative; z-index: 10; }
|
|
|
-.form-title { display: block; font-size: 38rpx; font-weight: 700; color: #1a1a1a; margin-bottom: 48rpx; }
|
|
|
-.input-group { display: flex; align-items: center; background: #f8f8f8; border-radius: 28rpx; padding: 8rpx 24rpx; margin-bottom: 28rpx; border: 3rpx solid transparent; }
|
|
|
-.input-icon-wrap { margin-right: 16rpx; flex-shrink: 0; }
|
|
|
-.custom-input { flex: 1; height: 88rpx; font-size: 30rpx; color: #222; background: transparent; }
|
|
|
-.input-placeholder { color: #c0c0c0; }
|
|
|
-.tip-row { display: flex; align-items: center; gap: 10rpx; font-size: 24rpx; color: #aaa; padding: 8rpx 8rpx 24rpx; }
|
|
|
-.agreement-row { margin-bottom: 48rpx; padding: 0 4rpx; }
|
|
|
-.agree-label { display: flex; align-items: center; flex-wrap: wrap; }
|
|
|
-.agree-text { font-size: 24rpx; color: #999; }
|
|
|
-.text-link { font-size: 24rpx; color: #ff9500; }
|
|
|
-.login-btn { width: 100%; height: 104rpx; font-size: 34rpx; font-weight: 700; color: #333; background: linear-gradient(90deg, #ffd53f, #ff9500); border: none; border-radius: 52rpx; letter-spacing: 4rpx; }
|
|
|
-.footer-hint { text-align: center; font-size: 22rpx; color: #bbb; padding: 32rpx 0 60rpx; background: #fff; }
|
|
|
+.login-page {
|
|
|
+ min-height: 100vh;
|
|
|
+ background: #f2f3f7;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-bg {
|
|
|
+ background: linear-gradient(150deg, #ffd53f 0%, #ff9500 100%);
|
|
|
+ padding: 0 40rpx 140rpx;
|
|
|
+ position: relative;
|
|
|
+ overflow: hidden;
|
|
|
+ min-height: 560rpx;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: flex-end;
|
|
|
+ margin-top: calc(-44px - var(--status-bar-height, 44px));
|
|
|
+}
|
|
|
+
|
|
|
+.deco-circle {
|
|
|
+ position: absolute;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: rgba(255, 255, 255, 0.12);
|
|
|
+}
|
|
|
+
|
|
|
+.c1 {
|
|
|
+ width: 400rpx;
|
|
|
+ height: 400rpx;
|
|
|
+ top: -160rpx;
|
|
|
+ right: -120rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.c2 {
|
|
|
+ width: 260rpx;
|
|
|
+ height: 260rpx;
|
|
|
+ top: 80rpx;
|
|
|
+ left: -100rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.c3 {
|
|
|
+ width: 160rpx;
|
|
|
+ height: 160rpx;
|
|
|
+ bottom: 80rpx;
|
|
|
+ right: 80rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.back-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: calc(var(--status-bar-height, 44px) + 20rpx);
|
|
|
+ left: 32rpx;
|
|
|
+ width: 72rpx;
|
|
|
+ height: 72rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: rgba(255, 255, 255, 0.25);
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+}
|
|
|
+
|
|
|
+.hero-content {
|
|
|
+ position: relative;
|
|
|
+ z-index: 2;
|
|
|
+}
|
|
|
+
|
|
|
+.logo-wrap {
|
|
|
+ width: 140rpx;
|
|
|
+ height: 140rpx;
|
|
|
+ background: rgba(255, 255, 255, 0.25);
|
|
|
+ border-radius: 44rpx;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-bottom: 28rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-name {
|
|
|
+ display: block;
|
|
|
+ font-size: 52rpx;
|
|
|
+ font-weight: 800;
|
|
|
+ color: #fff;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.brand-desc {
|
|
|
+ display: block;
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: rgba(255, 255, 255, 0.8);
|
|
|
+ letter-spacing: 4rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.form-card {
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 56rpx 56rpx 0 0;
|
|
|
+ margin-top: -60rpx;
|
|
|
+ padding: 60rpx 48rpx 40rpx;
|
|
|
+ flex: 1;
|
|
|
+ position: relative;
|
|
|
+ z-index: 10;
|
|
|
+}
|
|
|
+
|
|
|
+.form-title {
|
|
|
+ display: block;
|
|
|
+ font-size: 38rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #1a1a1a;
|
|
|
+ margin-bottom: 48rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.input-group {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ background: #f8f8f8;
|
|
|
+ border-radius: 28rpx;
|
|
|
+ padding: 8rpx 24rpx;
|
|
|
+ margin-bottom: 28rpx;
|
|
|
+ border: 3rpx solid transparent;
|
|
|
+}
|
|
|
+
|
|
|
+.input-icon-wrap {
|
|
|
+ margin-right: 16rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.custom-input {
|
|
|
+ flex: 1;
|
|
|
+ height: 88rpx;
|
|
|
+ font-size: 30rpx;
|
|
|
+ color: #222;
|
|
|
+ background: transparent;
|
|
|
+}
|
|
|
+
|
|
|
+.input-placeholder {
|
|
|
+ color: #c0c0c0;
|
|
|
+}
|
|
|
+
|
|
|
+.tip-row {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 10rpx;
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #aaa;
|
|
|
+ padding: 8rpx 8rpx 24rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.agreement-row {
|
|
|
+ margin-bottom: 48rpx;
|
|
|
+ padding: 0 4rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.agree-label {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-wrap: wrap;
|
|
|
+}
|
|
|
+
|
|
|
+.agree-text {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #999;
|
|
|
+}
|
|
|
+
|
|
|
+.text-link {
|
|
|
+ font-size: 24rpx;
|
|
|
+ color: #ff9500;
|
|
|
+}
|
|
|
+
|
|
|
+.login-btn {
|
|
|
+ width: 100%;
|
|
|
+ height: 104rpx;
|
|
|
+ font-size: 34rpx;
|
|
|
+ font-weight: 700;
|
|
|
+ color: #333;
|
|
|
+ background: linear-gradient(90deg, #ffd53f, #ff9500);
|
|
|
+ border: none;
|
|
|
+ border-radius: 52rpx;
|
|
|
+ letter-spacing: 4rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.footer-hint {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #bbb;
|
|
|
+ padding: 32rpx 0 60rpx;
|
|
|
+ background: #fff;
|
|
|
+}
|
|
|
</style>
|