2026-03-03 17:10:57 +08:00

231 lines
5.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<script lang="ts" setup>
import { getUserInfo, loginAPI } from '@/api/login'
import { useAppStore } from '@/store'
import { getImageFullPath } from '@/utils'
import CacheManager from '@/utils/CacheManager'
const { VITE_APP_TITLE } = import.meta.env
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({
username: '',
password: '',
})
const formRef = ref<any>(null)
// 是否在登录
const isLogin = ref(false)
const notifyRef = ref<any>(null)
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',
}
})
/**
* 登录
*/
async function login() {
const status = await formRef.value.validate()
if (!status) {
return
}
isLogin.value = true
uni.showLoading({
title: '登录中...',
mask: true,
})
try {
const token = await loginAPI(formData)
CacheManager.set('token', token)
isLogin.value = false
const userInfo = await getUserInfo()
appStore.setUserInfo(userInfo) // 获取字典数据
appStore.setDictData() // 获取字典数据
setTimeout(() => {
uni.hideLoading()
appStore.loginJump()
}, 800)
}
catch (e) {
isLogin.value = false
uni.hideLoading()
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: (e as Error).message || '登录失败,请稍后再试' })
}
}
onShareAppMessage(() => {
return {
title: `欢迎使用${VITE_APP_TITLE}`,
path: '/pages/login/login',
}
})
</script>
<template>
<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="">
您好
</view>
<view>欢迎使用{{ TITLE_NAME }}</view>
</view>
<!-- 登录表单 -->
<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"
/>
</view>
</view>
<uv-notify ref="notifyRef" />
</view>
</template>
<style lang="scss" scoped>
.container {
width: 100%;
.img_container {
position: fixed;
top: 0;
width: 100%;
z-index: -1;
}
.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;
}
.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;
.btn_bar {
position: relative;
transform: translateY(100rpx);
}
}
}
::v-deep .uv-input__content {
padding: 0 25rpx;
height: 80rpx !important;
}
</style>