2025-10-15 16:03:42 +08:00
|
|
|
|
<script lang="ts" setup>
|
2025-10-31 11:29:01 +08:00
|
|
|
|
import { getUserInfo, loginAPI } from '@/api/login'
|
2025-10-15 16:03:42 +08:00
|
|
|
|
import { useAppStore } from '@/store'
|
2026-01-28 15:55:55 +08:00
|
|
|
|
import { getImageFullPath } from '@/utils'
|
2025-10-15 16:03:42 +08:00
|
|
|
|
import CacheManager from '@/utils/CacheManager'
|
|
|
|
|
|
|
2026-02-26 09:39:10 +08:00
|
|
|
|
const { VITE_APP_TITLE } = import.meta.env
|
|
|
|
|
|
|
2025-10-15 16:03:42 +08:00
|
|
|
|
definePage({
|
|
|
|
|
|
// 使用 type: "home" 属性设置首页,其他页面不需要设置,默认为page
|
|
|
|
|
|
type: 'home',
|
|
|
|
|
|
style: {
|
|
|
|
|
|
navigationStyle: 'custom',
|
|
|
|
|
|
},
|
|
|
|
|
|
})
|
|
|
|
|
|
const appStore = useAppStore()
|
|
|
|
|
|
// 获取标题名称
|
|
|
|
|
|
const TITLE_NAME = import.meta.env.VITE_APP_TITLE
|
|
|
|
|
|
// 显示密码
|
|
|
|
|
|
const showMm = ref(false)
|
|
|
|
|
|
// 登录表单数据
|
|
|
|
|
|
const formData = reactive({
|
2025-12-19 17:18:47 +08:00
|
|
|
|
username: '',
|
|
|
|
|
|
password: '',
|
2025-10-15 16:03:42 +08:00
|
|
|
|
})
|
2026-01-28 15:55:55 +08:00
|
|
|
|
const formRef = ref<any>(null)
|
2025-10-15 16:03:42 +08:00
|
|
|
|
// 是否在登录
|
|
|
|
|
|
const isLogin = ref(false)
|
|
|
|
|
|
const notifyRef = ref<any>(null)
|
2026-01-28 15:55:55 +08:00
|
|
|
|
const rules = {
|
|
|
|
|
|
username: [
|
|
|
|
|
|
{
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
message: '请输入用户名',
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
password: [
|
|
|
|
|
|
{
|
|
|
|
|
|
required: true,
|
|
|
|
|
|
message: '请输入密码',
|
|
|
|
|
|
trigger: 'blur',
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
}
|
|
|
|
|
|
const labelStyles = computed(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
fontFamily: 'PingFangSC-Medium',
|
|
|
|
|
|
fontSize: '34rpx',
|
|
|
|
|
|
color: '#000000',
|
|
|
|
|
|
fontWeight: 500,
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
const InputPlaceholderStyle = computed(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
fontFamily: 'PingFangSC-Medium',
|
|
|
|
|
|
fontSize: '28rpx',
|
|
|
|
|
|
color: '#999999',
|
|
|
|
|
|
fontWeight: 400,
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
const inputCustomStyle = computed(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
backgroundColor: '#F5F8FF',
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-10-15 16:03:42 +08:00
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 登录
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function login() {
|
2026-01-28 15:55:55 +08:00
|
|
|
|
const status = await formRef.value.validate()
|
|
|
|
|
|
if (!status) {
|
2025-12-19 17:18:47 +08:00
|
|
|
|
return
|
|
|
|
|
|
}
|
2026-01-28 15:55:55 +08:00
|
|
|
|
|
2025-10-15 16:03:42 +08:00
|
|
|
|
isLogin.value = true
|
2026-01-14 17:31:26 +08:00
|
|
|
|
uni.showLoading({
|
|
|
|
|
|
title: '登录中...',
|
|
|
|
|
|
mask: true,
|
|
|
|
|
|
})
|
2025-10-15 16:03:42 +08:00
|
|
|
|
try {
|
|
|
|
|
|
const token = await loginAPI(formData)
|
|
|
|
|
|
CacheManager.set('token', token)
|
|
|
|
|
|
isLogin.value = false
|
2025-10-31 11:29:01 +08:00
|
|
|
|
const userInfo = await getUserInfo()
|
|
|
|
|
|
appStore.setUserInfo(userInfo) // 获取字典数据
|
2025-10-15 16:03:42 +08:00
|
|
|
|
appStore.setDictData() // 获取字典数据
|
2026-01-14 17:31:26 +08:00
|
|
|
|
|
|
|
|
|
|
setTimeout(() => {
|
2026-01-28 15:55:55 +08:00
|
|
|
|
uni.hideLoading()
|
2026-01-14 17:31:26 +08:00
|
|
|
|
appStore.loginJump()
|
|
|
|
|
|
}, 800)
|
2025-10-15 16:03:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
catch (e) {
|
|
|
|
|
|
isLogin.value = false
|
2026-01-14 17:31:26 +08:00
|
|
|
|
uni.hideLoading()
|
2025-10-15 16:03:42 +08:00
|
|
|
|
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: (e as Error).message || '登录失败,请稍后再试' })
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-02-26 09:39:10 +08:00
|
|
|
|
|
|
|
|
|
|
onShareAppMessage(() => {
|
|
|
|
|
|
return {
|
|
|
|
|
|
title: `欢迎使用${VITE_APP_TITLE}`,
|
|
|
|
|
|
path: '/pages/login/login',
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
2025-10-15 16:03:42 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
2026-01-28 15:55:55 +08:00
|
|
|
|
<view class="container">
|
|
|
|
|
|
<!-- logo -->
|
|
|
|
|
|
<view class="img_container">
|
|
|
|
|
|
<uv-image :src="getImageFullPath('DENGLU_LOGO_IMAGE')" mode="widthFix" width="100%" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<!-- 登录语 -->
|
|
|
|
|
|
<view class="login_text">
|
|
|
|
|
|
<view class="">
|
2025-10-15 16:03:42 +08:00
|
|
|
|
您好,
|
|
|
|
|
|
</view>
|
2026-01-28 15:55:55 +08:00
|
|
|
|
<view>欢迎使用{{ TITLE_NAME }}</view>
|
2025-10-15 16:03:42 +08:00
|
|
|
|
</view>
|
2026-01-28 15:55:55 +08:00
|
|
|
|
<!-- 登录表单 -->
|
|
|
|
|
|
<view class="login_form">
|
|
|
|
|
|
<uv-form
|
|
|
|
|
|
ref="formRef"
|
|
|
|
|
|
label-position="top"
|
|
|
|
|
|
:model="formData"
|
|
|
|
|
|
label-width="150"
|
|
|
|
|
|
:label-style="labelStyles"
|
|
|
|
|
|
:rules="rules"
|
|
|
|
|
|
>
|
|
|
|
|
|
<uv-form-item label="账号" prop="username">
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
v-model="formData.username"
|
|
|
|
|
|
placeholder="请输入账号"
|
|
|
|
|
|
:placeholder-style="InputPlaceholderStyle"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
:custom-style="inputCustomStyle"
|
|
|
|
|
|
border="none"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</uv-form-item>
|
|
|
|
|
|
<uv-form-item label="密码" prop="password">
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
v-model="formData.password"
|
|
|
|
|
|
placeholder="请输入密码"
|
|
|
|
|
|
:password="!showMm"
|
|
|
|
|
|
:placeholder-style="InputPlaceholderStyle"
|
|
|
|
|
|
:custom-style="inputCustomStyle"
|
|
|
|
|
|
border="none"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #suffix>
|
|
|
|
|
|
<uv-icon name="eye" size="20" :color="showMm ? '#36acf6' : '#CCCCCC'" @click="showMm = !showMm" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</uv-input>
|
|
|
|
|
|
</uv-form-item>
|
|
|
|
|
|
</uv-form>
|
|
|
|
|
|
<!-- 登录按钮 -->
|
|
|
|
|
|
<view class="btn_bar">
|
|
|
|
|
|
<uv-button
|
|
|
|
|
|
type="primary"
|
|
|
|
|
|
text="登录"
|
|
|
|
|
|
loading-text="正在登录中..."
|
|
|
|
|
|
:loading="isLogin"
|
|
|
|
|
|
:custom-style="{
|
|
|
|
|
|
backgroundImage: `linear-gradient(135deg, #1089FF 0%, #0F5BFF 100%)`,
|
|
|
|
|
|
borderRadius: '50rpx',
|
|
|
|
|
|
height: '100rpx',
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
}"
|
|
|
|
|
|
:custom-text-style="{
|
|
|
|
|
|
fontSize: '34rpx',
|
|
|
|
|
|
fontFamily: 'PingFangSC-Medium',
|
|
|
|
|
|
}"
|
|
|
|
|
|
@click="login"
|
|
|
|
|
|
/>
|
2025-10-15 16:03:42 +08:00
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
2026-01-28 15:55:55 +08:00
|
|
|
|
|
2025-10-15 16:03:42 +08:00
|
|
|
|
<uv-notify ref="notifyRef" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2026-01-28 15:55:55 +08:00
|
|
|
|
.container {
|
2025-10-15 16:03:42 +08:00
|
|
|
|
width: 100%;
|
|
|
|
|
|
|
2026-01-28 15:55:55 +08:00
|
|
|
|
.img_container {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
top: 0;
|
2025-10-15 16:03:42 +08:00
|
|
|
|
width: 100%;
|
2026-01-28 15:55:55 +08:00
|
|
|
|
z-index: -1;
|
2025-10-15 16:03:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-28 15:55:55 +08:00
|
|
|
|
.login_text {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
left: 40rpx;
|
|
|
|
|
|
top: 210rpx;
|
|
|
|
|
|
font-family: PingFangSC-Medium;
|
|
|
|
|
|
font-size: 36rpx;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
letter-spacing: 0;
|
|
|
|
|
|
line-height: 70rpx;
|
|
|
|
|
|
text-shadow: 0 2px 8px #708eae;
|
|
|
|
|
|
font-weight: 500;
|
|
|
|
|
|
}
|
2025-10-15 16:03:42 +08:00
|
|
|
|
|
2026-01-28 15:55:55 +08:00
|
|
|
|
.login_form {
|
|
|
|
|
|
position: fixed;
|
|
|
|
|
|
padding: 80rpx 60rpx 0 60rpx;
|
|
|
|
|
|
width: calc(100% - 120rpx);
|
|
|
|
|
|
z-index: 2;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
bottom: 0;
|
|
|
|
|
|
top: 448rpx;
|
|
|
|
|
|
background-color: white;
|
|
|
|
|
|
border-radius: 48rpx 48rpx 0 0;
|
2025-10-15 16:03:42 +08:00
|
|
|
|
|
|
|
|
|
|
.btn_bar {
|
2026-01-28 15:55:55 +08:00
|
|
|
|
position: relative;
|
|
|
|
|
|
transform: translateY(100rpx);
|
2025-10-15 16:03:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-01-28 15:55:55 +08:00
|
|
|
|
::v-deep .uv-input__content {
|
|
|
|
|
|
padding: 0 25rpx;
|
|
|
|
|
|
height: 80rpx !important;
|
2025-10-15 16:03:42 +08:00
|
|
|
|
}
|
|
|
|
|
|
</style>
|