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'
|
|
|
|
|
|
import CacheManager from '@/utils/CacheManager'
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
})
|
|
|
|
|
|
// 是否在登录
|
|
|
|
|
|
const isLogin = ref(false)
|
|
|
|
|
|
|
|
|
|
|
|
const notifyRef = ref<any>(null)
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
* 登录
|
|
|
|
|
|
*/
|
|
|
|
|
|
async function login() {
|
2025-12-19 17:18:47 +08:00
|
|
|
|
if (formData.username.trim() === '') {
|
|
|
|
|
|
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: '请输入用户名' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
if (formData.password.trim() === '') {
|
|
|
|
|
|
notifyRef.value?.show({ safeAreaInsetTop: true, type: 'error', message: '请输入密码' })
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
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)
|
2026-01-14 17:31:26 +08:00
|
|
|
|
uni.hideLoading()
|
2025-10-15 16:03:42 +08:00
|
|
|
|
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(() => {
|
|
|
|
|
|
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 || '登录失败,请稍后再试' })
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<view class="img-a">
|
|
|
|
|
|
<image src="@/static/head.png" class="imgStyle" />
|
|
|
|
|
|
<view class="t-b">
|
|
|
|
|
|
您好,
|
|
|
|
|
|
<br>
|
|
|
|
|
|
欢迎使用{{ TITLE_NAME }}
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="login-view">
|
|
|
|
|
|
<view class="t-login">
|
|
|
|
|
|
<form class="cl">
|
|
|
|
|
|
<view class="t-a">
|
|
|
|
|
|
<text class="txt">用户名</text>
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
v-model="formData.username" placeholder="请输入账号" border="bottom"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
:custom-style="{
|
|
|
|
|
|
paddingLeft: 0,
|
|
|
|
|
|
}"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="t-a">
|
|
|
|
|
|
<text class="txt">密码</text>
|
|
|
|
|
|
<uv-input
|
|
|
|
|
|
v-model="formData.password" placeholder="请输入密码" border="bottom"
|
|
|
|
|
|
:password="!showMm"
|
|
|
|
|
|
:custom-style="{
|
|
|
|
|
|
paddingLeft: 0,
|
|
|
|
|
|
}"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #suffix>
|
|
|
|
|
|
<uv-icon name="eye" size="20" :color="showMm ? '#36acf6' : '#333333'" @click="showMm = !showMm" />
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</uv-input>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</form>
|
|
|
|
|
|
<view class="btn_bar">
|
|
|
|
|
|
<uv-button type="primary" text="登录" loading-text="正在登录" :loading="isLogin" @click="login()" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<uv-notify ref="notifyRef" />
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
|
|
|
|
.img-a {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 600rpx;
|
|
|
|
|
|
background-size: 100%;
|
|
|
|
|
|
|
|
|
|
|
|
.imgStyle {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.t-b {
|
|
|
|
|
|
position: absolute;
|
|
|
|
|
|
top: 100rpx;
|
|
|
|
|
|
left: 0;
|
|
|
|
|
|
z-index: 2;
|
|
|
|
|
|
text-align: left;
|
|
|
|
|
|
font-size: 42rpx;
|
|
|
|
|
|
color: #ffffff;
|
|
|
|
|
|
padding: 130rpx 0 0 70rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
line-height: 70rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.login-view {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin-top: -200rpx;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
border-radius: 8% 8% 0% 0;
|
|
|
|
|
|
|
|
|
|
|
|
.t-login {
|
|
|
|
|
|
width: 600rpx;
|
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
|
font-size: 28rpx;
|
|
|
|
|
|
padding-top: 80rpx;
|
|
|
|
|
|
|
|
|
|
|
|
.t-a {
|
|
|
|
|
|
position: relative;
|
|
|
|
|
|
margin-bottom: 40rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
.btn_bar {
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
margin-top: 100rpx;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
txt {
|
|
|
|
|
|
font-size: 32rpx;
|
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
|
color: #333333;
|
|
|
|
|
|
}
|
|
|
|
|
|
.cl {
|
|
|
|
|
|
zoom: 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|